@mohasinac/appkit 2.8.2 → 2.8.4

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 (451) hide show
  1. package/dist/_internal/client/features/classified/ClassifiedDetailView.js +7 -1
  2. package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
  3. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +7 -1
  4. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -2
  5. package/dist/_internal/client/features/live/LiveItemDetailView.js +11 -2
  6. package/dist/_internal/client/scaffolds/AppShell.js +2 -1
  7. package/dist/_internal/client/scaffolds/DashboardScaffold.js +2 -1
  8. package/dist/_internal/server/features/checkout/actions.js +40 -39
  9. package/dist/_internal/shared/actions/action-registry.js +6 -0
  10. package/dist/_internal/shared/config/index.d.ts +1 -1
  11. package/dist/_internal/shared/config/schema.d.ts +0 -8
  12. package/dist/client-entry.d.ts +1 -1
  13. package/dist/client.d.ts +3 -1
  14. package/dist/client.js +3 -1
  15. package/dist/configs/next.js +12 -22
  16. package/dist/constants/api-endpoints.d.ts +6 -0
  17. package/dist/constants/api-endpoints.js +2 -0
  18. package/dist/features/about/components/AboutView.js +5 -2
  19. package/dist/features/about/components/FAQPageView.js +3 -3
  20. package/dist/features/about/components/FeesView.js +13 -5
  21. package/dist/features/about/components/HelpPageView.js +9 -5
  22. package/dist/features/about/components/HowAuctionsWorkView.js +9 -5
  23. package/dist/features/about/components/HowCheckoutWorksView.js +9 -5
  24. package/dist/features/about/components/HowOffersWorkView.js +10 -5
  25. package/dist/features/about/components/HowOrdersWorkView.js +10 -5
  26. package/dist/features/about/components/HowPayoutsWorkView.js +9 -5
  27. package/dist/features/about/components/HowPreOrdersWorkView.js +9 -5
  28. package/dist/features/about/components/HowReviewsWorkView.js +9 -5
  29. package/dist/features/about/components/PolicyPageView.js +3 -3
  30. package/dist/features/about/components/PublicProfileView.js +11 -4
  31. package/dist/features/about/components/SecurityPrivacyView.js +8 -4
  32. package/dist/features/about/components/ShippingPolicyView.js +3 -2
  33. package/dist/features/about/components/TrackOrderView.js +2 -2
  34. package/dist/features/about/components/UnauthorizedView.js +3 -3
  35. package/dist/features/account/components/AddressBook.js +1 -1
  36. package/dist/features/account/components/AddressForm.js +2 -2
  37. package/dist/features/account/components/AddressInlineSelect.d.ts +24 -0
  38. package/dist/features/account/components/AddressInlineSelect.js +78 -0
  39. package/dist/features/account/components/AddressSelectorCreate.d.ts +2 -1
  40. package/dist/features/account/components/AddressSelectorCreate.js +5 -32
  41. package/dist/features/account/components/AddressesIndexListing.js +3 -3
  42. package/dist/features/account/components/ChatWindow.js +2 -1
  43. package/dist/features/account/components/NotificationBell.js +13 -7
  44. package/dist/features/account/components/NotificationPreferencesPanel.js +4 -1
  45. package/dist/features/account/components/UserOffersPanel.js +2 -1
  46. package/dist/features/account/components/UserSidebar.js +11 -7
  47. package/dist/features/account/components/UserSupportView.js +13 -4
  48. package/dist/features/account/components/index.d.ts +2 -0
  49. package/dist/features/account/components/index.js +1 -0
  50. package/dist/features/addresses/repository/addresses.repository.d.ts +1 -0
  51. package/dist/features/addresses/repository/addresses.repository.js +13 -0
  52. package/dist/features/admin/components/AdminAdEditorView.js +8 -5
  53. package/dist/features/admin/components/AdminAddressEditorView.js +5 -5
  54. package/dist/features/admin/components/AdminAdsView.js +10 -7
  55. package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
  56. package/dist/features/admin/components/AdminBidsView.js +6 -4
  57. package/dist/features/admin/components/AdminBlogEditorView.js +15 -9
  58. package/dist/features/admin/components/AdminBlogView.js +6 -4
  59. package/dist/features/admin/components/AdminBrandEditorView.js +10 -4
  60. package/dist/features/admin/components/AdminBrandsView.js +12 -10
  61. package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
  62. package/dist/features/admin/components/AdminBundlesView.js +13 -11
  63. package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
  64. package/dist/features/admin/components/AdminCarouselView.js +6 -6
  65. package/dist/features/admin/components/AdminCartsView.js +6 -4
  66. package/dist/features/admin/components/AdminCatalogGuideView.js +2 -1
  67. package/dist/features/admin/components/AdminCategoriesView.js +12 -10
  68. package/dist/features/admin/components/AdminCategoryEditorView.js +11 -5
  69. package/dist/features/admin/components/AdminClassifiedView.js +4 -3
  70. package/dist/features/admin/components/AdminContactEditorView.js +8 -1
  71. package/dist/features/admin/components/AdminContactView.js +6 -4
  72. package/dist/features/admin/components/AdminCouponEditorView.js +23 -5
  73. package/dist/features/admin/components/AdminCouponsView.js +6 -4
  74. package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
  75. package/dist/features/admin/components/AdminEmployeeEditorView.js +7 -4
  76. package/dist/features/admin/components/AdminFaqEditorView.js +9 -3
  77. package/dist/features/admin/components/AdminFaqsView.js +9 -7
  78. package/dist/features/admin/components/AdminFeatureEditorView.js +7 -1
  79. package/dist/features/admin/components/AdminFeatureFlagsView.js +4 -1
  80. package/dist/features/admin/components/AdminFeaturesView.js +5 -4
  81. package/dist/features/admin/components/AdminFilterBar.js +4 -4
  82. package/dist/features/admin/components/AdminGroupedListingsView.js +66 -30
  83. package/dist/features/admin/components/AdminGuideHubView.js +4 -1
  84. package/dist/features/admin/components/AdminHistoryView.js +4 -3
  85. package/dist/features/admin/components/AdminLiveView.js +4 -3
  86. package/dist/features/admin/components/AdminMediaView.js +4 -1
  87. package/dist/features/admin/components/AdminNavigationView.js +7 -4
  88. package/dist/features/admin/components/AdminNewsletterView.js +5 -3
  89. package/dist/features/admin/components/AdminNotificationsView.js +8 -6
  90. package/dist/features/admin/components/AdminOrderEditorView.js +2 -2
  91. package/dist/features/admin/components/AdminOrdersView.js +6 -4
  92. package/dist/features/admin/components/AdminPageHeader.js +5 -2
  93. package/dist/features/admin/components/AdminPayoutsView.js +7 -5
  94. package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -9
  95. package/dist/features/admin/components/AdminProductEditorView.js +12 -5
  96. package/dist/features/admin/components/AdminProductsView.js +11 -9
  97. package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
  98. package/dist/features/admin/components/AdminReviewsView.js +10 -8
  99. package/dist/features/admin/components/AdminScammerEditorView.js +6 -2
  100. package/dist/features/admin/components/AdminScammersView.js +11 -9
  101. package/dist/features/admin/components/AdminSectionsView.js +20 -22
  102. package/dist/features/admin/components/AdminSessionsManager.js +2 -1
  103. package/dist/features/admin/components/AdminSessionsView.js +8 -6
  104. package/dist/features/admin/components/AdminSidebar.js +11 -7
  105. package/dist/features/admin/components/AdminSiteConfigGuideView.js +2 -1
  106. package/dist/features/admin/components/AdminSiteSettingsView.js +5 -1
  107. package/dist/features/admin/components/AdminStoreAddressesView.js +4 -3
  108. package/dist/features/admin/components/AdminStoreEditorView.js +5 -5
  109. package/dist/features/admin/components/AdminStoresView.js +6 -4
  110. package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
  111. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +3 -3
  112. package/dist/features/admin/components/AdminSupportTicketDetailView.js +10 -3
  113. package/dist/features/admin/components/AdminSupportTicketsView.js +11 -9
  114. package/dist/features/admin/components/AdminTeamView.js +6 -4
  115. package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
  116. package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
  117. package/dist/features/admin/components/AdminUsersView.js +6 -4
  118. package/dist/features/admin/components/AdminViewCards.js +12 -6
  119. package/dist/features/admin/components/AdminWishlistsView.js +4 -3
  120. package/dist/features/admin/components/BrandQuickCreateForm.js +2 -2
  121. package/dist/features/admin/components/CategoryQuickCreateForm.js +2 -2
  122. package/dist/features/admin/components/DashboardStats.js +9 -3
  123. package/dist/features/admin/components/DataListingView.js +3 -3
  124. package/dist/features/admin/components/DataTable.js +11 -7
  125. package/dist/features/admin/components/DrawerFormFooter.js +2 -2
  126. package/dist/features/admin/components/QuickEditMenu.js +2 -1
  127. package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +5 -1
  128. package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
  129. package/dist/features/admin/constants/filter-tabs.js +0 -11
  130. package/dist/features/admin/types/index.d.ts +1 -1
  131. package/dist/features/auctions/actions/bid-actions.js +4 -2
  132. package/dist/features/auctions/components/AuctionBidsTable.js +4 -1
  133. package/dist/features/auctions/components/AuctionDetailPageView.js +14 -6
  134. package/dist/features/auctions/components/AuctionsListView.js +7 -6
  135. package/dist/features/auctions/components/CollapsibleBidHistory.js +5 -1
  136. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
  137. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +8 -2
  138. package/dist/features/auctions/components/PlaceBidFormClient.js +4 -1
  139. package/dist/features/auth/components/RegisterForm.js +2 -2
  140. package/dist/features/auth/components/VerifyEmailView.js +5 -2
  141. package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
  142. package/dist/features/blog/actions/blog-actions.js +3 -2
  143. package/dist/features/blog/components/BlogFeaturedCard.js +8 -1
  144. package/dist/features/blog/components/BlogIndexListing.js +11 -5
  145. package/dist/features/blog/components/BlogListView.js +11 -3
  146. package/dist/features/blog/components/BlogPostView.js +10 -3
  147. package/dist/features/cart/components/CartDrawer.js +11 -3
  148. package/dist/features/cart/components/CartSummary.js +2 -2
  149. package/dist/features/cart/components/CheckoutOtpModal.js +2 -1
  150. package/dist/features/categories/components/BrandDetailPageView.js +15 -10
  151. package/dist/features/categories/components/BrandDetailTabs.js +5 -1
  152. package/dist/features/categories/components/BundleDetailView.js +6 -3
  153. package/dist/features/categories/components/BundleDynamicRuleEditor.js +3 -1
  154. package/dist/features/categories/components/BundleItemsPicker.js +10 -3
  155. package/dist/features/categories/components/CategoriesIndexListing.js +13 -7
  156. package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
  157. package/dist/features/categories/components/CategoryBundlesListing.js +10 -6
  158. package/dist/features/categories/components/CategoryDetailPageView.js +18 -12
  159. package/dist/features/categories/components/CategoryDetailTabs.js +5 -1
  160. package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
  161. package/dist/features/categories/components/CategoryFilters.js +13 -12
  162. package/dist/features/categories/components/CategoryForm.js +6 -3
  163. package/dist/features/categories/components/CategoryGrid.js +9 -2
  164. package/dist/features/categories/components/CategoryProductsListing.js +10 -4
  165. package/dist/features/categories/components/CategorySelectorCreate.js +3 -3
  166. package/dist/features/categories/components/CategorySortSelect.js +1 -1
  167. package/dist/features/categories/components/CategoryStoresListing.js +3 -3
  168. package/dist/features/categories/components/CategoryTableColumns.js +10 -6
  169. package/dist/features/categories/components/CategoryTree.d.ts +1 -1
  170. package/dist/features/categories/components/CategoryTree.js +2 -2
  171. package/dist/features/categories/schemas/firestore.d.ts +2 -2
  172. package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
  173. package/dist/features/checkout/actions/checkout-actions.js +1 -1
  174. package/dist/features/classified/components/ClassifiedFilters.js +2 -2
  175. package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
  176. package/dist/features/classified/components/ClassifiedListView.js +6 -5
  177. package/dist/features/collections/components/CollectionCard.js +2 -1
  178. package/dist/features/contact/components/ContactForm.js +4 -2
  179. package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
  180. package/dist/features/copilot/components/AdminCopilotView.js +13 -5
  181. package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
  182. package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
  183. package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
  184. package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
  185. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +9 -3
  186. package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
  187. package/dist/features/events/actions/event-actions.js +6 -4
  188. package/dist/features/events/components/AdminEventEditorView.js +63 -41
  189. package/dist/features/events/components/AdminEventEntriesView.js +9 -6
  190. package/dist/features/events/components/AdminEventsView.js +7 -5
  191. package/dist/features/events/components/EventCard.js +7 -1
  192. package/dist/features/events/components/EventFilters.d.ts +4 -4
  193. package/dist/features/events/components/EventFilters.js +2 -2
  194. package/dist/features/events/components/EventFormDrawer.js +2 -1
  195. package/dist/features/events/components/EventLeaderboard.js +4 -4
  196. package/dist/features/events/components/EventOfferCard.js +4 -1
  197. package/dist/features/events/components/EventParticipateView.js +3 -2
  198. package/dist/features/events/components/EventPollWidget.js +6 -5
  199. package/dist/features/events/components/EventRaffleEntryForm.js +5 -2
  200. package/dist/features/events/components/EventRaffleWinnerView.js +7 -1
  201. package/dist/features/events/components/EventRafflesSection.js +6 -4
  202. package/dist/features/events/components/EventSaleBanner.js +5 -2
  203. package/dist/features/events/components/EventsIndexListing.js +8 -2
  204. package/dist/features/events/components/EventsListView.js +4 -1
  205. package/dist/features/events/components/SpinWheelView.js +7 -2
  206. package/dist/features/events/schemas/firestore.d.ts +1 -0
  207. package/dist/features/events/types/index.d.ts +1 -0
  208. package/dist/features/faq/actions/faq-actions.js +4 -2
  209. package/dist/features/faq/components/ContactCTA.js +4 -1
  210. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  211. package/dist/features/faq/components/FAQHelpfulButtons.js +8 -5
  212. package/dist/features/faq/components/FAQPageContent.js +7 -6
  213. package/dist/features/faq/components/FAQSortDropdown.js +2 -2
  214. package/dist/features/filters/AsyncFacetSection.js +4 -2
  215. package/dist/features/filters/FilterFacetSection.js +14 -6
  216. package/dist/features/filters/RangeFilter.js +4 -2
  217. package/dist/features/filters/SwitchFilter.js +2 -1
  218. package/dist/features/forms/Checkbox.js +1 -1
  219. package/dist/features/forms/Radio.js +1 -1
  220. package/dist/features/forms/Slider.js +1 -1
  221. package/dist/features/homepage/components/AdSlot.js +4 -4
  222. package/dist/features/homepage/components/AdvertisementBanner.js +13 -4
  223. package/dist/features/homepage/components/AnnouncementBar.js +2 -1
  224. package/dist/features/homepage/components/BeforeAfterCard.js +8 -2
  225. package/dist/features/homepage/components/BrandsSection.js +6 -3
  226. package/dist/features/homepage/components/CTABannerSection.js +2 -2
  227. package/dist/features/homepage/components/CharacterHotspot.js +5 -2
  228. package/dist/features/homepage/components/CharacterHotspotForm.js +8 -4
  229. package/dist/features/homepage/components/CustomCardsSection.js +13 -7
  230. package/dist/features/homepage/components/CustomerReviewsSection.js +9 -3
  231. package/dist/features/homepage/components/FAQSection.js +7 -4
  232. package/dist/features/homepage/components/FeaturedBundlesSection.js +8 -2
  233. package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
  234. package/dist/features/homepage/components/GoogleReviewsSection.js +14 -8
  235. package/dist/features/homepage/components/HeroCarousel.js +1 -1
  236. package/dist/features/homepage/components/HomepageSkeleton.js +7 -1
  237. package/dist/features/homepage/components/HowItWorksInfoView.js +2 -2
  238. package/dist/features/homepage/components/HowItWorksSection.js +2 -2
  239. package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
  240. package/dist/features/homepage/components/NewsletterBanner.js +3 -2
  241. package/dist/features/homepage/components/NewsletterSection.js +5 -2
  242. package/dist/features/homepage/components/PromoGrid.js +4 -1
  243. package/dist/features/homepage/components/SectionCarousel.js +7 -4
  244. package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -3
  245. package/dist/features/homepage/components/ShopByCategorySection.js +10 -4
  246. package/dist/features/homepage/components/SiteFeaturesSection.js +5 -2
  247. package/dist/features/homepage/components/SocialFeedSection.js +4 -4
  248. package/dist/features/homepage/components/SocialPostCard.js +6 -3
  249. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  250. package/dist/features/homepage/components/TrustIndicatorsSection.js +5 -2
  251. package/dist/features/homepage/components/WelcomeSection.js +1 -1
  252. package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -3
  253. package/dist/features/layout/AppLayoutShell.js +2 -1
  254. package/dist/features/layout/BackToTop.js +1 -1
  255. package/dist/features/layout/BottomActions.js +4 -30
  256. package/dist/features/layout/BottomActionsContext.d.ts +0 -36
  257. package/dist/features/layout/BottomActionsContext.js +0 -36
  258. package/dist/features/layout/BottomNavItem.js +1 -1
  259. package/dist/features/layout/BottomSheet.js +4 -1
  260. package/dist/features/layout/FooterLayout.js +1 -1
  261. package/dist/features/layout/NavbarLayout.js +4 -1
  262. package/dist/features/layout/SidebarLayout.js +5 -2
  263. package/dist/features/live/components/LiveItemFilters.js +2 -2
  264. package/dist/features/live/components/LiveItemsIndexListing.js +9 -3
  265. package/dist/features/live/components/LiveItemsListView.js +6 -5
  266. package/dist/features/loyalty/components/CoinsDisplay.js +4 -2
  267. package/dist/features/media/AvatarUpload.js +2 -2
  268. package/dist/features/media/MediaLightbox.js +3 -2
  269. package/dist/features/media/modals/VideoThumbnailSelector.js +4 -1
  270. package/dist/features/media/modals/VideoTrimModal.js +1 -1
  271. package/dist/features/media/upload/CameraCapture.js +1 -1
  272. package/dist/features/media/upload/ImageUpload.js +4 -1
  273. package/dist/features/media/upload/MediaUploadField.js +11 -2
  274. package/dist/features/media/upload/MediaUploadList.js +5 -1
  275. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
  276. package/dist/features/orders/components/OrdersList.js +2 -1
  277. package/dist/features/orders/components/RefundHistoryTable.js +4 -1
  278. package/dist/features/orders/components/RefundRequestView.js +2 -1
  279. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -1
  280. package/dist/features/pre-orders/components/PreOrderActionsClient.js +3 -3
  281. package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
  282. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +16 -7
  283. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +32 -24
  284. package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
  285. package/dist/features/products/actions/product-actions.js +17 -15
  286. package/dist/features/products/columns/index.d.ts +1 -1
  287. package/dist/features/products/columns/index.js +1 -1
  288. package/dist/features/products/columns/productTableColumns.js +9 -4
  289. package/dist/features/products/components/AuctionsIndexListing.js +9 -3
  290. package/dist/features/products/components/BidHistory.js +4 -4
  291. package/dist/features/products/components/CompareOverlay.js +10 -2
  292. package/dist/features/products/components/CustomFieldsEditor.js +2 -1
  293. package/dist/features/products/components/CustomSectionTabContent.js +2 -2
  294. package/dist/features/products/components/CustomSectionsEditor.js +3 -2
  295. package/dist/features/products/components/GroupSettingsPanel.js +34 -26
  296. package/dist/features/products/components/MakeOfferButton.js +6 -2
  297. package/dist/features/products/components/MakeOfferForm.js +2 -1
  298. package/dist/features/products/components/MarketplaceBundleCard.js +6 -3
  299. package/dist/features/products/components/MarketplacePrizeDrawCard.js +3 -2
  300. package/dist/features/products/components/PlaceBidForm.js +2 -1
  301. package/dist/features/products/components/PrizeDrawCollage.js +6 -16
  302. package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
  303. package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -2
  304. package/dist/features/products/components/PrizeDrawsIndexListing.js +6 -3
  305. package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
  306. package/dist/features/products/components/PrizeDrawsSection.js +6 -4
  307. package/dist/features/products/components/PrizeRevealModal.js +5 -1
  308. package/dist/features/products/components/ProductDetailPageView.js +32 -16
  309. package/dist/features/products/components/ProductFeatureBadges.js +9 -9
  310. package/dist/features/products/components/ProductForm.d.ts +11 -1
  311. package/dist/features/products/components/ProductForm.js +10 -5
  312. package/dist/features/products/components/ProductGalleryClient.js +8 -4
  313. package/dist/features/products/components/ProductGradingTab.js +4 -1
  314. package/dist/features/products/components/ProductGrid.js +35 -14
  315. package/dist/features/products/components/ProductInfo.js +2 -1
  316. package/dist/features/products/components/ProductTabs.js +2 -1
  317. package/dist/features/products/components/ProductTabsShell.js +5 -1
  318. package/dist/features/products/components/ProductsIndexListing.js +32 -24
  319. package/dist/features/products/components/ProductsIndexPageView.js +2 -2
  320. package/dist/features/products/components/RelatedProducts.js +3 -3
  321. package/dist/features/products/components/ShowGroupSection.js +10 -6
  322. package/dist/features/products/components/SublistingCarouselSection.js +7 -3
  323. package/dist/features/products/components/SublistingCategorySelect.d.ts +3 -1
  324. package/dist/features/products/components/SublistingCategorySelect.js +4 -37
  325. package/dist/features/products/constants/action-defs.js +3 -3
  326. package/dist/features/products/constants/sieve.d.ts +2 -2
  327. package/dist/features/products/constants/sieve.js +2 -2
  328. package/dist/features/products/hooks/useRelatedProducts.js +5 -4
  329. package/dist/features/promotions/components/CouponCard.js +5 -3
  330. package/dist/features/promotions/components/CouponsIndexListing.js +7 -3
  331. package/dist/features/promotions/repository/coupons.repository.d.ts +8 -0
  332. package/dist/features/promotions/repository/coupons.repository.js +2 -0
  333. package/dist/features/reviews/actions/review-actions.js +2 -1
  334. package/dist/features/reviews/components/ReviewDetailPageView.js +3 -3
  335. package/dist/features/reviews/components/ReviewDetailShell.js +15 -3
  336. package/dist/features/reviews/components/ReviewSummary.js +4 -2
  337. package/dist/features/reviews/components/ReviewsIndexListing.js +8 -2
  338. package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
  339. package/dist/features/reviews/components/ReviewsList.js +1 -1
  340. package/dist/features/scams/actions/scam-actions.js +3 -2
  341. package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
  342. package/dist/features/scams/components/ScamProfileView.js +3 -3
  343. package/dist/features/scams/components/ScamRegistryView.js +11 -8
  344. package/dist/features/search/actions/search-actions.js +7 -6
  345. package/dist/features/search/components/Search.js +9 -6
  346. package/dist/features/search/components/SearchFiltersRow.js +1 -1
  347. package/dist/features/search/components/SearchResultsSection.js +1 -1
  348. package/dist/features/seller/components/CouponInlineSelect.d.ts +22 -0
  349. package/dist/features/seller/components/CouponInlineSelect.js +104 -0
  350. package/dist/features/seller/components/GroupInlineSelect.d.ts +23 -0
  351. package/dist/features/seller/components/GroupInlineSelect.js +80 -0
  352. package/dist/features/seller/components/PhysicalLocationModal.js +2 -1
  353. package/dist/features/seller/components/PrintCenterView.js +2 -1
  354. package/dist/features/seller/components/ProductInlineSelect.d.ts +24 -0
  355. package/dist/features/seller/components/ProductInlineSelect.js +42 -0
  356. package/dist/features/seller/components/QuickProductForm.js +4 -1
  357. package/dist/features/seller/components/SellerAddressesView.js +8 -3
  358. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +6 -3
  359. package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
  360. package/dist/features/seller/components/SellerAuctionsView.js +7 -5
  361. package/dist/features/seller/components/SellerBidsView.js +12 -10
  362. package/dist/features/seller/components/SellerBundlesView.js +9 -7
  363. package/dist/features/seller/components/SellerClassifiedView.js +6 -5
  364. package/dist/features/seller/components/SellerCouponEditorView.d.ts +2 -0
  365. package/dist/features/seller/components/SellerCouponEditorView.js +15 -3
  366. package/dist/features/seller/components/SellerCouponsView.js +7 -5
  367. package/dist/features/seller/components/SellerDashboardView.js +2 -2
  368. package/dist/features/seller/components/SellerDigitalCodesView.js +7 -6
  369. package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
  370. package/dist/features/seller/components/SellerGroupedListingsView.js +10 -9
  371. package/dist/features/seller/components/SellerLiveView.js +6 -5
  372. package/dist/features/seller/components/SellerOffersView.js +6 -4
  373. package/dist/features/seller/components/SellerOrdersView.js +18 -13
  374. package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -6
  375. package/dist/features/seller/components/SellerPayoutRequestView.js +5 -1
  376. package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -2
  377. package/dist/features/seller/components/SellerPayoutsView.js +6 -4
  378. package/dist/features/seller/components/SellerPreOrdersView.js +12 -10
  379. package/dist/features/seller/components/SellerPrizeDrawsView.js +12 -10
  380. package/dist/features/seller/components/SellerProductShell.js +1 -1
  381. package/dist/features/seller/components/SellerProductsCards.js +4 -1
  382. package/dist/features/seller/components/SellerProductsView.js +14 -12
  383. package/dist/features/seller/components/SellerReviewsView.js +7 -3
  384. package/dist/features/seller/components/SellerShippingConfigsView.js +7 -6
  385. package/dist/features/seller/components/SellerShippingView.js +1 -1
  386. package/dist/features/seller/components/SellerSidebar.js +15 -8
  387. package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -4
  388. package/dist/features/seller/components/SellerStorefrontView.js +2 -2
  389. package/dist/features/seller/components/SellerTemplatesView.js +11 -7
  390. package/dist/features/seller/components/SublistingInlineSelect.d.ts +19 -0
  391. package/dist/features/seller/components/SublistingInlineSelect.js +84 -0
  392. package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
  393. package/dist/features/seller/components/index.d.ts +8 -0
  394. package/dist/features/seller/components/index.js +4 -0
  395. package/dist/features/shell/FormShell.js +10 -2
  396. package/dist/features/shell/QuickFormDrawer.js +5 -5
  397. package/dist/features/shell/StepForm.js +6 -6
  398. package/dist/features/site-settings/components/ActionPermissionsManager.js +8 -4
  399. package/dist/features/site-settings/components/NavPermissionsManager.js +7 -4
  400. package/dist/features/stores/actions/store-query-actions.js +3 -2
  401. package/dist/features/stores/components/InteractiveStoreCard.js +5 -1
  402. package/dist/features/stores/components/StoreAboutView.js +4 -1
  403. package/dist/features/stores/components/StoreAddressSelectorCreate.d.ts +2 -1
  404. package/dist/features/stores/components/StoreAddressSelectorCreate.js +5 -31
  405. package/dist/features/stores/components/StoreAuctionsListing.js +6 -3
  406. package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
  407. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  408. package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
  409. package/dist/features/stores/components/StoreGuideHubView.js +5 -2
  410. package/dist/features/stores/components/StoreHeader.js +8 -1
  411. package/dist/features/stores/components/StorePreOrdersListing.js +6 -3
  412. package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
  413. package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
  414. package/dist/features/stores/components/StoreProductsListing.js +6 -3
  415. package/dist/features/stores/components/StoreProductsPageView.js +2 -1
  416. package/dist/features/stores/components/StoreProductsView.js +5 -4
  417. package/dist/features/stores/components/StoreReviewsListing.js +8 -2
  418. package/dist/features/stores/components/StoresIndexListing.js +16 -9
  419. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +7 -1
  420. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +2 -1
  421. package/dist/features/wishlist/components/WishlistPage.js +2 -1
  422. package/dist/features/wishlist/components/WishlistView.js +4 -3
  423. package/dist/index.d.ts +10 -0
  424. package/dist/index.js +13 -1
  425. package/dist/next/components/GlobalError.js +2 -2
  426. package/dist/next/routing/route-map.d.ts +2 -0
  427. package/dist/next/routing/route-map.js +1 -0
  428. package/dist/react/ErrorBoundary.js +2 -2
  429. package/dist/styles.css +2 -1
  430. package/dist/tailwind-utilities.css +1 -1
  431. package/dist/ui/DataTable.js +17 -16
  432. package/dist/ui/components/DateInput.js +2 -2
  433. package/dist/ui/components/DetailPageGallery.js +4 -1
  434. package/dist/ui/components/DetailPageTabs.js +6 -2
  435. package/dist/ui/components/ImageLightbox.js +5 -3
  436. package/dist/ui/components/Input.js +6 -3
  437. package/dist/ui/components/Layout.d.ts +4 -0
  438. package/dist/ui/components/Layout.js +1 -1
  439. package/dist/ui/components/Layout.style.css +1 -0
  440. package/dist/ui/components/ListingFilterDrawer.js +4 -1
  441. package/dist/ui/components/ListingLayout.js +9 -8
  442. package/dist/ui/components/ListingToolbar.js +5 -1
  443. package/dist/ui/components/PaginatedSelect.d.ts +1 -2
  444. package/dist/ui/components/PaginatedSelect.js +1 -2
  445. package/dist/ui/components/Radio.js +1 -1
  446. package/dist/ui/components/Select.js +2 -1
  447. package/dist/ui/components/Slider.js +1 -1
  448. package/dist/ui/components/VacationBanner.js +2 -1
  449. package/dist/ui/components/surface-tokens.d.ts +1 -0
  450. package/dist/ui/components/surface-tokens.js +1 -0
  451. package/package.json +11 -2
