@mohasinac/appkit 2.7.27 → 2.7.31

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 (397) hide show
  1. package/dist/_internal/client/features/filters/filter-load-options.d.ts +29 -0
  2. package/dist/_internal/client/features/filters/filter-load-options.js +98 -0
  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 +504 -9
  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 +4 -0
  46. package/dist/client.js +2 -0
  47. package/dist/configs/next.js +4 -0
  48. package/dist/constants/api-endpoints.d.ts +6 -0
  49. package/dist/constants/api-endpoints.js +2 -0
  50. package/dist/constants/field-names.d.ts +1 -0
  51. package/dist/constants/field-names.js +1 -0
  52. package/dist/constants/table-keys.d.ts +6 -0
  53. package/dist/constants/table-keys.js +9 -0
  54. package/dist/core/hooks/useSyncManager.js +9 -8
  55. package/dist/features/about/components/FeesView.js +10 -7
  56. package/dist/features/about/components/HelpPageView.js +10 -1
  57. package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
  58. package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
  59. package/dist/features/about/components/HowOffersWorkView.js +10 -1
  60. package/dist/features/about/components/HowOrdersWorkView.js +10 -1
  61. package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
  62. package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
  63. package/dist/features/about/components/HowReviewsWorkView.js +10 -1
  64. package/dist/features/about/components/PublicProfileView.js +46 -16
  65. package/dist/features/about/components/SecurityPrivacyView.js +7 -1
  66. package/dist/features/account/components/AddressesIndexListing.js +2 -2
  67. package/dist/features/account/components/NotificationBell.js +27 -16
  68. package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
  69. package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
  70. package/dist/features/account/components/UserSidebar.js +4 -4
  71. package/dist/features/account/components/UserSupportView.js +16 -6
  72. package/dist/features/account/components/index.d.ts +2 -0
  73. package/dist/features/account/components/index.js +1 -0
  74. package/dist/features/account/schemas/index.d.ts +4 -4
  75. package/dist/features/account/types/index.d.ts +34 -0
  76. package/dist/features/admin/actions/admin-actions.js +4 -3
  77. package/dist/features/admin/actions/notification-actions.d.ts +24 -22
  78. package/dist/features/admin/actions/notification-actions.js +122 -22
  79. package/dist/features/admin/components/AdminAdEditorView.js +29 -15
  80. package/dist/features/admin/components/AdminAddressEditorView.d.ts +7 -0
  81. package/dist/features/admin/components/AdminAddressEditorView.js +117 -0
  82. package/dist/features/admin/components/AdminAdsView.js +22 -28
  83. package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
  84. package/dist/features/admin/components/AdminBidsView.js +10 -3
  85. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  86. package/dist/features/admin/components/AdminBlogView.js +8 -3
  87. package/dist/features/admin/components/AdminBrandsView.js +7 -2
  88. package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
  89. package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
  90. package/dist/features/admin/components/AdminCarouselView.js +13 -7
  91. package/dist/features/admin/components/AdminCategoriesView.js +8 -3
  92. package/dist/features/admin/components/AdminCategoryEditorView.js +12 -9
  93. package/dist/features/admin/components/AdminContactView.js +6 -1
  94. package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
  95. package/dist/features/admin/components/AdminCouponsView.js +6 -1
  96. package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
  97. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  98. package/dist/features/admin/components/AdminFaqsView.js +7 -2
  99. package/dist/features/admin/components/AdminFeatureFlagsView.js +58 -13
  100. package/dist/features/admin/components/AdminFeaturesView.js +4 -3
  101. package/dist/features/admin/components/AdminMediaView.js +9 -8
  102. package/dist/features/admin/components/AdminNavigationView.js +10 -17
  103. package/dist/features/admin/components/AdminNewsletterView.js +6 -1
  104. package/dist/features/admin/components/AdminNotificationsView.js +11 -3
  105. package/dist/features/admin/components/AdminOrdersView.js +6 -1
  106. package/dist/features/admin/components/AdminPayoutsView.js +10 -3
  107. package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
  108. package/dist/features/admin/components/AdminProductEditorView.d.ts +3 -1
  109. package/dist/features/admin/components/AdminProductEditorView.js +12 -9
  110. package/dist/features/admin/components/AdminProductsView.js +18 -12
  111. package/dist/features/admin/components/AdminReturnRequestsView.js +5 -4
  112. package/dist/features/admin/components/AdminReviewsView.js +36 -26
  113. package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
  114. package/dist/features/admin/components/AdminScammersView.js +28 -26
  115. package/dist/features/admin/components/AdminSectionsView.js +112 -99
  116. package/dist/features/admin/components/AdminSessionsView.js +10 -3
  117. package/dist/features/admin/components/AdminSidebar.js +4 -4
  118. package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
  119. package/dist/features/admin/components/AdminStoresView.js +6 -1
  120. package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
  121. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  122. package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
  123. package/dist/features/admin/components/AdminTeamView.js +6 -1
  124. package/dist/features/admin/components/AdminUserEditorView.js +8 -15
  125. package/dist/features/admin/components/AdminUsersView.js +6 -1
  126. package/dist/features/admin/components/AdminViewCards.js +4 -3
  127. package/dist/features/admin/components/DashboardStats.js +2 -2
  128. package/dist/features/admin/components/DataTable.js +2 -2
  129. package/dist/features/admin/components/index.d.ts +2 -0
  130. package/dist/features/admin/components/index.js +1 -0
  131. package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
  132. package/dist/features/admin/repository/chat.repository.js +8 -8
  133. package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
  134. package/dist/features/admin/repository/site-settings.repository.js +11 -9
  135. package/dist/features/admin/schemas/firestore.d.ts +38 -0
  136. package/dist/features/admin/schemas/firestore.js +15 -0
  137. package/dist/features/auctions/components/AuctionBidsTable.d.ts +13 -0
  138. package/dist/features/auctions/components/AuctionBidsTable.js +62 -0
  139. package/dist/features/auctions/components/AuctionDetailPageView.js +15 -21
  140. package/dist/features/auctions/components/AuctionFilters.d.ts +7 -1
  141. package/dist/features/auctions/components/AuctionFilters.js +3 -2
  142. package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
  143. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
  144. package/dist/features/auctions/components/index.d.ts +2 -1
  145. package/dist/features/auctions/components/index.js +1 -1
  146. package/dist/features/auctions/schemas/index.d.ts +14 -14
  147. package/dist/features/auth/actions/realtime-token-actions.js +19 -4
  148. package/dist/features/auth/components/RegisterForm.js +8 -4
  149. package/dist/features/auth/consent-otp.d.ts +2 -0
  150. package/dist/features/auth/consent-otp.js +8 -0
  151. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  152. package/dist/features/auth/schemas/firestore.js +18 -25
  153. package/dist/features/auth/schemas/index.d.ts +2 -2
  154. package/dist/features/before-after/api/[id]/route.js +8 -6
  155. package/dist/features/before-after/schemas/index.d.ts +2 -2
  156. package/dist/features/blog/actions/blog-actions.d.ts +3 -3
  157. package/dist/features/blog/components/BlogIndexListing.js +21 -2
  158. package/dist/features/blog/components/BlogPostForm.js +11 -5
  159. package/dist/features/blog/components/BlogPostView.js +10 -2
  160. package/dist/features/blog/schemas/index.d.ts +18 -18
  161. package/dist/features/cart/components/CartDrawer.js +3 -2
  162. package/dist/features/cart/components/CartView.js +2 -1
  163. package/dist/features/cart/components/CheckoutView.js +2 -1
  164. package/dist/features/cart/repository/cart.repository.js +4 -3
  165. package/dist/features/cart/utils/pending-ops.d.ts +1 -1
  166. package/dist/features/categories/api/[id]/route.js +4 -3
  167. package/dist/features/categories/api/route.js +4 -3
  168. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  169. package/dist/features/categories/components/BrandDetailTabs.d.ts +5 -1
  170. package/dist/features/categories/components/BrandDetailTabs.js +30 -16
  171. package/dist/features/categories/components/BundleCollage.d.ts +8 -0
  172. package/dist/features/categories/components/BundleCollage.js +50 -0
  173. package/dist/features/categories/components/BundleDetailView.js +2 -10
  174. package/dist/features/categories/components/BundleItemsPicker.js +20 -13
  175. package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
  176. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  177. package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -1
  178. package/dist/features/categories/components/CategoryDetailTabs.js +31 -16
  179. package/dist/features/categories/components/CategoryProductsListing.js +52 -13
  180. package/dist/features/categories/components/index.d.ts +2 -0
  181. package/dist/features/categories/components/index.js +1 -0
  182. package/dist/features/categories/schemas/index.d.ts +6 -6
  183. package/dist/features/checkout/actions/checkout-actions.js +4 -3
  184. package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
  185. package/dist/features/classified/components/ClassifiedFilters.d.ts +12 -0
  186. package/dist/features/classified/components/ClassifiedFilters.js +20 -0
  187. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
  188. package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
  189. package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
  190. package/dist/features/classified/components/ClassifiedListView.js +43 -0
  191. package/dist/features/classified/components/index.d.ts +6 -0
  192. package/dist/features/classified/components/index.js +3 -0
  193. package/dist/features/collections/api/[slug]/route.js +16 -12
  194. package/dist/features/collections/schemas/index.d.ts +5 -5
  195. package/dist/features/consultation/api/[id]/route.js +12 -9
  196. package/dist/features/consultation/components/ConsultationForm.js +3 -2
  197. package/dist/features/consultation/schemas/index.d.ts +6 -6
  198. package/dist/features/contact/email.js +77 -116
  199. package/dist/features/copilot/components/AdminCopilotView.js +12 -2
  200. package/dist/features/corporate/api/[id]/route.js +12 -9
  201. package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
  202. package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +12 -0
  203. package/dist/features/digital-codes/components/DigitalCodeFilters.js +17 -0
  204. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
  205. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
  206. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
  207. package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
  208. package/dist/features/digital-codes/components/index.d.ts +6 -0
  209. package/dist/features/digital-codes/components/index.js +3 -0
  210. package/dist/features/events/actions/event-actions.js +4 -3
  211. package/dist/features/events/components/AdminEventEditorView.js +3 -2
  212. package/dist/features/events/components/AdminEventsView.js +4 -2
  213. package/dist/features/events/components/EventPollWidget.js +5 -5
  214. package/dist/features/events/components/EventsIndexListing.js +2 -2
  215. package/dist/features/events/repository/event-entry.repository.d.ts +1 -0
  216. package/dist/features/events/repository/event-entry.repository.js +5 -0
  217. package/dist/features/events/schemas/index.d.ts +20 -20
  218. package/dist/features/faq/actions/faq-actions.d.ts +8 -8
  219. package/dist/features/faq/components/ContactCTA.js +3 -1
  220. package/dist/features/faq/components/FAQAccordion.js +1 -1
  221. package/dist/features/faq/schemas/index.d.ts +4 -4
  222. package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
  223. package/dist/features/filters/AsyncFacetSection.js +65 -0
  224. package/dist/features/filters/index.d.ts +2 -0
  225. package/dist/features/filters/index.js +1 -0
  226. package/dist/features/forms/Checkbox.js +2 -2
  227. package/dist/features/forms/Input.js +2 -2
  228. package/dist/features/forms/Radio.js +5 -5
  229. package/dist/features/forms/Select.js +2 -2
  230. package/dist/features/forms/Slider.js +2 -2
  231. package/dist/features/forms/Textarea.js +2 -2
  232. package/dist/features/homepage/api/[id]/route.js +4 -3
  233. package/dist/features/homepage/api/sections/[id]/route.js +12 -9
  234. package/dist/features/homepage/components/AdSlot.js +2 -1
  235. package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
  236. package/dist/features/homepage/components/BrandsSection.js +2 -2
  237. package/dist/features/homepage/components/CTABannerSection.js +2 -2
  238. package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
  239. package/dist/features/homepage/components/CharacterHotspot.js +119 -157
  240. package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
  241. package/dist/features/homepage/components/CustomCardsSection.js +8 -6
  242. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  243. package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
  244. package/dist/features/homepage/components/HeroBanner.js +5 -4
  245. package/dist/features/homepage/components/HeroCarousel.js +13 -26
  246. package/dist/features/homepage/components/HowItWorksSection.js +4 -2
  247. package/dist/features/homepage/components/SocialFeedSection.js +2 -2
  248. package/dist/features/homepage/components/SocialPostCard.js +3 -2
  249. package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
  250. package/dist/features/layout/AppLayoutShell.d.ts +8 -2
  251. package/dist/features/layout/AppLayoutShell.js +54 -78
  252. package/dist/features/layout/BottomActions.js +43 -48
  253. package/dist/features/live/components/LiveItemFilters.d.ts +12 -0
  254. package/dist/features/live/components/LiveItemFilters.js +24 -0
  255. package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
  256. package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
  257. package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
  258. package/dist/features/live/components/LiveItemsListView.js +43 -0
  259. package/dist/features/live/components/index.d.ts +6 -0
  260. package/dist/features/live/components/index.js +3 -0
  261. package/dist/features/media/MediaLightbox.js +8 -14
  262. package/dist/features/media/types/index.d.ts +2 -2
  263. package/dist/features/media/upload/CameraCapture.js +2 -2
  264. package/dist/features/media/upload/ImageUpload.js +4 -2
  265. package/dist/features/media/upload/MediaUploadField.js +24 -8
  266. package/dist/features/media/upload/MediaUploadList.js +1 -1
  267. package/dist/features/orders/actions/order-actions.js +4 -3
  268. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
  269. package/dist/features/orders/components/OrderFilters.js +12 -9
  270. package/dist/features/orders/schemas/index.d.ts +6 -6
  271. package/dist/features/pre-orders/api/[id]/route.js +12 -9
  272. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
  273. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +29 -22
  274. package/dist/features/pre-orders/components/PreOrderFilters.d.ts +7 -1
  275. package/dist/features/pre-orders/components/PreOrderFilters.js +3 -2
  276. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
  277. package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
  278. package/dist/features/pre-orders/components/PreorderCard.js +2 -13
  279. package/dist/features/pre-orders/components/index.d.ts +1 -1
  280. package/dist/features/pre-orders/components/index.js +1 -1
  281. package/dist/features/pre-orders/schemas/index.d.ts +10 -10
  282. package/dist/features/products/api/[id]/route.js +9 -7
  283. package/dist/features/products/api/route.js +1 -1
  284. package/dist/features/products/columns/productTableColumns.js +3 -3
  285. package/dist/features/products/components/AuctionsIndexListing.js +15 -51
  286. package/dist/features/products/components/BidHistory.js +2 -2
  287. package/dist/features/products/components/CompareOverlay.d.ts +2 -0
  288. package/dist/features/products/components/CompareOverlay.js +3 -2
  289. package/dist/features/products/components/MakeOfferButton.js +20 -14
  290. package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
  291. package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
  292. package/dist/features/products/components/PrizeDrawCollage.js +54 -14
  293. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  294. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  295. package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
  296. package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
  297. package/dist/features/products/components/PrizeRevealModal.js +24 -14
  298. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  299. package/dist/features/products/components/ProductFilters.d.ts +7 -1
  300. package/dist/features/products/components/ProductFilters.js +11 -8
  301. package/dist/features/products/components/ProductForm.js +18 -16
  302. package/dist/features/products/components/ProductGalleryClient.js +2 -1
  303. package/dist/features/products/components/ProductGrid.js +12 -15
  304. package/dist/features/products/components/ProductsIndexListing.js +16 -52
  305. package/dist/features/products/components/ProductsIndexPageView.js +2 -2
  306. package/dist/features/products/repository/products.repository.d.ts +4 -0
  307. package/dist/features/products/repository/products.repository.js +22 -3
  308. package/dist/features/products/schemas/firestore.d.ts +7 -1
  309. package/dist/features/products/schemas/index.d.ts +56 -56
  310. package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
  311. package/dist/features/products/types/index.d.ts +4 -0
  312. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  313. package/dist/features/promotions/schemas/index.d.ts +6 -6
  314. package/dist/features/reviews/actions/review-actions.js +6 -5
  315. package/dist/features/reviews/api/[id]/route.js +4 -3
  316. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
  317. package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
  318. package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
  319. package/dist/features/reviews/schemas/index.d.ts +6 -6
  320. package/dist/features/scams/components/ScamProfileView.js +19 -10
  321. package/dist/features/scams/components/ScamRegistryView.js +2 -1
  322. package/dist/features/search/components/Search.d.ts +1 -1
  323. package/dist/features/search/components/Search.js +56 -49
  324. package/dist/features/search/schemas/index.d.ts +5 -5
  325. package/dist/features/seller/actions/offer-actions.js +11 -9
  326. package/dist/features/seller/components/SellerAddressesView.js +6 -4
  327. package/dist/features/seller/components/SellerBidsView.js +2 -2
  328. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  329. package/dist/features/seller/components/SellerOffersPanel.js +6 -1
  330. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  331. package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
  332. package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
  333. package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
  334. package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
  335. package/dist/features/seller/components/SellerProductShell.js +75 -9
  336. package/dist/features/seller/components/SellerProductsView.js +10 -11
  337. package/dist/features/seller/components/SellerShippingView.js +3 -3
  338. package/dist/features/seller/components/SellerSidebar.js +10 -7
  339. package/dist/features/seller/components/SellerStorefrontView.js +3 -3
  340. package/dist/features/seller/schemas/index.d.ts +4 -4
  341. package/dist/features/shell/FormShell.js +2 -1
  342. package/dist/features/shell/QuickFormDrawer.js +4 -3
  343. package/dist/features/shell/StepForm.js +4 -3
  344. package/dist/features/stores/actions/store-query-actions.js +4 -3
  345. package/dist/features/stores/components/StoreAboutView.js +2 -1
  346. package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
  347. package/dist/features/stores/components/StoreDetailLayoutView.js +18 -4
  348. package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
  349. package/dist/features/stores/components/StoreProductsListing.js +16 -49
  350. package/dist/features/stores/components/StoresIndexListing.js +2 -2
  351. package/dist/features/stores/schemas/index.d.ts +2 -2
  352. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
  353. package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
  354. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
  355. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
  356. package/dist/index.d.ts +27 -3
  357. package/dist/index.js +1743 -1725
  358. package/dist/monitoring/server-logger.js +5 -9
  359. package/dist/next/api/apiHandler.js +56 -37
  360. package/dist/next/components/GlobalError.js +2 -1
  361. package/dist/next/routing/route-map.d.ts +41 -0
  362. package/dist/next/routing/route-map.js +17 -0
  363. package/dist/react/ErrorBoundary.js +2 -1
  364. package/dist/react/contexts/SessionContext.js +38 -28
  365. package/dist/react/hooks/useCamera.d.ts +1 -1
  366. package/dist/react/hooks/useCamera.js +8 -7
  367. package/dist/seed/products-auctions-seed-data.js +40 -40
  368. package/dist/seed/products-preorders-seed-data.js +16 -16
  369. package/dist/seed/products-prize-draws-seed-data.js +4 -4
  370. package/dist/seed/products-standard-seed-data.js +202 -202
  371. package/dist/seed/site-settings-seed-data.js +6 -0
  372. package/dist/server-entry.d.ts +3 -0
  373. package/dist/server-entry.js +3 -0
  374. package/dist/server.d.ts +12 -0
  375. package/dist/server.js +15 -0
  376. package/dist/tailwind-utilities.css +1 -1
  377. package/dist/ui/DataTable.js +28 -7
  378. package/dist/ui/components/Button.d.ts +8 -1
  379. package/dist/ui/components/Button.js +47 -8
  380. package/dist/ui/components/CollageLightbox.d.ts +18 -0
  381. package/dist/ui/components/CollageLightbox.js +41 -0
  382. package/dist/ui/components/Dropdown.js +7 -6
  383. package/dist/ui/components/ImageLightbox.d.ts +7 -1
  384. package/dist/ui/components/ImageLightbox.js +15 -5
  385. package/dist/ui/components/PageLoader.js +4 -3
  386. package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
  387. package/dist/ui/components/PaginatedMultiSelect.js +141 -0
  388. package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
  389. package/dist/ui/components/Semantic.js +1 -1
  390. package/dist/ui/components/SideDrawer.js +17 -15
  391. package/dist/ui/components/index.style.css +1 -0
  392. package/dist/ui/index.d.ts +2 -0
  393. package/dist/ui/index.js +1 -0
  394. package/dist/utils/number.formatter.js +5 -13
  395. package/dist/utils/string.formatter.js +21 -18
  396. package/dist/validation/schemas.d.ts +2 -2
  397. package/package.json +1 -1
