@mohasinac/appkit 2.7.27 → 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 (359) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
  2. package/dist/_internal/server/features/checkout/actions.js +42 -35
  3. package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
  4. package/dist/_internal/server/features/classified/adapters.js +24 -0
  5. package/dist/_internal/server/features/classified/index.d.ts +3 -0
  6. package/dist/_internal/server/features/classified/index.js +3 -0
  7. package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
  8. package/dist/_internal/server/features/classified/metadata.js +43 -0
  9. package/dist/_internal/server/features/classified/og.d.ts +30 -0
  10. package/dist/_internal/server/features/classified/og.js +76 -0
  11. package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
  12. package/dist/_internal/server/features/digital-code/adapters.js +29 -0
  13. package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
  14. package/dist/_internal/server/features/digital-code/index.js +3 -0
  15. package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
  16. package/dist/_internal/server/features/digital-code/metadata.js +36 -0
  17. package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
  18. package/dist/_internal/server/features/digital-code/og.js +77 -0
  19. package/dist/_internal/server/features/live/adapters.d.ts +21 -0
  20. package/dist/_internal/server/features/live/adapters.js +34 -0
  21. package/dist/_internal/server/features/live/index.d.ts +3 -0
  22. package/dist/_internal/server/features/live/index.js +3 -0
  23. package/dist/_internal/server/features/live/metadata.d.ts +8 -0
  24. package/dist/_internal/server/features/live/metadata.js +39 -0
  25. package/dist/_internal/server/features/live/og.d.ts +27 -0
  26. package/dist/_internal/server/features/live/og.js +72 -0
  27. package/dist/_internal/server/features/promotions/actions.js +4 -3
  28. package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
  29. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
  30. package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
  31. package/dist/_internal/shared/actions/action-registry.js +310 -8
  32. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  33. package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
  34. package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
  35. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  36. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
  37. package/dist/_internal/shared/features/events/schema.d.ts +8 -8
  38. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  39. package/dist/_internal/shared/features/products/schema.d.ts +42 -42
  40. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  41. package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
  42. package/dist/_internal/shared/media/limits.js +4 -3
  43. package/dist/client.d.ts +2 -0
  44. package/dist/client.js +1 -0
  45. package/dist/configs/next.js +4 -0
  46. package/dist/constants/table-keys.d.ts +6 -0
  47. package/dist/constants/table-keys.js +9 -0
  48. package/dist/core/hooks/useSyncManager.js +9 -8
  49. package/dist/features/about/components/FeesView.js +10 -7
  50. package/dist/features/about/components/HelpPageView.js +10 -1
  51. package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
  52. package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
  53. package/dist/features/about/components/HowOffersWorkView.js +10 -1
  54. package/dist/features/about/components/HowOrdersWorkView.js +10 -1
  55. package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
  56. package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
  57. package/dist/features/about/components/HowReviewsWorkView.js +10 -1
  58. package/dist/features/about/components/PublicProfileView.js +44 -14
  59. package/dist/features/about/components/SecurityPrivacyView.js +7 -1
  60. package/dist/features/account/components/AddressesIndexListing.js +2 -2
  61. package/dist/features/account/components/NotificationBell.js +27 -16
  62. package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
  63. package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
  64. package/dist/features/account/components/UserSidebar.js +4 -4
  65. package/dist/features/account/components/UserSupportView.js +16 -6
  66. package/dist/features/account/components/index.d.ts +2 -0
  67. package/dist/features/account/components/index.js +1 -0
  68. package/dist/features/account/schemas/index.d.ts +4 -4
  69. package/dist/features/account/types/index.d.ts +34 -0
  70. package/dist/features/admin/actions/admin-actions.js +4 -3
  71. package/dist/features/admin/actions/notification-actions.d.ts +24 -22
  72. package/dist/features/admin/actions/notification-actions.js +122 -22
  73. package/dist/features/admin/components/AdminAdEditorView.js +29 -15
  74. package/dist/features/admin/components/AdminAdsView.js +22 -28
  75. package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
  76. package/dist/features/admin/components/AdminBidsView.js +10 -3
  77. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  78. package/dist/features/admin/components/AdminBlogView.js +8 -3
  79. package/dist/features/admin/components/AdminBrandsView.js +7 -2
  80. package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
  81. package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
  82. package/dist/features/admin/components/AdminCarouselView.js +13 -7
  83. package/dist/features/admin/components/AdminCategoriesView.js +8 -3
  84. package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
  85. package/dist/features/admin/components/AdminContactView.js +6 -1
  86. package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
  87. package/dist/features/admin/components/AdminCouponsView.js +6 -1
  88. package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
  89. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  90. package/dist/features/admin/components/AdminFaqsView.js +7 -2
  91. package/dist/features/admin/components/AdminFeaturesView.js +4 -3
  92. package/dist/features/admin/components/AdminMediaView.js +9 -8
  93. package/dist/features/admin/components/AdminNavigationView.js +10 -17
  94. package/dist/features/admin/components/AdminNewsletterView.js +6 -1
  95. package/dist/features/admin/components/AdminNotificationsView.js +11 -3
  96. package/dist/features/admin/components/AdminOrdersView.js +6 -1
  97. package/dist/features/admin/components/AdminPayoutsView.js +10 -3
  98. package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
  99. package/dist/features/admin/components/AdminProductsView.js +18 -12
  100. package/dist/features/admin/components/AdminReviewsView.js +33 -24
  101. package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
  102. package/dist/features/admin/components/AdminScammersView.js +28 -26
  103. package/dist/features/admin/components/AdminSectionsView.js +112 -99
  104. package/dist/features/admin/components/AdminSessionsView.js +10 -3
  105. package/dist/features/admin/components/AdminSidebar.js +4 -4
  106. package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
  107. package/dist/features/admin/components/AdminStoresView.js +6 -1
  108. package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
  109. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  110. package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
  111. package/dist/features/admin/components/AdminTeamView.js +6 -1
  112. package/dist/features/admin/components/AdminUserEditorView.js +8 -15
  113. package/dist/features/admin/components/AdminUsersView.js +6 -1
  114. package/dist/features/admin/components/AdminViewCards.js +4 -3
  115. package/dist/features/admin/components/DashboardStats.js +2 -2
  116. package/dist/features/admin/components/DataTable.js +2 -2
  117. package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
  118. package/dist/features/admin/repository/chat.repository.js +8 -8
  119. package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
  120. package/dist/features/admin/repository/site-settings.repository.js +11 -9
  121. package/dist/features/admin/schemas/firestore.d.ts +38 -0
  122. package/dist/features/admin/schemas/firestore.js +15 -0
  123. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -19
  124. package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
  125. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
  126. package/dist/features/auctions/components/index.d.ts +0 -1
  127. package/dist/features/auctions/components/index.js +0 -1
  128. package/dist/features/auctions/schemas/index.d.ts +14 -14
  129. package/dist/features/auth/actions/realtime-token-actions.js +19 -4
  130. package/dist/features/auth/components/RegisterForm.js +8 -4
  131. package/dist/features/auth/consent-otp.d.ts +2 -0
  132. package/dist/features/auth/consent-otp.js +8 -0
  133. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  134. package/dist/features/auth/schemas/firestore.js +18 -25
  135. package/dist/features/auth/schemas/index.d.ts +2 -2
  136. package/dist/features/before-after/api/[id]/route.js +8 -6
  137. package/dist/features/before-after/schemas/index.d.ts +2 -2
  138. package/dist/features/blog/actions/blog-actions.d.ts +3 -3
  139. package/dist/features/blog/components/BlogIndexListing.js +21 -2
  140. package/dist/features/blog/components/BlogPostForm.js +11 -5
  141. package/dist/features/blog/components/BlogPostView.js +10 -2
  142. package/dist/features/blog/schemas/index.d.ts +18 -18
  143. package/dist/features/cart/components/CartDrawer.js +3 -2
  144. package/dist/features/cart/repository/cart.repository.js +4 -3
  145. package/dist/features/cart/utils/pending-ops.d.ts +1 -1
  146. package/dist/features/categories/api/[id]/route.js +4 -3
  147. package/dist/features/categories/api/route.js +4 -3
  148. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  149. package/dist/features/categories/components/BrandDetailTabs.js +2 -2
  150. package/dist/features/categories/components/BundleCollage.d.ts +8 -0
  151. package/dist/features/categories/components/BundleCollage.js +50 -0
  152. package/dist/features/categories/components/BundleDetailView.js +2 -10
  153. package/dist/features/categories/components/BundleItemsPicker.js +20 -13
  154. package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
  155. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  156. package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
  157. package/dist/features/categories/components/CategoryProductsListing.js +52 -13
  158. package/dist/features/categories/components/index.d.ts +2 -0
  159. package/dist/features/categories/components/index.js +1 -0
  160. package/dist/features/categories/schemas/index.d.ts +6 -6
  161. package/dist/features/checkout/actions/checkout-actions.js +4 -3
  162. package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
  163. package/dist/features/classified/components/ClassifiedFilters.d.ts +8 -0
  164. package/dist/features/classified/components/ClassifiedFilters.js +19 -0
  165. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
  166. package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
  167. package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
  168. package/dist/features/classified/components/ClassifiedListView.js +43 -0
  169. package/dist/features/classified/components/index.d.ts +6 -0
  170. package/dist/features/classified/components/index.js +3 -0
  171. package/dist/features/collections/api/[slug]/route.js +16 -12
  172. package/dist/features/collections/schemas/index.d.ts +5 -5
  173. package/dist/features/consultation/api/[id]/route.js +12 -9
  174. package/dist/features/consultation/components/ConsultationForm.js +3 -2
  175. package/dist/features/consultation/schemas/index.d.ts +6 -6
  176. package/dist/features/contact/email.js +77 -116
  177. package/dist/features/copilot/components/AdminCopilotView.js +12 -2
  178. package/dist/features/corporate/api/[id]/route.js +12 -9
  179. package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
  180. package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +8 -0
  181. package/dist/features/digital-codes/components/DigitalCodeFilters.js +16 -0
  182. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
  183. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
  184. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
  185. package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
  186. package/dist/features/digital-codes/components/index.d.ts +6 -0
  187. package/dist/features/digital-codes/components/index.js +3 -0
  188. package/dist/features/events/actions/event-actions.js +4 -3
  189. package/dist/features/events/components/AdminEventEditorView.js +3 -2
  190. package/dist/features/events/components/AdminEventsView.js +4 -2
  191. package/dist/features/events/components/EventPollWidget.js +5 -5
  192. package/dist/features/events/components/EventsIndexListing.js +2 -2
  193. package/dist/features/events/schemas/index.d.ts +20 -20
  194. package/dist/features/faq/actions/faq-actions.d.ts +8 -8
  195. package/dist/features/faq/components/ContactCTA.js +3 -1
  196. package/dist/features/faq/components/FAQAccordion.js +1 -1
  197. package/dist/features/faq/schemas/index.d.ts +4 -4
  198. package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
  199. package/dist/features/filters/AsyncFacetSection.js +65 -0
  200. package/dist/features/forms/Checkbox.js +2 -2
  201. package/dist/features/forms/Input.js +2 -2
  202. package/dist/features/forms/Radio.js +5 -5
  203. package/dist/features/forms/Select.js +2 -2
  204. package/dist/features/forms/Slider.js +2 -2
  205. package/dist/features/forms/Textarea.js +2 -2
  206. package/dist/features/homepage/api/[id]/route.js +4 -3
  207. package/dist/features/homepage/api/sections/[id]/route.js +12 -9
  208. package/dist/features/homepage/components/AdSlot.js +2 -1
  209. package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
  210. package/dist/features/homepage/components/BrandsSection.js +2 -2
  211. package/dist/features/homepage/components/CTABannerSection.js +2 -2
  212. package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
  213. package/dist/features/homepage/components/CharacterHotspot.js +119 -157
  214. package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
  215. package/dist/features/homepage/components/CustomCardsSection.js +8 -6
  216. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  217. package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
  218. package/dist/features/homepage/components/HeroBanner.js +5 -4
  219. package/dist/features/homepage/components/HeroCarousel.js +13 -26
  220. package/dist/features/homepage/components/HowItWorksSection.js +4 -2
  221. package/dist/features/homepage/components/SocialFeedSection.js +2 -2
  222. package/dist/features/homepage/components/SocialPostCard.js +3 -2
  223. package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
  224. package/dist/features/layout/AppLayoutShell.d.ts +8 -2
  225. package/dist/features/layout/AppLayoutShell.js +54 -78
  226. package/dist/features/layout/BottomActions.js +43 -48
  227. package/dist/features/live/components/LiveItemFilters.d.ts +8 -0
  228. package/dist/features/live/components/LiveItemFilters.js +23 -0
  229. package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
  230. package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
  231. package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
  232. package/dist/features/live/components/LiveItemsListView.js +43 -0
  233. package/dist/features/live/components/index.d.ts +6 -0
  234. package/dist/features/live/components/index.js +3 -0
  235. package/dist/features/media/MediaLightbox.js +8 -14
  236. package/dist/features/media/types/index.d.ts +2 -2
  237. package/dist/features/media/upload/CameraCapture.js +2 -2
  238. package/dist/features/media/upload/ImageUpload.js +4 -2
  239. package/dist/features/media/upload/MediaUploadField.js +24 -8
  240. package/dist/features/media/upload/MediaUploadList.js +1 -1
  241. package/dist/features/orders/actions/order-actions.js +4 -3
  242. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
  243. package/dist/features/orders/components/OrderFilters.js +12 -9
  244. package/dist/features/orders/schemas/index.d.ts +6 -6
  245. package/dist/features/pre-orders/api/[id]/route.js +12 -9
  246. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
  247. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +27 -20
  248. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
  249. package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
  250. package/dist/features/pre-orders/components/PreorderCard.js +2 -13
  251. package/dist/features/pre-orders/components/index.d.ts +1 -1
  252. package/dist/features/pre-orders/components/index.js +1 -1
  253. package/dist/features/pre-orders/schemas/index.d.ts +10 -10
  254. package/dist/features/products/api/[id]/route.js +9 -7
  255. package/dist/features/products/api/route.js +1 -1
  256. package/dist/features/products/columns/productTableColumns.js +2 -2
  257. package/dist/features/products/components/AuctionsIndexListing.js +15 -51
  258. package/dist/features/products/components/BidHistory.js +2 -2
  259. package/dist/features/products/components/CompareOverlay.js +3 -2
  260. package/dist/features/products/components/MakeOfferButton.js +20 -14
  261. package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
  262. package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
  263. package/dist/features/products/components/PrizeDrawCollage.js +54 -14
  264. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  265. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  266. package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
  267. package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
  268. package/dist/features/products/components/PrizeRevealModal.js +24 -14
  269. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  270. package/dist/features/products/components/ProductFilters.js +8 -6
  271. package/dist/features/products/components/ProductForm.js +12 -10
  272. package/dist/features/products/components/ProductGalleryClient.js +2 -1
  273. package/dist/features/products/components/ProductGrid.js +11 -14
  274. package/dist/features/products/components/ProductsIndexListing.js +16 -52
  275. package/dist/features/products/components/ProductsIndexPageView.js +2 -2
  276. package/dist/features/products/schemas/index.d.ts +56 -56
  277. package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
  278. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  279. package/dist/features/promotions/schemas/index.d.ts +6 -6
  280. package/dist/features/reviews/actions/review-actions.js +6 -5
  281. package/dist/features/reviews/api/[id]/route.js +4 -3
  282. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
  283. package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
  284. package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
  285. package/dist/features/reviews/schemas/index.d.ts +6 -6
  286. package/dist/features/scams/components/ScamProfileView.js +19 -10
  287. package/dist/features/scams/components/ScamRegistryView.js +2 -1
  288. package/dist/features/search/components/Search.d.ts +1 -1
  289. package/dist/features/search/components/Search.js +56 -49
  290. package/dist/features/search/schemas/index.d.ts +5 -5
  291. package/dist/features/seller/actions/offer-actions.js +11 -9
  292. package/dist/features/seller/components/SellerAddressesView.js +6 -4
  293. package/dist/features/seller/components/SellerBidsView.js +2 -2
  294. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  295. package/dist/features/seller/components/SellerOffersPanel.js +6 -1
  296. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  297. package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
  298. package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
  299. package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
  300. package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
  301. package/dist/features/seller/components/SellerProductShell.js +75 -9
  302. package/dist/features/seller/components/SellerProductsView.js +10 -11
  303. package/dist/features/seller/components/SellerShippingView.js +3 -3
  304. package/dist/features/seller/components/SellerSidebar.js +10 -7
  305. package/dist/features/seller/components/SellerStorefrontView.js +3 -3
  306. package/dist/features/seller/schemas/index.d.ts +4 -4
  307. package/dist/features/shell/FormShell.js +2 -1
  308. package/dist/features/shell/QuickFormDrawer.js +4 -3
  309. package/dist/features/shell/StepForm.js +4 -3
  310. package/dist/features/stores/actions/store-query-actions.js +4 -3
  311. package/dist/features/stores/components/StoreAboutView.js +2 -1
  312. package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
  313. package/dist/features/stores/components/StoreDetailLayoutView.js +2 -2
  314. package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
  315. package/dist/features/stores/components/StoreProductsListing.js +16 -49
  316. package/dist/features/stores/components/StoresIndexListing.js +2 -2
  317. package/dist/features/stores/schemas/index.d.ts +2 -2
  318. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
  319. package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
  320. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
  321. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
  322. package/dist/index.d.ts +21 -3
  323. package/dist/index.js +1737 -1725
  324. package/dist/monitoring/server-logger.js +5 -9
  325. package/dist/next/api/apiHandler.js +56 -37
  326. package/dist/next/components/GlobalError.js +2 -1
  327. package/dist/next/routing/route-map.d.ts +27 -0
  328. package/dist/next/routing/route-map.js +10 -0
  329. package/dist/react/ErrorBoundary.js +2 -1
  330. package/dist/react/contexts/SessionContext.js +38 -28
  331. package/dist/react/hooks/useCamera.d.ts +1 -1
  332. package/dist/react/hooks/useCamera.js +8 -7
  333. package/dist/seed/site-settings-seed-data.js +6 -0
  334. package/dist/server-entry.d.ts +3 -0
  335. package/dist/server-entry.js +3 -0
  336. package/dist/server.d.ts +12 -0
  337. package/dist/server.js +15 -0
  338. package/dist/tailwind-utilities.css +1 -1
  339. package/dist/ui/DataTable.js +28 -7
  340. package/dist/ui/components/Button.d.ts +8 -1
  341. package/dist/ui/components/Button.js +47 -8
  342. package/dist/ui/components/CollageLightbox.d.ts +18 -0
  343. package/dist/ui/components/CollageLightbox.js +41 -0
  344. package/dist/ui/components/Dropdown.js +7 -6
  345. package/dist/ui/components/ImageLightbox.d.ts +7 -1
  346. package/dist/ui/components/ImageLightbox.js +15 -5
  347. package/dist/ui/components/PageLoader.js +4 -3
  348. package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
  349. package/dist/ui/components/PaginatedMultiSelect.js +141 -0
  350. package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
  351. package/dist/ui/components/Semantic.js +1 -1
  352. package/dist/ui/components/SideDrawer.js +17 -15
  353. package/dist/ui/components/index.style.css +1 -0
  354. package/dist/ui/index.d.ts +2 -0
  355. package/dist/ui/index.js +1 -0
  356. package/dist/utils/number.formatter.js +5 -13
  357. package/dist/utils/string.formatter.js +21 -18
  358. package/dist/validation/schemas.d.ts +2 -2
  359. package/package.json +1 -1