@@ -23,5 +23,5 @@ export function BeforeAfterSlider({ item, className = "", }) {
23
23
  return (_jsxs(Div, { ref: containerRef, className: `relative aspect-square select-none overflow-hidden rounded-xl ${className}`, onPointerMove: handlePointerMove, onTouchMove: handleTouchMove, children: [_jsx(Div, { role: "img", "aria-label": "After", className: "absolute inset-0 h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${item.afterImageUrl})` } }), _jsx(Div, { className: "absolute inset-0 overflow-hidden", style: { width: `${position}%` }, children: _jsx(Div, { role: "img", "aria-label": "Before", className: "h-full w-full bg-center bg-cover", style: {
24
24
  width: containerRef.current?.offsetWidth ?? "100%",
25
25
  backgroundImage: `url(${item.beforeImageUrl})`,
26
- } }) }), _jsxs(Div, { className: "absolute inset-y-0 flex w-1 -translate-x-1/2 cursor-ew-resize flex-col items-center justify-center", style: { left: `${position}%` }, children: [_jsx(Div, { className: "h-full w-0.5 bg-white/80 shadow" }), _jsx(Div, { className: "absolute h-8 w-8 rounded-full border-2 border-white bg-white/80 shadow-md" })] }), _jsx(Span, { className: "absolute left-2 top-2 rounded bg-black/40 px-2 py-0.5 text-xs font-medium text-white", children: "Before" }), _jsx(Span, { className: "absolute right-2 top-2 rounded bg-black/40 px-2 py-0.5 text-xs font-medium text-white", children: "After" }), item.durationWeeks && (_jsxs(Span, { className: "absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/50 px-3 py-1 text-xs font-medium text-white", children: [item.durationWeeks, " weeks"] }))] }));
26
+ } }) }), _jsxs(Div, { className: "absolute inset-y-0 flex w-1 -translate-x-1/2 cursor-ew-resize flex-col items-center justify-center", style: { left: `${position}%` }, children: [_jsx(Div, { className: "h-full w-0.5 bg-white/80 shadow" }), _jsx(Div, { className: "absolute h-8 w-8 rounded-full border-2 border-white bg-white/80 shadow-md" })] }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute left-2 top-2 rounded bg-black/40 px-2 py-0.5 text-white", children: "Before" }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute right-2 top-2 rounded bg-black/40 px-2 py-0.5 text-white", children: "After" }), item.durationWeeks && (_jsxs(Span, { size: "xs", weight: "medium", className: "absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/50 px-3 py-1 text-white", children: [item.durationWeeks, " weeks"] }))] }));
27
27
  }