@@ -91,6 +91,7 @@ export declare const faqSchema: z.ZodObject<{
91
91
  };
92
92
  createdAt?: string | undefined;
93
93
  updatedAt?: string | undefined;
94
+ tags?: string[] | undefined;
94
95
  order?: number | undefined;
95
96
  priority?: number | undefined;
96
97
  stats?: {
@@ -99,7 +100,6 @@ export declare const faqSchema: z.ZodObject<{
99
100
  notHelpful?: number | undefined;
100
101
  } | undefined;
101
102
  isActive?: boolean | undefined;
102
- tags?: string[] | undefined;
103
103
  seo?: {
104
104
  slug?: string | undefined;
105
105
  } | undefined;
@@ -117,6 +117,7 @@ export declare const faqSchema: z.ZodObject<{
117
117
  };
118
118
  createdAt?: string | undefined;
119
119
  updatedAt?: string | undefined;
120
+ tags?: string[] | undefined;
120
121
  order?: number | undefined;
121
122
  priority?: number | undefined;
122
123
  stats?: {
@@ -125,7 +126,6 @@ export declare const faqSchema: z.ZodObject<{
125
126
  notHelpful?: number | undefined;
126
127
  } | undefined;
127
128
  isActive?: boolean | undefined;
128
- tags?: string[] | undefined;
129
129
  seo?: {
130
130
  slug?: string | undefined;
131
131
  } | undefined;
@@ -144,14 +144,14 @@ export declare const faqListParamsSchema: z.ZodObject<{
144
144
  }, "strip", z.ZodTypeAny, {
145
145
  perPage?: number | undefined;
146
146
  q?: string | undefined;
147
- page?: number | undefined;
148
147
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
148
+ page?: number | undefined;
149
149
  homepage?: boolean | undefined;
150
150
  }, {
151
151
  perPage?: number | undefined;
152
152
  q?: string | undefined;
153
- page?: number | undefined;
154
153
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
154
+ page?: number | undefined;
155
155
  homepage?: boolean | undefined;
156
156
  }>;
157
157
  export * from "./firestore";
@@ -0,0 +1,18 @@
1
+ import type { FacetOption } from "./FilterFacetSection";
2
+ import type { AsyncPage } from "../../ui/components/DynamicSelect";
3
+ export interface AsyncFacetSectionProps {
4
+ title: string;
5
+ selected: string[];
6
+ onChange: (selected: string[]) => void;
7
+ loadOptions: (query: string, page: number) => Promise<AsyncPage<FacetOption>>;
8
+ selectionMode?: "single" | "multi";
9
+ defaultCollapsed?: boolean;
10
+ onClear?: () => void;
11
+ className?: string;
12
+ }
13
+ /**
14
+ * AsyncFacetSection — collapsible filter section that loads options from the API
15
+ * with search + pagination. Replaces static `FilterFacetSection` for large datasets
16
+ * (>20 items). Uses the same accordion UX pattern for visual consistency.
17
+ */
18
+ export declare function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode, defaultCollapsed, onClear, className, }: AsyncFacetSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { Button, Div, Input, Row, Span, Text } from "../../ui";
5
+ import { cn } from "./filterUtils";
6
+ /**
7
+ * AsyncFacetSection — collapsible filter section that loads options from the API
8
+ * with search + pagination. Replaces static `FilterFacetSection` for large datasets
9
+ * (>20 items). Uses the same accordion UX pattern for visual consistency.
10
+ */
11
+ export function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode = "multi", defaultCollapsed = true, onClear, className = "", }) {
12
+ const [collapsed, setCollapsed] = useState(defaultCollapsed);
13
+ const [query, setQuery] = useState("");
14
+ const [options, setOptions] = useState([]);
15
+ const [page, setPage] = useState(1);
16
+ const [hasMore, setHasMore] = useState(false);
17
+ const [loading, setLoading] = useState(false);
18
+ // label cache so chips show labels even after options change
19
+ const labelMap = useRef(new Map());
20
+ const load = useCallback(async (search, nextPage, reset = false) => {
21
+ setLoading(true);
22
+ try {
23
+ const res = await loadOptions(search, nextPage);
24
+ setOptions((prev) => {
25
+ const merged = reset ? res.items : [...prev, ...res.items];
26
+ merged.forEach((o) => labelMap.current.set(o.value, o.label));
27
+ return merged;
28
+ });
29
+ setPage(nextPage);
30
+ setHasMore(res.hasMore);
31
+ }
32
+ finally {
33
+ setLoading(false);
34
+ }
35
+ }, [loadOptions]);
36
+ // Load whenever the section is expanded or query changes
37
+ useEffect(() => {
38
+ if (collapsed)
39
+ return;
40
+ void load(query, 1, true);
41
+ }, [collapsed, query, load]);
42
+ function handleQueryChange(val) {
43
+ setQuery(val);
44
+ if (collapsed)
45
+ setCollapsed(false);
46
+ }
47
+ function toggle(value) {
48
+ if (selectionMode === "single") {
49
+ onChange(selected.includes(value) ? [] : [value]);
50
+ }
51
+ else {
52
+ onChange(selected.includes(value)
53
+ ? selected.filter((v) => v !== value)
54
+ : [...selected, value]);
55
+ }
56
+ }
57
+ const hasValue = selected.length > 0;
58
+ const selectedLabels = selected
59
+ .map((v) => labelMap.current.get(v) ?? v)
60
+ .slice(0, 3);
61
+ return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: () => setCollapsed((c) => !c), variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !collapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20 dark:ring-emerald-400/20", children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", collapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full", "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), collapsed && hasValue && (_jsxs(Div, { className: "mt-2 flex flex-wrap gap-1", children: [selectedLabels.map((label) => (_jsx(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-slate-700 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-slate-600", children: label }, label))), selected.length > 3 && (_jsxs(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs text-zinc-400 dark:text-zinc-500", children: ["+", selected.length - 3, " more"] }))] })), _jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: query, onChange: (e) => handleQueryChange(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }) }), !collapsed && (_jsxs(Div, { className: "mt-3 space-y-1", children: [options.map((opt) => {
62
+ const isSelected = selected.includes(opt.value);
63
+ return (_jsxs(Row, { gap: "2.5", className: "py-1 cursor-pointer group", children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(opt.value), "aria-label": opt.label, className: "flex-shrink-0 w-4 h-4 rounded border-zinc-300 dark:border-slate-600 cursor-pointer text-primary-600 dark:text-secondary-500" }), _jsx(Span, { className: "flex-1 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors truncate", children: opt.label }), opt.count !== undefined && (_jsx(Span, { className: "text-xs text-zinc-400 dark:text-zinc-500 tabular-nums flex-shrink-0", children: opt.count }))] }, opt.value));
64
+ }), options.length === 0 && !loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1", children: "No results" })), loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1 animate-pulse", children: "Loading\u2026" })), hasMore && !loading && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full text-xs text-left text-zinc-400 dark:text-zinc-500 hover:text-zinc-600 dark:hover:text-zinc-300 py-1", onClick: () => void load(query, page + 1), children: "Load more\u2026" }))] }))] }));
65
+ }
@@ -1,5 +1,7 @@
1
1
  export { FilterFacetSection } from "./FilterFacetSection";