@@ -90,14 +90,14 @@ export declare const eventItemSchema: z.ZodObject<{
90
90
  }, "strip", z.ZodTypeAny, {
91
91
  type: "video" | "image" | "file";
92
92
  url: string;
93
- source?: "external" | "upload" | "youtube" | undefined;
93
+ source?: "upload" | "youtube" | "external" | undefined;
94
94
  alt?: string | undefined;
95
95
  thumbnailUrl?: string | undefined;
96
96
  youtubeId?: string | undefined;
97
97
  }, {
98
98
  type: "video" | "image" | "file";
99
99
  url: string;
100
- source?: "external" | "upload" | "youtube" | undefined;
100
+ source?: "upload" | "youtube" | "external" | undefined;
101
101
  alt?: string | undefined;
102
102
  thumbnailUrl?: string | undefined;
103
103
  youtubeId?: string | undefined;
@@ -107,7 +107,7 @@ export declare const eventItemSchema: z.ZodObject<{
107
107
  }, string>]>>>, {
108
108
  type: "video" | "image" | "file";
109
109
  url: string;
110
- source?: "external" | "upload" | "youtube" | undefined;
110
+ source?: "upload" | "youtube" | "external" | undefined;
111
111
  alt?: string | undefined;
112
112
  thumbnailUrl?: string | undefined;
113
113
  youtubeId?: string | undefined;
@@ -117,7 +117,7 @@ export declare const eventItemSchema: z.ZodObject<{
117
117
  } | null, string | {
118
118
  type: "video" | "image" | "file";
119
119
  url: string;
120
- source?: "external" | "upload" | "youtube" | undefined;
120
+ source?: "upload" | "youtube" | "external" | undefined;
121
121
  alt?: string | undefined;
122
122
  thumbnailUrl?: string | undefined;
123
123
  youtubeId?: string | undefined;
@@ -133,14 +133,14 @@ export declare const eventItemSchema: z.ZodObject<{
133
133
  }, "strip", z.ZodTypeAny, {
134
134
  type: "video" | "image" | "file";
135
135
  url: string;
136
- source?: "external" | "upload" | "youtube" | undefined;
136
+ source?: "upload" | "youtube" | "external" | undefined;
137
137
  alt?: string | undefined;
138
138
  thumbnailUrl?: string | undefined;
139
139
  youtubeId?: string | undefined;
140
140
  }, {
141
141
  type: "video" | "image" | "file";
142
142
  url: string;
143
- source?: "external" | "upload" | "youtube" | undefined;
143
+ source?: "upload" | "youtube" | "external" | undefined;
144
144
  alt?: string | undefined;
145
145
  thumbnailUrl?: string | undefined;
146
146
  youtubeId?: string | undefined;
@@ -155,14 +155,14 @@ export declare const eventItemSchema: z.ZodObject<{
155
155
  }, "strip", z.ZodTypeAny, {
156
156
  type: "video" | "image" | "file";
157
157
  url: string;
158
- source?: "external" | "upload" | "youtube" | undefined;
158
+ source?: "upload" | "youtube" | "external" | undefined;
159
159
  alt?: string | undefined;
160
160
  thumbnailUrl?: string | undefined;
161
161
  youtubeId?: string | undefined;
162
162
  }, {
163
163
  type: "video" | "image" | "file";
164
164
  url: string;
165
- source?: "external" | "upload" | "youtube" | undefined;
165
+ source?: "upload" | "youtube" | "external" | undefined;
166
166
  alt?: string | undefined;
167
167
  thumbnailUrl?: string | undefined;
168
168
  youtubeId?: string | undefined;
@@ -177,14 +177,14 @@ export declare const eventItemSchema: z.ZodObject<{
177
177
  }, "strip", z.ZodTypeAny, {
178
178
  type: "video" | "image" | "file";
179
179
  url: string;
180
- source?: "external" | "upload" | "youtube" | undefined;
180
+ source?: "upload" | "youtube" | "external" | undefined;
181
181
  alt?: string | undefined;
182
182
  thumbnailUrl?: string | undefined;
183
183
  youtubeId?: string | undefined;
184
184
  }, {
185
185
  type: "video" | "image" | "file";
186
186
  url: string;
187
- source?: "external" | "upload" | "youtube" | undefined;
187
+ source?: "upload" | "youtube" | "external" | undefined;
188
188
  alt?: string | undefined;
189
189
  thumbnailUrl?: string | undefined;
190
190
  youtubeId?: string | undefined;
@@ -269,17 +269,17 @@ export declare const eventItemSchema: z.ZodObject<{
269
269
  status: "draft" | "ended" | "active" | "paused";
270
270
  type: "offer" | "feedback" | "sale" | "poll" | "survey";
271
271
  title: string;
272
+ description: string;
272
273
  stats: {
273
274
  totalEntries: number;
274
275
  approvedEntries: number;
275
276
  flaggedEntries: number;
276
277
  };
277
- description: string;
278
278
  createdBy: string;
279
279
  coverImage: {
280
280
  type: "video" | "image" | "file";
281
281
  url: string;
282
- source?: "external" | "upload" | "youtube" | undefined;
282
+ source?: "upload" | "youtube" | "external" | undefined;
283
283
  alt?: string | undefined;
284
284
  thumbnailUrl?: string | undefined;
285
285
  youtubeId?: string | undefined;
@@ -292,7 +292,7 @@ export declare const eventItemSchema: z.ZodObject<{
292
292
  additionalImages: {
293
293
  type: "video" | "image" | "file";
294
294
  url: string;
295
- source?: "external" | "upload" | "youtube" | undefined;
295
+ source?: "upload" | "youtube" | "external" | undefined;
296
296
  alt?: string | undefined;
297
297
  thumbnailUrl?: string | undefined;
298
298
  youtubeId?: string | undefined;
@@ -300,7 +300,7 @@ export declare const eventItemSchema: z.ZodObject<{
300
300
  eventImages: {
301
301
  type: "video" | "image" | "file";
302
302
  url: string;
303
- source?: "external" | "upload" | "youtube" | undefined;
303
+ source?: "upload" | "youtube" | "external" | undefined;
304
304
  alt?: string | undefined;
305
305
  thumbnailUrl?: string | undefined;
306
306
  youtubeId?: string | undefined;
@@ -308,7 +308,7 @@ export declare const eventItemSchema: z.ZodObject<{
308
308
  winnerImages: {
309
309
  type: "video" | "image" | "file";
310
310
  url: string;
311
- source?: "external" | "upload" | "youtube" | undefined;
311
+ source?: "upload" | "youtube" | "external" | undefined;
312
312
  alt?: string | undefined;
313
313
  thumbnailUrl?: string | undefined;
314
314
  youtubeId?: string | undefined;
@@ -340,19 +340,19 @@ export declare const eventItemSchema: z.ZodObject<{
340
340
  status: "draft" | "ended" | "active" | "paused";
341
341
  type: "offer" | "feedback" | "sale" | "poll" | "survey";
342
342
  title: string;
343
+ description: string;
343
344
  stats: {
344
345
  totalEntries: number;
345
346
  approvedEntries: number;
346
347
  flaggedEntries: number;
347
348
  };
348
- description: string;
349
349
  createdBy: string;
350
350
  startsAt: string;
351
351
  endsAt: string;
352
352
  coverImage?: string | {
353
353
  type: "video" | "image" | "file";
354
354
  url: string;
355
- source?: "external" | "upload" | "youtube" | undefined;
355
+ source?: "upload" | "youtube" | "external" | undefined;
356
356
  alt?: string | undefined;
357
357
  thumbnailUrl?: string | undefined;
358
358
  youtubeId?: string | undefined;
@@ -360,7 +360,7 @@ export declare const eventItemSchema: z.ZodObject<{
360
360
  additionalImages?: {
361
361
  type: "video" | "image" | "file";
362
362
  url: string;
363
- source?: "external" | "upload" | "youtube" | undefined;
363
+ source?: "upload" | "youtube" | "external" | undefined;
364
364
  alt?: string | undefined;
365
365
  thumbnailUrl?: string | undefined;
366
366
  youtubeId?: string | undefined;
@@ -369,7 +369,7 @@ export declare const eventItemSchema: z.ZodObject<{
369
369
  eventImages?: {
370
370
  type: "video" | "image" | "file";
371
371
  url: string;
372
- source?: "external" | "upload" | "youtube" | undefined;
372
+ source?: "upload" | "youtube" | "external" | undefined;
373
373
  alt?: string | undefined;
374
374
  thumbnailUrl?: string | undefined;
375
375
  youtubeId?: string | undefined;
@@ -377,7 +377,7 @@ export declare const eventItemSchema: z.ZodObject<{
377
377
  winnerImages?: {
378
378
  type: "video" | "image" | "file";
379
379
  url: string;
380
- source?: "external" | "upload" | "youtube" | undefined;
380
+ source?: "upload" | "youtube" | "external" | undefined;
381
381
  alt?: string | undefined;
382
382
  thumbnailUrl?: string | undefined;
383
383
  youtubeId?: string | undefined;
@@ -26,10 +26,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
26
26
  variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
27
27
  template: z.ZodOptional<z.ZodString>;
28
28
  }, "strip", z.ZodTypeAny, {
29
+ category: string;
29
30
  order: number;
30
31
  priority: number;
31
32
  isActive: boolean;
32
- category: string;
33
33
  question: string;
34
34
  showInFooter: boolean;
35
35
  showOnHomepage: boolean;
@@ -51,10 +51,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
51
51
  format?: "html" | "plain" | "markdown" | undefined;
52
52
  };
53
53
  template?: string | undefined;
54
+ tags?: string[] | undefined;
54
55
  order?: number | undefined;
55
56
  priority?: number | undefined;
56
57
  isActive?: boolean | undefined;
57
- tags?: string[] | undefined;
58
58
  variables?: Record<string, string> | undefined;
59
59
  showInFooter?: boolean | undefined;
60
60
  showOnHomepage?: boolean | undefined;
@@ -62,10 +62,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
62
62
  relatedFAQs?: string[] | undefined;
63
63
  useSiteSettings?: boolean | undefined;
64
64
  }>, {
65
+ category: string;
65
66
  order: number;
66
67
  priority: number;
67
68
  isActive: boolean;
68
- category: string;
69
69
  question: string;
70
70
  showInFooter: boolean;
71
71
  showOnHomepage: boolean;
@@ -87,10 +87,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
87
87
  format?: "html" | "plain" | "markdown" | undefined;
88
88
  };
89
89
  template?: string | undefined;
90
+ tags?: string[] | undefined;
90
91
  order?: number | undefined;
91
92
  priority?: number | undefined;
92
93
  isActive?: boolean | undefined;
93
- tags?: string[] | undefined;
94
94
  variables?: Record<string, string> | undefined;
95
95
  showInFooter?: boolean | undefined;
96
96
  showOnHomepage?: boolean | undefined;
@@ -124,11 +124,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
124
124
  template: z.ZodOptional<z.ZodOptional<z.ZodString>>;
125
125
  }, "strip", z.ZodTypeAny, {
126
126
  template?: string | undefined;
127
+ category?: string | undefined;
128
+ tags?: string[] | undefined;
127
129
  order?: number | undefined;
128
130
  priority?: number | undefined;
129
131
  isActive?: boolean | undefined;
130
- category?: string | undefined;
131
- tags?: string[] | undefined;
132
132
  variables?: Record<string, string> | undefined;
133
133
  question?: string | undefined;
134
134
  showInFooter?: boolean | undefined;
@@ -142,11 +142,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
142
142
  useSiteSettings?: boolean | undefined;
143
143
  }, {
144
144
  template?: string | undefined;
145
+ category?: string | undefined;
146
+ tags?: string[] | undefined;
145
147
  order?: number | undefined;
146
148
  priority?: number | undefined;
147
149
  isActive?: boolean | undefined;
148
- category?: string | undefined;
149
- tags?: string[] | undefined;
150
150
  variables?: Record<string, string> | undefined;
151
151
  question?: string | undefined;
152
152
  showInFooter?: boolean | undefined;
@@ -1,5 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Card, Div, Heading, Span, Text, TextLink } from "../../../ui";
3
+ const CLS_CONTACT_CARD = "flex items-center gap-3 rounded-lg border border-zinc-100 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 px-4 py-3 hover:border-primary/40 transition-colors";
4
+ const CLS_CONTACT_LABEL = "text-xs text-zinc-500 dark:text-zinc-400";
3
5
  export function ContactCTA({ email, phone, contactHref, labels, }) {
4
- return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className: "group rounded-xl bg-zinc-100 p-6 transition-colors hover:bg-zinc-200 dark:bg-slate-700 dark:hover:bg-slate-600", children: [_jsx(Text, { className: "mb-1 text-sm font-medium", children: labels?.emailUs ?? "Email Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: email })] }), _jsxs(TextLink, { href: `tel:${phone}`, variant: "none", className: "group rounded-xl bg-zinc-100 p-6 transition-colors hover:bg-zinc-200 dark:bg-slate-700 dark:hover:bg-slate-600", children: [_jsx(Text, { className: "mb-1 text-sm font-medium", children: labels?.callUs ?? "Call Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: phone })] }), _jsxs(TextLink, { href: contactHref, className: "group rounded-xl bg-zinc-100 p-6 transition-colors hover:bg-zinc-200 dark:bg-slate-700 dark:hover:bg-slate-600", children: [_jsx(Text, { className: "mb-1 text-sm font-medium", children: labels?.contactForm ?? "Contact Form" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: labels?.submitRequest ?? "Submit a request" })] })] }), _jsxs(TextLink, { href: contactHref, className: "inline-flex items-center gap-2 rounded-xl bg-primary p-6 font-medium text-white transition-colors hover:bg-primary/90", children: [_jsx(Span, { children: labels?.contactTeam ?? "Contact Team" }), _jsx("svg", { className: "h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }));
6
+ return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.emailUs ?? "Email Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: email })] }), _jsxs(TextLink, { href: `tel:${phone}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.callUs ?? "Call Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: phone })] }), _jsxs(TextLink, { href: contactHref, className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.contactForm ?? "Contact Form" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: labels?.submitRequest ?? "Submit a request" })] })] }), _jsxs(TextLink, { href: contactHref, className: "inline-flex items-center gap-2 rounded-xl bg-primary p-6 font-medium text-white transition-colors hover:bg-primary/90", children: [_jsx(Span, { children: labels?.contactTeam ?? "Contact Team" }), _jsx("svg", { className: "h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }));
5
7
  }
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import { Button, Div, RichText, Row, Span, Text } from "../../../ui";
5
5
  function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, }) {
6
- return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
6
+ return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
7
7
  }
8
8
  export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, }) {
9
9
  const [openId, setOpenId] = useState(null);
@@ -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,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
  },