@mohasinac/appkit 2.7.26 → 2.7.30

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.
Files changed (363) hide show
  1. package/dist/_internal/client/features/classified/ClassifiedDetailView.js +2 -2
  2. package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +2 -2
  3. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
  4. package/dist/_internal/server/features/checkout/actions.js +42 -35
  5. package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
  6. package/dist/_internal/server/features/classified/adapters.js +24 -0
  7. package/dist/_internal/server/features/classified/index.d.ts +3 -0
  8. package/dist/_internal/server/features/classified/index.js +3 -0
  9. package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
  10. package/dist/_internal/server/features/classified/metadata.js +43 -0
  11. package/dist/_internal/server/features/classified/og.d.ts +30 -0
  12. package/dist/_internal/server/features/classified/og.js +76 -0
  13. package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
  14. package/dist/_internal/server/features/digital-code/adapters.js +29 -0
  15. package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
  16. package/dist/_internal/server/features/digital-code/index.js +3 -0
  17. package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
  18. package/dist/_internal/server/features/digital-code/metadata.js +36 -0
  19. package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
  20. package/dist/_internal/server/features/digital-code/og.js +77 -0
  21. package/dist/_internal/server/features/live/adapters.d.ts +21 -0
  22. package/dist/_internal/server/features/live/adapters.js +34 -0
  23. package/dist/_internal/server/features/live/index.d.ts +3 -0
  24. package/dist/_internal/server/features/live/index.js +3 -0
  25. package/dist/_internal/server/features/live/metadata.d.ts +8 -0
  26. package/dist/_internal/server/features/live/metadata.js +39 -0
  27. package/dist/_internal/server/features/live/og.d.ts +27 -0
  28. package/dist/_internal/server/features/live/og.js +72 -0
  29. package/dist/_internal/server/features/promotions/actions.js +4 -3
  30. package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
  31. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
  32. package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
  33. package/dist/_internal/shared/actions/action-registry.js +310 -8
  34. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  35. package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
  36. package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
  37. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  38. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
  39. package/dist/_internal/shared/features/events/schema.d.ts +8 -8
  40. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  41. package/dist/_internal/shared/features/products/schema.d.ts +42 -42
  42. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  43. package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
  44. package/dist/_internal/shared/media/limits.js +4 -3
  45. package/dist/client.d.ts +2 -0
  46. package/dist/client.js +1 -0
  47. package/dist/configs/next.js +4 -0
  48. package/dist/constants/table-keys.d.ts +6 -0
  49. package/dist/constants/table-keys.js +9 -0
  50. package/dist/core/hooks/useSyncManager.js +9 -8
  51. package/dist/features/about/components/FeesView.js +10 -7
  52. package/dist/features/about/components/HelpPageView.js +10 -1
  53. package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
  54. package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
  55. package/dist/features/about/components/HowOffersWorkView.js +10 -1
  56. package/dist/features/about/components/HowOrdersWorkView.js +10 -1
  57. package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
  58. package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
  59. package/dist/features/about/components/HowReviewsWorkView.js +10 -1
  60. package/dist/features/about/components/PublicProfileView.js +44 -14
  61. package/dist/features/about/components/SecurityPrivacyView.js +7 -1
  62. package/dist/features/account/components/AddressesIndexListing.js +2 -2
  63. package/dist/features/account/components/NotificationBell.js +27 -16
  64. package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
  65. package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
  66. package/dist/features/account/components/UserSidebar.js +4 -4
  67. package/dist/features/account/components/UserSupportView.js +16 -6
  68. package/dist/features/account/components/index.d.ts +2 -0
  69. package/dist/features/account/components/index.js +1 -0
  70. package/dist/features/account/schemas/index.d.ts +4 -4
  71. package/dist/features/account/types/index.d.ts +34 -0
  72. package/dist/features/admin/actions/admin-actions.js +4 -3
  73. package/dist/features/admin/actions/notification-actions.d.ts +24 -22
  74. package/dist/features/admin/actions/notification-actions.js +122 -22
  75. package/dist/features/admin/components/AdminAdEditorView.js +29 -15
  76. package/dist/features/admin/components/AdminAdsView.js +22 -28
  77. package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
  78. package/dist/features/admin/components/AdminBidsView.js +10 -3
  79. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  80. package/dist/features/admin/components/AdminBlogView.js +8 -3
  81. package/dist/features/admin/components/AdminBrandsView.js +7 -2
  82. package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
  83. package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
  84. package/dist/features/admin/components/AdminCarouselView.js +13 -7
  85. package/dist/features/admin/components/AdminCategoriesView.js +8 -3
  86. package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
  87. package/dist/features/admin/components/AdminContactView.js +6 -1
  88. package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
  89. package/dist/features/admin/components/AdminCouponsView.js +6 -1
  90. package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
  91. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  92. package/dist/features/admin/components/AdminFaqsView.js +7 -2
  93. package/dist/features/admin/components/AdminFeaturesView.js +4 -3
  94. package/dist/features/admin/components/AdminMediaView.js +9 -8
  95. package/dist/features/admin/components/AdminNavigationView.js +10 -17
  96. package/dist/features/admin/components/AdminNewsletterView.js +6 -1
  97. package/dist/features/admin/components/AdminNotificationsView.js +11 -3
  98. package/dist/features/admin/components/AdminOrdersView.js +6 -1
  99. package/dist/features/admin/components/AdminPayoutsView.js +10 -3
  100. package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
  101. package/dist/features/admin/components/AdminProductsView.js +18 -12
  102. package/dist/features/admin/components/AdminReviewsView.js +33 -24
  103. package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
  104. package/dist/features/admin/components/AdminScammersView.js +28 -26
  105. package/dist/features/admin/components/AdminSectionsView.js +112 -99
  106. package/dist/features/admin/components/AdminSessionsView.js +10 -3
  107. package/dist/features/admin/components/AdminSidebar.js +4 -4
  108. package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
  109. package/dist/features/admin/components/AdminStoresView.js +6 -1
  110. package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
  111. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  112. package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
  113. package/dist/features/admin/components/AdminTeamView.js +6 -1
  114. package/dist/features/admin/components/AdminUserEditorView.js +8 -15
  115. package/dist/features/admin/components/AdminUsersView.js +6 -1
  116. package/dist/features/admin/components/AdminViewCards.js +4 -3
  117. package/dist/features/admin/components/DashboardStats.js +2 -2
  118. package/dist/features/admin/components/DataTable.js +2 -2
  119. package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
  120. package/dist/features/admin/repository/chat.repository.js +8 -8
  121. package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
  122. package/dist/features/admin/repository/site-settings.repository.js +11 -9
  123. package/dist/features/admin/schemas/firestore.d.ts +38 -0
  124. package/dist/features/admin/schemas/firestore.js +15 -0
  125. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -19
  126. package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
  127. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
  128. package/dist/features/auctions/components/index.d.ts +0 -1
  129. package/dist/features/auctions/components/index.js +0 -1
  130. package/dist/features/auctions/schemas/index.d.ts +14 -14
  131. package/dist/features/auth/actions/realtime-token-actions.js +19 -4
  132. package/dist/features/auth/components/RegisterForm.js +8 -4
  133. package/dist/features/auth/consent-otp.d.ts +2 -0
  134. package/dist/features/auth/consent-otp.js +8 -0
  135. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  136. package/dist/features/auth/schemas/firestore.js +18 -25
  137. package/dist/features/auth/schemas/index.d.ts +2 -2
  138. package/dist/features/before-after/api/[id]/route.js +8 -6
  139. package/dist/features/before-after/schemas/index.d.ts +2 -2
  140. package/dist/features/blog/actions/blog-actions.d.ts +3 -3
  141. package/dist/features/blog/components/BlogIndexListing.js +21 -2
  142. package/dist/features/blog/components/BlogPostForm.js +11 -5
  143. package/dist/features/blog/components/BlogPostView.js +10 -2
  144. package/dist/features/blog/schemas/index.d.ts +18 -18
  145. package/dist/features/cart/components/CartDrawer.js +3 -2
  146. package/dist/features/cart/repository/cart.repository.js +4 -3
  147. package/dist/features/cart/utils/pending-ops.d.ts +1 -1
  148. package/dist/features/categories/api/[id]/route.js +4 -3
  149. package/dist/features/categories/api/route.js +4 -3
  150. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  151. package/dist/features/categories/components/BrandDetailTabs.js +2 -2
  152. package/dist/features/categories/components/BundleCollage.d.ts +8 -0
  153. package/dist/features/categories/components/BundleCollage.js +50 -0
  154. package/dist/features/categories/components/BundleDetailView.js +2 -10
  155. package/dist/features/categories/components/BundleItemsPicker.js +20 -13
  156. package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
  157. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  158. package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
  159. package/dist/features/categories/components/CategoryProductsListing.js +52 -13
  160. package/dist/features/categories/components/index.d.ts +2 -0
  161. package/dist/features/categories/components/index.js +1 -0
  162. package/dist/features/categories/schemas/index.d.ts +6 -6
  163. package/dist/features/checkout/actions/checkout-actions.js +4 -3
  164. package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
  165. package/dist/features/classified/components/ClassifiedFilters.d.ts +8 -0
  166. package/dist/features/classified/components/ClassifiedFilters.js +19 -0
  167. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
  168. package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
  169. package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
  170. package/dist/features/classified/components/ClassifiedListView.js +43 -0
  171. package/dist/features/classified/components/index.d.ts +6 -0
  172. package/dist/features/classified/components/index.js +3 -0
  173. package/dist/features/collections/api/[slug]/route.js +16 -12
  174. package/dist/features/collections/schemas/index.d.ts +5 -5
  175. package/dist/features/consultation/api/[id]/route.js +12 -9
  176. package/dist/features/consultation/components/ConsultationForm.js +3 -2
  177. package/dist/features/consultation/schemas/index.d.ts +6 -6
  178. package/dist/features/contact/email.js +77 -116
  179. package/dist/features/copilot/components/AdminCopilotView.js +12 -2
  180. package/dist/features/corporate/api/[id]/route.js +12 -9
  181. package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
  182. package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +8 -0
  183. package/dist/features/digital-codes/components/DigitalCodeFilters.js +16 -0
  184. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
  185. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
  186. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
  187. package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
  188. package/dist/features/digital-codes/components/index.d.ts +6 -0
  189. package/dist/features/digital-codes/components/index.js +3 -0
  190. package/dist/features/events/actions/event-actions.js +4 -3
  191. package/dist/features/events/components/AdminEventEditorView.js +3 -2
  192. package/dist/features/events/components/AdminEventsView.js +4 -2
  193. package/dist/features/events/components/EventPollWidget.js +5 -5
  194. package/dist/features/events/components/EventsIndexListing.js +2 -2
  195. package/dist/features/events/schemas/index.d.ts +20 -20
  196. package/dist/features/faq/actions/faq-actions.d.ts +8 -8
  197. package/dist/features/faq/components/ContactCTA.js +3 -1
  198. package/dist/features/faq/components/FAQAccordion.js +1 -1
  199. package/dist/features/faq/schemas/index.d.ts +4 -4
  200. package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
  201. package/dist/features/filters/AsyncFacetSection.js +65 -0
  202. package/dist/features/forms/Checkbox.js +2 -2
  203. package/dist/features/forms/Input.js +2 -2
  204. package/dist/features/forms/Radio.js +5 -5
  205. package/dist/features/forms/Select.js +2 -2
  206. package/dist/features/forms/Slider.js +2 -2
  207. package/dist/features/forms/Textarea.js +2 -2
  208. package/dist/features/homepage/api/[id]/route.js +4 -3
  209. package/dist/features/homepage/api/sections/[id]/route.js +12 -9
  210. package/dist/features/homepage/components/AdSlot.js +2 -1
  211. package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
  212. package/dist/features/homepage/components/BrandsSection.js +2 -2
  213. package/dist/features/homepage/components/CTABannerSection.js +2 -2
  214. package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
  215. package/dist/features/homepage/components/CharacterHotspot.js +119 -157
  216. package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
  217. package/dist/features/homepage/components/CustomCardsSection.js +8 -6
  218. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  219. package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
  220. package/dist/features/homepage/components/HeroBanner.js +5 -4
  221. package/dist/features/homepage/components/HeroCarousel.js +13 -26
  222. package/dist/features/homepage/components/HowItWorksSection.js +4 -2
  223. package/dist/features/homepage/components/SocialFeedSection.js +2 -2
  224. package/dist/features/homepage/components/SocialPostCard.js +3 -2
  225. package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
  226. package/dist/features/layout/AppLayoutShell.d.ts +8 -2
  227. package/dist/features/layout/AppLayoutShell.js +55 -84
  228. package/dist/features/layout/BottomActions.js +43 -48
  229. package/dist/features/layout/NavbarWithSettings.d.ts +6 -0
  230. package/dist/features/layout/NavbarWithSettings.js +11 -0
  231. package/dist/features/live/components/LiveItemFilters.d.ts +8 -0
  232. package/dist/features/live/components/LiveItemFilters.js +23 -0
  233. package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
  234. package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
  235. package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
  236. package/dist/features/live/components/LiveItemsListView.js +43 -0
  237. package/dist/features/live/components/index.d.ts +6 -0
  238. package/dist/features/live/components/index.js +3 -0
  239. package/dist/features/media/MediaLightbox.js +8 -14
  240. package/dist/features/media/types/index.d.ts +2 -2
  241. package/dist/features/media/upload/CameraCapture.js +2 -2
  242. package/dist/features/media/upload/ImageUpload.js +4 -2
  243. package/dist/features/media/upload/MediaUploadField.js +24 -8
  244. package/dist/features/media/upload/MediaUploadList.js +1 -1
  245. package/dist/features/orders/actions/order-actions.js +4 -3
  246. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
  247. package/dist/features/orders/components/OrderFilters.js +12 -9
  248. package/dist/features/orders/schemas/index.d.ts +6 -6
  249. package/dist/features/pre-orders/api/[id]/route.js +12 -9
  250. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
  251. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +27 -20
  252. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
  253. package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
  254. package/dist/features/pre-orders/components/PreorderCard.js +2 -13
  255. package/dist/features/pre-orders/components/index.d.ts +1 -1
  256. package/dist/features/pre-orders/components/index.js +1 -1
  257. package/dist/features/pre-orders/schemas/index.d.ts +10 -10
  258. package/dist/features/products/api/[id]/route.js +9 -7
  259. package/dist/features/products/api/route.js +1 -1
  260. package/dist/features/products/columns/productTableColumns.js +2 -2
  261. package/dist/features/products/components/AuctionsIndexListing.js +15 -51
  262. package/dist/features/products/components/BidHistory.js +2 -2
  263. package/dist/features/products/components/CompareOverlay.js +3 -2
  264. package/dist/features/products/components/MakeOfferButton.js +20 -14
  265. package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
  266. package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
  267. package/dist/features/products/components/PrizeDrawCollage.js +54 -14
  268. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  269. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  270. package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
  271. package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
  272. package/dist/features/products/components/PrizeRevealModal.js +24 -14
  273. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  274. package/dist/features/products/components/ProductFilters.js +8 -6
  275. package/dist/features/products/components/ProductForm.js +12 -10
  276. package/dist/features/products/components/ProductGalleryClient.js +2 -1
  277. package/dist/features/products/components/ProductGrid.js +11 -14
  278. package/dist/features/products/components/ProductsIndexListing.js +16 -52
  279. package/dist/features/products/components/ProductsIndexPageView.js +2 -2
  280. package/dist/features/products/schemas/index.d.ts +56 -56
  281. package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
  282. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  283. package/dist/features/promotions/schemas/index.d.ts +6 -6
  284. package/dist/features/reviews/actions/review-actions.js +6 -5
  285. package/dist/features/reviews/api/[id]/route.js +4 -3
  286. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
  287. package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
  288. package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
  289. package/dist/features/reviews/schemas/index.d.ts +6 -6
  290. package/dist/features/scams/components/ScamProfileView.js +19 -10
  291. package/dist/features/scams/components/ScamRegistryView.js +2 -1
  292. package/dist/features/search/components/Search.d.ts +1 -1
  293. package/dist/features/search/components/Search.js +56 -49
  294. package/dist/features/search/schemas/index.d.ts +5 -5
  295. package/dist/features/seller/actions/offer-actions.js +11 -9
  296. package/dist/features/seller/components/SellerAddressesView.js +6 -4
  297. package/dist/features/seller/components/SellerBidsView.js +2 -2
  298. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  299. package/dist/features/seller/components/SellerOffersPanel.js +6 -1
  300. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  301. package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
  302. package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
  303. package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
  304. package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
  305. package/dist/features/seller/components/SellerProductShell.js +75 -9
  306. package/dist/features/seller/components/SellerProductsView.js +10 -11
  307. package/dist/features/seller/components/SellerShippingView.js +3 -3
  308. package/dist/features/seller/components/SellerSidebar.js +10 -7
  309. package/dist/features/seller/components/SellerStorefrontView.js +3 -3
  310. package/dist/features/seller/schemas/index.d.ts +4 -4
  311. package/dist/features/shell/FormShell.js +2 -1
  312. package/dist/features/shell/QuickFormDrawer.js +4 -3
  313. package/dist/features/shell/StepForm.js +4 -3
  314. package/dist/features/stores/actions/store-query-actions.js +4 -3
  315. package/dist/features/stores/components/StoreAboutView.js +2 -1
  316. package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
  317. package/dist/features/stores/components/StoreDetailLayoutView.js +2 -2
  318. package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
  319. package/dist/features/stores/components/StoreProductsListing.js +16 -49
  320. package/dist/features/stores/components/StoresIndexListing.js +2 -2
  321. package/dist/features/stores/schemas/index.d.ts +2 -2
  322. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
  323. package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
  324. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
  325. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
  326. package/dist/index.d.ts +21 -3
  327. package/dist/index.js +1737 -1725
  328. package/dist/monitoring/server-logger.js +5 -9
  329. package/dist/next/api/apiHandler.js +56 -37
  330. package/dist/next/components/GlobalError.js +2 -1
  331. package/dist/next/routing/route-map.d.ts +27 -0
  332. package/dist/next/routing/route-map.js +10 -0
  333. package/dist/react/ErrorBoundary.js +2 -1
  334. package/dist/react/contexts/SessionContext.js +38 -28
  335. package/dist/react/hooks/useCamera.d.ts +1 -1
  336. package/dist/react/hooks/useCamera.js +8 -7
  337. package/dist/seed/site-settings-seed-data.js +6 -0
  338. package/dist/server-entry.d.ts +3 -0
  339. package/dist/server-entry.js +3 -0
  340. package/dist/server.d.ts +12 -0
  341. package/dist/server.js +15 -0
  342. package/dist/tailwind-utilities.css +1 -1
  343. package/dist/ui/DataTable.js +28 -7
  344. package/dist/ui/components/Button.d.ts +8 -1
  345. package/dist/ui/components/Button.js +47 -8
  346. package/dist/ui/components/CollageLightbox.d.ts +18 -0
  347. package/dist/ui/components/CollageLightbox.js +41 -0
  348. package/dist/ui/components/Dropdown.js +7 -6
  349. package/dist/ui/components/ImageLightbox.d.ts +7 -1
  350. package/dist/ui/components/ImageLightbox.js +15 -5
  351. package/dist/ui/components/PageLoader.js +4 -3
  352. package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
  353. package/dist/ui/components/PaginatedMultiSelect.js +141 -0
  354. package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
  355. package/dist/ui/components/Semantic.js +1 -1
  356. package/dist/ui/components/SideDrawer.js +17 -15
  357. package/dist/ui/components/index.style.css +1 -0
  358. package/dist/ui/index.d.ts +2 -0
  359. package/dist/ui/index.js +1 -0
  360. package/dist/utils/number.formatter.js +5 -13
  361. package/dist/utils/string.formatter.js +21 -18
  362. package/dist/validation/schemas.d.ts +2 -2
  363. package/package.json +2 -2
