@mohasinac/appkit 2.7.58 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/filters/filter-load-options.d.ts +4 -5
- package/dist/_internal/server/features/auctions/og.js +8 -32
- package/dist/_internal/server/features/blog/og.js +10 -49
- package/dist/_internal/server/features/checkout/actions.js +6 -0
- package/dist/_internal/server/features/classified/og.js +9 -51
- package/dist/_internal/server/features/digital-code/actions.d.ts +11 -0
- package/dist/_internal/server/features/digital-code/actions.js +30 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +1 -0
- package/dist/_internal/server/features/digital-code/index.js +1 -0
- package/dist/_internal/server/features/digital-code/og.js +9 -51
- package/dist/_internal/server/features/events/og.js +10 -49
- package/dist/_internal/server/features/item-requests/data.d.ts +17 -0
- package/dist/_internal/server/features/item-requests/data.js +20 -0
- package/dist/_internal/server/features/item-requests/index.d.ts +2 -0
- package/dist/_internal/server/features/item-requests/index.js +2 -0
- package/dist/_internal/server/features/item-requests/og.d.ts +40 -0
- package/dist/_internal/server/features/item-requests/og.js +136 -0
- package/dist/_internal/server/features/live/actions.d.ts +5 -0
- package/dist/_internal/server/features/live/actions.js +24 -0
- package/dist/_internal/server/features/live/index.d.ts +1 -0
- package/dist/_internal/server/features/live/index.js +1 -0
- package/dist/_internal/server/features/live/og.js +9 -51
- package/dist/_internal/server/features/media/contextGuards.js +19 -8
- package/dist/_internal/server/features/pre-orders/og.js +8 -32
- package/dist/_internal/server/features/prize-draws/data.d.ts +17 -0
- package/dist/_internal/server/features/prize-draws/data.js +20 -0
- package/dist/_internal/server/features/prize-draws/index.d.ts +2 -0
- package/dist/_internal/server/features/prize-draws/index.js +2 -0
- package/dist/_internal/server/features/prize-draws/og.d.ts +30 -0
- package/dist/_internal/server/features/prize-draws/og.js +50 -0
- package/dist/_internal/server/features/products/og.js +8 -33
- package/dist/_internal/server/features/scams/og.js +1 -1
- package/dist/_internal/server/features/seo/og-layout.d.ts +42 -0
- package/dist/_internal/server/features/seo/og-layout.js +69 -0
- package/dist/_internal/server/features/stores/og.js +8 -41
- package/dist/_internal/server/features/sublisting-categories/og.js +11 -42
- package/dist/_internal/shared/actions/bulk-helpers.d.ts +3 -0
- package/dist/_internal/shared/actions/bulk-helpers.js +19 -0
- package/dist/_internal/shared/config/schema.d.ts +4 -4
- package/dist/client.d.ts +13 -6
- package/dist/client.js +9 -3
- package/dist/configs/next.js +11 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/notification-types.d.ts +20 -0
- package/dist/constants/notification-types.js +37 -0
- package/dist/constants/pagination-presets.d.ts +39 -0
- package/dist/constants/pagination-presets.js +38 -0
- package/dist/errors/messages.d.ts +0 -4
- package/dist/errors/messages.js +0 -4
- package/dist/features/account/components/AddressesIndexListing.js +3 -4
- package/dist/features/account/components/UserOffersPanel.js +1 -1
- package/dist/features/account/components/UserSidebar.js +14 -10
- package/dist/features/account/components/UserSupportView.d.ts +1 -2
- package/dist/features/account/components/UserSupportView.js +9 -1
- package/dist/features/admin/actions/admin-actions.js +16 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +2 -3
- package/dist/features/admin/components/AdminAllEventEntriesView.js +50 -89
- package/dist/features/admin/components/AdminBidsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBidsView.js +64 -104
- package/dist/features/admin/components/AdminBlogView.d.ts +3 -7
- package/dist/features/admin/components/AdminBlogView.js +53 -88
- package/dist/features/admin/components/AdminBrandEditorView.js +14 -17
- package/dist/features/admin/components/AdminBrandsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBrandsView.js +85 -89
- package/dist/features/admin/components/AdminBundlesView.js +68 -130
- package/dist/features/admin/components/AdminCarouselView.d.ts +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +22 -70
- package/dist/features/admin/components/AdminCartsView.d.ts +2 -3
- package/dist/features/admin/components/AdminCartsView.js +39 -89
- package/dist/features/admin/components/AdminCategoriesView.d.ts +3 -3
- package/dist/features/admin/components/AdminCategoriesView.js +97 -96
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -6
- package/dist/features/admin/components/AdminClassifiedView.d.ts +3 -0
- package/dist/features/admin/components/AdminClassifiedView.js +44 -0
- package/dist/features/admin/components/AdminContactView.d.ts +2 -2
- package/dist/features/admin/components/AdminContactView.js +105 -130
- package/dist/features/admin/components/AdminCouponEditorView.js +14 -17
- package/dist/features/admin/components/AdminCouponsView.d.ts +3 -6
- package/dist/features/admin/components/AdminCouponsView.js +69 -97
- package/dist/features/admin/components/AdminDigitalCodesView.d.ts +3 -0
- package/dist/features/admin/components/AdminDigitalCodesView.js +51 -0
- package/dist/features/admin/components/AdminFaqEditorView.js +14 -17
- package/dist/features/admin/components/AdminFaqsView.d.ts +4 -4
- package/dist/features/admin/components/AdminFaqsView.js +79 -86
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -9
- package/dist/features/admin/components/AdminFeaturesView.d.ts +2 -3
- package/dist/features/admin/components/AdminFeaturesView.js +57 -70
- package/dist/features/admin/components/AdminGroupedListingsView.d.ts +3 -0
- package/dist/features/admin/components/AdminGroupedListingsView.js +43 -0
- package/dist/features/admin/components/AdminHistoryView.d.ts +2 -3
- package/dist/features/admin/components/AdminHistoryView.js +35 -52
- package/dist/features/admin/components/AdminListingScaffold.d.ts +2 -2
- package/dist/features/admin/components/AdminListingScaffold.js +3 -3
- package/dist/features/admin/components/AdminLiveView.d.ts +3 -0
- package/dist/features/admin/components/AdminLiveView.js +50 -0
- package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -2
- package/dist/features/admin/components/AdminNewsletterView.js +68 -108
- package/dist/features/admin/components/AdminNotificationsView.d.ts +2 -3
- package/dist/features/admin/components/AdminNotificationsView.js +67 -99
- package/dist/features/admin/components/AdminOrderEditorView.js +10 -10
- package/dist/features/admin/components/AdminOrdersView.d.ts +2 -3
- package/dist/features/admin/components/AdminOrdersView.js +93 -113
- package/dist/features/admin/components/AdminPayoutsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPayoutsView.js +51 -97
- package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +41 -83
- package/dist/features/admin/components/AdminProductEditorView.js +3 -7
- package/dist/features/admin/components/AdminProductsView.d.ts +4 -4
- package/dist/features/admin/components/AdminProductsView.js +166 -167
- package/dist/features/admin/components/AdminReturnRequestsView.d.ts +1 -1
- package/dist/features/admin/components/AdminReturnRequestsView.js +64 -66
- package/dist/features/admin/components/AdminReviewsView.d.ts +3 -7
- package/dist/features/admin/components/AdminReviewsView.js +94 -116
- package/dist/features/admin/components/AdminScammersView.d.ts +2 -3
- package/dist/features/admin/components/AdminScammersView.js +53 -103
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSessionsView.js +62 -95
- package/dist/features/admin/components/AdminStoreAddressesView.d.ts +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +39 -53
- package/dist/features/admin/components/AdminStoreEditorView.js +21 -8
- package/dist/features/admin/components/AdminStoresView.d.ts +2 -3
- package/dist/features/admin/components/AdminStoresView.js +67 -105
- package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +29 -49
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +17 -20
- package/dist/features/admin/components/AdminSupportTicketDetailView.d.ts +10 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +191 -5
- package/dist/features/admin/components/AdminSupportTicketsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +65 -102
- package/dist/features/admin/components/AdminTeamView.d.ts +2 -2
- package/dist/features/admin/components/AdminTeamView.js +42 -85
- package/dist/features/admin/components/AdminUserEditorView.d.ts +11 -1
- package/dist/features/admin/components/AdminUserEditorView.js +80 -6
- package/dist/features/admin/components/AdminUsersView.d.ts +2 -3
- package/dist/features/admin/components/AdminUsersView.js +108 -106
- package/dist/features/admin/components/AdminViewCards.d.ts +1 -1
- package/dist/features/admin/components/AdminWishlistsView.d.ts +2 -3
- package/dist/features/admin/components/AdminWishlistsView.js +36 -62
- package/dist/features/admin/components/DataListingView.d.ts +122 -0
- package/dist/features/admin/components/DataListingView.js +66 -0
- package/dist/features/admin/components/index.d.ts +10 -4
- package/dist/features/admin/components/index.js +6 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +23 -17
- package/dist/features/admin/constants/filter-tabs.js +21 -17
- package/dist/features/admin/hooks/useAdminListing.d.ts +59 -0
- package/dist/features/admin/hooks/useAdminListing.js +71 -0
- package/dist/features/admin/schemas/firestore.js +6 -7
- package/dist/features/auctions/server.d.ts +0 -1
- package/dist/features/auctions/server.js +0 -1
- package/dist/features/auth/actions/realtime-token-actions.js +1 -1
- package/dist/features/auth/repository/user.repository.js +1 -1
- package/dist/features/auth/schemas/firestore.d.ts +1 -0
- package/dist/features/blog/components/BlogIndexListing.js +3 -6
- package/dist/features/cart/repository/cart.repository.d.ts +4 -1
- package/dist/features/cart/repository/cart.repository.js +12 -0
- package/dist/features/categories/components/CategoriesIndexListing.js +3 -6
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -2
- package/dist/features/checkout/index.d.ts +1 -1
- package/dist/features/events/components/AdminEventsView.d.ts +3 -3
- package/dist/features/events/components/AdminEventsView.js +50 -86
- package/dist/features/events/components/EventOfferCard.d.ts +19 -0
- package/dist/features/events/components/EventOfferCard.js +29 -0
- package/dist/features/events/components/EventRaffleEntryForm.d.ts +25 -0
- package/dist/features/events/components/EventRaffleEntryForm.js +37 -0
- package/dist/features/events/components/EventRafflesSection.d.ts +1 -4
- package/dist/features/events/components/EventRafflesSection.js +17 -6
- package/dist/features/events/components/EventSaleBanner.d.ts +21 -0
- package/dist/features/events/components/EventSaleBanner.js +18 -0
- package/dist/features/events/components/EventsIndexListing.js +3 -4
- package/dist/features/events/components/index.d.ts +6 -0
- package/dist/features/events/components/index.js +4 -0
- package/dist/features/events/repository/event-entry.repository.d.ts +5 -0
- package/dist/features/events/repository/event-entry.repository.js +7 -0
- package/dist/features/filters/AsyncFacetSection.d.ts +1 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +4 -1
- package/dist/features/homepage/components/AnnouncementBar.js +51 -4
- package/dist/features/homepage/components/FAQSection.d.ts +0 -5
- package/dist/features/homepage/components/MarketplaceHomepageView.d.ts +3 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
- package/dist/features/homepage/components/index.d.ts +1 -1
- package/dist/features/homepage/components/index.js +1 -1
- package/dist/features/homepage/lib/live-stats.js +1 -1
- package/dist/features/homepage/lib/section-renderer.d.ts +2 -2
- package/dist/features/homepage/lib/section-renderer.js +2 -2
- package/dist/features/homepage/schemas/firestore.d.ts +0 -2
- package/dist/features/layout/index.d.ts +0 -2
- package/dist/features/layout/index.js +0 -1
- package/dist/features/orders/repository/orders.repository.d.ts +0 -1
- package/dist/features/orders/repository/orders.repository.js +0 -1
- package/dist/features/orders/server.d.ts +1 -1
- package/dist/features/orders/server.js +1 -1
- package/dist/features/pre-orders/server.d.ts +0 -1
- package/dist/features/pre-orders/server.js +0 -1
- package/dist/features/products/components/GroupSettingsPanel.js +65 -49
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.d.ts +1 -4
- package/dist/features/products/components/PrizeDrawsSection.js +17 -6
- package/dist/features/products/components/PrizeRevealModal.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.d.ts +11 -0
- package/dist/features/products/components/ProductCardMetadataSection.js +25 -0
- package/dist/features/products/components/ProductDetailPageView.js +3 -1
- package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
- package/dist/features/products/components/ProductGradingTab.d.ts +13 -0
- package/dist/features/products/components/ProductGradingTab.js +25 -0
- package/dist/features/products/components/ProductGrid.js +14 -2
- package/dist/features/products/components/ProductTabsShell.d.ts +5 -1
- package/dist/features/products/components/ProductTabsShell.js +6 -1
- package/dist/features/products/components/index.d.ts +4 -0
- package/dist/features/products/components/index.js +3 -0
- package/dist/features/products/constants/action-defs.d.ts +5 -0
- package/dist/features/products/constants/action-defs.js +52 -32
- package/dist/features/products/constants/sieve.d.ts +24 -4
- package/dist/features/products/constants/sieve.js +20 -11
- package/dist/features/products/repository/products.repository.d.ts +0 -2
- package/dist/features/products/repository/products.repository.js +0 -2
- package/dist/features/products/schemas/firestore.d.ts +17 -0
- package/dist/features/products/schemas/product-features.validators.d.ts +2 -2
- package/dist/features/products/schemas/product-templates.d.ts +2 -4
- package/dist/features/products/server.d.ts +1 -1
- package/dist/features/products/server.js +1 -1
- package/dist/features/products/types/index.d.ts +4 -0
- package/dist/features/promotions/components/CouponCard.js +5 -5
- package/dist/features/promotions/components/CouponsIndexListing.js +3 -2
- package/dist/features/promotions/server.d.ts +0 -1
- package/dist/features/promotions/server.js +0 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +3 -4
- package/dist/features/reviews/repository/reviews.repository.d.ts +0 -1
- package/dist/features/reviews/repository/reviews.repository.js +0 -1
- package/dist/features/reviews/server.d.ts +1 -1
- package/dist/features/reviews/server.js +1 -1
- package/dist/features/search/api/route.js +44 -1
- package/dist/features/search/components/Search.js +2 -0
- package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
- package/dist/features/search/hooks/useNavSuggestions.js +31 -4
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/SellerAddressesView.js +10 -20
- package/dist/features/seller/components/SellerAuctionsView.d.ts +3 -3
- package/dist/features/seller/components/SellerAuctionsView.js +67 -106
- package/dist/features/seller/components/SellerBidsView.js +6 -6
- package/dist/features/seller/components/SellerBundlesView.js +72 -105
- package/dist/features/seller/components/SellerClassifiedView.js +74 -105
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.d.ts +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +51 -96
- package/dist/features/seller/components/SellerDigitalCodesView.js +70 -103
- package/dist/features/seller/components/SellerGroupedListingsView.js +34 -54
- package/dist/features/seller/components/SellerLiveView.js +70 -99
- package/dist/features/seller/components/SellerOffersPanel.js +1 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOffersView.js +37 -70
- package/dist/features/seller/components/SellerOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +10 -24
- package/dist/features/seller/components/SellerPayoutMethodsView.js +12 -24
- package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +34 -69
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +55 -97
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +55 -97
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +3 -6
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -2
- package/dist/features/seller/components/SellerProductsView.js +24 -32
- package/dist/features/seller/components/SellerShippingConfigsView.js +12 -24
- package/dist/features/seller/components/SellerSidebar.d.ts +0 -4
- package/dist/features/seller/components/SellerSidebar.js +0 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +15 -34
- package/dist/features/seller/components/SellerTemplatesView.js +27 -43
- package/dist/features/seller/components/SellersListView.d.ts +1 -2
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.d.ts +5 -0
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.js +2 -8
- package/dist/features/seller/components/index.d.ts +0 -3
- package/dist/features/seller/components/index.js +0 -2
- package/dist/features/seller/server.d.ts +0 -1
- package/dist/features/seller/server.js +0 -1
- package/dist/features/shell/FormShell.d.ts +1 -1
- package/dist/features/shell/FormShell.js +4 -1
- package/dist/features/shell/field-groups/ImageFieldGroup.d.ts +18 -0
- package/dist/features/shell/field-groups/ImageFieldGroup.js +15 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.d.ts +22 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.d.ts +35 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.d.ts +40 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.js +16 -0
- package/dist/features/shell/field-groups/index.d.ts +13 -0
- package/dist/features/shell/field-groups/index.js +9 -0
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/stores/components/StoreCapabilitiesGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreFinanceGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreHeader.js +2 -1
- package/dist/features/stores/components/StoreListingsGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreOrdersGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreReviewsListing.js +3 -4
- package/dist/features/stores/components/StoreScopedSearch.d.ts +16 -0
- package/dist/features/stores/components/StoreScopedSearch.js +27 -0
- package/dist/features/stores/components/StoreSettingsGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoresIndexListing.js +3 -4
- package/dist/features/stores/server.d.ts +0 -1
- package/dist/features/stores/server.js +0 -1
- package/dist/features/support/schemas/firestore.d.ts +22 -1
- package/dist/features/support/schemas/firestore.js +10 -0
- package/dist/features/wishlist/server.d.ts +0 -1
- package/dist/features/wishlist/server.js +0 -1
- package/dist/index.d.ts +11 -33
- package/dist/index.js +17 -62
- package/dist/next/routing/route-map.d.ts +8 -0
- package/dist/next/routing/route-map.js +4 -0
- package/dist/react/contexts/SessionContext.d.ts +2 -0
- package/dist/react/contexts/SessionContext.js +2 -0
- package/dist/react/hooks/useEntityDelete.d.ts +15 -0
- package/dist/react/hooks/useEntityDelete.js +39 -0
- package/dist/react/hooks/useListingTypeFlags.d.ts +32 -0
- package/dist/react/hooks/useListingTypeFlags.js +19 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/repositories/index.d.ts +3 -3
- package/dist/repositories/index.js +3 -3
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/pii-redact.d.ts +8 -0
- package/dist/security/pii-redact.js +10 -1
- package/dist/seed/grouped-listings-seed-data.d.ts +4 -0
- package/dist/seed/products-preorders-seed-data.d.ts +4 -0
- package/dist/seed/products-prize-draws-seed-data.js +3 -0
- package/dist/seed/site-settings-seed-data.js +5 -5
- package/dist/seed/sub-listings-seed-data.d.ts +4 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +4 -0
- package/dist/styles.css +54 -395
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/BaseListingCard.d.ts +10 -0
- package/dist/ui/components/BaseListingCard.js +17 -1
- package/dist/ui/components/DetailPageGallery.d.ts +32 -0
- package/dist/ui/components/DetailPageGallery.js +47 -0
- package/dist/ui/components/DetailPageHero.d.ts +30 -0
- package/dist/ui/components/DetailPageHero.js +22 -0
- package/dist/ui/components/DetailPageTabs.d.ts +34 -0
- package/dist/ui/components/DetailPageTabs.js +38 -0
- package/dist/ui/components/HorizontalScroller.style.css +15 -2
- package/dist/ui/components/ListingFilterDrawer.d.ts +10 -0
- package/dist/ui/components/ListingFilterDrawer.js +8 -0
- package/dist/ui/components/ListingLayout.d.ts +11 -2
- package/dist/ui/components/ListingLayout.js +12 -6
- package/dist/ui/components/PaginatedSelect.d.ts +66 -0
- package/dist/ui/components/PaginatedSelect.js +201 -0
- package/dist/ui/components/PaginatedSelect.style.css +254 -0
- package/dist/ui/components/Semantic.d.ts +0 -4
- package/dist/ui/components/Semantic.js +0 -2
- package/dist/ui/components/SettingsSection.d.ts +47 -0
- package/dist/ui/components/SettingsSection.js +38 -0
- package/dist/ui/components/index.style.css +1 -4
- package/dist/ui/index.d.ts +14 -14
- package/dist/ui/index.js +7 -7
- package/dist/utils/id-generators.d.ts +1 -18
- package/dist/utils/id-generators.js +51 -18
- package/dist/validation/schemas.d.ts +25 -0
- package/dist/validation/schemas.js +28 -0
- package/package.json +1 -1
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
3
|
-
import { useState, useCallback } from "react";
|
|
4
|
-
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
|
-
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
6
|
-
import { BulkActionBar, ListingToolbar, Pagination } from "../../../ui";
|
|
7
|
-
import { useBottomActions } from "../../layout";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
3
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
4
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
const [view, setView] = useState("table");
|
|
22
|
-
const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
|
|
23
|
-
const [searchInput, setSearchInput] = useState(table.get("q") || "");
|
|
24
|
-
const commitSearch = useCallback(() => {
|
|
25
|
-
table.set("q", searchInput.trim());
|
|
26
|
-
}, [searchInput, table]);
|
|
27
|
-
const resetAll = useCallback(() => {
|
|
28
|
-
table.setMany({ q: "", sort: "" });
|
|
29
|
-
setSearchInput("");
|
|
30
|
-
}, [table]);
|
|
31
|
-
const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT;
|
|
32
|
-
const { rows, total, isLoading, errorMessage } = useAdminListingData({
|
|
5
|
+
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
6
|
+
import { toRecordArray, toRelativeDate, toStringValue, } from "../hooks/useAdminListingData";
|
|
7
|
+
import { DataListingView } from "./DataListingView";
|
|
8
|
+
export function AdminSublistingCategoriesView({ onBulkDelete, }) {
|
|
9
|
+
const config = {
|
|
10
|
+
portal: "admin",
|
|
11
|
+
title: "Sub-listing Categories",
|
|
12
|
+
searchPlaceholder: "Search sub-listing categories…",
|
|
13
|
+
emptyLabel: "No sub-listing categories found",
|
|
14
|
+
filterKeys: [],
|
|
15
|
+
defaultSort: "name",
|
|
33
16
|
queryKey: ["admin", "sublisting-categories", "listing"],
|
|
34
17
|
endpoint: ADMIN_ENDPOINTS.SUBLISTING_CATEGORIES,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
18
|
+
sortOptions: [
|
|
19
|
+
{ value: "name", label: "Name A–Z" },
|
|
20
|
+
{ value: "-name", label: "Name Z–A" },
|
|
21
|
+
{ value: "-productCount", label: "Most listings" },
|
|
22
|
+
{ value: "-createdAt", label: "Newest" },
|
|
23
|
+
],
|
|
39
24
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
40
25
|
id: toStringValue(item.id, `sc-${index}`),
|
|
41
26
|
primary: toStringValue(item.name, "Untitled"),
|
|
@@ -49,20 +34,15 @@ export function AdminSublistingCategoriesView({ onBulkDelete }) {
|
|
|
49
34
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
50
35
|
})),
|
|
51
36
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
];
|
|
64
|
-
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
65
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { searchValue: searchInput, searchPlaceholder: "Search sub-listing categories\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => {
|
|
66
|
-
table.set("sort", v);
|
|
67
|
-
}, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), selection.selectedCount > 0 && bulkActions.length > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-error-surface px-4 py-3 text-sm text-error dark:border-red-900/60", children: errorMessage })), _jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No sub-listing categories found" })] })] }));
|
|
37
|
+
buildFilters: () => undefined,
|
|
38
|
+
buildBulkActions: onBulkDelete
|
|
39
|
+
? (selection) => [
|
|
40
|
+
buildBulkAction(ACTIONS.ADMIN["delete-sublisting-category"], async () => {
|
|
41
|
+
await onBulkDelete(selection.selectedIds);
|
|
42
|
+
selection.clearSelection();
|
|
43
|
+
}),
|
|
44
|
+
]
|
|
45
|
+
: undefined,
|
|
46
|
+
};
|
|
47
|
+
return _jsx(DataListingView, { config: config });
|
|
68
48
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Form, Input, StackedViewShell, useToast, } from "../../../ui";
|
|
5
|
+
import { Button, ConfirmDeleteModal, Form, Input, StackedViewShell, useToast, } from "../../../ui";
|
|
6
6
|
import { FieldInput, FormShellContext, useFormShellState } from "../../../ui/forms";
|
|
7
7
|
import { ImageUpload } from "../../media/upload/ImageUpload";
|
|
8
8
|
import { useMediaUpload } from "../../media";
|
|
@@ -15,6 +15,7 @@ export function AdminSublistingCategoryEditorView({ categoryId, onSaved, onDelet
|
|
|
15
15
|
const [itemCode, setItemCode] = React.useState("");
|
|
16
16
|
const [description, setDescription] = React.useState("");
|
|
17
17
|
const [coverImage, setCoverImage] = React.useState("");
|
|
18
|
+
const [deleteConfirmOpen, setDeleteConfirmOpen] = React.useState(false);
|
|
18
19
|
const categoryQuery = useQuery({
|
|
19
20
|
queryKey: ["admin", "sublisting-category", categoryId],
|
|
20
21
|
queryFn: async () => {
|
|
@@ -69,22 +70,18 @@ export function AdminSublistingCategoryEditorView({ categoryId, onSaved, onDelet
|
|
|
69
70
|
const { upload } = useMediaUpload();
|
|
70
71
|
const isSubmitting = saveMutation.isPending || categoryQuery.isLoading;
|
|
71
72
|
const { shellCtx, setFieldError, clearErrors } = useFormShellState();
|
|
72
|
-
return (_jsx(StackedViewShell, { portal: "admin", ...rest, title: isEdit ? "Edit Sub-listing Category" : "New Sub-listing Category", sections: [
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
deleteMutation.mutate();
|
|
87
|
-
}
|
|
88
|
-
}, children: "Delete" }))] })] }, "sc-editor-form") }, "sc-ctx"),
|
|
89
|
-
] }));
|
|
73
|
+
return (_jsxs(_Fragment, { children: [_jsx(StackedViewShell, { portal: "admin", ...rest, title: isEdit ? "Edit Sub-listing Category" : "New Sub-listing Category", sections: [
|
|
74
|
+
_jsx(FormShellContext.Provider, { value: shellCtx, children: _jsxs(Form, { onSubmit: (e) => {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
clearErrors();
|
|
77
|
+
if (!name.trim()) {
|
|
78
|
+
setFieldError("name", "Category name is required");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
saveMutation.mutate();
|
|
82
|
+
}, className: "space-y-4", children: [_jsxs("div", { className: "grid sm:grid-cols-2 gap-4", children: [_jsx(FieldInput, { name: "name", label: "Category name", value: name, onChange: (v) => setName(v), required: true, placeholder: "e.g. Base Set Charizard 108/120" }), _jsx(Input, { label: "Item code", value: itemCode, onChange: (e) => setItemCode(e.target.value), placeholder: "e.g. PSA 10, 108/120, STH", helperText: "Grade, card number, or series code. Optional." })] }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Brief description shown on the public category page" }), _jsx(ImageUpload, { label: "Cover image", currentImage: coverImage, onUpload: (file) => upload(file, "sublisting-categories", true, {
|
|
83
|
+
type: "category-image",
|
|
84
|
+
name: name || "sublisting",
|
|
85
|
+
}), onChange: setCoverImage }), _jsxs("div", { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !name || isSubmitting, children: isEdit ? "Save changes" : "Create category" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteConfirmOpen(true), children: "Delete" }))] })] }, "sc-editor-form") }, "sc-ctx"),
|
|
86
|
+
] }), deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Sublisting Category", message: "Delete this category? All linked listings will be unlinked. This cannot be undone.", onConfirm: () => { deleteMutation.mutate(); setDeleteConfirmOpen(false); }, onClose: () => setDeleteConfirmOpen(false), isDeleting: deleteMutation.isPending }))] }));
|
|
90
87
|
}
|
|
@@ -5,6 +5,13 @@ interface TicketMessageClient {
|
|
|
5
5
|
body?: string;
|
|
6
6
|
createdAt?: string;
|
|
7
7
|
}
|
|
8
|
+
interface RelatedPartiesClient {
|
|
9
|
+
userId?: string;
|
|
10
|
+
storeId?: string;
|
|
11
|
+
orderId?: string;
|
|
12
|
+
productId?: string;
|
|
13
|
+
bidId?: string;
|
|
14
|
+
}
|
|
8
15
|
export interface AdminSupportTicketDetailViewProps {
|
|
9
16
|
open: boolean;
|
|
10
17
|
onClose: () => void;
|
|
@@ -18,6 +25,8 @@ export interface AdminSupportTicketDetailViewProps {
|
|
|
18
25
|
messages?: TicketMessageClient[];
|
|
19
26
|
internalNotes?: string;
|
|
20
27
|
orderId?: string;
|
|
28
|
+
/** ST-6 — current relatedParties snapshot from the ticket document. */
|
|
29
|
+
relatedParties?: RelatedPartiesClient;
|
|
21
30
|
}
|
|
22
|
-
export declare function AdminSupportTicketDetailView({ open, onClose, ticketId, subject, userDisplayName, category, currentStatus, currentPriority, description, messages, internalNotes, orderId, }: AdminSupportTicketDetailViewProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function AdminSupportTicketDetailView({ open, onClose, ticketId, subject, userDisplayName, category, currentStatus, currentPriority, description, messages, internalNotes, orderId, relatedParties, }: AdminSupportTicketDetailViewProps): import("react/jsx-runtime").JSX.Element;
|
|
23
32
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Div, FormActions, Select, SideDrawer, Text, useToast, } from "../../../ui";
|
|
5
|
+
import { Button, Div, FormActions, Input, Row, Select, SideDrawer, Text, Toggle, useToast, } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
const STATUS_OPTIONS = [
|
|
@@ -30,28 +30,46 @@ const ROLE_LABEL = {
|
|
|
30
30
|
support: "Support",
|
|
31
31
|
admin: "Admin",
|
|
32
32
|
};
|
|
33
|
-
export function AdminSupportTicketDetailView({ open, onClose, ticketId, subject, userDisplayName, category, currentStatus, currentPriority, description, messages = [], internalNotes, orderId, }) {
|
|
33
|
+
export function AdminSupportTicketDetailView({ open, onClose, ticketId, subject, userDisplayName, category, currentStatus, currentPriority, description, messages = [], internalNotes, orderId, relatedParties, }) {
|
|
34
34
|
const queryClient = useQueryClient();
|
|
35
35
|
const { showToast } = useToast();
|
|
36
36
|
const [status, setStatus] = React.useState(currentStatus ?? "open");
|
|
37
37
|
const [priority, setPriority] = React.useState(currentPriority ?? "normal");
|
|
38
38
|
const [notes, setNotes] = React.useState(internalNotes ?? "");
|
|
39
39
|
const [replyBody, setReplyBody] = React.useState("");
|
|
40
|
+
// ST-6 — local edits for the linked-parties panel
|
|
41
|
+
const [parties, setParties] = React.useState(relatedParties ?? {});
|
|
40
42
|
React.useEffect(() => {
|
|
41
43
|
if (open) {
|
|
42
44
|
setStatus(currentStatus ?? "open");
|
|
43
45
|
setPriority(currentPriority ?? "normal");
|
|
44
46
|
setNotes(internalNotes ?? "");
|
|
45
47
|
setReplyBody("");
|
|
48
|
+
setParties(relatedParties ?? {});
|
|
46
49
|
}
|
|
47
|
-
}, [open, currentStatus, currentPriority, internalNotes]);
|
|
50
|
+
}, [open, currentStatus, currentPriority, internalNotes, relatedParties]);
|
|
48
51
|
const invalidate = () => queryClient.invalidateQueries({ queryKey: ["admin", "support-tickets"] });
|
|
52
|
+
const cleanedParties = React.useMemo(() => {
|
|
53
|
+
const out = {};
|
|
54
|
+
if (parties.userId?.trim())
|
|
55
|
+
out.userId = parties.userId.trim();
|
|
56
|
+
if (parties.storeId?.trim())
|
|
57
|
+
out.storeId = parties.storeId.trim();
|
|
58
|
+
if (parties.orderId?.trim())
|
|
59
|
+
out.orderId = parties.orderId.trim();
|
|
60
|
+
if (parties.productId?.trim())
|
|
61
|
+
out.productId = parties.productId.trim();
|
|
62
|
+
if (parties.bidId?.trim())
|
|
63
|
+
out.bidId = parties.bidId.trim();
|
|
64
|
+
return out;
|
|
65
|
+
}, [parties]);
|
|
49
66
|
const updateMutation = useMutation({
|
|
50
67
|
mutationFn: async () => {
|
|
51
68
|
await apiClient.patch(ADMIN_ENDPOINTS.SUPPORT_TICKET_BY_ID(ticketId), {
|
|
52
69
|
status,
|
|
53
70
|
priority,
|
|
54
71
|
internalNotes: notes || undefined,
|
|
72
|
+
relatedParties: Object.keys(cleanedParties).length > 0 ? cleanedParties : undefined,
|
|
55
73
|
});
|
|
56
74
|
},
|
|
57
75
|
onSuccess: () => {
|
|
@@ -77,7 +95,175 @@ export function AdminSupportTicketDetailView({ open, onClose, ticketId, subject,
|
|
|
77
95
|
showToast(err?.message ?? "Failed to send reply.", "error");
|
|
78
96
|
},
|
|
79
97
|
});
|
|
98
|
+
// ST-4 — Apply Store Change action (only relevant for store_change_request)
|
|
99
|
+
const [storeStatus, setStoreStatus] = React.useState("active");
|
|
100
|
+
const [storeIsVerified, setStoreIsVerified] = React.useState(false);
|
|
101
|
+
const [storeIsFeatured, setStoreIsFeatured] = React.useState(false);
|
|
102
|
+
const linkedStoreId = parties.storeId?.trim();
|
|
103
|
+
const isStoreChangeRequest = category === "store_change_request";
|
|
104
|
+
const applyStoreChange = useMutation({
|
|
105
|
+
mutationFn: async () => {
|
|
106
|
+
if (!linkedStoreId)
|
|
107
|
+
throw new Error("No linked store on this ticket.");
|
|
108
|
+
await apiClient.patch(ADMIN_ENDPOINTS.STORE_BY_ID(linkedStoreId), {
|
|
109
|
+
storeStatus,
|
|
110
|
+
isVerified: storeIsVerified,
|
|
111
|
+
isFeatured: storeIsFeatured,
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
onSuccess: () => {
|
|
115
|
+
showToast("Store change applied.", "success");
|
|
116
|
+
// Append an internal note marking the action; non-fatal if it fails.
|
|
117
|
+
apiClient
|
|
118
|
+
.patch(ADMIN_ENDPOINTS.SUPPORT_TICKET_BY_ID(ticketId), {
|
|
119
|
+
internalNotes: (notes ? notes + "\n" : "") +
|
|
120
|
+
`[${new Date().toISOString()}] Applied store change to ${linkedStoreId}: status=${storeStatus}, verified=${storeIsVerified}, featured=${storeIsFeatured}`,
|
|
121
|
+
})
|
|
122
|
+
.catch(() => { });
|
|
123
|
+
invalidate();
|
|
124
|
+
},
|
|
125
|
+
onError: (err) => {
|
|
126
|
+
showToast(err?.message ?? "Failed to apply store change.", "error");
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
// ST-3 — Modify Order Items panel (fetches current items on demand, lets
|
|
130
|
+
// admin edit quantity per line + remove lines, then PATCHes the order).
|
|
131
|
+
const [orderItemsOpen, setOrderItemsOpen] = React.useState(false);
|
|
132
|
+
const [orderItems, setOrderItems] = React.useState([]);
|
|
133
|
+
const linkedOrderId = parties.orderId?.trim() || orderId;
|
|
134
|
+
const isOrderModificationRequest = category === "order_modification_request" || category === "order_issue";
|
|
135
|
+
const loadOrderItems = useMutation({
|
|
136
|
+
mutationFn: async () => {
|
|
137
|
+
if (!linkedOrderId)
|
|
138
|
+
throw new Error("No linked order on this ticket.");
|
|
139
|
+
const res = await apiClient.get(ADMIN_ENDPOINTS.ORDER_BY_ID(linkedOrderId));
|
|
140
|
+
const items = Array.isArray(res?.items) ? res.items : [];
|
|
141
|
+
setOrderItems(items.map((it) => ({
|
|
142
|
+
productId: String(it.productId ?? ""),
|
|
143
|
+
productTitle: String(it.productTitle ?? ""),
|
|
144
|
+
quantity: Number(it.quantity ?? 0),
|
|
145
|
+
unitPrice: Number(it.unitPrice ?? 0),
|
|
146
|
+
totalPrice: Number(it.totalPrice ?? 0),
|
|
147
|
+
})));
|
|
148
|
+
setOrderItemsOpen(true);
|
|
149
|
+
},
|
|
150
|
+
onError: (err) => {
|
|
151
|
+
showToast(err?.message ?? "Failed to load order.", "error");
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
// ST-5 — Lift Ban actions for unban_request tickets
|
|
155
|
+
const linkedUserId = parties.userId?.trim();
|
|
156
|
+
const isUnbanRequest = category === "unban_request";
|
|
157
|
+
const liftHardBan = useMutation({
|
|
158
|
+
mutationFn: async () => {
|
|
159
|
+
if (!linkedUserId)
|
|
160
|
+
throw new Error("No linked user on this ticket.");
|
|
161
|
+
await apiClient.post(ADMIN_ENDPOINTS.USER_UNBAN(linkedUserId), {});
|
|
162
|
+
},
|
|
163
|
+
onSuccess: () => {
|
|
164
|
+
showToast("Hard ban lifted.", "success");
|
|
165
|
+
apiClient
|
|
166
|
+
.patch(ADMIN_ENDPOINTS.SUPPORT_TICKET_BY_ID(ticketId), {
|
|
167
|
+
internalNotes: (notes ? notes + "\n" : "") +
|
|
168
|
+
`[${new Date().toISOString()}] Lifted hard ban for ${linkedUserId}`,
|
|
169
|
+
status: "resolved",
|
|
170
|
+
})
|
|
171
|
+
.catch(() => { });
|
|
172
|
+
invalidate();
|
|
173
|
+
},
|
|
174
|
+
onError: (err) => {
|
|
175
|
+
showToast(err?.message ?? "Failed to lift hard ban.", "error");
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
const liftSoftBanTickets = useMutation({
|
|
179
|
+
mutationFn: async () => {
|
|
180
|
+
if (!linkedUserId)
|
|
181
|
+
throw new Error("No linked user on this ticket.");
|
|
182
|
+
await apiClient.delete(ADMIN_ENDPOINTS.USER_SOFT_BAN_LIFT(linkedUserId, "create_support_tickets"));
|
|
183
|
+
},
|
|
184
|
+
onSuccess: () => {
|
|
185
|
+
showToast("Ticket-creation soft ban lifted.", "success");
|
|
186
|
+
apiClient
|
|
187
|
+
.patch(ADMIN_ENDPOINTS.SUPPORT_TICKET_BY_ID(ticketId), {
|
|
188
|
+
internalNotes: (notes ? notes + "\n" : "") +
|
|
189
|
+
`[${new Date().toISOString()}] Lifted create_support_tickets soft ban for ${linkedUserId}`,
|
|
190
|
+
status: "resolved",
|
|
191
|
+
})
|
|
192
|
+
.catch(() => { });
|
|
193
|
+
invalidate();
|
|
194
|
+
},
|
|
195
|
+
onError: (err) => {
|
|
196
|
+
showToast(err?.message ?? "Failed to lift soft ban.", "error");
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
const applyOrderItems = useMutation({
|
|
200
|
+
mutationFn: async () => {
|
|
201
|
+
if (!linkedOrderId)
|
|
202
|
+
throw new Error("No linked order on this ticket.");
|
|
203
|
+
// Recalculate totalPrice per line from quantity × unitPrice so qty edits
|
|
204
|
+
// flow through. Lines with quantity 0 are dropped.
|
|
205
|
+
const items = orderItems
|
|
206
|
+
.filter((it) => it.quantity > 0)
|
|
207
|
+
.map((it) => ({
|
|
208
|
+
productId: it.productId,
|
|
209
|
+
productTitle: it.productTitle,
|
|
210
|
+
quantity: it.quantity,
|
|
211
|
+
unitPrice: it.unitPrice,
|
|
212
|
+
totalPrice: it.quantity * it.unitPrice,
|
|
213
|
+
}));
|
|
214
|
+
await apiClient.patch(ADMIN_ENDPOINTS.ORDER_BY_ID(linkedOrderId), {
|
|
215
|
+
items,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
onSuccess: () => {
|
|
219
|
+
showToast("Order items updated.", "success");
|
|
220
|
+
apiClient
|
|
221
|
+
.patch(ADMIN_ENDPOINTS.SUPPORT_TICKET_BY_ID(ticketId), {
|
|
222
|
+
internalNotes: (notes ? notes + "\n" : "") +
|
|
223
|
+
`[${new Date().toISOString()}] Modified order ${linkedOrderId} items: ${orderItems
|
|
224
|
+
.filter((it) => it.quantity > 0)
|
|
225
|
+
.map((it) => `${it.productId}x${it.quantity}`)
|
|
226
|
+
.join(", ")}`,
|
|
227
|
+
})
|
|
228
|
+
.catch(() => { });
|
|
229
|
+
invalidate();
|
|
230
|
+
setOrderItemsOpen(false);
|
|
231
|
+
},
|
|
232
|
+
onError: (err) => {
|
|
233
|
+
showToast(err?.message ?? "Failed to update order items.", "error");
|
|
234
|
+
},
|
|
235
|
+
});
|
|
80
236
|
return (_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: subject ?? "Support Ticket", children: _jsxs(Div, { className: "flex flex-col gap-4 p-4", children: [_jsxs(Div, { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: `inline-flex rounded-full px-2.5 py-1 text-xs font-medium ${STATUS_COLOR[currentStatus ?? "open"] ?? STATUS_COLOR.open}`, children: (currentStatus ?? "open").replace(/_/g, " ") }), _jsx("span", { className: "rounded-full bg-zinc-100 px-2.5 py-1 text-xs text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300", children: category }), orderId && (_jsxs("span", { className: "rounded-full bg-zinc-100 px-2.5 py-1 text-xs text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300", children: ["Order: ", orderId] }))] }), _jsxs(Div, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: ["From: ", _jsx("span", { className: "font-medium text-zinc-700 dark:text-zinc-200", children: userDisplayName })] }), description && (_jsxs(Div, { className: "rounded-lg border border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-700 dark:bg-zinc-900/40", children: [_jsx(Text, { className: "mb-1 text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Description" }), _jsx(Text, { className: "whitespace-pre-wrap text-sm text-zinc-700 dark:text-zinc-200", children: description })] })), messages.length > 0 && (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: ["Messages (", messages.length, ")"] }), _jsx("div", { className: "space-y-2 max-h-64 overflow-y-auto", children: messages.map((msg, i) => (_jsxs("div", { className: `rounded-lg p-3 text-sm ${msg.authorRole === "user"
|
|
81
237
|
? "bg-zinc-50 border border-zinc-200 dark:bg-zinc-900/40 dark:border-zinc-700"
|
|
82
|
-
: "bg-info-surface border border-blue-200 dark:border-blue-800"}`, children: [_jsxs("div", { className: "mb-1 flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-400", children: [_jsx("span", { className: "font-medium text-zinc-600 dark:text-zinc-300", children: ROLE_LABEL[msg.authorRole ?? "user"] ?? msg.authorRole }), msg.createdAt && (_jsx("span", { children: new Date(msg.createdAt).toLocaleString() }))] }), _jsx(Text, { className: "whitespace-pre-wrap text-zinc-700 dark:text-zinc-200", children: msg.body })] }, msg.id ?? i))) })] })), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Reply to user" }), _jsx("textarea", { value: replyBody, onChange: (e) => setReplyBody(e.target.value), rows: 3, placeholder: "Type a reply\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: replyMutation.isPending, disabled: !replyBody.trim() || !ticketId || replyMutation.isPending, onClick: () => replyMutation.mutate(), children: "Send reply" })] }), _jsx("hr", { className: "border-zinc-200 dark:border-zinc-700" }), _jsx(Select, { label: "Status", options: STATUS_OPTIONS, value: status, onValueChange: setStatus }), _jsx(Select, { label: "Priority", options: PRIORITY_OPTIONS, value: priority, onValueChange: setPriority }), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Internal notes (staff only)" }), _jsx("textarea", { value: notes, onChange: (e) => setNotes(e.target.value), rows: 3, placeholder: "Notes visible only to admins and employees\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" })] }), _jsxs(
|
|
238
|
+
: "bg-info-surface border border-blue-200 dark:border-blue-800"}`, children: [_jsxs("div", { className: "mb-1 flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-400", children: [_jsx("span", { className: "font-medium text-zinc-600 dark:text-zinc-300", children: ROLE_LABEL[msg.authorRole ?? "user"] ?? msg.authorRole }), msg.createdAt && (_jsx("span", { children: new Date(msg.createdAt).toLocaleString() }))] }), _jsx(Text, { className: "whitespace-pre-wrap text-zinc-700 dark:text-zinc-200", children: msg.body })] }, msg.id ?? i))) })] })), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Reply to user" }), _jsx("textarea", { value: replyBody, onChange: (e) => setReplyBody(e.target.value), rows: 3, placeholder: "Type a reply\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: replyMutation.isPending, disabled: !replyBody.trim() || !ticketId || replyMutation.isPending, onClick: () => replyMutation.mutate(), children: "Send reply" })] }), _jsx("hr", { className: "border-zinc-200 dark:border-zinc-700" }), _jsx(Select, { label: "Status", options: STATUS_OPTIONS, value: status, onValueChange: setStatus }), _jsx(Select, { label: "Priority", options: PRIORITY_OPTIONS, value: priority, onValueChange: setPriority }), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Internal notes (staff only)" }), _jsx("textarea", { value: notes, onChange: (e) => setNotes(e.target.value), rows: 3, placeholder: "Notes visible only to admins and employees\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" })] }), _jsxs(Div, { padding: "sm", className: "flex flex-col gap-2 rounded-lg border border-zinc-200 dark:border-zinc-700", children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Linked parties" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Tag the buyer / store / order / product / bid this ticket concerns." }), [
|
|
239
|
+
["userId", "User slug"],
|
|
240
|
+
["storeId", "Store slug"],
|
|
241
|
+
["orderId", "Order ID"],
|
|
242
|
+
["productId", "Product slug"],
|
|
243
|
+
["bidId", "Bid ID"],
|
|
244
|
+
].map(([key, label]) => (_jsx(Input, { label: label, type: "text", value: parties[key] ?? "", onChange: (e) => setParties((p) => ({ ...p, [key]: e.target.value })), placeholder: label }, key)))] }), isOrderModificationRequest && (_jsx(OrderItemsPanel, { linkedOrderId: linkedOrderId, orderItemsOpen: orderItemsOpen, setOrderItemsOpen: setOrderItemsOpen, orderItems: orderItems, setOrderItems: setOrderItems, loadOrderItems: loadOrderItems, applyOrderItems: applyOrderItems })), isStoreChangeRequest && (_jsx(StoreChangePanel, { linkedStoreId: linkedStoreId, storeStatus: storeStatus, setStoreStatus: setStoreStatus, storeIsVerified: storeIsVerified, setStoreIsVerified: setStoreIsVerified, storeIsFeatured: storeIsFeatured, setStoreIsFeatured: setStoreIsFeatured, applyStoreChange: applyStoreChange })), isUnbanRequest && (_jsx(UnbanRequestPanel, { linkedUserId: linkedUserId, liftHardBan: liftHardBan, liftSoftBanTickets: liftSoftBanTickets })), _jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "secondary", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "button", isLoading: updateMutation.isPending, disabled: !ticketId || updateMutation.isPending, onClick: () => updateMutation.mutate(), children: "Save changes" })] })] }) }));
|
|
245
|
+
}
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
247
|
+
function OrderItemsPanel(props) {
|
|
248
|
+
const { linkedOrderId, orderItemsOpen, setOrderItemsOpen, orderItems, setOrderItems, loadOrderItems, applyOrderItems, } = props;
|
|
249
|
+
const updateQty = (idx, raw) => {
|
|
250
|
+
const q = Math.max(0, parseInt(raw, 10) || 0);
|
|
251
|
+
setOrderItems((prev) => prev.map((p, i) => (i === idx ? { ...p, quantity: q } : p)));
|
|
252
|
+
};
|
|
253
|
+
return (_jsxs(Div, { padding: "sm", className: "flex flex-col gap-2 rounded-lg border border-info/40 bg-info-surface/40", children: [_jsx(Text, { className: "text-xs font-semibold text-info uppercase tracking-wide", children: "Modify order items" }), linkedOrderId ? (_jsxs(_Fragment, { children: [_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Editing order: ", _jsx("code", { className: "font-mono", children: linkedOrderId })] }), !orderItemsOpen ? (_jsx(Button, { type: "button", variant: "secondary", size: "sm", isLoading: loadOrderItems.isPending, disabled: loadOrderItems.isPending, onClick: () => loadOrderItems.mutate(), children: "Load current items" })) : (_jsxs(_Fragment, { children: [orderItems.length === 0 ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Order has no items." })) : (_jsx(Div, { className: "flex flex-col gap-2", children: orderItems.map((it, idx) => (_jsxs(Div, { className: "flex items-center gap-2 rounded border border-zinc-200 dark:border-zinc-700 px-2 py-1", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { className: "text-xs font-medium truncate", children: it.productTitle }), _jsxs(Text, { size: "xs", color: "muted", children: [it.productId, " \u00B7 \u20B9", (it.unitPrice / 100).toFixed(2), "/ea"] })] }), _jsx("input", { type: "number", min: "0", value: it.quantity, onChange: (e) => updateQty(idx, e.target.value), className: "w-16 rounded border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-2 py-1 text-xs" })] }, `${it.productId}-${idx}`))) })), _jsxs(Row, { gap: "sm", children: [_jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => setOrderItemsOpen(false), children: "Cancel" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: applyOrderItems.isPending, disabled: applyOrderItems.isPending, onClick: () => applyOrderItems.mutate(), children: "Apply changes" })] })] }))] })) : (_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Set the", " ", _jsx(Text, { as: "span", weight: "semibold", children: "Order ID" }), " ", "field in the Linked parties panel above to enable this action."] }))] }));
|
|
254
|
+
}
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
256
|
+
function StoreChangePanel(props) {
|
|
257
|
+
const { linkedStoreId, storeStatus, setStoreStatus, storeIsVerified, setStoreIsVerified, storeIsFeatured, setStoreIsFeatured, applyStoreChange, } = props;
|
|
258
|
+
return (_jsxs(Div, { padding: "sm", className: "flex flex-col gap-2 rounded-lg border border-warning/40 bg-warning-surface/40", children: [_jsx(Text, { className: "text-xs font-semibold text-warning uppercase tracking-wide", children: "Apply store change" }), linkedStoreId ? (_jsxs(_Fragment, { children: [_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Editing store: ", _jsx("code", { className: "font-mono", children: linkedStoreId })] }), _jsx(Select, { label: "Store status", options: [
|
|
259
|
+
{ label: "Active", value: "active" },
|
|
260
|
+
{ label: "Pending", value: "pending" },
|
|
261
|
+
{ label: "Suspended", value: "suspended" },
|
|
262
|
+
{ label: "Rejected", value: "rejected" },
|
|
263
|
+
], value: storeStatus, onValueChange: setStoreStatus }), _jsx(Toggle, { label: "Verified badge", checked: storeIsVerified, onChange: setStoreIsVerified }), _jsx(Toggle, { label: "Featured store", checked: storeIsFeatured, onChange: setStoreIsFeatured }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: applyStoreChange.isPending, disabled: applyStoreChange.isPending, onClick: () => applyStoreChange.mutate(), children: "Apply store change" })] })) : (_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Set the", " ", _jsx(Text, { as: "span", weight: "semibold", children: "Store slug" }), " ", "field in the Linked parties panel above to enable this action."] }))] }));
|
|
264
|
+
}
|
|
265
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
266
|
+
function UnbanRequestPanel(props) {
|
|
267
|
+
const { linkedUserId, liftHardBan, liftSoftBanTickets } = props;
|
|
268
|
+
return (_jsxs(Div, { padding: "sm", className: "flex flex-col gap-2 rounded-lg border border-error/40 bg-error-surface/40", children: [_jsx(Text, { className: "text-xs font-semibold text-error uppercase tracking-wide", children: "Lift account ban" }), linkedUserId ? (_jsxs(_Fragment, { children: [_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Appellant: ", _jsx("code", { className: "font-mono", children: linkedUserId })] }), _jsx(Text, { size: "xs", color: "muted", children: "Resolves the ticket and appends an audit note on success." }), _jsxs(Row, { gap: "sm", children: [_jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: liftHardBan.isPending, disabled: liftHardBan.isPending, onClick: () => liftHardBan.mutate(), children: "Lift hard ban" }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", isLoading: liftSoftBanTickets.isPending, disabled: liftSoftBanTickets.isPending, onClick: () => liftSoftBanTickets.mutate(), children: "Lift ticket soft ban" })] })] })) : (_jsxs(Text, { className: "text-xs text-zinc-600 dark:text-zinc-300", children: ["Set the", " ", _jsx(Text, { as: "span", weight: "semibold", children: "User slug" }), " ", "field in the Linked parties panel above to enable these actions."] }))] }));
|
|
83
269
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export
|
|
3
|
-
}
|
|
1
|
+
import type { ListingLayoutProps } from "../../../ui";
|
|
2
|
+
export type AdminSupportTicketsViewProps = ListingLayoutProps;
|
|
4
3
|
export declare function AdminSupportTicketsView({ children, ...props }: AdminSupportTicketsViewProps): import("react/jsx-runtime").JSX.Element;
|