2
2
  export type { FilterFacetSectionProps, FacetOption, } from "./FilterFacetSection";
3
+ export { AsyncFacetSection } from "./AsyncFacetSection";
4
+ export type { AsyncFacetSectionProps } from "./AsyncFacetSection";
3
5
  export { RangeFilter } from "./RangeFilter";
4
6
  export type { RangeFilterProps } from "./RangeFilter";
5
7
  export { SwitchFilter } from "./SwitchFilter";
@@ -1,5 +1,6 @@
1
1
  // Public API for @mohasinac/feat-filters
2
2
  export { FilterFacetSection } from "./FilterFacetSection";
3
+ export { AsyncFacetSection } from "./AsyncFacetSection";
3
4
  export { RangeFilter } from "./RangeFilter";
4
5
  export { SwitchFilter } from "./SwitchFilter";
5
6
  export { FilterPanel } from "./FilterPanel";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { Div, Span } from "../../ui";
4
+ import { Div, Span, Text } from "../../ui";
5
5
  import { cn, ERROR_BASE } from "./utils";
6
6
  export function Checkbox({ label, suffix, error, indeterminate, className = "", checked, ...props }) {
7
7
  const inputRef = React.useRef(null);
@@ -12,5 +12,5 @@ export function Checkbox({ label, suffix, error, indeterminate, className = "",
12
12
  }, [indeterminate]);
13
13
  return (_jsxs(Div, { className: "w-full", children: [_jsxs("label", { className: "flex flex-row items-center gap-3 cursor-pointer group", children: [_jsxs(Div, { className: "relative flex items-center justify-center flex-shrink-0", children: [_jsx("input", { ref: inputRef, type: "checkbox", checked: checked, className: cn("peer w-5 h-5 rounded-md border-2 cursor-pointer", "transition-all duration-200 appearance-none", error
14
14
  ? "border-red-400 dark:border-red-500"
15
- : "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx("p", { className: cn(ERROR_BASE, "mt-1.5"), role: "alert", children: error }))] }));
15
+ : "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx(Text, { className: cn(ERROR_BASE, "mt-1.5"), role: "alert", children: error }))] }));
16
16
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { Div, Span } from "../../ui";
3
+ import { Div, Span, Text } from "../../ui";
4
4
  import { cn, INPUT_BASE, INPUT_ERROR, INPUT_SUCCESS, INPUT_DISABLED, INPUT_WITH_ICON, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
5
5
  export const Input = React.forwardRef(function Input({ label, error, helperText, icon, rightIcon, success, className = "", required, disabled, ...props }, ref) {
6
6
  const stateClasses = error
@@ -18,6 +18,6 @@ export const Input = React.forwardRef(function Input({ label, error, helperText,
18
18
  ? `${props.id}-helper`
19
19
  : undefined, ...props }), rightIcon && (_jsx(Div, { className: cn("absolute right-3 top-1/2 -translate-y-1/2 transition-colors duration-150", error
20
20
  ? "text-red-600 dark:text-red-400"
21
- : "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx("p", { id: `${props.id}-error`, className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx("p", { id: `${props.id}-helper`, className: HELPER_BASE, children: helperText }))] }));
21
+ : "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx(Text, { id: `${props.id}-error`, className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { id: `${props.id}-helper`, className: HELPER_BASE, children: helperText }))] }));
22
22
  });
23
23
  Input.displayName = "Input";
@@ -1,18 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Div, Span } from "../../ui";
2
+ import { Div, Span, Text } from "../../ui";
3
3
  import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
4
4
  export function RadioGroup({ name, options, value, onChange, label, error, orientation = "vertical", variant = "toggle", }) {
5
5
  if (variant === "classic") {
6
- return (_jsxs(Div, { className: "w-full", children: [label && _jsx("p", { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-3", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), children: options.map((option) => {
6
+ return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-3", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), children: options.map((option) => {
7
7
  const isSelected = value === option.value;
8
8
  return (_jsxs("label", { className: cn("flex items-center gap-2.5 cursor-pointer", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "w-4 h-4 text-primary-600 dark:text-secondary-500 border-zinc-300 dark:border-slate-600 focus:ring-primary-500/30 dark:focus:ring-secondary-400/30" }), _jsx(Span, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: option.label })] }, option.value));
9
- }) }), error && (_jsx("p", { className: ERROR_BASE, role: "alert", children: error }))] }));
9
+ }) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
10
10
  }
11
11
  // Toggle variant — pill style
12
- return (_jsxs(Div, { className: "w-full", children: [label && _jsx("p", { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-2", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), role: "radiogroup", "aria-label": label, children: options.map((option) => {
12
+ return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-2", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), role: "radiogroup", "aria-label": label, children: options.map((option) => {
13
13
  const isSelected = value === option.value;
14
14
  return (_jsxs("label", { className: cn("flex items-center justify-center px-4 py-2.5 rounded-xl border text-sm font-medium cursor-pointer transition-all duration-200", isSelected
15
15
  ? "bg-primary-600 dark:bg-secondary-500 border-primary-600 dark:border-secondary-500 text-white shadow-sm"
16
16
  : "border-zinc-200 dark:border-slate-700 text-zinc-700 dark:text-zinc-300 hover:border-primary-400 dark:hover:border-secondary-400 hover:bg-primary-50/50 dark:hover:bg-secondary-900/20", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "sr-only" }), option.label] }, option.value));
17
- }) }), error && (_jsx("p", { className: ERROR_BASE, role: "alert", children: error }))] }));
17
+ }) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
18
18
  }
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Div, Span } from "../../ui";
2
+ import { Div, Span, Text } from "../../ui";
3
3
  import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
4
4
  export function Select({ label, error, helperText, options, placeholder, className = "", required, ...props }) {
5
5
  return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsxs(Div, { className: "relative group", children: [_jsxs("select", { className: cn(INPUT_BASE, "pr-10 appearance-none cursor-pointer", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, ...props, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), _jsx(Div, { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none transition-colors duration-150", children: _jsx("svg", { className: cn("w-5 h-5 transition-transform duration-200", error
6
6
  ? "text-red-500 dark:text-red-400"
7
- : "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx("p", { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && _jsx("p", { className: HELPER_BASE, children: helperText })] }));
7
+ : "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && _jsx(Text, { className: HELPER_BASE, children: helperText })] }));
8
8
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { Div, Row, Span } from "../../ui";
4
+ import { Div, Row, Span, Text } from "../../ui";
5
5
  import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
6
6
  /**
7
7
  * Slider — single-thumb range slider.
@@ -18,5 +18,5 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
18
18
  onChange?.(newVal);
19
19
  };
20
20
  const displayValue = formatValue ? formatValue(value) : String(value);
21
- return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx("p", { className: ERROR_BASE, role: "alert", children: error }))] }));
21
+ return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
22
22
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { Div, Span } from "../../ui";
3
+ import { Div, Span, Text } from "../../ui";
4
4
  import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
5
5
  export const Textarea = React.forwardRef(function Textarea({ label, error, helperText, showCharCount, className = "", required, maxLength, value, defaultValue, ...props }, ref) {
6
6
  const charCount = typeof value === "string"
@@ -8,7 +8,7 @@ export const Textarea = React.forwardRef(function Textarea({ label, error, helpe
8
8
  : typeof defaultValue === "string"
9
9
  ? defaultValue.length
10
10
  : 0;
11
- return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx("p", { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx("p", { className: HELPER_BASE, children: helperText }))] }), showCharCount && maxLength && (_jsxs("p", { className: cn("text-xs tabular-nums ml-2 flex-shrink-0", charCount >= maxLength
11
+ return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { className: HELPER_BASE, children: helperText }))] }), showCharCount && maxLength && (_jsxs("p", { className: cn("text-xs tabular-nums ml-2 flex-shrink-0", charCount >= maxLength
12
12
  ? "text-red-500 dark:text-red-400"
13
13
  : "text-zinc-400 dark:text-zinc-500"), children: [charCount, " / ", maxLength] }))] })] }));
14
14
  });
@@ -12,6 +12,7 @@ import { NextResponse } from "next/server.js";
12
12
  import { z } from "zod";
13
13
  import { getProviders } from "../../../../contracts";
14
14
  import { createRouteHandler } from "../../../../next";
15
+ const ERR_SECTION_NOT_FOUND = "Section not found";
15
16
  // ---- GET /api/homepage-sections/[id] ----------------------------------------
16
17
  export async function GET(_request, context) {
17
18
  try {
@@ -23,7 +24,7 @@ export async function GET(_request, context) {
23
24
  const repo = db.getRepository("homepageSections");
24
25
  const section = await repo.findById(id);
25
26
  if (!section) {
26
- return NextResponse.json({ success: false, error: "Section not found" }, { status: 404 });
27
+ return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
27
28
  }
28
29
  return NextResponse.json({ success: true, data: section });
29
30
  }
@@ -71,7 +72,7 @@ export const homepageSectionItemPATCH = createRouteHandler({
71
72
  const repo = db.getRepository("homepageSections");
72
73
  const section = await repo.findById(id);
73
74
  if (!section)
74
- return NextResponse.json({ success: false, error: "Section not found" }, { status: 404 });
75
+ return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
75
76
  const updated = await repo.update(id, {
76
77
  ...body,
77
78
  updatedAt: new Date().toISOString(),
@@ -93,7 +94,7 @@ export const homepageSectionItemDELETE = createRouteHandler({
93
94
  const repo = db.getRepository("homepageSections");
94
95
  const section = await repo.findById(id);
95
96
  if (!section)
96
- return NextResponse.json({ success: false, error: "Section not found" }, { status: 404 });
97
+ return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
97
98
  await repo.delete(id);
98
99
  return NextResponse.json({ success: true });
99
100
  },
@@ -10,15 +10,18 @@
10
10
  */
11
11
  import { NextResponse } from "next/server.js";
12
12
  import { getProviders } from "../../../../../contracts";
13
+ const ERR_SECTION_ID_REQUIRED = "Section ID is required";
14
+ const ERR_DB_NOT_CONFIGURED = "Database provider not configured";
15
+ const ERR_INTERNAL_SERVER_ERROR = "Internal server error";
13
16
  export async function GET(request, { params }) {
14
17
  try {
15
18
  const { id } = await params;
16
19
  if (!id) {
17
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
20
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
18
21
  }
19
22
  const { db } = getProviders();
20
23
  if (!db)
21
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
24
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
22
25
  const repo = db.getRepository("homepage_sections");
23
26
  const section = await repo.findById(id);
24
27
  if (!section) {
@@ -32,7 +35,7 @@ export async function GET(request, { params }) {
32
35
  catch (error) {
33
36
  return NextResponse.json({
34
37
  success: false,
35
- error: error instanceof Error ? error.message : "Internal server error",
38
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
36
39
  }, { status: 500 });
37
40
  }
38
41
  }
@@ -40,12 +43,12 @@ export async function PATCH(request, { params }) {
40
43
  try {
41
44
  const { id } = await params;
42
45
  if (!id) {
43
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
46
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
44
47
  }
45
48
  const body = await request.json();
46
49
  const { db } = getProviders();
47
50
  if (!db)
48
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
51
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
49
52
  const repo = db.getRepository("homepage_sections");
50
53
  const updated = await repo.update(id, body);
51
54
  if (!updated) {
@@ -59,7 +62,7 @@ export async function PATCH(request, { params }) {
59
62
  catch (error) {
60
63
  return NextResponse.json({
61
64
  success: false,
62
- error: error instanceof Error ? error.message : "Internal server error",
65
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
63
66
  }, { status: 500 });
64
67
  }
65
68
  }
@@ -67,11 +70,11 @@ export async function DELETE(request, { params }) {
67
70
  try {
68
71
  const { id } = await params;
69
72
  if (!id) {
70
- return NextResponse.json({ success: false, error: "Section ID required" }, { status: 400 });
73
+ return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
71
74
  }
72
75
  const { db } = getProviders();
73
76
  if (!db)
74
- return NextResponse.json({ success: false, error: "DB not configured" }, { status: 503 });
77
+ return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
75
78
  const repo = db.getRepository("homepage_sections");
76
79
  await repo.delete(id);
77
80
  return NextResponse.json({
@@ -82,7 +85,7 @@ export async function DELETE(request, { params }) {
82
85
  catch (error) {
83
86
  return NextResponse.json({
84
87
  success: false,
85
- error: error instanceof Error ? error.message : "Internal server error",
88
+ error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
86
89
  }, { status: 500 });
87
90
  }
88
91
  }
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useRef, useState } from "react";
4
4
  import { getAdSlot, isAdSlotRenderable } from "../ad-registry";
5
5
  import { useActiveAd } from "../hooks/useActiveAd";
6
+ import { Text } from "../../../ui";
6
7
  // ---------------------------------------------------------------------------
7
8
  // Sub-renderers
8
9
  // ---------------------------------------------------------------------------
@@ -31,7 +32,7 @@ function ManualAdBanner({ ad }) {
31
32
  const { creative } = ad;
32
33
  if (!creative)
33
34
  return null;
34
- return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx("p", { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx("p", { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx("span", { className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-xs font-semibold text-white", children: creative.ctaLabel })) : null] }));
35
+ return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx("span", { className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-xs font-semibold text-white", children: creative.ctaLabel })) : null] }));
35
36
  }
36
37
  // ---------------------------------------------------------------------------
37
38
  // Primary component
@@ -3,18 +3,20 @@ import { THEME_CONSTANTS } from "../../../tokens";
3
3
  import { Button, Heading, Row, Section, Span, Text } from "../../../ui";
4
4
  import { MediaImage } from "../../media/MediaImage";
5
5
  import { ArrowRight, Sparkles } from "lucide-react";
6
+ // --- Constants ---------------------------------------------------------------
7
+ const CLS_CONTAINER = "w-full max-w-7xl mx-auto";
6
8
  // --- Component ---------------------------------------------------------------
7
9
  export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", onCtaClick, backgroundImage, backgroundColor, tagLabel, isLoading = false, compact = false, className = "", }) {
8
10
  const wrapClass = "bg-gradient-to-br from-amber-50/40 to-orange-50/20 dark:from-amber-950/10 dark:to-orange-950/5";
9
11
  if (isLoading) {
10
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-297", children: _jsx("div", { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
12
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-297", children: _jsx("div", { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
11
13
  }
12
14
  // -- Split layout: when a backgroundImage is provided --
13
15
  if (backgroundImage) {
14
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
16
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
15
17
  }
16
18
  // -- Full-width gradient layout --
17
- return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: "w-full max-w-7xl mx-auto", "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
19
+ return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
18
20
  "relative overflow-hidden rounded-2xl flex items-center",
19
21
  compact
20
22
  ? "h-[clamp(112px,16vh,160px)]"
@@ -1,5 +1,5 @@
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 { useState } from "react";
4
4
  import Image from "next/image";
5
5
  import Link from "next/link";
@@ -39,5 +39,5 @@ export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, view
39
39
  });
40
40
  if (!isLoading && allBrands.length === 0)
41
41
  return null;
42
- return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs("div", { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs("div", { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 8 }).map((_, i) => (_jsx("div", { className: "h-24 w-28 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false })), cta && !isLoading && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
42
+ return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs("div", { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 8 }).map((_, i) => (_jsx("div", { className: "h-24 w-28 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false })), cta && !isLoading && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
43
43
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Link from "next/link";
3
- import { Section } from "../../../ui";
3
+ import { Heading, Section, Text } from "../../../ui";
4
4
  export function CTABannerSection({ title = "Thousands of collectibles. One marketplace.", subtitle, primaryLabel = "Shop All Products →", primaryHref = "/products", secondaryLabel = "Browse Auctions →", secondaryHref = "/auctions", className = "", }) {
5
- return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx("h2", { className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx("p", { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", "data-section": "ctabannersection-div-314", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
5
+ return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx(Heading, { level: 2, className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx(Text, { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", "data-section": "ctabannersection-div-314", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
6
6
  }
@@ -1,11 +1,11 @@
1
- import type { CharacterHotspotConfig, HotspotPin } from "../types";
1
+ import type { CharacterHotspotConfig, HotspotPin as HotspotPinData } from "../types";
2
2
  export interface CharacterHotspotProps {
3
3
  config?: CharacterHotspotConfig | null;
4
4
  /**
5
5
  * Override the default fallback hotspot pins shown when no config is supplied.
6
6
  * Useful for non-collectibles storefronts.
7
7
  */
8
- defaultHotspots?: HotspotPin[];
8
+ defaultHotspots?: HotspotPinData[];
9
9
  /** Universe quick-browse links shown below the panorama. */
10
10
  universeLinks?: {
11
11
  label: string;