@@ -1,3 +1,4 @@
1
+ import { sortBy } from "@mohasinac/appkit";
1
2
  import { z } from "zod";
2
3
  import { serverLogger } from "../../../monitoring";
3
4
  import { blogRepository } from "../repository/blog.repository";
@@ -104,11 +105,11 @@ export async function listBlogPosts(params) {
104
105
  return blogRepository.listPublished({ category: params?.category }, sieve);
105
106
  }
106
107
  export async function getFeaturedBlogPosts(count = 3) {
107
- const result = await blogRepository.listPublished({ featuredOnly: true }, { sorts: "-publishedAt", page: 1, pageSize: count });
108
+ const result = await blogRepository.listPublished({ featuredOnly: true }, { sorts: sortBy("publishedAt", "DESC"), page: 1, pageSize: count });
108
109
  return result.items;
109
110
  }
110
111
  export async function getLatestBlogPosts(count = 5) {
111
- const result = await blogRepository.listPublished({}, { sorts: "-publishedAt", page: 1, pageSize: count });
112
+ const result = await blogRepository.listPublished({}, { sorts: sortBy("publishedAt", "DESC"), page: 1, pageSize: count });
112
113
  return result.items;
113
114
  }
114
115
  export async function getBlogPostById(id) {
@@ -6,6 +6,12 @@ import { getMediaUrl } from "../../media/types/index";
6
6
  import { getDefaultLocale } from "../../../core/baseline-resolver";
7
7
  import { safeDisplayName } from "../../../security";
8
8
  import { useLongPress } from "../../../react/hooks/useLongPress";
9
+ const __P = {
10
+ p4: "p-4",
11
+ };
12
+ const __O = {
13
+ hidden: "overflow-hidden",
14
+ };
9
15
  const CATEGORY_BADGE = {
10
16
  news: "bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",
11
17
  tips: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-300",
@@ -13,6 +19,7 @@ const CATEGORY_BADGE = {
13
19
  updates: "bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300",
14
20
  community: "bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-300",
15
21
  };
22
+ const CLS_FEATURED_BADGE = "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300 px-2 py-0.5 rounded-full";
16
23
  export function BlogFeaturedCard({ post, href, labels = {}, className = "", selectable = false, isSelected = false, onSelect, }) {
17
24
  const longPress = useLongPress(() => onSelect?.(post.id, !isSelected));
18
25
  const safeTitle = post.title?.trim() || "Untitled post";
@@ -24,5 +31,5 @@ export function BlogFeaturedCard({ post, href, labels = {}, className = "", sele
24
31
  day: "numeric",
25
32
  })
26
33
  : "";
27
- return (_jsxs(Article, { className: `group relative flex h-full flex-col overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm hover:shadow-md transition-shadow duration-200 ${isSelected ? "ring-2 ring-primary outline outline-2 outline-primary" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(post.id, !isSelected); }, label: isSelected ? "Deselect post" : "Select post", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs(TextLink, { href: href, className: "flex h-full flex-col", children: [_jsx(Div, { className: "aspect-video overflow-hidden flex-shrink-0", children: coverImageUrl ? (_jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105", style: { backgroundImage: `url(${coverImageUrl})` } })) : (_jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-gradient-to-br from-zinc-200 via-zinc-100 to-zinc-300 dark:from-slate-800 dark:via-slate-700 dark:to-slate-900" })) }), _jsxs(Div, { className: "flex flex-1 flex-col p-4", children: [_jsxs(Row, { className: "gap-1.5 mb-2 flex-wrap", children: [_jsx(Span, { className: `inline-block px-2 py-0.5 rounded-full text-xs font-medium capitalize ${CATEGORY_BADGE[post.category] ?? "bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"}`, children: post.category }), post.isFeatured && (_jsx(Span, { className: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300 px-2 py-0.5 rounded-full text-xs font-medium", children: labels.featuredBadge ?? "Featured" }))] }), _jsx(Heading, { level: 3, className: `font-semibold text-neutral-900 dark:text-zinc-100 text-base leading-snug mb-1 ${THEME_CONSTANTS.utilities.textClamp2}`, children: safeTitle }), post.excerpt && (_jsx(Text, { className: `text-neutral-500 dark:text-zinc-400 text-sm ${THEME_CONSTANTS.utilities.textClamp2} mb-3`, children: post.excerpt })), _jsxs(Row, { className: "mt-auto gap-3 text-xs text-zinc-400 dark:text-zinc-400 flex-wrap", children: [post.authorName && (_jsx(Span, { children: safeDisplayName(post.authorName, "Author") })), post.readTimeMinutes != null && (_jsxs(Span, { children: [post.readTimeMinutes, " ", labels.readTime ?? "min read"] })), date && _jsx(Span, { children: date })] })] })] })] }));
34
+ return (_jsxs(Article, { className: `group relative flex h-full flex-col overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm hover:shadow-md transition-shadow duration-200 ${isSelected ? "ring-2 ring-primary outline outline-2 outline-primary" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(post.id, !isSelected); }, label: isSelected ? "Deselect post" : "Select post", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs(TextLink, { href: href, className: "flex h-full flex-col", children: [_jsx(Div, { className: `aspect-video ${__O.hidden} flex-shrink-0`, children: coverImageUrl ? (_jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105", style: { backgroundImage: `url(${coverImageUrl})` } })) : (_jsx(Div, { role: "img", "aria-label": safeTitle, className: "h-full w-full bg-gradient-to-br from-zinc-200 via-zinc-100 to-zinc-300 dark:from-slate-800 dark:via-slate-700 dark:to-slate-900" })) }), _jsxs(Div, { className: `flex flex-1 flex-col ${__P.p4}`, children: [_jsxs(Row, { className: "gap-1.5 mb-2 flex-wrap", children: [_jsx(Span, { size: "xs", weight: "medium", className: `inline-block px-2 py-0.5 rounded-full capitalize ${CATEGORY_BADGE[post.category] ?? "bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"}`, children: post.category }), post.isFeatured && (_jsx(Span, { size: "xs", weight: "medium", className: CLS_FEATURED_BADGE, children: labels.featuredBadge ?? "Featured" }))] }), _jsx(Heading, { level: 3, className: `font-semibold text-neutral-900 dark:text-zinc-100 text-base leading-snug mb-1 ${THEME_CONSTANTS.utilities.textClamp2}`, children: safeTitle }), post.excerpt && (_jsx(Text, { className: `text-neutral-500 dark:text-zinc-400 text-sm ${THEME_CONSTANTS.utilities.textClamp2} mb-3`, children: post.excerpt })), _jsxs(Row, { className: "mt-auto gap-3 text-xs text-zinc-400 dark:text-zinc-400 flex-wrap", children: [post.authorName && (_jsx(Span, { children: safeDisplayName(post.authorName, "Author") })), post.readTimeMinutes != null && (_jsxs(Span, { children: [post.readTimeMinutes, " ", labels.readTime ?? "min read"] })), date && _jsx(Span, { children: date })] })] })] })] }));
28
35
  }
@@ -3,25 +3,31 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useMemo } from "react";
4
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
5
  import { useBlogPosts } from "../hooks/useBlog";
6
- import { ListingFilterDrawer, ListingToolbar, Pagination, Text } from "../../../ui";
6
+ import { Div, ListingFilterDrawer, ListingToolbar, Pagination, Text } from "../../../ui";
7
7
  import { ROUTES } from "../../../next";
8
8
  import { BlogCard } from "./BlogListView";
9
9
  import { BlogFilters, BLOG_PUBLIC_SORT_OPTIONS } from "./BlogFilters";
10
10
  import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
11
11
  import { sortBy } from "../../../constants/sort";
12
12
  import { BLOG_FIELDS } from "../../../constants/field-names";
13
+ const __P = {
14
+ p5: "p-5",
15
+ };
16
+ const __O = {
17
+ hidden: "overflow-hidden",
18
+ };
13
19
  function renderBlogGrid(props) {
14
20
  const { isLoading, posts, view } = props;
15
21
  if (isLoading) {
16
- return (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-5 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" })] })] }, i))) }));
22
+ return (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p5} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/4" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" })] })] }, i))) }));
17
23
  }