@@ -1,27 +1,30 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { SlidersHorizontal, X } from "lucide-react";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
+ import { usePendingTable } from "../../../react/hooks/usePendingTable";
6
6
  import { useProducts } from "../../products/hooks/useProducts";
7
- import { Pagination, useToast, ListingToolbar, LoginRequiredModal } from "../../../ui";
7
+ import { Pagination, useToast, ListingToolbar, FilterDrawer, LoginRequiredModal, } from "../../../ui";
8
8
  import { useAuthGate } from "../../../react/hooks/useAuthGate";
9
9
  import { ACTION_ID } from "../../products/constants/action-defs";
10
10
  import { MarketplaceAuctionGrid } from "../../auctions/components/MarketplaceAuctionGrid";
11
- import { ProductFilters } from "../../products/components/ProductFilters";
11
+ import { AuctionFilters } from "../../auctions/components/AuctionFilters";
12
12
  import { getDefaultCurrency } from "../../../core/baseline-resolver";
13
13
  import { useGuestWishlist } from "../../wishlist/hooks/useGuestWishlist";
14
14
  import { pushWishlistOp } from "../../cart/utils/pending-ops";
15
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
16
+ import { sortBy } from "../../../constants/sort";
17
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.AUCTION_END_DATE, "ASC");
15
18
  const AUCTION_SORT_OPTIONS = [
16
- { value: "auctionEndDate", label: "Ending Soonest" },
17
- { value: "-createdAt", label: "Newest" },
18
- { value: "-currentBid", label: "Highest Bid" },
19
- { value: "price", label: "Price: Low to High" },
20
- { value: "-price", label: "Price: High to Low" },
19
+ { value: sortBy(PRODUCT_FIELDS.AUCTION_END_DATE, "ASC"), label: "Ending Soonest" },
20
+ { value: sortBy(PRODUCT_FIELDS.AUCTION_END_DATE), label: "Ending Latest" },
21
+ { value: sortBy(PRODUCT_FIELDS.CURRENT_BID), label: "Highest Bid" },
22
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
23
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
21
24
  ];
