@mohasinac/appkit 2.7.56 → 2.7.57
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/shared/actions/action-registry.js +31 -5
- package/dist/client.d.ts +1 -3
- package/dist/client.js +1 -2
- package/dist/constants/field-names.d.ts +3 -0
- package/dist/constants/field-names.js +3 -0
- package/dist/features/about/components/FAQPageView.js +2 -2
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/about/components/PolicyPageView.js +1 -1
- package/dist/features/about/components/PublicProfileView.js +1 -1
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationPreferencesPanel.js +12 -3
- package/dist/features/account/components/UserOffersPanel.js +2 -2
- package/dist/features/account/components/UserSidebar.js +3 -3
- package/dist/features/account/components/UserSupportView.js +1 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +1 -1
- package/dist/features/admin/components/AdminBidsView.js +5 -1
- package/dist/features/admin/components/AdminBlogView.js +6 -1
- package/dist/features/admin/components/AdminBrandsView.js +6 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +13 -9
- package/dist/features/admin/components/AdminBundlesView.js +3 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +7 -8
- package/dist/features/admin/components/AdminCarouselView.js +4 -2
- package/dist/features/admin/components/AdminCartsView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +6 -1
- package/dist/features/admin/components/AdminContactView.js +3 -1
- package/dist/features/admin/components/AdminCouponsView.js +4 -2
- package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +3 -1
- package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -1
- package/dist/features/admin/components/AdminFeaturesView.js +4 -0
- package/dist/features/admin/components/AdminMediaView.js +10 -5
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminNewsletterView.js +3 -1
- package/dist/features/admin/components/AdminNotificationsView.js +6 -1
- package/dist/features/admin/components/AdminOrdersView.js +10 -1
- package/dist/features/admin/components/AdminPayoutsView.js +5 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.js +4 -0
- package/dist/features/admin/components/AdminProductsView.js +13 -1
- package/dist/features/admin/components/AdminReviewsView.js +6 -1
- package/dist/features/admin/components/AdminScammersView.js +1 -1
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.js +5 -1
- package/dist/features/admin/components/AdminSidebar.js +3 -3
- package/dist/features/admin/components/AdminSiteSettingsView.js +1 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
- package/dist/features/admin/components/AdminStoresView.js +6 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +1 -1
- package/dist/features/admin/components/AdminTeamView.js +3 -1
- package/dist/features/admin/components/AdminUserEditorView.js +1 -1
- package/dist/features/admin/components/AdminUsersView.js +5 -1
- package/dist/features/admin/components/AdminViewCards.js +2 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +9 -0
- package/dist/features/admin/constants/filter-tabs.js +3 -0
- package/dist/features/auctions/components/AuctionBottomActions.d.ts +7 -0
- package/dist/features/auctions/components/AuctionBottomActions.js +24 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
- package/dist/features/auctions/components/AuctionsListView.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +1 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
- package/dist/features/auth/components/LoginForm.js +1 -1
- package/dist/features/auth/components/VerifyEmailView.js +2 -2
- package/dist/features/before-after/components/BeforeAfterGallery.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
- package/dist/features/blog/components/BlogIndexListing.js +1 -1
- package/dist/features/blog/components/BlogListView.js +2 -2
- package/dist/features/blog/components/BlogPostView.js +8 -8
- package/dist/features/cart/components/CartDrawer.js +1 -1
- package/dist/features/cart/repository/cart.repository.js +11 -4
- package/dist/features/cart/schemas/firestore.d.ts +3 -0
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +39 -3
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +4 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +7 -2
- package/dist/features/categories/components/CategoryGrid.js +1 -1
- package/dist/features/categories/components/CategoryProductsView.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.d.ts +5 -0
- package/dist/features/categories/components/CategoryStoresListing.js +11 -0
- package/dist/features/categories/components/CategoryTableColumns.js +2 -2
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/checkout/components/CheckoutStepper.js +1 -1
- package/dist/features/classified/components/ClassifiedIndexListing.js +2 -0
- package/dist/features/classified/components/ClassifiedListView.js +1 -1
- package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +2 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.js +1 -1
- package/dist/features/events/components/AdminEventsView.js +5 -1
- package/dist/features/events/components/EventCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +1 -1
- package/dist/features/events/components/EventStatusBadge.js +5 -5
- package/dist/features/events/components/EventsIndexListing.js +1 -1
- package/dist/features/events/components/EventsListView.js +2 -2
- package/dist/features/events/components/SpinWheelView.js +4 -2
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +5 -5
- package/dist/features/filters/RangeFilter.js +1 -1
- package/dist/features/forms/Input.js +2 -2
- package/dist/features/forms/Select.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/forms/Textarea.js +1 -1
- package/dist/features/forms/utils.d.ts +1 -1
- package/dist/features/forms/utils.js +1 -1
- package/dist/features/history/hooks/useHistory.js +23 -10
- package/dist/features/homepage/components/AdvertisementBanner.js +2 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/NewsletterSection.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/live/components/LiveItemsIndexListing.js +2 -0
- package/dist/features/live/components/LiveItemsListView.js +1 -1
- package/dist/features/orders/components/OrdersList.js +12 -12
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +5 -5
- package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +5 -0
- package/dist/features/pre-orders/components/PreOrderBottomActions.js +22 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +5 -5
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +47 -0
- package/dist/features/pre-orders/components/PreOrdersListView.js +1 -1
- package/dist/features/pre-orders/components/PreorderCard.js +3 -3
- package/dist/features/products/components/AuctionsIndexListing.js +23 -0
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.js +1 -1
- package/dist/features/products/components/CustomFieldsEditor.js +1 -1
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/CustomSectionsEditor.js +1 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/MakeOfferButton.js +1 -1
- package/dist/features/products/components/PrizeDrawBottomActions.d.ts +6 -0
- package/dist/features/products/components/PrizeDrawBottomActions.js +24 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.js +3 -5
- package/dist/features/products/components/PrizeDrawEntryActions.js +5 -18
- package/dist/features/products/components/PrizeRevealModal.js +5 -2
- package/dist/features/products/components/ProductDetailActions.d.ts +6 -1
- package/dist/features/products/components/ProductDetailActions.js +36 -6
- package/dist/features/products/components/ProductDetailPageView.js +17 -16
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +6 -6
- package/dist/features/products/components/ProductTabs.js +1 -1
- package/dist/features/products/components/ProductTabsShell.js +1 -1
- package/dist/features/products/components/ProductsIndexListing.js +47 -0
- package/dist/features/products/components/RelatedProducts.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +1 -1
- package/dist/features/products/components/SublistingCarouselSection.js +1 -1
- package/dist/features/products/components/SublistingCategorySelect.js +1 -1
- package/dist/features/products/components/index.d.ts +0 -2
- package/dist/features/products/components/index.js +0 -1
- package/dist/features/products/constants/action-defs.d.ts +7 -0
- package/dist/features/products/constants/action-defs.js +14 -0
- package/dist/features/products/constants/listing-tabs.d.ts +6 -0
- package/dist/features/products/constants/listing-tabs.js +1 -0
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +3 -3
- package/dist/features/reviews/components/ReviewModal.js +2 -2
- package/dist/features/reviews/components/ReviewSummary.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +1 -1
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +4 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
- package/dist/features/seller/components/SellerAuctionsView.js +10 -3
- package/dist/features/seller/components/SellerBidsView.js +22 -7
- package/dist/features/seller/components/SellerBundlesView.js +10 -3
- package/dist/features/seller/components/SellerClassifiedView.js +10 -3
- package/dist/features/seller/components/SellerCouponsView.js +13 -4
- package/dist/features/seller/components/SellerDigitalCodesView.js +10 -3
- package/dist/features/seller/components/SellerGoogleReviewsView.js +10 -5
- package/dist/features/seller/components/SellerGroupedListingsView.js +2 -0
- package/dist/features/seller/components/SellerLiveView.js +10 -3
- package/dist/features/seller/components/SellerOffersPanel.js +2 -2
- package/dist/features/seller/components/SellerOffersView.js +1 -1
- package/dist/features/seller/components/SellerOrdersView.js +40 -17
- package/dist/features/seller/components/SellerPayoutMethodsView.js +13 -4
- package/dist/features/seller/components/SellerPayoutsView.js +1 -1
- package/dist/features/seller/components/SellerPreOrdersView.js +7 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +7 -2
- package/dist/features/seller/components/SellerProductShell.js +27 -9
- package/dist/features/seller/components/SellerProductsCards.js +2 -1
- package/dist/features/seller/components/SellerProductsView.js +21 -8
- package/dist/features/seller/components/SellerReviewsView.js +8 -0
- package/dist/features/seller/components/SellerShippingConfigsView.js +13 -4
- package/dist/features/seller/components/SellerSidebar.js +2 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +10 -3
- package/dist/features/seller/components/SellerTemplatesView.js +19 -6
- package/dist/features/shell/StepForm.js +9 -3
- package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
- package/dist/features/stores/components/StoreReviewsListing.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +17 -1
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +1 -1
- package/dist/features/wishlist/components/WishlistPage.js +2 -2
- package/dist/features/wishlist/hooks/useWishlistToggle.js +6 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -3
- package/dist/react/hooks/use-action-dispatch.d.ts +5 -0
- package/dist/react/hooks/use-action-dispatch.js +10 -0
- package/dist/seed/cart-seed-data.js +50 -3
- package/dist/seed/categories-seed-data.js +80 -16
- package/dist/seed/index.d.ts +3 -0
- package/dist/seed/index.js +3 -0
- package/dist/seed/manifest.js +15 -1
- package/dist/seed/products-classifieds-seed-data.d.ts +10 -0
- package/dist/seed/products-classifieds-seed-data.js +197 -0
- package/dist/seed/products-digital-codes-seed-data.d.ts +10 -0
- package/dist/seed/products-digital-codes-seed-data.js +204 -0
- package/dist/seed/products-live-items-seed-data.d.ts +13 -0
- package/dist/seed/products-live-items-seed-data.js +190 -0
- package/dist/styles.css +16 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +3 -3
- package/dist/tokens/index.js +3 -3
- package/dist/ui/DataTable.js +3 -3
- package/dist/ui/components/Button.style.css +15 -0
- package/dist/ui/components/Input.js +1 -1
- package/dist/ui/components/ListingToolbar.js +1 -1
- package/dist/ui/components/Select.js +1 -1
- package/dist/ui/components/StatsGrid.js +1 -1
- package/dist/ui/index.d.ts +0 -4
- package/dist/ui/index.js +0 -2
- package/package.json +1 -1
- package/dist/_internal/client/features/seller/print-center/InventoryLabel.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/InventoryLabel.js +0 -49
- package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.d.ts +0 -7
- package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.js +0 -32
- package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.d.ts +0 -28
- package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.js +0 -33
- package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.js +0 -30
- package/dist/_internal/client/features/seller/print-center/PrintCenterView.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PrintCenterView.js +0 -102
- package/dist/_internal/client/features/seller/print-center/PrintGrid.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PrintGrid.js +0 -13
- package/dist/_internal/client/features/seller/print-center/StoreCard.d.ts +0 -19
- package/dist/_internal/client/features/seller/print-center/StoreCard.js +0 -30
- package/dist/_internal/client/features/seller/print-center/WebsiteCard.d.ts +0 -11
- package/dist/_internal/client/features/seller/print-center/WebsiteCard.js +0 -25
- package/dist/_internal/client/features/seller/print-center/index.d.ts +0 -11
- package/dist/_internal/client/features/seller/print-center/index.js +0 -10
- package/dist/_internal/client/features/seller/print-center/types.d.ts +0 -20
- package/dist/_internal/client/features/seller/print-center/types.js +0 -20
- package/dist/_internal/client/features/seller/print-center/useInventoryPdf.d.ts +0 -18
- package/dist/_internal/client/features/seller/print-center/useInventoryPdf.js +0 -76
- package/dist/features/account/repository/address.repository.d.ts +0 -17
- package/dist/features/account/repository/address.repository.js +0 -184
- package/dist/features/auctions/components/AuctionCard.d.ts +0 -29
- package/dist/features/auctions/components/AuctionCard.js +0 -38
- package/dist/features/categories/components/BundleAddToCartCta.d.ts +0 -16
- package/dist/features/categories/components/BundleAddToCartCta.js +0 -54
- package/dist/features/categories/components/CategoriesListView.d.ts +0 -31
- package/dist/features/categories/components/CategoriesListView.js +0 -27
- package/dist/features/products/components/AuctionsView.d.ts +0 -6
- package/dist/features/products/components/AuctionsView.js +0 -5
- package/dist/features/products/components/BuyBar.d.ts +0 -21
- package/dist/features/products/components/BuyBar.js +0 -19
- package/dist/features/products/components/PreOrdersView.d.ts +0 -6
- package/dist/features/products/components/PreOrdersView.js +0 -5
- package/dist/features/reviews/components/ReviewsListView.d.ts +0 -31
- package/dist/features/reviews/components/ReviewsListView.js +0 -16
- package/dist/features/stores/components/StoresListView.d.ts +0 -19
- package/dist/features/stores/components/StoresListView.js +0 -25
- package/dist/features/stores/repository/store-address.repository.d.ts +0 -55
- package/dist/features/stores/repository/store-address.repository.js +0 -187
- package/dist/ui/components/BulkActionsBar.d.ts +0 -18
- package/dist/ui/components/BulkActionsBar.js +0 -25
- package/dist/ui/components/CollageLightbox.d.ts +0 -18
- package/dist/ui/components/CollageLightbox.js +0 -41
- package/dist/ui/components/StickyBottomBar.d.ts +0 -22
- package/dist/ui/components/StickyBottomBar.js +0 -20
|
@@ -149,6 +149,13 @@ export const ACTIONS = {
|
|
|
149
149
|
},
|
|
150
150
|
},
|
|
151
151
|
PRE_ORDER: {
|
|
152
|
+
"add-to-cart": {
|
|
153
|
+
id: "pre-order.add-to-cart",
|
|
154
|
+
label: "Add to cart",
|
|
155
|
+
description: "Add a pre-order listing to the cart for checkout.",
|
|
156
|
+
kind: "secondary",
|
|
157
|
+
listingTypeScope: ["pre-order"],
|
|
158
|
+
},
|
|
152
159
|
"reserve-now": {
|
|
153
160
|
id: "pre-order.reserve-now",
|
|
154
161
|
label: "Reserve now",
|
|
@@ -171,11 +178,18 @@ export const ACTIONS = {
|
|
|
171
178
|
},
|
|
172
179
|
},
|
|
173
180
|
PRIZE_DRAW: {
|
|
181
|
+
"buy-now": {
|
|
182
|
+
id: "prize-draw.buy-now",
|
|
183
|
+
label: "Buy now",
|
|
184
|
+
description: "Purchase a prize-draw entry directly (buyout — skips cart, goes to checkout).",
|
|
185
|
+
kind: "primary",
|
|
186
|
+
listingTypeScope: ["prize-draw"],
|
|
187
|
+
},
|
|
174
188
|
"enter-draw": {
|
|
175
189
|
id: "prize-draw.enter-draw",
|
|
176
190
|
label: "Enter draw",
|
|
177
191
|
description: "Purchase an entry into the prize draw.",
|
|
178
|
-
kind: "
|
|
192
|
+
kind: "secondary",
|
|
179
193
|
listingTypeScope: ["prize-draw"],
|
|
180
194
|
},
|
|
181
195
|
"reveal-code": {
|
|
@@ -214,10 +228,10 @@ export const ACTIONS = {
|
|
|
214
228
|
},
|
|
215
229
|
},
|
|
216
230
|
BUNDLE: {
|
|
217
|
-
"
|
|
218
|
-
id: "bundle.
|
|
219
|
-
label: "
|
|
220
|
-
description: "
|
|
231
|
+
"buy-now": {
|
|
232
|
+
id: "bundle.buy-now",
|
|
233
|
+
label: "Buy now",
|
|
234
|
+
description: "Purchase a bundle directly (buyout — skips cart, goes to checkout).",
|
|
221
235
|
kind: "primary",
|
|
222
236
|
categoryTypeScope: ["bundle"],
|
|
223
237
|
},
|
|
@@ -1615,6 +1629,18 @@ export const ACTIONS = {
|
|
|
1615
1629
|
description: "Admin test mode: place a real order record without charging any payment.",
|
|
1616
1630
|
kind: "secondary",
|
|
1617
1631
|
},
|
|
1632
|
+
"apply-coupon": {
|
|
1633
|
+
id: "checkout.apply-coupon",
|
|
1634
|
+
label: "Apply coupon",
|
|
1635
|
+
description: "Validate and apply a coupon code at checkout before payment.",
|
|
1636
|
+
kind: "secondary",
|
|
1637
|
+
},
|
|
1638
|
+
"remove-coupon": {
|
|
1639
|
+
id: "checkout.remove-coupon",
|
|
1640
|
+
label: "Remove coupon",
|
|
1641
|
+
description: "Remove an applied coupon from the current checkout session.",
|
|
1642
|
+
kind: "ghost",
|
|
1643
|
+
},
|
|
1618
1644
|
},
|
|
1619
1645
|
NAV: {
|
|
1620
1646
|
"sign-in": {
|
package/dist/client.d.ts
CHANGED
|
@@ -65,8 +65,6 @@ export { Div } from "./ui/components/Div";
|
|
|
65
65
|
export { Main, Section } from "./ui/components/Semantic";
|
|
66
66
|
export { Badge } from "./ui/components/Badge";
|
|
67
67
|
export { Button } from "./ui/components/Button";
|
|
68
|
-
export { StickyBottomBar } from "./ui/components/StickyBottomBar";
|
|
69
|
-
export type { StickyBottomBarProps } from "./ui/components/StickyBottomBar";
|
|
70
68
|
export { ClaimCouponButton } from "./ui/components/ClaimCouponButton";
|
|
71
69
|
export type { ClaimCouponButtonProps } from "./ui/components/ClaimCouponButton";
|
|
72
70
|
export { Checkbox } from "./ui/components/Checkbox";
|
|
@@ -91,7 +89,7 @@ export { TextLink } from "./ui/components/TextLink";
|
|
|
91
89
|
export type { TextLinkProps } from "./ui/components/TextLink";
|
|
92
90
|
export { Textarea } from "./ui/components/Textarea";
|
|
93
91
|
export { GlobalError } from "./next/components/GlobalError";
|
|
94
|
-
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, DashboardNavProvider, LayoutClient, ListingLayout } from "./features/layout/index";
|
|
92
|
+
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient, ListingLayout } from "./features/layout/index";
|
|
95
93
|
export type { AppLayoutShellProps, AppLayoutShellSidebarLink, AppLayoutShellSidebarSection, DashboardNavState, MainNavbarItem, LayoutClientProps, ListingLayoutProps, ListingLayoutLabels } from "./features/layout/index";
|
|
96
94
|
export { Search } from "./features/search/components";
|
|
97
95
|
export type { SearchLabels, SearchProps, SearchQuickLink, SearchRouterAdapter, SearchResourceType, SearchResourceTypeOption } from "./features/search/components";
|
package/dist/client.js
CHANGED
|
@@ -129,7 +129,6 @@ export { Div } from "./ui/components/Div";
|
|
|
129
129
|
export { Main, Section } from "./ui/components/Semantic";
|
|
130
130
|
export { Badge } from "./ui/components/Badge";
|
|
131
131
|
export { Button } from "./ui/components/Button";
|
|
132
|
-
export { StickyBottomBar } from "./ui/components/StickyBottomBar";
|
|
133
132
|
export { ClaimCouponButton } from "./ui/components/ClaimCouponButton";
|
|
134
133
|
export { Checkbox } from "./ui/components/Checkbox";
|
|
135
134
|
export { Input } from "./ui/components/Input";
|
|
@@ -145,7 +144,7 @@ export { Label, Text } from "./ui/components/Typography";
|
|
|
145
144
|
export { TextLink } from "./ui/components/TextLink";
|
|
146
145
|
export { Textarea } from "./ui/components/Textarea";
|
|
147
146
|
export { GlobalError } from "./next/components/GlobalError";
|
|
148
|
-
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, DashboardNavProvider, LayoutClient, ListingLayout } from "./features/layout/index";
|
|
147
|
+
export { AppLayoutShell, LocaleSwitcher, useDashboardNav, BottomActionsProvider, useBottomActions, DashboardNavProvider, LayoutClient, ListingLayout } from "./features/layout/index";
|
|
149
148
|
export { Search } from "./features/search/components";
|
|
150
149
|
export { ToastProvider, SkipToMain, NavigationLoader } from "./ui/index";
|
|
151
150
|
export { ZodSetup } from "./validation/ZodSetup";
|
|
@@ -112,6 +112,9 @@ export declare const PRODUCT_FIELDS: {
|
|
|
112
112
|
readonly PRE_ORDER: "pre-order";
|
|
113
113
|
readonly PRIZE_DRAW: "prize-draw";
|
|
114
114
|
readonly BUNDLE: "bundle";
|
|
115
|
+
readonly CLASSIFIED: "classified";
|
|
116
|
+
readonly DIGITAL_CODE: "digital-code";
|
|
117
|
+
readonly LIVE: "live";
|
|
115
118
|
};
|
|
116
119
|
};
|
|
117
120
|
export declare const PRODUCT_STATUS_TRANSITIONS: Record<string, readonly string[]>;
|
|
@@ -117,6 +117,9 @@ export const PRODUCT_FIELDS = {
|
|
|
117
117
|
PRE_ORDER: "pre-order",
|
|
118
118
|
PRIZE_DRAW: "prize-draw",
|
|
119
119
|
BUNDLE: "bundle",
|
|
120
|
+
CLASSIFIED: "classified",
|
|
121
|
+
DIGITAL_CODE: "digital-code",
|
|
122
|
+
LIVE: "live",
|
|
120
123
|
},
|
|
121
124
|
};
|
|
122
125
|
export const PRODUCT_STATUS_TRANSITIONS = {
|
|
@@ -19,9 +19,9 @@ export async function FAQPageView({ category, heroBannerClass = DEFAULT_HERO_CLA
|
|
|
19
19
|
? allItems.filter((item) => item.category === category)
|
|
20
20
|
: allItems;
|
|
21
21
|
const activeCategory = categories.find((c) => c.slug === category);
|
|
22
|
-
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "faqpageview-div-93", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.md} text-center`, "data-section": "faqpageview-div-94", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-3 text-white", children: activeCategory ? activeCategory.label : t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 max-w-2xl mx-auto", children: t("subtitle") })] }) }), _jsx("div", { className: `${page.container.md} py-10 md:py-12 lg:py-16`, "data-section": "faqpageview-div-95", children: _jsxs("div", { className: "flex flex-col md:flex-row gap-8", "data-section": "faqpageview-div-96", children: [categories.length > 0 && (_jsxs("aside", { className: "md:w-56 flex-shrink-0", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold uppercase tracking-wide text-
|
|
22
|
+
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "faqpageview-div-93", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.md} text-center`, "data-section": "faqpageview-div-94", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-3 text-white", children: activeCategory ? activeCategory.label : t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 max-w-2xl mx-auto", children: t("subtitle") })] }) }), _jsx("div", { className: `${page.container.md} py-10 md:py-12 lg:py-16`, "data-section": "faqpageview-div-95", children: _jsxs("div", { className: "flex flex-col md:flex-row gap-8", "data-section": "faqpageview-div-96", children: [categories.length > 0 && (_jsxs("aside", { className: "md:w-56 flex-shrink-0", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-3", children: t("categoriesLabel") }), _jsxs("nav", { className: "space-y-1", children: [_jsxs(TextLink, { href: String(ROUTES.PUBLIC.FAQS), className: `flex items-center justify-between px-3 py-2 rounded-lg text-sm transition-colors ${!category
|
|
23
23
|
? "bg-primary/10 text-primary font-semibold"
|
|
24
24
|
: "hover:bg-neutral-100 dark:hover:bg-neutral-800"}`, children: [_jsxs("span", { className: `${flex.row} gap-2`, children: [_jsx(HelpCircle, { className: "w-4 h-4" }), t("allCategories")] }), _jsx(ChevronRight, { className: "w-3.5 h-3.5 opacity-50" })] }), categories.map((cat) => (_jsxs(TextLink, { href: String(ROUTES.PUBLIC.FAQ_CATEGORY(cat.slug)), className: `flex items-center justify-between px-3 py-2 rounded-lg text-sm transition-colors ${category === cat.slug
|
|
25
25
|
? "bg-primary/10 text-primary font-semibold"
|
|
26
|
-
: "hover:bg-neutral-100 dark:hover:bg-neutral-800"}`, children: [_jsxs("span", { className: `${flex.row} gap-2`, children: [_jsx("span", { children: cat.icon }), cat.label] }), _jsx(ChevronRight, { className: "w-3.5 h-3.5 opacity-50" })] }, cat.slug)))] })] })), _jsxs("div", { className: "flex-1 min-w-0", "data-section": "faqpageview-div-97", children: [visibleItems.length === 0 ? (_jsxs(Section, { className: `text-center py-16 rounded-2xl border ${themed.border} ${themed.bgSecondary}`, children: [_jsx(HelpCircle, { className: "w-10 h-10 mx-auto mb-3 text-
|
|
26
|
+
: "hover:bg-neutral-100 dark:hover:bg-neutral-800"}`, children: [_jsxs("span", { className: `${flex.row} gap-2`, children: [_jsx("span", { children: cat.icon }), cat.label] }), _jsx(ChevronRight, { className: "w-3.5 h-3.5 opacity-50" })] }, cat.slug)))] })] })), _jsxs("div", { className: "flex-1 min-w-0", "data-section": "faqpageview-div-97", children: [visibleItems.length === 0 ? (_jsxs(Section, { className: `text-center py-16 rounded-2xl border ${themed.border} ${themed.bgSecondary}`, children: [_jsx(HelpCircle, { className: "w-10 h-10 mx-auto mb-3 text-zinc-300 dark:text-zinc-600" }), _jsx(Heading, { level: 3, className: "mb-2 text-base", children: t("emptyTitle") }), _jsx(Text, { variant: "secondary", className: "text-sm", children: t("emptyText") })] })) : (_jsx(Stack, { gap: "sm", className: "space-y-3", children: visibleItems.map((item, i) => (_jsxs("details", { className: `group rounded-xl border ${themed.border} ${themed.bgPrimary} overflow-hidden`, children: [_jsxs("summary", { className: `flex items-center justify-between px-5 py-4 cursor-pointer list-none select-none font-medium text-sm hover:bg-neutral-50 dark:hover:bg-neutral-800/50 transition-colors`, children: [_jsx("span", { children: item.question }), _jsx(ChevronRight, { className: "w-4 h-4 flex-shrink-0 ml-3 transition-transform group-open:rotate-90" })] }), _jsx("div", { className: "px-5 pb-5 pt-1", "data-section": "faqpageview-div-98", children: _jsx(RichTextRenderer, { html: item.answer, proseClass: "prose prose-sm max-w-none dark:prose-invert" }) })] }, i))) })), _jsxs(Section, { className: `mt-10 rounded-2xl p-6 text-center border ${themed.border} ${themed.bgSecondary}`, children: [_jsx(Heading, { level: 3, className: "mb-2 text-base", children: t("stillNeedHelpTitle") }), _jsx(Text, { variant: "secondary", className: "text-sm mb-4", children: t("stillNeedHelpText") }), _jsxs("div", { className: `${flex.center} gap-4 flex-wrap`, "data-section": "faqpageview-div-99", children: [_jsx(TextLink, { href: String(ROUTES.PUBLIC.HELP), children: t("helpCenter") }), _jsx(TextLink, { href: String(ROUTES.PUBLIC.CONTACT), variant: "muted", children: t("contactUs") })] })] })] })] }) })] }));
|
|
27
27
|
}
|
|
@@ -56,7 +56,7 @@ export async function FeesView({ heroBannerClass = DEFAULT_HERO_CLASS, } = {}) {
|
|
|
56
56
|
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "feesview-div-100", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.sm} text-center`, "data-section": "feesview-div-101", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-4 text-white", children: t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 max-w-2xl mx-auto", children: t("subtitle") })] }) }), _jsxs("div", { className: `${page.container.sm} py-10 md:py-12 lg:py-16 space-y-12`, "data-section": "feesview-div-102", children: [renderFeeTableSection(t, themed, FEE_ROWS), renderPayoutExampleSection(t, themed, OFFER_PAYOUT_ROWS), renderDisclaimerSection(t, themed)] })] }));
|
|
57
57
|
}
|
|
58
58
|
function renderFeeTableSection(t, themed, rows) {
|
|
59
|
-
return (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-6", children: t("tableTitle") }), _jsx("div", { className: `overflow-x-auto rounded-xl border ${themed.border}`, "data-section": "feesview-div-103", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: themed.bgSecondary, children: _jsxs("tr", { children: [_jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colFeeType") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colRate") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colPaidBy") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold hidden md:table-cell", children: t("colNote") })] }) }), _jsx("tbody", { className: "divide-y divide-neutral-100 dark:divide-neutral-800", children: rows.map((row) => (_jsxs("tr", { className: `${themed.bgPrimary} hover:bg-neutral-50 dark:hover:bg-neutral-800/50`, children: [_jsx("td", { className: "py-3 px-4 font-medium", children: row.category }), _jsx("td", { className: "py-3 px-4 font-semibold text-violet-700 dark:text-violet-400", children: row.rate }), _jsx("td", { className: "py-3 px-4", children: _jsx(Caption, { children: row.who }) }), _jsx("td", { className: "py-3 px-4 text-neutral-500 dark:text-neutral-400 hidden md:table-cell text-xs", children: row.note })] }, row.category))) })] }) }), _jsx(Caption, { className: "mt-3 block text-
|
|
59
|
+
return (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-6", children: t("tableTitle") }), _jsx("div", { className: `overflow-x-auto rounded-xl border ${themed.border}`, "data-section": "feesview-div-103", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: themed.bgSecondary, children: _jsxs("tr", { children: [_jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colFeeType") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colRate") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold", children: t("colPaidBy") }), _jsx("th", { className: "py-3 px-4 text-left font-semibold hidden md:table-cell", children: t("colNote") })] }) }), _jsx("tbody", { className: "divide-y divide-neutral-100 dark:divide-neutral-800", children: rows.map((row) => (_jsxs("tr", { className: `${themed.bgPrimary} hover:bg-neutral-50 dark:hover:bg-neutral-800/50`, children: [_jsx("td", { className: "py-3 px-4 font-medium", children: row.category }), _jsx("td", { className: "py-3 px-4 font-semibold text-violet-700 dark:text-violet-400", children: row.rate }), _jsx("td", { className: "py-3 px-4", children: _jsx(Caption, { children: row.who }) }), _jsx("td", { className: "py-3 px-4 text-neutral-500 dark:text-neutral-400 hidden md:table-cell text-xs", children: row.note })] }, row.category))) })] }) }), _jsx(Caption, { className: "mt-3 block text-zinc-500 dark:text-zinc-400", children: t("tableNote") })] }));
|
|
60
60
|
}
|
|
61
61
|
function renderPayoutExampleSection(t, themed, rows) {
|
|
62
62
|
return (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-3", children: t("payoutExampleTitle") }), _jsx(Text, { variant: "secondary", className: "mb-6", children: t("payoutExampleSubtitle") }), _jsxs("div", { className: `rounded-xl border ${themed.border} ${themed.bgPrimary} p-5 max-w-sm`, "data-section": "feesview-div-104", children: [_jsx(Heading, { level: 3, className: "text-base mb-4", children: t("payoutExampleProduct") }), _jsx("div", { className: "space-y-2", "data-section": "feesview-div-105", children: rows.map((row, i) => (_jsxs("div", { className: `flex justify-between text-sm ${row.highlight ? "border-t border-neutral-200 dark:border-neutral-700 pt-2 mt-2 font-bold" : ""}`, "data-section": "feesview-div-106", children: [_jsx(Text, { className: row.highlight ? "font-bold" : "text-neutral-600 dark:text-neutral-400", children: row.label }), _jsx(Text, { className: row.highlight ? "font-bold text-green-700 dark:text-green-400" : "", children: row.example })] }, i))) })] })] }));
|
|
@@ -45,5 +45,5 @@ export async function PolicyPageView({ policy, heroBannerClass = DEFAULT_HERO_CL
|
|
|
45
45
|
});
|
|
46
46
|
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "policypageview-div-181", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.sm}`, "data-section": "policypageview-div-182", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-3 text-white", children: t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 text-sm", children: t("lastUpdated") })] }) }), _jsxs("div", { className: `${page.container.sm} py-10 md:py-12 lg:py-16`, "data-section": "policypageview-div-183", children: [adminHtml ? (
|
|
47
47
|
/* Admin-set HTML takes priority */
|
|
48
|
-
_jsx("div", { className: "prose prose-neutral dark:prose-invert max-w-none", dangerouslySetInnerHTML: { __html: adminHtml } })) : (_jsxs(_Fragment, { children: [t("intro") && (_jsx(Text, { variant: "secondary", className: "mb-10 text-base leading-relaxed", children: t("intro") })), _jsx(Stack, { gap: "xl", className: "space-y-10", children: sections.map((section, i) => (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-3", children: section.heading }), _jsx(Text, { variant: "secondary", className: "leading-relaxed whitespace-pre-line", children: section.body })] }, i))) })] })), relatedLinks.length > 0 && (_jsxs("div", { className: `mt-14 pt-8 border-t ${themed.border}`, "data-section": "policypageview-div-184", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold mb-3 uppercase tracking-wide text-
|
|
48
|
+
_jsx("div", { className: "prose prose-neutral dark:prose-invert max-w-none", dangerouslySetInnerHTML: { __html: adminHtml } })) : (_jsxs(_Fragment, { children: [t("intro") && (_jsx(Text, { variant: "secondary", className: "mb-10 text-base leading-relaxed", children: t("intro") })), _jsx(Stack, { gap: "xl", className: "space-y-10", children: sections.map((section, i) => (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-3", children: section.heading }), _jsx(Text, { variant: "secondary", className: "leading-relaxed whitespace-pre-line", children: section.body })] }, i))) })] })), relatedLinks.length > 0 && (_jsxs("div", { className: `mt-14 pt-8 border-t ${themed.border}`, "data-section": "policypageview-div-184", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold mb-3 uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: t("relatedTitle") }), _jsx("div", { className: "flex flex-wrap gap-4", "data-section": "policypageview-div-185", children: relatedLinks.map((l) => (_jsx(TextLink, { href: l.href, variant: "muted", className: "text-sm", children: l.label }, l.href))) })] }))] })] }));
|
|
49
49
|
}
|
|
@@ -80,7 +80,7 @@ export async function PublicProfileView({ userId, heroBannerClass = DEFAULT_HERO
|
|
|
80
80
|
const storeDescription = store?.storeDescription ?? pub?.storeDescription;
|
|
81
81
|
const profileHeroCtx = { displayName, photoURL, memberSince, isSeller, storeSlug, flex, page, heroBannerClass };
|
|
82
82
|
const statItems = buildProfileStatItems(t, { listingCount, reviewCount, itemsSold, auctionsWon, totalOrders, isSeller });
|
|
83
|
-
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "publicprofileview-div-186", children: [renderProfileHero(t, profileHeroCtx), _jsxs("div", { className: `${page.container.md} py-10 md:py-12 space-y-10`, children: [renderProfileStatsRow(themed, flex, statItems), renderProfileBioSection(themed, pub), renderStoreDescriptionSection(themed, isSeller, storeSlug ?? null, storeDescription ?? null, storeName, t), renderProfileListingsSection(t, themed, products, storeSlug ?? null), renderProfileReviewsSection(t, themed, reviews, storeSlug ?? null), _jsx("div", { className: "flex justify-center pt-2", children: _jsxs(Link, { href: String(ROUTES.HOME), className: "text-sm text-
|
|
83
|
+
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "publicprofileview-div-186", children: [renderProfileHero(t, profileHeroCtx), _jsxs("div", { className: `${page.container.md} py-10 md:py-12 space-y-10`, children: [renderProfileStatsRow(themed, flex, statItems), renderProfileBioSection(themed, pub), renderStoreDescriptionSection(themed, isSeller, storeSlug ?? null, storeDescription ?? null, storeName, t), renderProfileListingsSection(t, themed, products, storeSlug ?? null), renderProfileReviewsSection(t, themed, reviews, storeSlug ?? null), _jsx("div", { className: "flex justify-center pt-2", children: _jsxs(Link, { href: String(ROUTES.HOME), className: "text-sm text-zinc-400 dark:text-zinc-400 hover:text-neutral-600 dark:hover:text-zinc-300", children: ["\u2190 ", t("backHome")] }) })] })] }));
|
|
84
84
|
}
|
|
85
85
|
function buildProfileStatItems(t, ctx) {
|
|
86
86
|
const { listingCount, reviewCount, itemsSold, auctionsWon, totalOrders, isSeller } = ctx;
|
|
@@ -75,5 +75,5 @@ export function AddressesIndexListing({ onAdd, onEdit, onDelete, }) {
|
|
|
75
75
|
},
|
|
76
76
|
});
|
|
77
77
|
return (_jsxs("div", { className: "space-y-4", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by address, postcode or label...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, view: view, onViewChange: (v) => { if (v === "table")
|
|
78
|
-
return; setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), _jsx("div", { className: "px-3 sm:px-4", children: isLoading ? (_jsx("div", { className: "grid sm:grid-cols-2 gap-4", children: Array.from({ length: 4 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-200 dark:border-slate-700 animate-pulse p-4 space-y-2", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] }, i))) })) : addresses.length === 0 ? (_jsx(Text, { className: "py-8 text-center text-sm text-zinc-500 dark:text-zinc-400", children: table.get(TABLE_KEYS.QUERY) ? `No addresses matching "${table.get(TABLE_KEYS.QUERY)}"` : "No saved addresses." })) : (_jsx(AddressBook, { addresses: addresses, onEdit: onEdit, onDelete: onDelete, onAdd: onAdd })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-
|
|
78
|
+
return; setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), _jsx("div", { className: "px-3 sm:px-4", children: isLoading ? (_jsx("div", { className: "grid sm:grid-cols-2 gap-4", children: Array.from({ length: 4 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-200 dark:border-slate-700 animate-pulse p-4 space-y-2", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] }, i))) })) : addresses.length === 0 ? (_jsx(Text, { className: "py-8 text-center text-sm text-zinc-500 dark:text-zinc-400", children: table.get(TABLE_KEYS.QUERY) ? `No addresses matching "${table.get(TABLE_KEYS.QUERY)}"` : "No saved addresses." })) : (_jsx(AddressBook, { addresses: addresses, onEdit: onEdit, onDelete: onDelete, onAdd: onAdd })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(AddressFilters, { table: pendingTable }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
|
|
79
79
|
}
|
|
@@ -2,5 +2,5 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Div, Heading, Span } from "../../../ui";
|
|
3
3
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
4
4
|
export function MessagesView({ labels = {}, chatId, renderChatList, renderChatWindow, renderMobileBack, renderEmptyState, className = "", }) {
|
|
5
|
-
return (_jsxs(Div, { className: `grid grid-cols-1 md:grid-cols-[280px_1fr] xl:grid-cols-[320px_1fr] 2xl:grid-cols-[360px_1fr] gap-4 h-full min-h-[600px] ${className}`, children: [_jsxs(Div, { className: chatId ? "hidden md:block" : "block", children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 font-semibold", children: labels.title })), renderChatList?.()] }), chatId ? (_jsxs(Div, { className: `flex flex-col ${THEME_CONSTANTS.spacing.gap.xs}`, children: [renderMobileBack?.(), renderChatWindow?.()] })) : (_jsx(Div, { className: "hidden md:flex items-center justify-center text-
|
|
5
|
+
return (_jsxs(Div, { className: `grid grid-cols-1 md:grid-cols-[280px_1fr] xl:grid-cols-[320px_1fr] 2xl:grid-cols-[360px_1fr] gap-4 h-full min-h-[600px] ${className}`, children: [_jsxs(Div, { className: chatId ? "hidden md:block" : "block", children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 font-semibold", children: labels.title })), renderChatList?.()] }), chatId ? (_jsxs(Div, { className: `flex flex-col ${THEME_CONSTANTS.spacing.gap.xs}`, children: [renderMobileBack?.(), renderChatWindow?.()] })) : (_jsx(Div, { className: "hidden md:flex items-center justify-center text-zinc-400 dark:text-zinc-400 border border-dashed border-neutral-200 dark:border-neutral-700 rounded-xl", children: renderEmptyState?.() ?? (_jsx(Span, { children: labels.selectRoom ?? "Select a conversation" })) }))] }));
|
|
6
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useEffect, useCallback } from "react";
|
|
4
|
-
import { Stack, Row, Text, Button, Div } from "../../../ui";
|
|
4
|
+
import { Stack, Row, Text, Button, Div, useToast } from "../../../ui";
|
|
5
5
|
import { useSiteSettings } from "../../../core/hooks/useSiteSettings";
|
|
6
6
|
// ─── type-row config ────────────────────────────────────────────────────────
|
|
7
7
|
const TYPE_ROWS = [
|
|
@@ -31,6 +31,7 @@ function SectionCard({ title, children }) {
|
|
|
31
31
|
return (_jsxs(Div, { className: "rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] overflow-hidden", children: [_jsx(Div, { className: "px-4 py-3 border-b border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface-alt,var(--appkit-color-surface))]", children: _jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest text-[var(--appkit-color-text-muted)]", children: title }) }), _jsx(Div, { className: "px-4", children: children })] }));
|
|
32
32
|
}
|
|
33
33
|
export function NotificationPreferencesPanel({ fetchUrl = "/api/user/notification-preferences", saveUrl = "/api/user/notification-preferences", onSave, }) {
|
|
34
|
+
const { showToast } = useToast();
|
|
34
35
|
const { data: settings } = useSiteSettings();
|
|
35
36
|
const adminChannels = settings?.notificationChannels;
|
|
36
37
|
const [channels, setChannels] = useState({ email: true, whatsapp: true, sms: true });
|
|
@@ -66,19 +67,27 @@ export function NotificationPreferencesPanel({ fetchUrl = "/api/user/notificatio
|
|
|
66
67
|
setSaving(true);
|
|
67
68
|
try {
|
|
68
69
|
const prefs = { channels, types };
|
|
69
|
-
await fetch(saveUrl, {
|
|
70
|
+
const res = await fetch(saveUrl, {
|
|
70
71
|
method: "PUT",
|
|
71
72
|
credentials: "include",
|
|
72
73
|
headers: { "Content-Type": "application/json" },
|
|
73
74
|
body: JSON.stringify(prefs),
|
|
74
75
|
});
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
const body = await res.json().catch(() => null);
|
|
78
|
+
throw new Error(body?.error ?? "Failed to save preferences");
|
|
79
|
+
}
|
|
75
80
|
setSaved(true);
|
|
81
|
+
showToast("Preferences saved.", "success");
|
|
76
82
|
onSave?.(prefs);
|
|
77
83
|
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
showToast(err instanceof Error ? err.message : "Failed to save preferences.", "error");
|
|
86
|
+
}
|
|
78
87
|
finally {
|
|
79
88
|
setSaving(false);
|
|
80
89
|
}
|
|
81
|
-
}, [channels, types, saveUrl, onSave]);
|
|
90
|
+
}, [channels, types, saveUrl, onSave, showToast]);
|
|
82
91
|
if (loading) {
|
|
83
92
|
return (_jsx(Div, { className: "py-8 text-center", children: _jsx(Text, { variant: "secondary", className: "text-sm", children: "Loading preferences\u2026" }) }));
|
|
84
93
|
}
|
|
@@ -56,7 +56,7 @@ function BuyerOfferCard({ offer, onAcceptCounter, onWithdraw, onCheckout, onUpda
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
return (_jsxs(Div, { className: "rounded-xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 p-4 space-y-3", children: [_jsxs(Div, { className: "flex items-start justify-between gap-2 flex-wrap", children: [_jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: "font-semibold text-sm text-zinc-900 dark:text-zinc-100 truncate", children: offer.productTitle ?? "Unknown Product" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: relativeTime(offer.createdAt) })] }), _jsx(Badge, { variant: statusVariant(offer.status), className: "shrink-0 capitalize text-xs", children: offer.status })] }), _jsxs(Div, { className: "flex gap-4 flex-wrap", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-
|
|
59
|
+
return (_jsxs(Div, { className: "rounded-xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 p-4 space-y-3", children: [_jsxs(Div, { className: "flex items-start justify-between gap-2 flex-wrap", children: [_jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: "font-semibold text-sm text-zinc-900 dark:text-zinc-100 truncate", children: offer.productTitle ?? "Unknown Product" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: relativeTime(offer.createdAt) })] }), _jsx(Badge, { variant: statusVariant(offer.status), className: "shrink-0 capitalize text-xs", children: offer.status })] }), _jsxs(Div, { className: "flex gap-4 flex-wrap", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400 uppercase tracking-wide", children: "Listed" }), _jsx(Text, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: formatRupees(offer.listedPrice) })] }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400 uppercase tracking-wide", children: "Your Offer" }), _jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: formatRupees(offer.offerAmount) })] }), offer.counterAmount != null && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400 uppercase tracking-wide", children: "Seller Counter" }), _jsx(Text, { className: "text-sm font-semibold text-blue-600 dark:text-blue-400", children: formatRupees(offer.counterAmount) })] })), offer.lockedPrice != null && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400 uppercase tracking-wide", children: "Agreed Price" }), _jsx(Text, { className: "text-sm font-semibold text-emerald-600 dark:text-emerald-400", children: formatRupees(offer.lockedPrice) })] }))] }), offer.sellerNote && (_jsxs(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 italic", children: ["Seller note: \"", offer.sellerNote, "\""] })), offer.status === "countered" && (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Text, { className: "text-xs text-blue-600 dark:text-blue-400 font-medium", children: ["Seller countered at ", formatRupees(offer.counterAmount), ". Accept or withdraw your offer."] }), _jsxs(Div, { className: "flex gap-2 flex-wrap", children: [_jsx(Button, { size: "sm", variant: "primary", onClick: () => act(() => onAcceptCounter(offer.id), { status: "accepted", lockedPrice: offer.counterAmount }), disabled: isPending, children: isPending ? "Accepting…" : `Accept ${formatRupees(offer.counterAmount)}` }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => setConfirming("withdraw"), disabled: isPending, className: "text-red-600 dark:text-red-400 border border-red-200 dark:border-red-800", children: "Withdraw" })] })] })), offer.status === "accepted" && onCheckout && (_jsx(Button, { size: "sm", variant: "primary", onClick: () => act(() => onCheckout(offer.id), { status: "paid" }), disabled: isPending, children: isPending ? "Processing…" : "Checkout at Agreed Price" })), offer.status === "pending" && (_jsx(Button, { size: "sm", variant: "ghost", onClick: () => setConfirming("withdraw"), disabled: isPending, className: "text-red-600 dark:text-red-400 border border-red-200 dark:border-red-800 text-xs", children: "Withdraw Offer" })), confirming === "withdraw" && (_jsxs(Div, { className: "flex gap-2", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => act(() => onWithdraw(offer.id), { status: "withdrawn" }), disabled: isPending, className: "text-red-600 dark:text-red-400 border border-red-200 dark:border-red-800", children: isPending ? "Withdrawing…" : "Confirm Withdraw" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => setConfirming(null), disabled: isPending, children: "Cancel" })] })), error && _jsx(Alert, { variant: "error", children: _jsx(Text, { className: "text-xs", children: error }) })] }));
|
|
60
60
|
}
|
|
61
61
|
export function UserOffersPanel({ fetchEndpoint = "/api/user/offers", onAcceptCounter, onWithdraw, onCheckout, className = "", }) {
|
|
62
62
|
const [offers, setOffers] = useState([]);
|
|
@@ -90,5 +90,5 @@ export function UserOffersPanel({ fetchEndpoint = "/api/user/offers", onAcceptCo
|
|
|
90
90
|
function handleUpdate(id, patch) {
|
|
91
91
|
setOffers((prev) => prev.map((o) => (o.id === id ? { ...o, ...patch } : o)));
|
|
92
92
|
}
|
|
93
|
-
return (_jsxs(Div, { className: `space-y-4 ${className}`, children: [_jsx(LoginRequiredModal, { isOpen: showLoginModal, onClose: () => setShowLoginModal(false), message: "You need to be signed in to manage your offers. Please log in or create an account to continue." }), _jsxs(Div, { className: "flex items-center justify-between", children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: "My Offers" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: loadOffers, disabled: loading, className: "border border-zinc-300 dark:border-zinc-600 text-xs", children: loading ? "Refreshing…" : ACTIONS.USER["refresh-offers"].label })] }), fetchError && _jsx(Alert, { variant: "error", children: _jsx(Text, { className: "text-sm", children: fetchError }) }), loading && (_jsx(Div, { className: "flex justify-center py-12", children: _jsx(Spinner, { size: "lg" }) })), !loading && offers.length === 0 && (_jsx(Div, { className: "text-center py-12", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-
|
|
93
|
+
return (_jsxs(Div, { className: `space-y-4 ${className}`, children: [_jsx(LoginRequiredModal, { isOpen: showLoginModal, onClose: () => setShowLoginModal(false), message: "You need to be signed in to manage your offers. Please log in or create an account to continue." }), _jsxs(Div, { className: "flex items-center justify-between", children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold text-zinc-900 dark:text-zinc-100", children: "My Offers" }), _jsx(Button, { size: "sm", variant: "ghost", onClick: loadOffers, disabled: loading, className: "border border-zinc-300 dark:border-zinc-600 text-xs", children: loading ? "Refreshing…" : ACTIONS.USER["refresh-offers"].label })] }), fetchError && _jsx(Alert, { variant: "error", children: _jsx(Text, { className: "text-sm", children: fetchError }) }), loading && (_jsx(Div, { className: "flex justify-center py-12", children: _jsx(Spinner, { size: "lg" }) })), !loading && offers.length === 0 && (_jsx(Div, { className: "text-center py-12", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-400 text-sm", children: "No offers yet" }) })), !loading && offers.length > 0 && (_jsx(Div, { className: "space-y-3", children: offers.map((offer) => (_jsx(BuyerOfferCard, { offer: offer, onAcceptCounter: onAcceptCounter, onWithdraw: onWithdraw, onCheckout: onCheckout, onUpdate: handleUpdate, onNeedsLogin: () => setShowLoginModal(true) }, offer.id))) }))] }));
|
|
94
94
|
}
|
|
@@ -49,11 +49,11 @@ function DrawerContent({ groups, items, activeHref, onItemClick, }) {
|
|
|
49
49
|
const hasActive = group.items.some((i) => activeHref === i.href || activeHref.startsWith(i.href + "/"));
|
|
50
50
|
return (_jsxs("div", { className: "mb-0.5", children: [_jsxs("button", { type: "button", onClick: () => toggle(group.title), className: `flex w-full items-center justify-between px-4 py-2 text-[0.6875rem] font-semibold uppercase tracking-widest transition-colors ${hasActive && !isOpen
|
|
51
51
|
? "text-primary-600 dark:text-primary-400"
|
|
52
|
-
: "text-zinc-400 dark:text-zinc-
|
|
52
|
+
: "text-zinc-400 dark:text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"}`, children: [_jsx("span", { children: group.title }), _jsx("svg", { className: `w-3 h-3 transition-transform duration-150 ${isOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 9l-7 7-7-7" }) })] }), isOpen && (_jsx(Ul, { className: "space-y-0.5 px-3 pb-1", children: group.items.map((item) => (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isNavItemActive(item, activeHref), onClick: onItemClick }) }, item.href))) }))] }, group.title));
|
|
53
53
|
}) }));
|
|
54
54
|
}
|
|
55
55
|
function DrawerPanel({ title, onClose, children, }) {
|
|
56
|
-
return (_jsxs("div", { className: "hidden md:block", children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 bg-white dark:bg-slate-900 border-l border-zinc-200 dark:border-slate-700 flex flex-col shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: [_jsx("span", { className: "text-xs font-semibold uppercase tracking-widest text-zinc-400 dark:text-zinc-
|
|
56
|
+
return (_jsxs("div", { className: "hidden md:block", children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 bg-white dark:bg-slate-900 border-l border-zinc-200 dark:border-slate-700 flex flex-col shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: [_jsx("span", { className: "text-xs font-semibold uppercase tracking-widest text-zinc-400 dark:text-zinc-400", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: children })] })] }));
|
|
57
57
|
}
|
|
58
58
|
export function UserSidebar({ items, groups, mobileOpen = false, onCloseMobile, desktopOpen = false, onToggle, variant = "overlay" }) {
|
|
59
59
|
const pathname = usePathname();
|
|
@@ -74,7 +74,7 @@ export function UserSidebar({ items, groups, mobileOpen = false, onCloseMobile,
|
|
|
74
74
|
height: "calc(100vh - var(--header-height, 3.5rem))",
|
|
75
75
|
width: "13rem",
|
|
76
76
|
transform: desktopOpen ? "translateX(0)" : "translateX(calc(-100% + 1.25rem))",
|
|
77
|
-
}, children: [_jsxs("div", { className: "flex-1 bg-white dark:bg-slate-900 border-r border-zinc-200 dark:border-slate-800 flex flex-col overflow-hidden shadow-xl", children: [_jsx("div", { className: "px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: _jsx("span", { className: "text-xs font-semibold uppercase tracking-widest text-zinc-400 dark:text-zinc-
|
|
77
|
+
}, children: [_jsxs("div", { className: "flex-1 bg-white dark:bg-slate-900 border-r border-zinc-200 dark:border-slate-800 flex flex-col overflow-hidden shadow-xl", children: [_jsx("div", { className: "px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: _jsx("span", { className: "text-xs font-semibold uppercase tracking-widest text-zinc-400 dark:text-zinc-400", children: "My Account" }) }), _jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname }) })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx("div", { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "My Account", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }) }) })] }));
|
|
78
78
|
}
|
|
79
79
|
// ── Overlay variant (default) — portal on desktop, bottom-sheet on mobile ─
|
|
80
80
|
const content = (_jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }));
|
|
@@ -96,5 +96,5 @@ function renderNewTicketDrawer(props) {
|
|
|
96
96
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
97
97
|
function renderTicketDetailDrawer(props) {
|
|
98
98
|
const { detailOpen, setDetailOpen, selectedTicket, replyBody, setReplyBody, replyMutation } = props;
|
|
99
|
-
return (_jsx(SideDrawer, { isOpen: detailOpen, onClose: () => setDetailOpen(false), title: selectedTicket?.subject ?? "Ticket", children: selectedTicket && (_jsxs(Div, { className: "flex flex-col gap-4 p-4", children: [_jsxs(Div, { className: "flex flex-wrap gap-2", children: [_jsx("span", { className: `inline-flex rounded-full px-2.5 py-1 text-xs font-medium ${STATUS_BADGE[selectedTicket.status] ?? STATUS_BADGE.open}`, children: selectedTicket.status.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: selectedTicket.category.replace(/_/g, " ") }), selectedTicket.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: ", selectedTicket.orderId] })] }), selectedTicket.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 uppercase tracking-wide", children: "Your description" }), _jsx(Text, { className: "whitespace-pre-wrap text-sm text-zinc-700 dark:text-zinc-200", children: selectedTicket.description })] })), (selectedTicket.messages ?? []).length > 0 && (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 uppercase tracking-wide", children: "Messages" }), _jsx("div", { className: "space-y-2 max-h-72 overflow-y-auto", children: (selectedTicket.messages ?? []).map((msg, i) => (_jsxs("div", { className: `rounded-lg p-3 text-sm ${msg.authorRole === "user" ? "bg-zinc-50 border border-zinc-200 dark:bg-zinc-900/40 dark:border-zinc-700" : "bg-blue-50 border border-blue-200 dark:bg-blue-900/20 dark:border-blue-800"}`, children: [_jsxs("div", { className: "mb-1 flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-
|
|
99
|
+
return (_jsx(SideDrawer, { isOpen: detailOpen, onClose: () => setDetailOpen(false), title: selectedTicket?.subject ?? "Ticket", children: selectedTicket && (_jsxs(Div, { className: "flex flex-col gap-4 p-4", children: [_jsxs(Div, { className: "flex flex-wrap gap-2", children: [_jsx("span", { className: `inline-flex rounded-full px-2.5 py-1 text-xs font-medium ${STATUS_BADGE[selectedTicket.status] ?? STATUS_BADGE.open}`, children: selectedTicket.status.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: selectedTicket.category.replace(/_/g, " ") }), selectedTicket.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: ", selectedTicket.orderId] })] }), selectedTicket.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 uppercase tracking-wide", children: "Your description" }), _jsx(Text, { className: "whitespace-pre-wrap text-sm text-zinc-700 dark:text-zinc-200", children: selectedTicket.description })] })), (selectedTicket.messages ?? []).length > 0 && (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Messages" }), _jsx("div", { className: "space-y-2 max-h-72 overflow-y-auto", children: (selectedTicket.messages ?? []).map((msg, i) => (_jsxs("div", { className: `rounded-lg p-3 text-sm ${msg.authorRole === "user" ? "bg-zinc-50 border border-zinc-200 dark:bg-zinc-900/40 dark:border-zinc-700" : "bg-blue-50 border border-blue-200 dark:bg-blue-900/20 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))) })] })), selectedTicket.status !== "closed" && selectedTicket.status !== "resolved" && (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Reply" }), _jsx("textarea", { value: replyBody, onChange: (e) => setReplyBody(e.target.value), rows: 3, placeholder: "Add a message to your ticket\u2026", className: CLS_INPUT }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: replyMutation.isPending, disabled: !replyBody.trim() || replyMutation.isPending, onClick: () => replyMutation.mutate(), children: "Send reply" })] }))] })) }));
|
|
100
100
|
}
|
|
@@ -23,7 +23,7 @@ const STATUS_OPTIONS = ADMIN_EVENT_ENTRY_STATUS_TABS;
|
|
|
23
23
|
function EntriesFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, pendingFilters, setPendingFilters, applyFilters, }) {
|
|
24
24
|
if (!filterOpen)
|
|
25
25
|
return null;
|
|
26
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-
|
|
26
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }));
|
|
27
27
|
}
|
|
28
28
|
export function AdminAllEventEntriesView({ children, ...props }) {
|
|
29
29
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -13,6 +13,7 @@ import { ROW_ACTION_META, ROW_ACTION_ID } from "../../products/constants/action-
|
|
|
13
13
|
import { toRecordArray, toRelativeDate, toRupees, toStringValue, useAdminListingData, } from "../hooks/useAdminListingData";
|
|
14
14
|
import { DataTable } from "./DataTable";
|
|
15
15
|
import { apiClient } from "../../../http";
|
|
16
|
+
import { useBottomActions } from "../../layout";
|
|
16
17
|
const PAGE_SIZE = 25;
|
|
17
18
|
const FILTER_KEYS = ["status"];
|
|
18
19
|
const DEFAULT_SORT = "-bidTime";
|
|
@@ -25,7 +26,7 @@ const STATUS_OPTIONS = ADMIN_BID_STATUS_TABS;
|
|
|
25
26
|
function BidsFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, pendingFilters, setPendingFilters, applyFilters, }) {
|
|
26
27
|
if (!filterOpen)
|
|
27
28
|
return null;
|
|
28
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-
|
|
29
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }));
|
|
29
30
|
}
|
|
30
31
|
export function AdminBidsView({ children, ...props }) {
|
|
31
32
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -112,6 +113,9 @@ export function AdminBidsView({ children, ...props }) {
|
|
|
112
113
|
] }), 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-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), _jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No bids found", renderRowActions: (row) => {
|
|
113
114
|
const bidRow = row;
|
|
114
115
|
const isCancelled = bidRow.status === "cancelled" || bidRow.status === "voided";
|
|
116
|
+
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
117
|
+
{ id: ROW_ACTION_ID.CANCEL, label: ACTIONS.ADMIN["cancel-bid"].label, variant: "secondary", onClick: () => { selection.clearSelection(); } },
|
|
118
|
+
] } } : {});
|
|
115
119
|
return (_jsx(RowActionMenu, { actions: [
|
|
116
120
|
{
|
|
117
121
|
label: ROW_ACTION_META[ROW_ACTION_ID.CANCEL].label,
|
|
@@ -13,6 +13,7 @@ import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
|
13
13
|
import { toRecordArray, toRelativeDate, toStringValue, useAdminListingData, } from "../hooks/useAdminListingData";
|
|
14
14
|
import { DataTable } from "./DataTable";
|
|
15
15
|
import { AdminBlogEditorView } from "./AdminBlogEditorView";
|
|
16
|
+
import { useBottomActions } from "../../layout";
|
|
16
17
|
const PAGE_SIZE = 25;
|
|
17
18
|
const FILTER_KEYS = ["status", "isFeatured"];
|
|
18
19
|
const DEFAULT_SORT = "-publishedAt";
|
|
@@ -30,7 +31,7 @@ const FEATURED_TABS = [
|
|
|
30
31
|
function BlogFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, pendingFilters, setPendingFilters, applyFilters, }) {
|
|
31
32
|
if (!filterOpen)
|
|
32
33
|
return null;
|
|
33
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-
|
|
34
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: [_jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }), _jsx(FilterChipGroup, { label: "Featured", tabs: FEATURED_TABS, value: pendingFilters.isFeatured ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, isFeatured: id })), allId: "" })] }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }));
|
|
34
35
|
}
|
|
35
36
|
export function AdminBlogView({ children, getRowHref, ...props }) {
|
|
36
37
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -105,6 +106,10 @@ export function AdminBlogView({ children, getRowHref, ...props }) {
|
|
|
105
106
|
if (hasChildren) {
|
|
106
107
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
107
108
|
}
|
|
109
|
+
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
110
|
+
{ id: "publish", label: ACTIONS.ADMIN["publish-blog"].label, variant: "primary", onClick: () => { selection.clearSelection(); } },
|
|
111
|
+
{ id: "draft", label: ACTIONS.ADMIN["draft-blog"].label, variant: "secondary", onClick: () => { selection.clearSelection(); } },
|
|
112
|
+
] } } : {});
|
|
108
113
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(Heading, { level: 1, className: "sr-only", children: "Blog Posts" }), _jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search articles, authors, or tags", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: openCreatePanel, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), "New Post"] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
109
114
|
{ id: "publish", label: ACTIONS.ADMIN["publish-blog"].label, variant: "primary", onClick: () => { selection.clearSelection(); } },
|
|
110
115
|
{ id: "draft", label: ACTIONS.ADMIN["draft-blog"].label, variant: "secondary", onClick: () => { selection.clearSelection(); } },
|
|
@@ -12,6 +12,7 @@ import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
|
12
12
|
import { toRecordArray, toRelativeDate, toStringValue, useAdminListingData, } from "../hooks/useAdminListingData";
|
|
13
13
|
import { DataTable } from "./DataTable";
|
|
14
14
|
import { AdminBrandEditorView } from "./AdminBrandEditorView";
|
|
15
|
+
import { useBottomActions } from "../../layout";
|
|
15
16
|
const PAGE_SIZE = 25;
|
|
16
17
|
const FILTER_KEYS = ["isActive"];
|
|
17
18
|
const DEFAULT_SORT = "displayOrder";
|
|
@@ -24,7 +25,7 @@ const SORT_OPTIONS = [
|
|
|
24
25
|
function BrandsFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, pendingFilters, setPendingFilters, applyFilters, }) {
|
|
25
26
|
if (!filterOpen)
|
|
26
27
|
return null;
|
|
27
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-
|
|
28
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsxs("div", { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest text-zinc-500 dark:text-zinc-400", children: "Status" }), _jsx("div", { className: "flex flex-wrap gap-2", children: [{ label: "All", value: "" }, { label: "Active", value: "true" }, { label: "Inactive", value: "false" }].map((opt) => (_jsx("button", { type: "button", onClick: () => setPendingFilters((p) => ({ ...p, isActive: opt.value })), className: `rounded-full px-3 py-1 text-xs font-medium border transition-colors ${(pendingFilters.isActive || "") === opt.value ? "bg-primary text-white border-primary" : "border-zinc-300 dark:border-slate-600 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-slate-800"}`, children: opt.label }, opt.label))) })] }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }));
|
|
28
29
|
}
|
|
29
30
|
export function AdminBrandsView({ children, ...props }) {
|
|
30
31
|
const hasChildren = React.Children.count(children) > 0;
|
|
@@ -85,6 +86,10 @@ export function AdminBrandsView({ children, ...props }) {
|
|
|
85
86
|
if (hasChildren) {
|
|
86
87
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
87
88
|
}
|
|
89
|
+
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
90
|
+
{ id: "edit", label: ACTIONS.ADMIN["edit-brand"].label, variant: "primary", onClick: () => { const id = selection.selectedIds[0]; if (id)
|
|
91
|
+
openEditPanel(id); selection.clearSelection(); } },
|
|
92
|
+
] } } : {});
|
|
88
93
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search brands by name or slug", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: openCreatePanel, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), "Add Brand"] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
89
94
|
{ id: "edit", label: ACTIONS.ADMIN["edit-brand"].label, variant: "primary", onClick: () => { const id = selection.selectedIds[0]; if (id)
|
|
90
95
|
openEditPanel(id); selection.clearSelection(); } },
|
|
@@ -13,7 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
13
13
|
* static).
|
|
14
14
|
*/
|
|
15
15
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
16
|
-
import { Button, Checkbox, ConfirmDeleteModal, Container, Heading, Input, Row, Section, Select, Stack, Text, Textarea, } from "../../../ui";
|
|
16
|
+
import { Button, Checkbox, ConfirmDeleteModal, Container, Heading, Input, Row, Section, Select, Stack, Text, Textarea, useToast, } from "../../../ui";
|
|
17
17
|
import { FieldInput, FormShellContext, useFormShellState } from "../../../ui/forms";
|
|
18
18
|
import { BundleItemsPicker, defaultBundleItemsFetch, } from "../../categories/components/BundleItemsPicker";
|
|
19
19
|
import { BundleDynamicRuleEditor } from "../../categories/components/BundleDynamicRuleEditor";
|
|
@@ -81,6 +81,7 @@ export function AdminBundleEditorView({ bundleId, onSaved, onDeleted, }) {
|
|
|
81
81
|
const [apiError, setApiError] = useState(null);
|
|
82
82
|
const [metadata, setMetadata] = useState({});
|
|
83
83
|
const { shellCtx, setFieldError, clearErrors } = useFormShellState();
|
|
84
|
+
const { showToast } = useToast();
|
|
84
85
|
// Load existing bundle on mount when editing
|
|
85
86
|
useEffect(() => {
|
|
86
87
|
if (!bundleId)
|
|
@@ -160,6 +161,7 @@ export function AdminBundleEditorView({ bundleId, onSaved, onDeleted, }) {
|
|
|
160
161
|
});
|
|
161
162
|
if (!res.ok)
|
|
162
163
|
throw new Error(`Update failed: ${res.status}`);
|
|
164
|
+
showToast("Bundle saved.", "success");
|
|
163
165
|
onSaved?.(bundleId);
|
|
164
166
|
}
|
|
165
167
|
else {
|
|
@@ -173,19 +175,20 @@ export function AdminBundleEditorView({ bundleId, onSaved, onDeleted, }) {
|
|
|
173
175
|
}
|
|
174
176
|
const json = (await res.json());
|
|
175
177
|
const newId = json?.data?.id;
|
|
178
|
+
showToast("Bundle created.", "success");
|
|
176
179
|
if (newId)
|
|
177
180
|
onSaved?.(newId);
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
catch (err) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
const msg = err instanceof Error ? err.message : BUNDLE_COPY.adminEditor.errors.saveFailed;
|
|
185
|
+
setApiError(msg);
|
|
186
|
+
showToast(msg, "error");
|
|
184
187
|
}
|
|
185
188
|
finally {
|
|
186
189
|
setSaving(false);
|
|
187
190
|
}
|
|
188
|
-
}, [form, bundleId, isEdit, onSaved, clearErrors, setFieldError]);
|
|
191
|
+
}, [form, bundleId, isEdit, onSaved, clearErrors, setFieldError, showToast]);
|
|
189
192
|
const handleDelete = useCallback(async () => {
|
|
190
193
|
if (!bundleId)
|
|
191
194
|
return;
|
|
@@ -195,18 +198,19 @@ export function AdminBundleEditorView({ bundleId, onSaved, onDeleted, }) {
|
|
|
195
198
|
const res = await fetch(`/api/admin/bundles/${encodeURIComponent(bundleId)}`, { method: "DELETE" });
|
|
196
199
|
if (!res.ok)
|
|
197
200
|
throw new Error(`Delete failed: ${res.status}`);
|
|
201
|
+
showToast("Bundle deleted.", "success");
|
|
198
202
|
setDeleteConfirmOpen(false);
|
|
199
203
|
onDeleted?.();
|
|
200
204
|
}
|
|
201
205
|
catch (err) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
const msg = err instanceof Error ? err.message : BUNDLE_COPY.adminEditor.errors.deleteFailed;
|
|
207
|
+
setApiError(msg);
|
|
208
|
+
showToast(msg, "error");
|
|
205
209
|
}
|
|
206
210
|
finally {
|
|
207
211
|
setDeleting(false);
|
|
208
212
|
}
|
|
209
|
-
}, [bundleId, onDeleted]);
|
|
213
|
+
}, [bundleId, onDeleted, showToast]);
|
|
210
214
|
const fetchProducts = useMemo(() => defaultBundleItemsFetch, []);
|
|
211
215
|
if (loading) {
|
|
212
216
|
return (_jsx(Section, { className: "py-10", children: _jsx(Container, { size: "lg", children: _jsx(Text, { children: BUNDLE_COPY.adminEditor.loading }) }) }));
|