18
24
  if (posts.length === 0) {
19
25
  return _jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No posts found." });
20
26
  }
21
27
  if (view === "list") {
22
- return (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: posts.map((post) => _jsx(BlogCard, { post: post, href: String(ROUTES.BLOG.ARTICLE(post.slug)) }, post.id)) }));
28
+ return (_jsx(Div, { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: posts.map((post) => _jsx(BlogCard, { post: post, href: String(ROUTES.BLOG.ARTICLE(post.slug)) }, post.id)) }));
23
29
  }
24
- return (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: posts.map((post) => _jsx(BlogCard, { post: post, href: String(ROUTES.BLOG.ARTICLE(post.slug)) }, post.id)) }));
30
+ return (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: posts.map((post) => _jsx(BlogCard, { post: post, href: String(ROUTES.BLOG.ARTICLE(post.slug)) }, post.id)) }));
25
31
  }
26
32
  function renderBlogFilterDrawer(props) {
27
33
  const { filterOpen, setFilterOpen, activeFilterCount, clearFilters, applyFilters, pendingTable } = props;
@@ -107,5 +113,5 @@ export function BlogIndexListing({ initialData }) {
107
113
  const commitSearch = useCallback(() => {
108
114
  table.set(TABLE_KEYS.QUERY, searchInput.trim());
109
115
  }, [searchInput, table]);
110
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search posts...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: BLOG_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: renderBlogGrid({ isLoading, posts, view }) }), renderBlogFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, applyFilters, pendingTable })] }));
116
+ return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search posts...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: BLOG_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: renderBlogGrid({ isLoading, posts, view }) }), renderBlogFilterDrawer({ filterOpen, setFilterOpen, activeFilterCount, clearFilters, applyFilters, pendingTable })] }));
111
117
  }
@@ -6,6 +6,14 @@ import { THEME_CONSTANTS } from "../../../tokens";
6
6
  import { getDefaultLocale } from "../../../core/baseline-resolver";
7
7
  import { getMediaUrl } from "../../media/types/index";
8
8
  import { safeDisplayName } from "../../../security";