22
- const FILTER_KEYS = ["minPrice", "maxPrice"];
25
+ const FILTER_KEYS = ["minBid", "maxBid", "dateFrom", "dateTo"];
23
26
  export function StoreAuctionsListing({ storeId, initialData }) {
24
- const table = useUrlTable({ defaults: { pageSize: "24", sort: "auctionEndDate" } });
27
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
25
28
  const { showToast } = useToast();
26
29
  const { requireAuth, modalOpen, modalMessage, closeModal } = useAuthGate();
27
30
  const [searchInput, setSearchInput] = useState(table.get("q") || "");
@@ -29,63 +32,30 @@ export function StoreAuctionsListing({ storeId, initialData }) {
29
32
  const [view, setView] = useState(table.get("view") || "grid");
30
33
  const localWishlist = useGuestWishlist();
31
34
  const wishlistedIds = new Set(localWishlist.items.filter((i) => i.type === "auction").map((i) => i.itemId));
32
- // Pending filter state buffered until "Apply Filters" clicked
33
- const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
34
- const pendingTable = useMemo(() => ({
35
- get: (key) => pendingFilters[key] ?? "",
36
- getNumber: (key, fallback = 0) => {
37
- const v = pendingFilters[key];
38
- if (!v)
39
- return fallback;
40
- const n = Number(v);
41
- return isNaN(n) ? fallback : n;
42
- },
43
- set: (key, value) => setPendingFilters((p) => ({ ...p, [key]: value })),
44
- setMany: (updates) => setPendingFilters((p) => ({ ...p, ...updates })),
45
- clear: (keys) => {
46
- const ks = keys ?? FILTER_KEYS;
47
- setPendingFilters((p) => ({
48
- ...p,
49
- ...Object.fromEntries(ks.map((k) => [k, ""])),
50
- }));
51
- },
52
- setPage: (_) => { },
53
- setPageSize: (_) => { },
54
- setSort: (_) => { },
55
- buildSieveParams: () => "",
56
- buildSearchParams: () => "",
57
- params: new URLSearchParams(),
58
- }), [pendingFilters]);
35
+ const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onFilterReset } = usePendingTable(table, FILTER_KEYS);
59
36
  const openFilters = useCallback(() => {
60
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
37
+ onFilterReset();
61
38
  setFilterOpen(true);
62
- }, [table]);
39
+ }, [onFilterReset]);
63
40
  const applyFilters = useCallback(() => {
64
- const updates = { page: "1" };
65
- for (const k of FILTER_KEYS)
66
- updates[k] = pendingFilters[k] ?? "";
67
- table.setMany(updates);
41
+ onFilterApply();
68
42
  setFilterOpen(false);
69
- }, [pendingFilters, table]);
70
- const clearFilters = useCallback(() => {
71
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
72
- }, []);
43
+ }, [onFilterApply]);
73
44
  const resetAll = useCallback(() => {
74
- const updates = { q: "", sort: "" };
75
- for (const k of FILTER_KEYS)
76
- updates[k] = "";
77
- table.setMany(updates);
45
+ table.setMany({ q: "", sort: "" });
46
+ onFilterClear();
78
47
  setSearchInput("");
79
- }, [table]);
80
- const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
48
+ }, [table, onFilterClear]);
81
49
  const hasActiveState = !!table.get("q") ||
82
- table.get("sort") !== "auctionEndDate" ||
83
- activeFilterCount > 0;
50
+ table.get("sort") !== DEFAULT_SORT ||
51
+ filterActiveCount > 0;
84
52
  const params = {
85
53
  q: table.get("q") || undefined,
86
- minPrice: table.get("minPrice") ? Number(table.get("minPrice")) : undefined,
87
- maxPrice: table.get("maxPrice") ? Number(table.get("maxPrice")) : undefined,
88
- sort: table.get("sort") || "auctionEndDate",
54
+ minBid: table.get("minBid") ? Number(table.get("minBid")) : undefined,
55
+ maxBid: table.get("maxBid") ? Number(table.get("maxBid")) : undefined,
56
+ dateFrom: table.get("dateFrom") || undefined,
57
+ dateTo: table.get("dateTo") || undefined,
58
+ sort: table.get("sort") || DEFAULT_SORT,
89
59
  page: table.getNumber("page", 1),
90
60
  perPage: table.getNumber("pageSize", 24),
91
61
  storeId: storeId || undefined,
@@ -119,7 +89,7 @@ export function StoreAuctionsListing({ storeId, initialData }) {
119
89
  requireAuth(ACTION_ID.WATCH_AUCTION, () => {
120
90
  localWishlist.add(productId, "auction");
121
91
  pushWishlistOp({ op: "add", itemId: productId, type: "auction" });
122
- showToast("Added to wishlist", "success");
92
+ showToast("Added to watchlist", "success");
123
93
  });
124
94
  return Promise.resolve();
125
95
  },
@@ -127,13 +97,22 @@ export function StoreAuctionsListing({ storeId, initialData }) {
127
97
  requireAuth(ACTION_ID.UNWATCH_AUCTION, () => {
128
98
  localWishlist.remove(productId, "auction");
129
99
  pushWishlistOp({ op: "remove", itemId: productId, type: "auction" });
130
- showToast("Removed from wishlist", "info");
100
+ showToast("Removed from watchlist", "info");
131
101
  });
132
102
  return Promise.resolve();
133
103
  },
134
104
  isWishlisted: (productId) => wishlistedIds.has(productId),
135
105
  };
136
106
  const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4";