9
+ const __P = {
10
+ p5: "p-5",
11
+ };
12
+ const __O = {
13
+ hidden: "overflow-hidden",
14
+ xAuto: "overflow-x-auto",
15
+ };
16
+ const CLS_FEATURED_BADGE = "rounded-full bg-yellow-100 px-2 py-0.5 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300";
9
17
  export function BlogCard({ post, href, onClick, className = "" }) {
10
18
  const coverImageUrl = getMediaUrl(post.coverImage);
11
19
  const date = post.publishedAt
@@ -18,18 +26,18 @@ export function BlogCard({ post, href, onClick, className = "" }) {
18
26
  const isInteractive = !!(href || onClick);
19
27
  const card = (_jsxs(Article, { role: onClick && !href ? "button" : undefined, tabIndex: onClick && !href ? 0 : undefined, onKeyDown: onClick && !href
20
28
  ? (e) => (e.key === "Enter" || e.key === " ") && onClick(post)
21
- : undefined, onClick: onClick && !href ? () => onClick(post) : undefined, className: `group flex flex-col h-full overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm transition hover:shadow-md ${isInteractive ? "cursor-pointer" : ""} ${className}`, children: [_jsx(Div, { className: "aspect-video w-full overflow-hidden bg-neutral-100 dark:bg-slate-800 flex-shrink-0", children: coverImageUrl ? (_jsx(Div, { role: "img", "aria-label": post.title, className: "h-full w-full bg-center bg-cover transition-transform duration-300 group-hover:scale-105", style: { backgroundImage: `url(${coverImageUrl})` } })) : (_jsx(Div, { className: "h-full w-full bg-gradient-to-br from-zinc-200 via-zinc-100 to-zinc-300 dark:from-slate-800 dark:via-slate-700 dark:to-slate-900 flex items-center justify-center", children: _jsx("span", { className: "text-4xl opacity-30", "aria-hidden": "true", children: "\u270D\uFE0F" }) })) }), _jsxs(Div, { className: "flex flex-1 flex-col p-5", children: [_jsxs(Row, { className: "mb-2 gap-2 flex-wrap", children: [_jsx(Span, { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium capitalize text-primary", children: post.category }), post.isFeatured && (_jsx(Span, { className: "rounded-full bg-yellow-100 px-2 py-0.5 text-xs font-medium text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300", children: "Featured" })), post.readTimeMinutes && (_jsxs(Span, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: [post.readTimeMinutes, " min read"] }))] }), _jsx(Heading, { level: 3, className: `${THEME_CONSTANTS.utilities.textClamp2} text-base font-semibold text-neutral-900 dark:text-zinc-100 group-hover:text-primary`, children: post.title }), post.excerpt && (_jsx(Text, { className: `mt-2 ${THEME_CONSTANTS.utilities.textClamp3} flex-1 text-sm text-neutral-500 dark:text-zinc-400`, children: post.excerpt })), _jsxs(Row, { className: "mt-auto pt-3 gap-3", children: [post.authorAvatar ? (_jsx(Div, { role: "img", "aria-label": post.authorName ?? "author", className: "h-7 w-7 flex-shrink-0 rounded-full bg-center bg-cover", style: { backgroundImage: `url(${post.authorAvatar})` } })) : post.authorName ? (_jsx(Div, { className: "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-bold text-primary", children: post.authorName.charAt(0).toUpperCase() })) : null, _jsxs(Text, { className: "text-xs text-neutral-500 dark:text-zinc-400 min-w-0", children: [post.authorName && (_jsx(Span, { className: "font-medium text-neutral-700 dark:text-zinc-300", children: safeDisplayName(post.authorName, "Author") })), date && _jsxs(Span, { className: "ml-1 text-neutral-400", children: ["\u00B7 ", date] })] })] })] })] }));
29
+ : undefined, onClick: onClick && !href ? () => onClick(post) : undefined, className: `group flex flex-col h-full overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm transition hover:shadow-md ${isInteractive ? "cursor-pointer" : ""} ${className}`, children: [_jsx(Div, { className: `aspect-video w-full ${__O.hidden} bg-neutral-100 dark:bg-slate-800 flex-shrink-0`, children: coverImageUrl ? (_jsx(Div, { role: "img", "aria-label": post.title, className: "h-full w-full bg-center bg-cover transition-transform duration-300 group-hover:scale-105", style: { backgroundImage: `url(${coverImageUrl})` } })) : (_jsx(Div, { className: "h-full w-full bg-gradient-to-br from-zinc-200 via-zinc-100 to-zinc-300 dark:from-slate-800 dark:via-slate-700 dark:to-slate-900 flex items-center justify-center", children: _jsx(Span, { className: "text-4xl opacity-30", "aria-hidden": "true", children: "\u270D\uFE0F" }) })) }), _jsxs(Div, { className: `flex flex-1 flex-col ${__P.p5}`, children: [_jsxs(Row, { className: "mb-2 gap-2 flex-wrap", children: [_jsx(Span, { size: "xs", weight: "medium", className: "rounded-full bg-primary/10 px-2 py-0.5 capitalize text-primary", children: post.category }), post.isFeatured && (_jsx(Span, { size: "xs", weight: "medium", className: CLS_FEATURED_BADGE, children: "Featured" })), post.readTimeMinutes && (_jsxs(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400", children: [post.readTimeMinutes, " min read"] }))] }), _jsx(Heading, { level: 3, className: `${THEME_CONSTANTS.utilities.textClamp2} text-base font-semibold text-neutral-900 dark:text-zinc-100 group-hover:text-primary`, children: post.title }), post.excerpt && (_jsx(Text, { className: `mt-2 ${THEME_CONSTANTS.utilities.textClamp3} flex-1 text-sm text-neutral-500 dark:text-zinc-400`, children: post.excerpt })), _jsxs(Row, { className: "mt-auto pt-3 gap-3", children: [post.authorAvatar ? (_jsx(Div, { role: "img", "aria-label": post.authorName ?? "author", className: "h-7 w-7 flex-shrink-0 rounded-full bg-center bg-cover", style: { backgroundImage: `url(${post.authorAvatar})` } })) : post.authorName ? (_jsx(Div, { className: "flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-bold text-primary", children: post.authorName.charAt(0).toUpperCase() })) : null, _jsxs(Text, { className: "text-xs text-neutral-500 dark:text-zinc-400 min-w-0", children: [post.authorName && (_jsx(Span, { weight: "medium", className: "text-neutral-700 dark:text-zinc-300", children: safeDisplayName(post.authorName, "Author") })), date && _jsxs(Span, { className: "ml-1 text-neutral-400", children: ["\u00B7 ", date] })] })] })] })] }));
22
30
  if (href) {
23
31
  return (_jsx(Link, { href: href, className: "block h-full", children: card }));
24
32
  }
25
33
  return card;
26
34
  }
27
35
  export function BlogCategoryTabs({ categories, active, onSelect, labels = {}, }) {
28
- return (_jsxs(Div, { className: "scrollbar-none flex gap-2 overflow-x-auto pb-1", children: [_jsx(Button, { onClick: () => onSelect(null), variant: !active ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-4 py-1.5 text-sm font-medium transition ${!active ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-neutral-600 dark:text-zinc-300 hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels.all ?? "All" }), categories.map((cat) => (_jsx(Button, { onClick: () => onSelect(cat), variant: active === cat ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-4 py-1.5 text-sm font-medium capitalize transition ${active === cat ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-neutral-600 dark:text-zinc-300 hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels[cat] ?? cat }, cat)))] }));
36
+ return (_jsxs(Div, { className: `scrollbar-none flex gap-2 ${__O.xAuto} pb-1`, children: [_jsx(Button, { onClick: () => onSelect(null), variant: !active ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-4 py-1.5 text-sm font-medium transition ${!active ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-neutral-600 dark:text-zinc-300 hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels.all ?? "All" }), categories.map((cat) => (_jsx(Button, { onClick: () => onSelect(cat), variant: active === cat ? "primary" : "ghost", size: "sm", className: `whitespace-nowrap rounded-full px-4 py-1.5 text-sm font-medium capitalize transition ${active === cat ? "bg-neutral-900 text-white" : "bg-neutral-100 dark:bg-slate-800 text-neutral-600 dark:text-zinc-300 hover:bg-neutral-200 dark:hover:bg-slate-700"}`, children: labels[cat] ?? cat }, cat)))] }));
29
37
  }
30
38
  export function BlogListView({ posts, isLoading, totalPages = 1, currentPage = 1, total = 0, onPageChange, onPostClick, emptyLabel = "No posts found", slots, }) {
31
39
  if (isLoading) {
32
- return (_jsx(Div, { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Div, { className: "animate-pulse overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-neutral-100 dark:bg-slate-800", children: [_jsx(Div, { className: "aspect-video bg-neutral-200 dark:bg-slate-700" }), _jsxs(Div, { className: "space-y-2 p-5", children: [_jsx(Div, { className: "h-4 w-16 rounded bg-neutral-200 dark:bg-slate-700" }), _jsx(Div, { className: "h-5 w-full rounded bg-neutral-200 dark:bg-slate-700" }), _jsx(Div, { className: "h-4 w-3/4 rounded bg-neutral-200 dark:bg-slate-700" })] })] }, i))) }));
40
+ return (_jsx(Div, { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Div, { className: "animate-pulse overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-neutral-100 dark:bg-slate-800", children: [_jsx(Div, { className: "aspect-video bg-neutral-200 dark:bg-slate-700" }), _jsxs(Div, { className: `space-y-2 ${__P.p5}`, children: [_jsx(Div, { className: "h-4 w-16 rounded bg-neutral-200 dark:bg-slate-700" }), _jsx(Div, { className: "h-5 w-full rounded bg-neutral-200 dark:bg-slate-700" }), _jsx(Div, { className: "h-4 w-3/4 rounded bg-neutral-200 dark:bg-slate-700" })] })] }, i))) }));
33
41
  }
34
42
  if (posts.length === 0) {
35
43
  if (slots?.renderEmptyState) {
@@ -9,6 +9,12 @@ import { getMediaUrl } from "../../media/types/index";
9
9
  import { getDefaultLocale } from "../../../core/baseline-resolver";
10
10
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
11
11
  import { ROUTES } from "../../../next/routing/route-map";
12
+ const __P = {
13
+ p8: "p-8",
14
+ };
15
+ const __O = {
16
+ hidden: "overflow-hidden",
17
+ };
12
18
  const CATEGORY_BADGE = {
13
19
  news: "bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",
14
20
  tips: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-300",
@@ -16,8 +22,9 @@ const CATEGORY_BADGE = {
16
22
  updates: "bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300",
17
23
  community: "bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-300",
18
24
  };
25
+ const CLS_FEATURED_BADGE = "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300 px-2 py-0.5 rounded-full";
19
26
  function renderBlogPostHeader(post, date, labels) {
20
- return (_jsxs(Div, { className: "mb-8", children: [_jsxs(Row, { className: "gap-2 mb-4", children: [_jsx(Span, { className: `inline-block px-2 py-0.5 rounded-full text-xs font-medium capitalize ${CATEGORY_BADGE[post.category] ?? ""}`, children: post.category }), post.isFeatured && _jsx(Span, { className: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300 px-2 py-0.5 rounded-full text-xs font-medium", children: labels?.featured ?? "Featured" })] }), _jsx(Heading, { level: 1, className: "text-3xl font-bold mb-4", children: post.title }), post.excerpt && _jsx(Text, { className: "text-lg text-zinc-500 dark:text-zinc-400 mb-6", children: post.excerpt }), _jsxs(Row, { wrap: true, gap: "md", className: "text-sm text-zinc-400 dark:text-zinc-400", children: [post.authorName && _jsxs(Span, { children: [labels?.author ?? "By", " ", _jsx(Span, { className: "font-medium text-zinc-700 dark:text-zinc-300", children: post.authorName })] }), post.readTimeMinutes != null && _jsxs(Span, { children: [post.readTimeMinutes, " ", labels?.readTime ?? "min read"] }), date && _jsxs(Span, { children: [labels?.publishedOn ?? "Published", " ", date] }), post.views != null && _jsxs(Span, { children: [post.views, " ", labels?.viewsLabel ?? "views"] })] })] }));
27
+ return (_jsxs(Div, { className: "mb-8", children: [_jsxs(Row, { className: "gap-2 mb-4", children: [_jsx(Span, { size: "xs", weight: "medium", className: `inline-block px-2 py-0.5 rounded-full capitalize ${CATEGORY_BADGE[post.category] ?? ""}`, children: post.category }), post.isFeatured && _jsx(Span, { size: "xs", weight: "medium", className: CLS_FEATURED_BADGE, children: labels?.featured ?? "Featured" })] }), _jsx(Heading, { level: 1, className: "text-3xl font-bold mb-4", children: post.title }), post.excerpt && _jsx(Text, { className: "text-lg text-zinc-500 dark:text-zinc-400 mb-6", children: post.excerpt }), _jsxs(Row, { wrap: true, gap: "md", className: "text-sm text-zinc-400 dark:text-zinc-400", children: [post.authorName && _jsxs(Span, { children: [labels?.author ?? "By", " ", _jsx(Span, { weight: "medium", className: "text-zinc-700 dark:text-zinc-300", children: post.authorName })] }), post.readTimeMinutes != null && _jsxs(Span, { children: [post.readTimeMinutes, " ", labels?.readTime ?? "min read"] }), date && _jsxs(Span, { children: [labels?.publishedOn ?? "Published", " ", date] }), post.views != null && _jsxs(Span, { children: [post.views, " ", labels?.viewsLabel ?? "views"] })] })] }));
21
28
  }
22
29
  function renderBlogPostRelated(related, labels, renderRelatedCard) {
23
30
  if (related.length === 0)
@@ -36,7 +43,7 @@ export function BlogPostView({ slug, initialData, labels = {}, renderImage, rend
36
43
  if (error || !post) {
37
44
  if (renderError)
38
45
  return _jsx(_Fragment, { children: renderError(error ?? null) });
39
- return (_jsxs(Div, { className: "flex flex-col items-center justify-center min-h-screen gap-4 p-8", children: [_jsx(Heading, { level: 1, className: "text-xl font-semibold", children: labels.notFound ?? "Post not found" }), _jsx(Text, { className: "text-zinc-500 dark:text-zinc-400", children: labels.notFoundDescription ?? "This post is not available." }), renderBackButton?.()] }));
46
+ return (_jsxs(Div, { className: `flex flex-col items-center justify-center min-h-screen gap-4 ${__P.p8}`, children: [_jsx(Heading, { level: 1, className: "text-xl font-semibold", children: labels.notFound ?? "Post not found" }), _jsx(Text, { className: "text-zinc-500 dark:text-zinc-400", children: labels.notFoundDescription ?? "This post is not available." }), renderBackButton?.()] }));
40
47
  }
41
48
  const date = post.publishedAt
42
49
  ? new Date(post.publishedAt).toLocaleDateString(getDefaultLocale(), {
@@ -46,5 +53,5 @@ export function BlogPostView({ slug, initialData, labels = {}, renderImage, rend
46
53
  })
47
54
  : "";
48
55
  const coverImageUrl = getMediaUrl(post.coverImage);
49
- return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: "relative h-72 md:h-96 overflow-hidden", children: [renderImage ? (renderImage(post)) : (_jsx(Div, { role: "img", "aria-label": post.title, className: "h-full w-full bg-cover bg-center", style: { backgroundImage: `url(${coverImageUrl})` } })), _jsx(Div, { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" })] })), _jsxs(Div, { className: "max-w-3xl mx-auto px-4 py-12", children: [renderBlogPostHeader(post, date, labels), post.tags && post.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-8", children: post.tags.map((tag) => (_jsxs(Link, { href: `${String(ROUTES.PUBLIC.BLOG)}?tags=${encodeURIComponent(tag)}`, className: "inline-block px-3 py-1 rounded-full bg-neutral-100 dark:bg-zinc-800 hover:bg-primary/10 text-zinc-600 dark:text-zinc-400 hover:text-primary text-xs font-medium transition-colors", children: ["#", tag] }, tag))) })), renderAuthorBio && _jsx(Div, { className: "mb-6", children: renderAuthorBio(post) }), _jsx(Div, { surface: "card", padding: "xl", className: "mb-12", children: renderContent ? renderContent(post) : (_jsx(RichText, { html: normalizeRichTextHtml(post.content ?? ""), proseClass: "prose max-w-none dark:prose-invert" })) }), renderBlogPostRelated(related, labels, renderRelatedCard), renderBackButton && _jsx(Div, { className: "mt-10 pt-8 border-t border-zinc-200 dark:border-zinc-700", children: renderBackButton() })] })] }));
56
+ return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: `relative h-72 md:h-96 ${__O.hidden}`, children: [renderImage ? (renderImage(post)) : (_jsx(Div, { role: "img", "aria-label": post.title, className: "h-full w-full bg-cover bg-center", style: { backgroundImage: `url(${coverImageUrl})` } })), _jsx(Div, { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" })] })), _jsxs(Div, { className: "max-w-3xl mx-auto px-4 py-12", children: [renderBlogPostHeader(post, date, labels), post.tags && post.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-8", children: post.tags.map((tag) => (_jsxs(Link, { href: `${String(ROUTES.PUBLIC.BLOG)}?tags=${encodeURIComponent(tag)}`, className: "inline-block px-3 py-1 rounded-full bg-neutral-100 dark:bg-zinc-800 hover:bg-primary/10 text-zinc-600 dark:text-zinc-400 hover:text-primary text-xs font-medium transition-colors", children: ["#", tag] }, tag))) })), renderAuthorBio && _jsx(Div, { className: "mb-6", children: renderAuthorBio(post) }), _jsx(Div, { surface: "card", padding: "xl", className: "mb-12", children: renderContent ? renderContent(post) : (_jsx(RichText, { html: normalizeRichTextHtml(post.content ?? ""), proseClass: "prose max-w-none dark:prose-invert" })) }), renderBlogPostRelated(related, labels, renderRelatedCard), renderBackButton && _jsx(Div, { className: "mt-10 pt-8 border-t border-zinc-200 dark:border-zinc-700", children: renderBackButton() })] })] }));
50
57
  }
@@ -3,14 +3,22 @@ import { Aside, Button, Div, Heading, Row, Span, Text } from "../../../ui";
3
3
  import { formatCurrency } from "../../../utils/number.formatter";
4
4
  import { THEME_CONSTANTS } from "../../../tokens";
5
5
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
6
+ const __P = {
7
+ p4: "p-4",
8
+ };
9
+ const __O = {
10
+ hidden: "overflow-hidden",
11
+ yAuto: "overflow-y-auto",
12
+ };
13
+ const CLS_REMOVE_BTN = "self-start text-zinc-400 dark:text-zinc-400 transition hover:text-red-500";
6
14
  export function CartItemRow({ item, onQtyChange, onRemove, href, isOutOfStock = false }) {
7
- return (_jsxs(Div, { surface: "card", padding: "sm", className: `flex gap-4 transition-opacity ${isOutOfStock ? "opacity-60" : ""}`, children: [_jsx(Div, { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-neutral-100 dark:bg-slate-800", children: item.meta.image && (_jsx(Div, { role: "img", "aria-label": item.meta.title, className: "h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${item.meta.image})` } })) }), _jsxs(Div, { className: "flex flex-1 flex-col justify-between", children: [_jsxs(Div, { className: "flex items-start gap-1.5", children: [href ? (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: `font-medium text-neutral-900 dark:text-zinc-100 hover:underline underline-offset-2 ${THEME_CONSTANTS.utilities.textClamp2}`, children: item.meta.title })) : (_jsx(Text, { className: `font-medium text-neutral-900 dark:text-zinc-100 ${THEME_CONSTANTS.utilities.textClamp2}`, children: item.meta.title })), isOutOfStock && (_jsx(Span, { className: "flex-shrink-0 rounded bg-error-surface px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-error", children: "Out of Stock" }))] }), item.meta.attributes &&
15
+ return (_jsxs(Div, { surface: "card", padding: "sm", className: `flex gap-4 transition-opacity ${isOutOfStock ? "opacity-60" : ""}`, children: [_jsx(Div, { className: `h-20 w-20 flex-shrink-0 ${__O.hidden} rounded-lg bg-neutral-100 dark:bg-slate-800`, children: item.meta.image && (_jsx(Div, { role: "img", "aria-label": item.meta.title, className: "h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${item.meta.image})` } })) }), _jsxs(Div, { className: "flex flex-1 flex-col justify-between", children: [_jsxs(Div, { className: "flex items-start gap-1.5", children: [href ? (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: `font-medium text-neutral-900 dark:text-zinc-100 hover:underline underline-offset-2 ${THEME_CONSTANTS.utilities.textClamp2}`, children: item.meta.title })) : (_jsx(Text, { className: `font-medium text-neutral-900 dark:text-zinc-100 ${THEME_CONSTANTS.utilities.textClamp2}`, children: item.meta.title })), isOutOfStock && (_jsx(Span, { weight: "semibold", className: "flex-shrink-0 rounded bg-error-surface px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-error", children: "Out of Stock" }))] }), item.meta.attributes &&
8
16
  Object.keys(item.meta.attributes).length > 0 && (_jsx(Text, { className: "text-xs text-neutral-500 dark:text-zinc-400", children: Object.entries(item.meta.attributes)
9
17
  .map(([k, v]) => `${k}: ${v}`)
10
- .join(", ") })), _jsxs(Row, { justify: "between", children: [_jsx(Text, { className: "font-semibold text-neutral-900 dark:text-zinc-100", children: formatCurrency(item.meta.price * item.quantity, item.meta.currency) }), onQtyChange && !isOutOfStock && (_jsxs(Row, { className: "gap-2", children: [_jsx(Button, { onClick: () => onQtyChange(item.id, item.quantity - 1), disabled: item.quantity <= 1, variant: "outline", size: "sm", className: "flex h-7 w-7 items-center justify-center rounded-full border border-neutral-200 dark:border-slate-600 text-sm disabled:opacity-40", children: "\u2212" }), _jsx(Span, { className: "min-w-[1.5rem] text-center text-sm", children: item.quantity }), _jsx(Button, { onClick: () => onQtyChange(item.id, item.quantity + 1), variant: "outline", size: "sm", className: "flex h-7 w-7 items-center justify-center rounded-full border border-neutral-200 dark:border-slate-600 text-sm", children: "+" })] })), isOutOfStock && (_jsxs(Span, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: ["Qty: ", item.quantity] }))] })] }), onRemove && (_jsx(Button, { onClick: () => onRemove(item.id), variant: "ghost", size: "sm", "aria-label": ACTIONS.CART["remove-item"].ariaLabel, className: "self-start text-zinc-400 dark:text-zinc-400 transition hover:text-red-500", children: "\u2715" }))] }));
18
+ .join(", ") })), _jsxs(Row, { justify: "between", children: [_jsx(Text, { className: "font-semibold text-neutral-900 dark:text-zinc-100", children: formatCurrency(item.meta.price * item.quantity, item.meta.currency) }), onQtyChange && !isOutOfStock && (_jsxs(Row, { className: "gap-2", children: [_jsx(Button, { onClick: () => onQtyChange(item.id, item.quantity - 1), disabled: item.quantity <= 1, variant: "outline", size: "sm", className: "flex h-7 w-7 items-center justify-center rounded-full border border-neutral-200 dark:border-slate-600 text-sm disabled:opacity-40", children: "\u2212" }), _jsx(Span, { size: "sm", className: "min-w-[1.5rem] text-center", children: item.quantity }), _jsx(Button, { onClick: () => onQtyChange(item.id, item.quantity + 1), variant: "outline", size: "sm", className: "flex h-7 w-7 items-center justify-center rounded-full border border-neutral-200 dark:border-slate-600 text-sm", children: "+" })] })), isOutOfStock && (_jsxs(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400", children: ["Qty: ", item.quantity] }))] })] }), onRemove && (_jsx(Button, { onClick: () => onRemove(item.id), variant: "ghost", size: "sm", "aria-label": ACTIONS.CART["remove-item"].ariaLabel, className: CLS_REMOVE_BTN, children: "\u2715" }))] }));
11
19
  }
12
20
  export function CartDrawer({ isOpen, onClose, items, subtotal = 0, currency, isLoading, onQtyChange, onRemove, onCheckout, labels = {}, }) {
13
21
  if (!isOpen)
14
22
  return null;
15
- return (_jsxs(_Fragment, { children: [_jsx(Div, { role: "presentation", className: "fixed inset-0 z-40 bg-black/40", onClick: onClose }), _jsxs(Aside, { className: "fixed inset-y-0 right-0 z-50 flex w-full max-w-sm flex-col bg-white dark:bg-slate-900 shadow-xl", children: [_jsxs(Row, { justify: "between", className: "border-b border-neutral-200 dark:border-slate-700 p-4", children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold", children: labels.title ?? "Cart" }), _jsx(Button, { onClick: onClose, variant: "ghost", size: "sm", "aria-label": "Close cart", className: "text-neutral-500 dark:text-zinc-400 hover:text-neutral-900 dark:hover:text-zinc-100", children: "\u2715" })] }), _jsx(Div, { className: "flex-1 overflow-y-auto p-4 space-y-3", children: isLoading ? (_jsx(Div, { className: "flex justify-center py-12", children: _jsx(Div, { className: "h-8 w-8 animate-spin rounded-full border-2 border-neutral-300 dark:border-slate-600 border-t-neutral-800 dark:border-t-zinc-200" }) })) : items.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-neutral-500 dark:text-zinc-400", children: labels.empty ?? "Your cart is empty" })) : (items.map((item) => (_jsx(CartItemRow, { item: item, onQtyChange: onQtyChange, onRemove: onRemove }, item.id)))) }), items.length > 0 && (_jsxs(Div, { className: "border-t border-neutral-200 dark:border-slate-700 p-4 space-y-4", children: [_jsxs(Row, { justify: "between", className: "text-sm", children: [_jsx(Span, { className: "text-neutral-600 dark:text-zinc-300", children: labels.subtotal ?? "Subtotal" }), _jsx(Span, { className: "font-semibold", children: formatCurrency(subtotal, currency) })] }), onCheckout && (_jsx(Button, { onClick: onCheckout, variant: "primary", className: "w-full rounded-xl bg-neutral-900 py-3 text-sm font-semibold text-white transition hover:bg-neutral-800", children: labels.checkout ?? ACTIONS.CART["checkout"].label }))] }))] })] }));
23
+ return (_jsxs(_Fragment, { children: [_jsx(Div, { role: "presentation", className: "fixed inset-0 z-40 bg-black/40", onClick: onClose }), _jsxs(Aside, { className: "fixed inset-y-0 right-0 z-50 flex w-full max-w-sm flex-col bg-white dark:bg-slate-900 shadow-xl", children: [_jsxs(Row, { justify: "between", className: `border-b border-neutral-200 dark:border-slate-700 ${__P.p4}`, children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold", children: labels.title ?? "Cart" }), _jsx(Button, { onClick: onClose, variant: "ghost", size: "sm", "aria-label": "Close cart", className: "text-neutral-500 dark:text-zinc-400 hover:text-neutral-900 dark:hover:text-zinc-100", children: "\u2715" })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto} ${__P.p4} space-y-3`, children: isLoading ? (_jsx(Div, { className: "flex justify-center py-12", children: _jsx(Div, { className: "h-8 w-8 animate-spin rounded-full border-2 border-neutral-300 dark:border-slate-600 border-t-neutral-800 dark:border-t-zinc-200" }) })) : items.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-neutral-500 dark:text-zinc-400", children: labels.empty ?? "Your cart is empty" })) : (items.map((item) => (_jsx(CartItemRow, { item: item, onQtyChange: onQtyChange, onRemove: onRemove }, item.id)))) }), items.length > 0 && (_jsxs(Div, { className: `border-t border-neutral-200 dark:border-slate-700 ${__P.p4} space-y-4`, children: [_jsxs(Row, { justify: "between", className: "text-sm", children: [_jsx(Span, { className: "text-neutral-600 dark:text-zinc-300", children: labels.subtotal ?? "Subtotal" }), _jsx(Span, { weight: "semibold", children: formatCurrency(subtotal, currency) })] }), onCheckout && (_jsx(Button, { onClick: onCheckout, variant: "primary", className: "w-full rounded-xl bg-neutral-900 py-3 text-sm font-semibold text-white transition hover:bg-neutral-800", children: labels.checkout ?? ACTIONS.CART["checkout"].label }))] }))] })] }));
16
24
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Heading } from "../../../ui";
2
+ import { Div, Heading } from "../../../ui";
3
3
  export function CartSummary({ renderBreakdown, renderTotal, renderCheckoutAction, renderPromoCode, renderContinueShopping, labels = {}, className = "", }) {
4
- return (_jsxs("div", { className: `space-y-4 ${className}`, "data-section": "cartsummary-div-260", children: [labels.title && (_jsx(Heading, { level: 2, className: "text-base font-bold", variant: "none", children: labels.title })), renderBreakdown?.(), renderPromoCode?.(), renderTotal?.(), renderCheckoutAction?.(), renderContinueShopping?.()] }));
4
+ return (_jsxs(Div, { className: `space-y-4 ${className}`, children: [labels.title && (_jsx(Heading, { level: 2, className: "text-base font-bold", variant: "none", children: labels.title })), renderBreakdown?.(), renderPromoCode?.(), renderTotal?.(), renderCheckoutAction?.(), renderContinueShopping?.()] }));
5
5
  }
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Div } from "../../../ui";
2
3
  export function CheckoutOtpModal({ isOpen, title, onClose, renderContainer, renderBody, className = "", }) {
3
4
  if (!isOpen)
4
5
  return null;
@@ -6,6 +7,6 @@ export function CheckoutOtpModal({ isOpen, title, onClose, renderContainer, rend
6
7
  isOpen,
7
8
  title,
8
9
  onClose,
9
- children: _jsx("div", { className: className, "data-section": "checkoutotpmodal-div-261", children: renderBody() }),
10
+ children: _jsx(Div, { className: className, children: renderBody() }),
10
11
  }) }));
11
12
  }
@@ -1,9 +1,14 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
3
+ import { sortBy } from "@mohasinac/appkit";
2
4
  import Link from "next/link";
3
5
  import { categoriesRepository, productRepository, } from "../../../repositories";
4
6
  import { ROUTES } from "../../../next";
5
- import { Container, Heading, Main, Section, Text } from "../../../ui";
7
+ import { Container, Div, Heading, Main, Nav, Section, Span, Text } from "../../../ui";
6
8
  import { BrandDetailTabs } from "./BrandDetailTabs";
9
+ const __O = {
10
+ hidden: "overflow-hidden",
11
+ };
7
12
  export async function BrandDetailPageView({ slug, initialBrand }) {
8
13
  const brand = (initialBrand ?? (await categoriesRepository
9
14
  .getCategoryBySlug(slug)
@@ -13,8 +18,8 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
13
18
  brandName
14
19
  ? productRepository
15
20
  .list({
16
- filters: `status==published,brand==${brandName},listingType==standard`,
17
- sorts: "-createdAt",
21
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("brand", SIEVE_OP.EQ, brandName), sieveFilter("listingType", SIEVE_OP.EQ, "standard")),
22
+ sorts: sortBy("createdAt", "DESC"),
18
23
  page: 1,
19
24
  pageSize: 24,
20
25
  })
@@ -23,8 +28,8 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
23
28
  brandName
24
29
  ? productRepository
25
30
  .list({
26
- filters: `status==published,brand==${brandName},listingType==auction`,
27
- sorts: "auctionEndDate",
31
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("brand", SIEVE_OP.EQ, brandName), sieveFilter("listingType", SIEVE_OP.EQ, "auction")),
32
+ sorts: sortBy("auctionEndDate", "ASC"),
28
33
  page: 1,
29
34
  pageSize: 1,
30
35
  })
@@ -33,8 +38,8 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
33
38
  brandName
34
39
  ? productRepository
35
40
  .list({
36
- filters: `status==published,brand==${brandName},listingType==pre-order`,
37
- sorts: "-createdAt",
41
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("brand", SIEVE_OP.EQ, brandName), sieveFilter("listingType", SIEVE_OP.EQ, "pre-order")),
42
+ sorts: sortBy("createdAt", "DESC"),
38
43
  page: 1,
39
44
  pageSize: 1,
40
45
  })
@@ -43,8 +48,8 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
43
48
  brandName
44
49
  ? productRepository
45
50
  .list({
46
- filters: `status==published,brand==${brandName},listingType==prize-draw`,
47
- sorts: "-createdAt",
51
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("brand", SIEVE_OP.EQ, brandName), sieveFilter("listingType", SIEVE_OP.EQ, "prize-draw")),
52
+ sorts: sortBy("createdAt", "DESC"),
48
53
  page: 1,
49
54
  pageSize: 1,
50
55
  })
@@ -81,5 +86,5 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
81
86
  counts.preOrders +
82
87
  counts.prizeDraws +
83
88
  counts.bundles;
84
- return (_jsxs(Main, { children: [_jsxs(Section, { className: `relative overflow-hidden ${hasCover ? "min-h-[220px] md:min-h-[280px]" : "bg-zinc-50 dark:bg-zinc-900"}`, children: [hasCover && (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute inset-0 bg-center bg-cover", style: { backgroundImage: `url(${coverImage})` } }), _jsx("div", { className: "absolute inset-0 bg-black/55" })] })), !hasCover && (_jsx("div", { className: "absolute inset-0 opacity-10", style: { backgroundColor: brandColor } })), _jsxs("div", { className: `relative z-10 max-w-7xl mx-auto px-4 ${hasCover ? "py-12" : "py-8"}`, children: [_jsxs("nav", { className: "flex items-center gap-1.5 text-sm mb-4", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Home" }), _jsx("span", { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.BRANDS ?? "/brands"), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Brands" }), _jsx("span", { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx("span", { className: hasCover ? "text-white font-medium" : "text-zinc-900 dark:text-zinc-100 font-medium", children: brand?.name ?? slug })] }), _jsxs("div", { className: "flex items-center gap-4 mb-3", children: [brand?.display?.icon && (_jsx("span", { className: `text-5xl leading-none ${!hasCover ? "" : ""}`, children: brand.display.icon })), _jsxs(_Fragment, { children: [_jsx(Heading, { level: 1, className: `text-3xl md:text-4xl font-bold ${hasCover ? "text-white" : "text-zinc-900 dark:text-zinc-50"}`, children: brand?.name ?? slug }), brand?.description && typeof brand.description === "string" && !brand.description.startsWith("{") && (_jsx(Text, { className: `text-base max-w-2xl mt-1 ${hasCover ? "text-white/80" : "text-zinc-600 dark:text-zinc-400"}`, children: brand.description }))] })] }), _jsxs("div", { className: "flex flex-wrap gap-2 mt-3", children: [counts.products > 0 && (_jsxs("span", { className: `inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-primary/10 text-primary-700 dark:text-primary-400"}`, children: [counts.products.toLocaleString(), " ", counts.products === 1 ? "product" : "products"] })), counts.auctions > 0 && (_jsxs("span", { className: `inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"}`, children: [counts.auctions.toLocaleString(), " ", counts.auctions === 1 ? "auction" : "auctions"] })), counts.preOrders > 0 && (_jsxs("span", { className: `inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-400"}`, children: [counts.preOrders.toLocaleString(), " ", counts.preOrders === 1 ? "pre-order" : "pre-orders"] })), totalItems === 0 && (_jsx("span", { className: `text-sm ${hasCover ? "text-white/60" : "text-zinc-400"}`, children: "No items listed yet" }))] })] })] }), _jsx(Section, { className: "py-6", children: _jsx(Container, { size: "xl", children: brandName ? (_jsx(BrandDetailTabs, { brandName: brandName, initialProductsData: productsResult ?? undefined, initialBundles: brandBundles, counts: counts })) : (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "Brand not found." })) }) })] }));
89
+ return (_jsxs(Main, { children: [_jsxs(Section, { className: `relative ${__O.hidden} ${hasCover ? "min-h-[220px] md:min-h-[280px]" : "bg-zinc-50 dark:bg-zinc-900"}`, children: [hasCover && (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute inset-0 bg-center bg-cover", style: { backgroundImage: `url(${coverImage})` } }), _jsx(Div, { className: "absolute inset-0 bg-black/55" })] })), !hasCover && (_jsx("div", { className: "absolute inset-0 opacity-10", style: { backgroundColor: brandColor } })), _jsxs(Div, { className: `relative z-10 max-w-7xl mx-auto px-4 ${hasCover ? "py-12" : "py-8"}`, children: [_jsxs(Nav, { className: "flex items-center gap-1.5 text-sm mb-4", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Home" }), _jsx(Span, { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.BRANDS ?? "/brands"), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Brands" }), _jsx(Span, { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx(Span, { weight: "medium", className: hasCover ? "text-white" : "text-zinc-900 dark:text-zinc-100", children: brand?.name ?? slug })] }), _jsxs(Div, { className: "flex items-center gap-4 mb-3", children: [brand?.display?.icon && (_jsx(Span, { className: "text-5xl leading-none", children: brand.display.icon })), _jsxs(_Fragment, { children: [_jsx(Heading, { level: 1, className: `text-3xl md:text-4xl font-bold ${hasCover ? "text-white" : "text-zinc-900 dark:text-zinc-50"}`, children: brand?.name ?? slug }), brand?.description && typeof brand.description === "string" && !brand.description.startsWith("{") && (_jsx(Text, { className: `text-base max-w-2xl mt-1 ${hasCover ? "text-white/80" : "text-zinc-600 dark:text-zinc-400"}`, children: brand.description }))] })] }), _jsxs(Div, { className: "flex flex-wrap gap-2 mt-3", children: [counts.products > 0 && (_jsxs(Span, { size: "xs", weight: "medium", className: `inline-flex items-center gap-1 px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-primary/10 text-primary-700 dark:text-primary-400"}`, children: [counts.products.toLocaleString(), " ", counts.products === 1 ? "product" : "products"] })), counts.auctions > 0 && (_jsxs(Span, { size: "xs", weight: "medium", className: `inline-flex items-center gap-1 px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"}`, children: [counts.auctions.toLocaleString(), " ", counts.auctions === 1 ? "auction" : "auctions"] })), counts.preOrders > 0 && (_jsxs(Span, { size: "xs", weight: "medium", className: `inline-flex items-center gap-1 px-2.5 py-1 rounded-full ${hasCover ? "bg-white/20 text-white backdrop-blur-sm" : "bg-violet-100 text-violet-700 dark:bg-violet-900/30 dark:text-violet-400"}`, children: [counts.preOrders.toLocaleString(), " ", counts.preOrders === 1 ? "pre-order" : "pre-orders"] })), totalItems === 0 && (_jsx(Span, { size: "sm", className: hasCover ? "text-white/60" : "text-zinc-400", children: "No items listed yet" }))] })] })] }), _jsx(Section, { className: "py-6", children: _jsx(Container, { size: "xl", children: brandName ? (_jsx(BrandDetailTabs, { brandName: brandName, initialProductsData: productsResult ?? undefined, initialBundles: brandBundles, counts: counts })) : (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "Brand not found." })) }) })] }));
85
90
  }
@@ -1,12 +1,16 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
+ import { Div } from "../../../ui";
4
5
  import { CategoryProductsListing } from "./CategoryProductsListing";
5
6
  import { AuctionsIndexListing } from "../../products/components/AuctionsIndexListing";
6
7
  import { PreOrdersIndexListing } from "../../pre-orders/components/PreOrdersIndexListing";
7
8
  import { PrizeDrawsIndexListing } from "../../products/components/PrizeDrawsIndexListing";
8
9
  import { CategoryBundlesListing } from "./CategoryBundlesListing";
9
10
  import { CATEGORY_PAGE_TABS } from "../../products/constants/listing-tabs";
11
+ const __O = {
12
+ xAuto: "overflow-x-auto",
13
+ };
10
14
  function tabLabel(label, count) {
11
15
  if (!count)
12
16
  return label;
@@ -44,7 +48,7 @@ export function BrandDetailTabs({ brandName, initialProductsData, initialBundles
44
48
  default: return undefined;
45
49
  }
46
50
  };
47
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex border-b border-zinc-200 dark:border-slate-700 mb-6 overflow-x-auto", children: visibleTabs.map((t) => (_jsx("button", { type: "button", onClick: () => setActiveTab(t.id), className: `px-5 py-2.5 text-sm font-medium whitespace-nowrap transition-colors -mb-px border-b-2 ${activeTab === t.id
51
+ return (_jsxs(_Fragment, { children: [_jsx(Div, { className: `flex border-b border-zinc-200 dark:border-slate-700 mb-6 ${__O.xAuto}`, children: visibleTabs.map((t) => (_jsx("button", { type: "button", onClick: () => setActiveTab(t.id), className: `px-5 py-2.5 text-sm font-medium whitespace-nowrap transition-colors -mb-px border-b-2 ${activeTab === t.id
48
52
  ? "border-primary text-primary"
49
53
  : "border-transparent text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100"}`, children: tabLabel(t.label, countFor(t.id)) }, t.id))) }), activeTab === "products" && (_jsx(CategoryProductsListing, { categorySlug: "", brandName: brandName, initialData: initialProductsData })), activeTab === "auctions" && (_jsx(AuctionsIndexListing, { brandName: brandName })), activeTab === "pre-orders" && (_jsx(PreOrdersIndexListing, { brandName: brandName })), activeTab === "prize-draws" && (_jsx(PrizeDrawsIndexListing, { brandName: brandName })), activeTab === "bundles" && (_jsx(CategoryBundlesListing, { initialBundles: initialBundles, brandName: brandName }))] }));
50
54
  }
@@ -1,11 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Badge, Container, Div, Heading, Main, Row, Section, Stack, Text, } from "../../../ui";
2
+ import { Badge, Container, Div, Heading, Li, Main, Row, Section, Span, Stack, Text, Ul, } from "../../../ui";
3
3
  import { formatCurrency } from "../../../utils/number.formatter";
4
4
  import Link from "next/link";
5
5
  import { BUNDLE_COPY, BUNDLE_STOCK_VARIANT, } from "../../../_internal/shared/features/categories/bundle-copy";
6
6
  import { BundleBuyNowCta } from "./BundleBuyNowCta";
7
7
  import { BundleCollage } from "./BundleCollage";
8
8
  import { ROUTES } from "../../../next/routing/route-map";
9
+ const __O = {
10
+ hidden: "overflow-hidden",
11
+ };
9
12
  const STOCK_BADGE_TEXT = {
10
13
  in_stock: BUNDLE_COPY.stockBadge.in_stock,
11
14
  out_of_stock: BUNDLE_COPY.stockBadge.out_of_stock,
@@ -18,7 +21,7 @@ export function BundleDetailView({ bundle, members = [], onBuyNow, }) {
18
21
  const priceLabel = bundle.bundlePriceInPaise
19
22
  ? formatCurrency(bundle.bundlePriceInPaise / 100, "INR")
20
23
  : BUNDLE_COPY.detail.priceFallback;
21
- return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "lg", children: [_jsxs(Row, { gap: "lg", align: "start", className: "flex-col md:flex-row", children: [_jsx(Div, { className: "w-full md:w-2/5", children: members.length > 0 ? (_jsx(BundleCollage, { members: members })) : (_jsx(Div, { className: "aspect-video w-full overflow-hidden rounded-2xl bg-zinc-100 dark:bg-zinc-800", children: cover ? (
24
+ return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "lg", children: [_jsxs(Row, { gap: "lg", align: "start", className: "flex-col md:flex-row", children: [_jsx(Div, { className: "w-full md:w-2/5", children: members.length > 0 ? (_jsx(BundleCollage, { members: members })) : (_jsx(Div, { className: `aspect-video w-full ${__O.hidden} rounded-2xl bg-zinc-100 dark:bg-zinc-800`, children: cover ? (
22
25
  // eslint-disable-next-line @next/next/no-img-element, lir/no-raw-media-elements
23
- _jsx("img", { src: cover, alt: bundle.name, className: "h-full w-full object-cover" })) : (_jsx(Div, { className: "flex h-full w-full items-center justify-center text-6xl", children: PLACEHOLDER_EMOJI })) })) }), _jsxs(Stack, { gap: "md", className: "flex-1", children: [_jsx(Heading, { level: 1, className: "text-3xl font-semibold text-zinc-900 dark:text-zinc-100", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "lg", weight: "bold", children: priceLabel }), _jsxs(Text, { size: "sm", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.detail.itemCount(memberCount)] }), _jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: STOCK_BADGE_TEXT[stock] })] }), bundle.description && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-[var(--appkit-color-text-muted)]", children: BUNDLE_COPY.detailDescriptionHeading }), _jsx(Text, { className: "whitespace-pre-line", children: bundle.description })] })), onBuyNow ? (_jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow })) : (_jsxs(Div, { className: "rounded-xl border border-dashed border-zinc-300 bg-zinc-50 p-4 text-sm dark:border-zinc-700 dark:bg-zinc-900", "aria-live": "polite", children: [_jsx(Text, { weight: "semibold", className: "mb-1 block", children: BUNDLE_COPY.detail.ctaDisabled }), _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }))] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 2, className: "text-xl font-semibold text-zinc-900 dark:text-zinc-100", children: BUNDLE_COPY.detailItemsHeading }), members.length === 0 ? (_jsx(Text, { color: "muted", children: BUNDLE_COPY.detail.emptyMembers })) : (_jsx("ul", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: members.map((p, i) => (_jsxs("li", { className: "flex items-center gap-2 rounded-lg border border-zinc-100 dark:border-zinc-800 px-3 py-2 text-sm", children: [_jsxs("span", { className: "text-xs font-semibold text-zinc-400 w-5", children: ["#", i + 1] }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCT_DETAIL?.(p.slug ?? p.id) ?? "#"), className: "flex-1 truncate font-medium hover:underline hover:text-primary", children: p.title })] }, p.id))) }))] })] }) }) }) }));
26
+ _jsx("img", { src: cover, alt: bundle.name, className: "h-full w-full object-cover" })) : (_jsx(Div, { className: "flex h-full w-full items-center justify-center text-6xl", children: PLACEHOLDER_EMOJI })) })) }), _jsxs(Stack, { gap: "md", className: "flex-1", children: [_jsx(Heading, { level: 1, className: "text-3xl font-semibold text-zinc-900 dark:text-zinc-100", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "lg", weight: "bold", children: priceLabel }), _jsxs(Text, { size: "sm", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.detail.itemCount(memberCount)] }), _jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: STOCK_BADGE_TEXT[stock] })] }), bundle.description && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-[var(--appkit-color-text-muted)]", children: BUNDLE_COPY.detailDescriptionHeading }), _jsx(Text, { className: "whitespace-pre-line", children: bundle.description })] })), onBuyNow ? (_jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow })) : (_jsxs(Div, { className: "rounded-xl border border-dashed border-zinc-300 bg-zinc-50 p-4 text-sm dark:border-zinc-700 dark:bg-zinc-900", "aria-live": "polite", children: [_jsx(Text, { weight: "semibold", className: "mb-1 block", children: BUNDLE_COPY.detail.ctaDisabled }), _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }))] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 2, className: "text-xl font-semibold text-zinc-900 dark:text-zinc-100", children: BUNDLE_COPY.detailItemsHeading }), members.length === 0 ? (_jsx(Text, { color: "muted", children: BUNDLE_COPY.detail.emptyMembers })) : (_jsx(Ul, { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: members.map((p, i) => (_jsxs(Li, { className: "flex items-center gap-2 rounded-lg border border-zinc-100 dark:border-zinc-800 px-3 py-2 text-sm", children: [_jsxs(Span, { size: "xs", weight: "semibold", className: "text-zinc-400 w-5", children: ["#", i + 1] }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCT_DETAIL?.(p.slug ?? p.id) ?? "#"), className: "flex-1 truncate font-medium hover:underline hover:text-primary", children: p.title })] }, p.id))) }))] })] }) }) }) }));
24
27
  }
@@ -15,6 +15,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  */
16
16
  import { useCallback } from "react";
17
17
  import { Div, Input, Row, Select, Stack, Text } from "../../../ui";
18
+ import { CategoryInlineSelect } from "../../seller/components/CategoryInlineSelect";
19
+ import { BrandInlineSelect } from "../../seller/components/BrandInlineSelect";
18
20
  import { BUNDLE_MAX_ITEMS } from "../../../_internal/shared/features/categories/bundle-config";
19
21
  import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
20
22
  const DEFAULT_DYNAMIC_RULE = {
@@ -39,7 +41,7 @@ export function BundleDynamicRuleEditor({ value, onChange, disabled = false, })
39
41
  const patch = useCallback((next) => onChange({ ...rule, ...next }), [rule, onChange]);
40
42
  const patchFilter = useCallback((next) => onChange({ ...rule, filter: { ...rule.filter, ...next } }), [rule, onChange]);
41
43
  const tagsValue = (rule.filter.tags ?? []).join(", ");
42
- return (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", className: "flex-wrap", children: [_jsx(Text, { size: "sm", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.title }), _jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.adminEditor.dynamic.hint })] }), _jsxs(Div, { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.categorySlug }), _jsx(Input, { type: "text", value: rule.filter.categorySlug ?? "", onChange: (e) => patchFilter({ categorySlug: e.target.value.trim() || undefined }), placeholder: "category-action-figures", disabled: disabled })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.brandSlug }), _jsx(Input, { type: "text", value: rule.filter.brandSlug ?? "", onChange: (e) => patchFilter({ brandSlug: e.target.value.trim() || undefined }), placeholder: "brand-bandai", disabled: disabled })] })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.tags }), _jsx(Input, { type: "text", value: tagsValue, onChange: (e) => {
44
+ return (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", className: "flex-wrap", children: [_jsx(Text, { size: "sm", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.title }), _jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.adminEditor.dynamic.hint })] }), _jsxs(Div, { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.categorySlug }), _jsx(CategoryInlineSelect, { value: rule.filter.categorySlug ?? "", onChange: (id) => patchFilter({ categorySlug: id || undefined }), disabled: disabled, placeholder: "Filter by category\u2026" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.brandSlug }), _jsx(BrandInlineSelect, { value: rule.filter.brandSlug ?? "", onChange: (id) => patchFilter({ brandSlug: id || undefined }), disabled: disabled, placeholder: "Filter by brand\u2026" })] })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.tags }), _jsx(Input, { type: "text", value: tagsValue, onChange: (e) => {
43
45
  const parsed = e.target.value
44
46
  .split(",")
45
47
  .map((t) => t.trim())
@@ -17,12 +17,19 @@ import { useCallback, useEffect, useMemo, useState } from "react";
17
17
  import { Badge, Button, Checkbox, Div, Input, Row, Stack, Text } from "../../../ui";
18
18
  import { BUNDLE_MAX_ITEMS, BUNDLE_MIN_ITEMS, } from "../../../_internal/shared/features/categories/bundle-config";
19
19
  import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
20
+ const __P = {
21
+ p3: "p-3",
22
+ };
23
+ const __O = {
24
+ yAuto: "overflow-y-auto",
25
+ };
20
26
  const SEARCH_DEBOUNCE_MS = 250;
27
+ const CLS_ROW_SELECTED = "bg-blue-50 dark:bg-blue-950";
21
28
  function renderBundleSelectedChips(props) {
22
29
  const { value, metadata, remove } = props;
23
30
  if (value.length === 0)
24
31
  return null;
25
- return (_jsx(Div, { className: "flex flex-wrap gap-2 rounded-lg border border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-700 dark:bg-zinc-900", children: value.map((id) => {
32
+ return (_jsx(Div, { className: `flex flex-wrap gap-2 rounded-lg border border-zinc-200 bg-zinc-50 ${__P.p3} dark:border-zinc-700 dark:bg-zinc-900`, children: value.map((id) => {
26
33
  const meta = metadata[id];
27
34
  const label = meta?.title ?? id;
28
35
  return (_jsxs(Row, { gap: "xs", align: "center", className: "rounded-full border border-zinc-300 bg-white px-3 py-1 text-xs dark:border-zinc-600 dark:bg-zinc-800", children: [_jsx(Text, { size: "xs", className: "max-w-[200px] truncate", children: label }), _jsx(Button, { variant: "ghost", size: "sm", "aria-label": BUNDLE_COPY.picker.removeAria(label), onClick: () => remove(id), children: "\u00D7" })] }, id));
@@ -30,10 +37,10 @@ function renderBundleSelectedChips(props) {
30
37
  }
31
38
  function renderBundleSearchResults(props) {
32
39
  const { results, selectedSet, value, maxItems, toggle, isSearching, searchError, debouncedQuery } = props;
33
- return (_jsxs(_Fragment, { children: [searchError && _jsx(Text, { size: "sm", color: "danger", children: searchError }), isSearching && _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.searchingHint }), !isSearching && debouncedQuery.length >= 2 && results.length === 0 && !searchError && (_jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.noMatches(debouncedQuery) })), results.length > 0 && (_jsx(Div, { className: "max-h-72 overflow-y-auto rounded-lg border border-zinc-200 dark:border-zinc-700", children: results.map((r) => {
40
+ return (_jsxs(_Fragment, { children: [searchError && _jsx(Text, { size: "sm", color: "danger", children: searchError }), isSearching && _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.searchingHint }), !isSearching && debouncedQuery.length >= 2 && results.length === 0 && !searchError && (_jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.noMatches(debouncedQuery) })), results.length > 0 && (_jsx(Div, { className: `max-h-72 ${__O.yAuto} rounded-lg border border-zinc-200 dark:border-zinc-700`, children: results.map((r) => {
34
41
  const isSelected = selectedSet.has(r.id);
35
42
  const atCap = !isSelected && value.length >= maxItems;
36
- return (_jsxs(Row, { gap: "sm", align: "center", className: `border-b border-zinc-100 px-3 py-2 last:border-b-0 dark:border-zinc-800 ${isSelected ? "bg-blue-50 dark:bg-blue-950" : ""} ${atCap ? "opacity-50" : ""}`, children: [_jsx(Checkbox, { checked: isSelected, disabled: atCap, onChange: () => toggle(r.id), "aria-label": BUNDLE_COPY.picker.toggleAria(r.title) }), _jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsx(Text, { size: "sm", weight: "medium", children: r.title }), _jsxs(Row, { gap: "sm", children: [_jsx(Text, { size: "xs", color: "muted", children: r.id }), typeof r.priceInPaise === "number" && _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 \u20B9", Math.round(r.priceInPaise / 100).toLocaleString("en-IN")] })] })] })] }, r.id));
43
+ return (_jsxs(Row, { gap: "sm", align: "center", className: `border-b border-zinc-100 px-3 py-2 last:border-b-0 dark:border-zinc-800 ${isSelected ? CLS_ROW_SELECTED : ""} ${atCap ? "opacity-50" : ""}`, children: [_jsx(Checkbox, { checked: isSelected, disabled: atCap, onChange: () => toggle(r.id), "aria-label": BUNDLE_COPY.picker.toggleAria(r.title) }), _jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsx(Text, { size: "sm", weight: "medium", children: r.title }), _jsxs(Row, { gap: "sm", children: [_jsx(Text, { size: "xs", color: "muted", children: r.id }), typeof r.priceInPaise === "number" && _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 \u20B9", Math.round(r.priceInPaise / 100).toLocaleString("en-IN")] })] })] })] }, r.id));
37
44
  }) }))] }));
38
45
  }
39
46
  export function BundleItemsPicker({ value, onChange, fetchProducts, minItems = BUNDLE_MIN_ITEMS, maxItems = BUNDLE_MAX_ITEMS, initialMetadata = {}, }) {