137
- return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store auctions...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "auctionEndDate", sortOptions: AUCTION_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => { if (v === "table")
138
- return; setView(v); table.set("view", v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : (_jsx(MarketplaceAuctionGrid, { auctions: auctions, variant: view === "list" ? "list" : "grid", gridClassName: view === "list" ? "flex flex-col gap-4" : gridClass, wishlistActions: wishlistActions, labels: { emptyTitle: "No auctions yet", emptyDescription: "This store has no active auctions." } })) }), 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: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "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-slate-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(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _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})` : ""] }) })] })] })), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
107
+ return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store auctions...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: AUCTION_SORT_OPTIONS, onSortChange: (v) => {
108
+ table.set("sort", v);
109
+ }, view: view, onViewChange: (v) => {
110
+ if (v === "table")
111
+ return;
112
+ setView(v);
113
+ table.set("view", v);
114
+ }, onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : (_jsx(MarketplaceAuctionGrid, { auctions: auctions, variant: view === "list" ? "list" : "grid", gridClassName: view === "list" ? "flex flex-col gap-4" : gridClass, wishlistActions: wishlistActions, labels: {
115
+ emptyTitle: "No auctions yet",
116
+ emptyDescription: "This store has no active auctions.",
117
+ } })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(AuctionFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
139
118
  }
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cache } from "react";
3
3
  import { storeRepository, productRepository, categoriesRepository } from "../../../repositories";
4
4
  import { ROUTES } from "../../../next";
5
- import { Container, Main, Section } from "../../../ui";
5
+ import { Container, Main, Section, Text } from "../../../ui";
6
6
  import { STORE_PAGE_TABS } from "../../products/constants/listing-tabs";
7
7
  import { StoreHeader } from "./StoreHeader";
8
8
  import { StoreNavTabs } from "./StoreNavTabs";
@@ -22,7 +22,7 @@ function tabLabel(base, count) {
22
22
  export async function StoreDetailLayoutView({ storeSlug, activeTab, children, }) {
23
23
  const store = await getStoreBySlug(storeSlug);
24
24
  if (!store) {
25
- return (_jsx(Main, { children: _jsx(Section, { className: "py-20", children: _jsx(Container, { size: "md", children: _jsx("p", { className: "text-center text-zinc-500", children: "Store not found." }) }) }) }));
25
+ return (_jsx(Main, { children: _jsx(Section, { className: "py-20", children: _jsx(Container, { size: "md", children: _jsx(Text, { className: "text-center text-zinc-500", children: "Store not found." }) }) }) }));
26
26
  }
27
27
  const storeId = store?.id;
28
28
  const [productsCount, auctionsCount, preOrdersCount, prizeDrawsCount, bundlesCount] = storeId
@@ -1,92 +1,68 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { SlidersHorizontal, X } from "lucide-react";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
+ import { usePendingTable } from "../../../react/hooks/usePendingTable";
6
6
  import { useProducts } from "../../products/hooks/useProducts";
7
- import { Pagination, ListingToolbar } from "../../../ui";
7
+ import { FilterDrawer, ListingToolbar, Pagination, Text } from "../../../ui";
8
8
  import { MarketplacePreorderCard } from "../../pre-orders/components/MarketplacePreorderCard";
9
9
  import { ProductFilters } from "../../products/components/ProductFilters";
10
10
  import { ROUTES } from "../../../next";
11
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
12
+ import { sortBy } from "../../../constants/sort";
13
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
11
14
  const PREORDER_SORT_OPTIONS = [
12
- { value: "-createdAt", label: "Newest First" },
13
- { value: "preOrderDeliveryDate", label: "Delivery Soon" },
14
- { value: "price", label: "Price: Low to High" },
15
- { value: "-price", label: "Price: High to Low" },
15
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
16
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
17
+ { value: sortBy(PRODUCT_FIELDS.PRE_ORDER_DELIVERY_DATE, "ASC"), label: "Delivery Soon" },
18
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
19
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
16
20
  ];
17
21
  const FILTER_KEYS = ["minPrice", "maxPrice"];
18
22
  export function StorePreOrdersListing({ storeId, initialData }) {
19
- const table = useUrlTable({ defaults: { pageSize: "24", sort: "-createdAt" } });
23
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
20
24
  const [searchInput, setSearchInput] = useState(table.get("q") || "");
21
25
  const [filterOpen, setFilterOpen] = useState(false);
22
26
  const [view, setView] = useState(table.get("view") || "grid");
23
- const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
24
- const pendingTable = useMemo(() => ({
25
- get: (key) => pendingFilters[key] ?? "",
26
- getNumber: (key, fallback = 0) => {
27
- const v = pendingFilters[key];
28
- if (!v)
29
- return fallback;
30
- const n = Number(v);
31
- return isNaN(n) ? fallback : n;
32
- },
33
- set: (key, value) => setPendingFilters((p) => ({ ...p, [key]: value })),
34
- setMany: (updates) => setPendingFilters((p) => ({ ...p, ...updates })),
35
- clear: (keys) => {
36
- const ks = keys ?? FILTER_KEYS;
37
- setPendingFilters((p) => ({
38
- ...p,
39
- ...Object.fromEntries(ks.map((k) => [k, ""])),
40
- }));
41
- },
42
- setPage: (_) => { },
43
- setPageSize: (_) => { },
44
- setSort: (_) => { },
45
- buildSieveParams: () => "",
46
- buildSearchParams: () => "",
47
- params: new URLSearchParams(),
48
- }), [pendingFilters]);
27
+ const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onFilterReset } = usePendingTable(table, FILTER_KEYS);
49
28
  const openFilters = useCallback(() => {
50
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
29
+ onFilterReset();
51
30
  setFilterOpen(true);
52
- }, [table]);
31
+ }, [onFilterReset]);
53
32
  const applyFilters = useCallback(() => {
54
- const updates = { page: "1" };
55
- for (const k of FILTER_KEYS)
56
- updates[k] = pendingFilters[k] ?? "";
57
- table.setMany(updates);
33
+ onFilterApply();
58
34
  setFilterOpen(false);
59
- }, [pendingFilters, table]);
60
- const clearFilters = useCallback(() => {
61
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
62
- }, []);
35
+ }, [onFilterApply]);
63
36
  const resetAll = useCallback(() => {
64
- const updates = { q: "", sort: "" };
65
- for (const k of FILTER_KEYS)
66
- updates[k] = "";
67
- table.setMany(updates);
37
+ table.setMany({ q: "", sort: "" });
38
+ onFilterClear();
68
39
  setSearchInput("");
69
- }, [table]);
70
- const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
40
+ }, [table, onFilterClear]);
71
41
  const hasActiveState = !!table.get("q") ||
72
- table.get("sort") !== "-createdAt" ||
73
- activeFilterCount > 0;
42
+ table.get("sort") !== DEFAULT_SORT ||
43
+ filterActiveCount > 0;
74
44
  const params = {
75
45
  q: table.get("q") || undefined,
76
46
  minPrice: table.get("minPrice") ? Number(table.get("minPrice")) : undefined,
77
47
  maxPrice: table.get("maxPrice") ? Number(table.get("maxPrice")) : undefined,
78
- sort: table.get("sort") || "-createdAt",
48
+ sort: table.get("sort") || DEFAULT_SORT,
79
49
  page: table.getNumber("page", 1),
80
50
  perPage: table.getNumber("pageSize", 24),
81
51
  storeId: storeId || undefined,
82
52
  listingType: "pre-order",
83
53
  };
84
- const { products: preOrders, total, totalPages, page, isLoading } = useProducts(params, { initialData });
54
+ const { products: preOrders, totalPages, page, isLoading } = useProducts(params, { initialData });
85
55
  const commitSearch = useCallback(() => {
86
56
  table.set("q", searchInput.trim());
87
57
  table.setPage(1);
88
58
  }, [searchInput, table]);
89
59
  const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
90
- return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store pre-orders...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PREORDER_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => { if (v === "table")
91
- return; setView(v); table.set("view", v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_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" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx("p", { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "This store has no pre-orders yet." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) : (_jsx("div", { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) }), 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: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "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-slate-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(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _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})` : ""] }) })] })] }))] }));
60
+ return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store pre-orders...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: PREORDER_SORT_OPTIONS, onSortChange: (v) => {
61
+ table.set("sort", v);
62
+ }, view: view, onViewChange: (v) => {
63
+ if (v === "table")
64
+ return;
65
+ setView(v);
66
+ table.set("view", v);
67
+ }, onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_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" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "This store has no pre-orders yet." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) : (_jsx("div", { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) })] }));
92
68
  }
@@ -1,10 +1,10 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { SlidersHorizontal, X } from "lucide-react";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
+ import { usePendingTable } from "../../../react/hooks/usePendingTable";
6
6
  import { useProducts } from "../../products/hooks/useProducts";
7
- import { Pagination, useToast, ListingToolbar, LoginRequiredModal } from "../../../ui";
7
+ import { Pagination, useToast, ListingToolbar, FilterDrawer, LoginRequiredModal, } from "../../../ui";
8
8
  import { useAuthGate } from "../../../react/hooks/useAuthGate";
9
9
  import { ACTION_ID } from "../../products/constants/action-defs";
10
10
  import { ROUTES } from "../../../next";
@@ -24,58 +24,23 @@ export function StoreProductsListing({ storeId, initialData }) {
24
24
  const localCart = useGuestCart();
25
25
  const localWishlist = useGuestWishlist();
26
26
  const wishlistedIds = new Set(localWishlist.items.filter((i) => i.type === "product").map((i) => i.itemId));
27
- // Pending filter state buffered until "Apply Filters" clicked
28
- const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
29
- const pendingTable = useMemo(() => ({
30
- get: (key) => pendingFilters[key] ?? "",
31
- getNumber: (key, fallback = 0) => {
32
- const v = pendingFilters[key];
33
- if (!v)
34
- return fallback;
35
- const n = Number(v);
36
- return isNaN(n) ? fallback : n;
37
- },
38
- set: (key, value) => setPendingFilters((p) => ({ ...p, [key]: value })),
39
- setMany: (updates) => setPendingFilters((p) => ({ ...p, ...updates })),
40
- clear: (keys) => {
41
- const ks = keys ?? FILTER_KEYS;
42
- setPendingFilters((p) => ({
43
- ...p,
44
- ...Object.fromEntries(ks.map((k) => [k, ""])),
45
- }));
46
- },
47
- setPage: (_) => { },
48
- setPageSize: (_) => { },
49
- setSort: (_) => { },
50
- buildSieveParams: () => "",
51
- buildSearchParams: () => "",
52
- params: new URLSearchParams(),
53
- }), [pendingFilters]);
27
+ const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onFilterReset } = usePendingTable(table, FILTER_KEYS);
54
28
  const openFilters = useCallback(() => {
55
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
29
+ onFilterReset();
56
30
  setFilterOpen(true);
57
- }, [table]);
31
+ }, [onFilterReset]);
58
32
  const applyFilters = useCallback(() => {
59
- const updates = { page: "1" };
60
- for (const k of FILTER_KEYS)
61
- updates[k] = pendingFilters[k] ?? "";
62
- table.setMany(updates);
33
+ onFilterApply();
63
34
  setFilterOpen(false);
64
- }, [pendingFilters, table]);
65
- const clearFilters = useCallback(() => {
66
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
67
- }, []);
35
+ }, [onFilterApply]);
68
36
  const resetAll = useCallback(() => {
69
- const updates = { q: "", sort: "" };
70
- for (const k of FILTER_KEYS)
71
- updates[k] = "";
72
- table.setMany(updates);
37
+ table.setMany({ q: "", sort: "" });
38
+ onFilterClear();
73
39
  setSearchInput("");
74
- }, [table]);
75
- const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
40
+ }, [table, onFilterClear]);
76
41
  const hasActiveState = !!table.get("q") ||
77
42
  table.get("sort") !== "-createdAt" ||
78
- activeFilterCount > 0;
43
+ filterActiveCount > 0;
79
44
  const params = {
80
45
  q: table.get("q") || undefined,
81
46
  condition: table.get("condition") || undefined,
@@ -128,5 +93,7 @@ export function StoreProductsListing({ storeId, initialData }) {
128
93
  });
129
94
  showToast("Added to cart", "success");
130
95
  }, [localCart, showToast]);
131
- return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view === "card" ? "grid" : "list", onViewChange: (v) => handleViewToggle(v === "grid" ? "card" : "list"), onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-6", children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_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" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view, emptyLabel: "This store has no products yet.", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart })) }), 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: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "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-slate-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(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _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})` : ""] }) })] })] })), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
96
+ return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => {
97
+ table.set("sort", v);
98
+ }, view: view === "card" ? "grid" : "list", onViewChange: (v) => handleViewToggle(v === "grid" ? "card" : "list"), onResetAll: resetAll, hasActiveState: hasActiveState }), 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: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-6", children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_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" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view, emptyLabel: "This store has no products yet.", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
132
99
  }
@@ -4,7 +4,7 @@ import { useState, useCallback, useMemo } from "react";
4
4
  import { SlidersHorizontal, X } from "lucide-react";
5
5
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
6
  import { useStores } from "../hooks/useStores";
7
- import { BulkActionBar, Pagination, ListingToolbar } from "../../../ui";
7
+ import { BulkActionBar, ListingToolbar, Pagination, Text } from "../../../ui";
8
8
  import { ROUTES } from "../../../next";
9
9
  import { InteractiveStoreCard } from "./InteractiveStoreCard";
10
10
  import { StoreFilters } from "./StoreFilters";
@@ -128,7 +128,7 @@ export function StoresIndexListing({ initialData }) {
128
128
  disabled: selection.selectedCount !== 1,
129
129
  onClick: () => { selection.clearSelection(); },
130
130
  },
131
- ] }), 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: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-4 space-y-2.5", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("div", { className: "h-10 w-10 rounded-lg bg-zinc-200 dark:bg-slate-700" }) }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] })] }, i))) })) : stores.length === 0 ? (_jsx("p", { className: "py-16 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No stores found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: stores.map((store) => {
131
+ ] }), 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: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-4 space-y-2.5", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("div", { className: "h-10 w-10 rounded-lg bg-zinc-200 dark:bg-slate-700" }) }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] })] }, i))) })) : stores.length === 0 ? (_jsx(Text, { className: "py-16 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No stores found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: stores.map((store) => {
132
132
  const storeKey = store.storeSlug ?? store.id;
133
133
  return (_jsx(InteractiveStoreCard, { store: store, href: String(ROUTES.PUBLIC.STORE_DETAIL(storeKey)), selectable: selection.isSelecting, isSelected: selection.isSelected(store.id ?? store.storeSlug), onSelect: (id, sel) => { void sel; selection.toggle(id); } }, storeKey));
134
134
  }) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: stores.map((store) => {
@@ -73,13 +73,13 @@ export declare const storeListParamsSchema: z.ZodObject<{
73
73
  }, "strip", z.ZodTypeAny, {
74
74
  sort?: string | undefined;
75
75
  pageSize?: number | undefined;
76
- page?: number | undefined;
77
76
  category?: string | undefined;
77
+ page?: number | undefined;
78
78
  filters?: string | undefined;
79
79
  }, {
80
80
  sort?: string | undefined;
81
81
  pageSize?: number | undefined;
82
- page?: number | undefined;
83
82
  category?: string | undefined;
83
+ page?: number | undefined;
84
84
  filters?: string | undefined;
85
85
  }>;
@@ -1,8 +1,9 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import React from "react";
4
+ const CLS_SECTION_CARD = "border border-zinc-200 dark:border-zinc-700 rounded-xl p-5";
4
5
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
- import { Alert, Button, Form, FormActions, Input, Toggle, useToast, } from "../../../ui";
6
+ import { Alert, Button, Form, FormActions, Heading, Input, Section, Text, Toggle, useToast } from "../../../ui";
6
7
  import { apiClient } from "../../../http";
7
8
  import { WHATSAPP_SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
8
9
  import { buildPurchaseAnnouncementMessage } from "../helpers/whatsapp";
@@ -119,9 +120,9 @@ export function SellerWhatsAppSettingsView({ hasCapability }) {
119
120
  },
120
121
  });
121
122
  if (!hasCapability) {
122
- return (_jsx("div", { className: "max-w-xl mx-auto py-8 px-4", children: _jsxs(Alert, { variant: "warning", children: [_jsx("p", { className: "font-medium", children: "WhatsApp catalog sync is not enabled for your store." }), _jsx("p", { className: "text-sm mt-1", children: "Contact LetItRip support to request access to the WhatsApp Business integration." })] }) }));
123
+ return (_jsx("div", { className: "max-w-xl mx-auto py-8 px-4", children: _jsxs(Alert, { variant: "warning", children: [_jsx(Text, { className: "font-medium", children: "WhatsApp catalog sync is not enabled for your store." }), _jsx(Text, { className: "text-sm mt-1", children: "Contact LetItRip support to request access to the WhatsApp Business integration." })] }) }));
123
124
  }
124
- return (_jsxs("div", { className: "max-w-2xl mx-auto space-y-8 py-6 px-4", children: [_jsxs("section", { children: [_jsx("h2", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "How to connect your WhatsApp Business account" }), _jsx("ol", { className: "space-y-3", children: STEPS.map((step) => {
125
+ return (_jsxs("div", { className: "max-w-2xl mx-auto space-y-8 py-6 px-4", children: [_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "How to connect your WhatsApp Business account" }), _jsx("ol", { className: "space-y-3", children: STEPS.map((step) => {
125
126
  const done = step.checkKey === undefined
126
127
  ? false
127
128
  : step.checkKey === "connected"
@@ -129,11 +130,11 @@ export function SellerWhatsAppSettingsView({ hasCapability }) {
129
130
  : Boolean(cfg?.[step.checkKey]);
130
131
  return (_jsxs("li", { className: "flex gap-3", children: [_jsx("span", { className: `flex-shrink-0 w-6 h-6 rounded-full text-xs font-bold flex items-center justify-center mt-0.5 ${done
131
132
  ? "bg-green-500 text-white"
132
- : "bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300"}`, children: done ? "✓" : step.n }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: step.title }), _jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: step.body })] })] }, step.n));
133
- }) })] }), _jsxs("section", { className: "border border-zinc-200 dark:border-zinc-700 rounded-xl p-5", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h2", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Connection" }), isLoading ? null : cfg?.connected ? (_jsx("span", { className: "text-xs font-medium px-2 py-0.5 rounded-full bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-300", children: "Connected" })) : (_jsx("span", { className: "text-xs font-medium px-2 py-0.5 rounded-full bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400", children: "Not configured" }))] }), _jsxs(Form, { onSubmit: (e) => {
133
+ : "bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300"}`, children: done ? "✓" : step.n }), _jsxs(_Fragment, { children: [_jsx(Text, { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: step.title }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: step.body })] })] }, step.n));
134
+ }) })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Connection" }), isLoading ? null : cfg?.connected ? (_jsx("span", { className: "text-xs font-medium px-2 py-0.5 rounded-full bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-300", children: "Connected" })) : (_jsx("span", { className: "text-xs font-medium px-2 py-0.5 rounded-full bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400", children: "Not configured" }))] }), _jsxs(Form, { onSubmit: (e) => {
134
135
  e.preventDefault();
135
136
  saveMutation.mutate();
136
- }, className: "space-y-4", children: [_jsx(Input, { label: "WhatsApp Business Phone Number", value: phoneNumber, onChange: (e) => setPhoneNumber(e.target.value), placeholder: "919876543210", helperText: "Digits only, include country code (e.g. 91 for India)" }), _jsx(Input, { label: "WABA ID (WhatsApp Business Account ID)", value: wabaId, onChange: (e) => setWabaId(e.target.value), placeholder: "123456789012345", helperText: "From Meta Business Manager \u2192 WhatsApp Accounts" }), _jsx(Input, { label: "Catalog ID", value: catalogId, onChange: (e) => setCatalogId(e.target.value), placeholder: "987654321098765", helperText: "From Meta Commerce Manager \u2192 Catalogs" }), _jsx(MaskedTokenInput, { label: "System User Access Token", value: accessToken, onChange: setAccessToken, placeholder: "EAAxxxxxxxx\u2026", helperText: "Long-lived token with WhatsApp Business permissions" }), _jsx(FormActions, { align: "right", children: _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: saveMutation.isPending, children: saveMutation.isPending ? "Saving…" : "Save & Connect" }) })] })] }), _jsxs("section", { className: "border border-zinc-200 dark:border-zinc-700 rounded-xl p-5", children: [_jsx("h2", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "Catalog Sync" }), _jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Enable catalog sync" }), _jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "When enabled, your published standard products can be synced to WhatsApp." })] }), _jsx(Toggle, { checked: syncEnabled, onChange: setSyncEnabled, disabled: !cfg?.connected })] }), cfg?.lastCatalogSyncAt && (_jsxs("div", { className: "flex items-center gap-2 text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: [_jsxs("span", { children: ["Last sync: ", new Date(cfg.lastCatalogSyncAt).toLocaleString("en-IN")] }), cfg.lastSyncCount !== undefined && _jsxs("span", { children: ["\u00B7 ", cfg.lastSyncCount, " products"] }), cfg.lastSyncStatus && (_jsx("span", { className: `px-1.5 py-0.5 rounded ${STATUS_COLOR[cfg.lastSyncStatus] ?? ""}`, children: cfg.lastSyncStatus }))] })), _jsx("p", { className: "text-xs text-zinc-400 dark:text-zinc-500 mb-3", children: "Only published standard products are synced. Auctions and pre-orders are excluded. Batches of up to 50 products per call." }), _jsx(Button, { onClick: () => syncMutation.mutate(), isLoading: syncMutation.isPending, disabled: !cfg?.connected || !syncEnabled || syncMutation.isPending, variant: "secondary", children: syncMutation.isPending ? "Syncing…" : "Sync Now" })] }), _jsxs("section", { className: "border border-zinc-200 dark:border-zinc-700 rounded-xl p-5", children: [_jsx("h2", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-2", children: "Purchase Announcement Preview" }), _jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: "This message is sent automatically to your phone and the platform admin when a new order is placed." }), _jsx("div", { className: "bg-zinc-50 dark:bg-zinc-800/60 rounded-lg px-4 py-3 text-sm text-zinc-700 dark:text-zinc-200 font-mono", children: buildPurchaseAnnouncementMessage({
137
+ }, className: "space-y-4", children: [_jsx(Input, { label: "WhatsApp Business Phone Number", value: phoneNumber, onChange: (e) => setPhoneNumber(e.target.value), placeholder: "919876543210", helperText: "Digits only, include country code (e.g. 91 for India)" }), _jsx(Input, { label: "WABA ID (WhatsApp Business Account ID)", value: wabaId, onChange: (e) => setWabaId(e.target.value), placeholder: "123456789012345", helperText: "From Meta Business Manager \u2192 WhatsApp Accounts" }), _jsx(Input, { label: "Catalog ID", value: catalogId, onChange: (e) => setCatalogId(e.target.value), placeholder: "987654321098765", helperText: "From Meta Commerce Manager \u2192 Catalogs" }), _jsx(MaskedTokenInput, { label: "System User Access Token", value: accessToken, onChange: setAccessToken, placeholder: "EAAxxxxxxxx\u2026", helperText: "Long-lived token with WhatsApp Business permissions" }), _jsx(FormActions, { align: "right", children: _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: saveMutation.isPending, children: saveMutation.isPending ? "Saving…" : "Save & Connect" }) })] })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-4", children: "Catalog Sync" }), _jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs(_Fragment, { children: [_jsx(Text, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Enable catalog sync" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "When enabled, your published standard products can be synced to WhatsApp." })] }), _jsx(Toggle, { checked: syncEnabled, onChange: setSyncEnabled, disabled: !cfg?.connected })] }), cfg?.lastCatalogSyncAt && (_jsxs("div", { className: "flex items-center gap-2 text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: [_jsxs("span", { children: ["Last sync: ", new Date(cfg.lastCatalogSyncAt).toLocaleString("en-IN")] }), cfg.lastSyncCount !== undefined && _jsxs("span", { children: ["\u00B7 ", cfg.lastSyncCount, " products"] }), cfg.lastSyncStatus && (_jsx("span", { className: `px-1.5 py-0.5 rounded ${STATUS_COLOR[cfg.lastSyncStatus] ?? ""}`, children: cfg.lastSyncStatus }))] })), _jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 mb-3", children: "Only published standard products are synced. Auctions and pre-orders are excluded. Batches of up to 50 products per call." }), _jsx(Button, { onClick: () => syncMutation.mutate(), isLoading: syncMutation.isPending, disabled: !cfg?.connected || !syncEnabled || syncMutation.isPending, variant: "secondary", children: syncMutation.isPending ? "Syncing…" : "Sync Now" })] }), _jsxs(Section, { className: CLS_SECTION_CARD, children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-2", children: "Purchase Announcement Preview" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-3", children: "This message is sent automatically to your phone and the platform admin when a new order is placed." }), _jsx("div", { className: "bg-zinc-50 dark:bg-zinc-800/60 rounded-lg px-4 py-3 text-sm text-zinc-700 dark:text-zinc-200 font-mono", children: buildPurchaseAnnouncementMessage({
137
138
  buyerName: "Ravi K.",
138
139
  firstItemName: "Charizard PSA 9",
139
140
  additionalItemCount: 2,
@@ -7,14 +7,14 @@ import { type GuestWishlistItem } from "../utils/guest-wishlist";
7
7
  export declare function useGuestWishlist(): {
8
8
  items: GuestWishlistItem[];
9
9
  count: number;
10
- countByType: (type: "product" | "auction" | "preorder" | "category" | "store") => number;
11
- add: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store", snapshot?: {
10
+ countByType: (type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => number;
11
+ add: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live", snapshot?: {
12
12
  title?: string;
13
13
  image?: string;
14
14
  }) => void;
15
- remove: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store") => void;
16
- isInWishlist: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store") => boolean;
15
+ remove: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => void;
16
+ isInWishlist: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => boolean;
17
17
  clear: () => void;
18
- getByType: (type: "product" | "auction" | "preorder" | "category" | "store") => GuestWishlistItem[];
18
+ getByType: (type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => GuestWishlistItem[];
19
19
  isInitialized: boolean;
20
20
  };
@@ -29,7 +29,7 @@ export declare function useWishlistWithGuest(userId: string | null | undefined,
29
29
  productPrice: number;
30
30
  productSlug: string;
31
31
  addedAt: string | undefined;
32
- type: "product" | "auction" | "preorder" | "category" | "store";
32
+ type: "auction" | "classified" | "digital-code" | "live" | "category" | "product" | "preorder" | "store";
33
33
  }[];
34
34
  total: number;
35
35
  wishlistedIds: Set<string>;
@@ -41,15 +41,15 @@ export declare function useWishlistWithGuest(userId: string | null | undefined,
41
41
  guestWishlist: {
42
42
  items: import("..").GuestWishlistItem[];
43
43
  count: number;
44
- countByType: (type: "product" | "auction" | "preorder" | "category" | "store") => number;
45
- add: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store", snapshot?: {
44
+ countByType: (type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => number;
45
+ add: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live", snapshot?: {
46
46
  title?: string;
47
47
  image?: string;
48
48
  }) => void;
49
- remove: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store") => void;
50
- isInWishlist: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store") => boolean;
49
+ remove: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => void;
50
+ isInWishlist: (itemId: string, type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => boolean;
51
51
  clear: () => void;
52
- getByType: (type: "product" | "auction" | "preorder" | "category" | "store") => import("..").GuestWishlistItem[];
52
+ getByType: (type: "product" | "auction" | "preorder" | "category" | "store" | "classified" | "digital-code" | "live") => import("..").GuestWishlistItem[];
53
53
  isInitialized: boolean;
54
54
  };
55
55
  };