@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
@@ -1,6 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { StatusBadge, Span, Button } from "../../../ui";
2
+ import { Div, StatusBadge, Span, Button } from "../../../ui";
3
3
  import { MediaImage } from "../../media";
4
+ const __O = {
5
+ hidden: "overflow-hidden",
6
+ };
7
+ const CLS_DELETE_BTN = "text-red-600 hover:text-red-800 dark:text-red-400";
4
8
  const DEFAULT_LABELS = {
5
9
  colName: "Name",
6
10
  colSlug: "Slug",
@@ -18,13 +22,13 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
18
22
  {
19
23
  key: "image",
20
24
  header: "",
21
- render: (cat) => (_jsx("div", { className: "relative w-9 h-9 rounded overflow-hidden flex-shrink-0", "data-section": "categorytablecolumns-div-270", children: cat.display?.coverImage ? (_jsx(MediaImage, { src: cat.display.coverImage, alt: "", size: "thumbnail", className: "w-full h-full object-cover" })) : (_jsx("div", { className: "w-full h-full flex items-center justify-center text-base", style: { backgroundColor: cat.display?.color ?? "#94a3b8", color: "#fff" }, "data-section": "categorytablecolumns-div-271", children: cat.display?.icon ?? "🗂️" })) })),
25
+ render: (cat) => (_jsx(Div, { className: `relative w-9 h-9 rounded ${__O.hidden} flex-shrink-0`, children: cat.display?.coverImage ? (_jsx(MediaImage, { src: cat.display.coverImage, alt: "", size: "thumbnail", className: "w-full h-full object-cover" })) : (_jsx(Div, { className: "w-full h-full flex items-center justify-center text-base", style: { backgroundColor: cat.display?.color ?? "#94a3b8", color: "#fff" }, children: cat.display?.icon ?? "🗂️" })) })),
22
26
  },
23
27
  {
24
28
  key: "name",
25
29
  header: L.colName,
26
30
  sortable: true,
27
- render: (cat) => (_jsxs("div", { style: { paddingLeft: `${cat.tier * 20}px` }, "data-section": "categorytablecolumns-div-272", children: [cat.name, cat.tier > 0 && (_jsxs(Span, { className: "text-zinc-400 dark:text-zinc-400 text-xs ml-2", children: ["(Tier ", cat.tier, ")"] }))] })),
31
+ render: (cat) => (_jsxs(Div, { style: { paddingLeft: `${cat.tier * 20}px` }, children: [cat.name, cat.tier > 0 && (_jsxs(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400 ml-2", children: ["(Tier ", cat.tier, ")"] }))] })),
28
32
  },
29
33
  {
30
34
  key: "slug",
@@ -34,7 +38,7 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
34
38
  {
35
39
  key: "metrics",
36
40
  header: L.colProducts,
37
- render: (cat) => (_jsxs(Span, { className: "text-sm", children: [cat.metrics.productCount, " (", cat.metrics.totalProductCount, ")"] })),
41
+ render: (cat) => (_jsxs(Span, { size: "sm", children: [cat.metrics.productCount, " (", cat.metrics.totalProductCount, ")"] })),
38
42
  },
39
43
  {
40
44
  key: "isActive",
@@ -43,12 +47,12 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
43
47
  render: (cat) => (_jsx(StatusBadge, { status: cat.isActive ? "active" : "inactive", label: cat.isActive ? L.statusActive : L.statusInactive })),
44
48
  },
45
49
  ],
46
- actions: (cat) => (_jsxs("div", { className: "flex gap-2", "data-section": "categorytablecolumns-div-273", children: [_jsx(Button, { variant: "ghost", onClick: (e) => {
50
+ actions: (cat) => (_jsxs(Div, { className: "flex gap-2", children: [_jsx(Button, { variant: "ghost", onClick: (e) => {
47
51
  e.stopPropagation();
48
52
  onEdit(cat);
49
53
  }, className: "text-primary hover:text-primary/80", children: L.actionEdit }), _jsx(Button, { variant: "ghost", onClick: (e) => {
50
54
  e.stopPropagation();
51
55
  onDelete(cat);
52
- }, className: "text-red-600 hover:text-red-800 dark:text-red-400", children: L.actionDelete })] })),
56
+ }, className: CLS_DELETE_BTN, children: L.actionDelete })] })),
53
57
  };
54
58
  }
@@ -10,6 +10,6 @@ export interface CategoryTreeProps {
10
10
  * CategoryTree — hierarchical expandable navigation for categories.
11
11
  *
12
12
  * Builds a tree from a flat list by grouping on `rootId` and `parentIds`.
13
- * Root-level nodes have `tier === 0` or no `parentIds`.
13
+ * Root-level nodes have sieveFilter("tier", SIEVE_OP.EQ, "= 0") or no `parentIds`.
14
14
  */
15
15
  export declare function CategoryTree({ categories, activeId, onSelect, className, }: CategoryTreeProps): import("react/jsx-runtime").JSX.Element;
@@ -19,13 +19,13 @@ function CategoryTreeNode({ item, children = [], activeId, onSelect, depth = 0,
19
19
  setExpanded((p) => !p);
20
20
  onSelect?.(item);
21
21
  }, className: `flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-sm transition select-none
22
- ${isActive ? "bg-primary-50 font-semibold text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, style: { paddingLeft: `${8 + indent}px` }, children: [hasChildren && (_jsx(Span, { "aria-hidden": "true", className: `text-xs text-zinc-400 dark:text-zinc-400 transition-transform duration-150 ${expanded ? "rotate-90" : ""}`, children: "\u25B6" })), !hasChildren && _jsx(Span, { className: "w-3" }), item.display?.icon && (_jsx(Span, { className: "flex-shrink-0 text-base", "aria-hidden": "true", children: item.display.icon })), _jsx(Text, { className: "flex-1 truncate", children: item.name }), item.metrics && (_jsx(Span, { className: "ml-auto flex-shrink-0 text-xs text-zinc-400 dark:text-zinc-400 tabular-nums", children: item.metrics.productCount }))] }), hasChildren && expanded && (_jsx(Div, { role: "group", children: children.map((child) => (_jsx(CategoryTreeNode, { item: child, activeId: activeId, onSelect: onSelect, depth: depth + 1 }, child.id))) }))] }));
22
+ ${isActive ? "bg-primary-50 font-semibold text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, style: { paddingLeft: `${8 + indent}px` }, children: [hasChildren && (_jsx(Span, { size: "xs", "aria-hidden": "true", className: `text-zinc-400 dark:text-zinc-400 transition-transform duration-150 ${expanded ? "rotate-90" : ""}`, children: "\u25B6" })), !hasChildren && _jsx(Span, { className: "w-3" }), item.display?.icon && (_jsx(Span, { size: "base", "aria-hidden": "true", className: "flex-shrink-0", children: item.display.icon })), _jsx(Text, { className: "flex-1 truncate", children: item.name }), item.metrics && (_jsx(Span, { size: "xs", className: "ml-auto flex-shrink-0 text-zinc-400 dark:text-zinc-400 tabular-nums", children: item.metrics.productCount }))] }), hasChildren && expanded && (_jsx(Div, { role: "group", children: children.map((child) => (_jsx(CategoryTreeNode, { item: child, activeId: activeId, onSelect: onSelect, depth: depth + 1 }, child.id))) }))] }));
23
23
  }
24
24
  /**
25
25
  * CategoryTree — hierarchical expandable navigation for categories.
26
26
  *
27
27
  * Builds a tree from a flat list by grouping on `rootId` and `parentIds`.
28
- * Root-level nodes have `tier === 0` or no `parentIds`.
28
+ * Root-level nodes have sieveFilter("tier", SIEVE_OP.EQ, "= 0") or no `parentIds`.
29
29
  */
30
30
  export function CategoryTree({ categories, activeId, onSelect, className = "", }) {
31
31
  // Group children by parent
@@ -36,7 +36,7 @@ export type BundleQueryRule = {
36
36
  /**
37
37
  * Per-member metadata stored alongside `bundleProductIds`.
38
38
  * `drawCount` — only meaningful when the member product has
39
- * `listingType === "prize-draw"`. Represents how many draw entries
39
+ * sieveFilter("listingType", SIEVE_OP.EQ, "= "prize-draw""). Represents how many draw entries
40
40
  * the buyer receives for that product when they purchase the bundle
41
41
  * (e.g. drawCount=5 means 5 raffle entries, not 5 copies of the draw).
42
42
  */
@@ -195,7 +195,7 @@ export declare const categoryQueryHelpers: {
195
195
  /** @deprecated Use byCategoryType("brand"). */
196
196
  readonly brands: () => readonly ["isBrand", "==", true];
197
197
  /** SB-UNI B + C + D — discriminator-based listing. */
198
- readonly byCategoryType: (type: import("../types").CategoryType) => readonly ["categoryType", "==", import("..").CategoryType];
198
+ readonly byCategoryType: (type: import("../types").CategoryType) => readonly ["categoryType", "==", import("@mohasinac/appkit").CategoryType];
199
199
  readonly sublistings: () => readonly ["categoryType", "==", "sublisting"];
200
200
  readonly brandPages: () => readonly ["categoryType", "==", "brand"];
201
201
  readonly active: () => readonly ["isActive", "==", true];
@@ -25,7 +25,7 @@ export declare function grantCheckoutConsentViaSms(userId: string, userPhone: st
25
25
  * `verifiedVia: "admin_bypass"` marker prevents bypass-credit grants.
26
26
  *
27
27
  * Security: callers MUST verify the requesting user is an admin AND that
28
- * `siteSettings.featureFlags.adminCheckoutBypass === true` before calling this.
28
+ * sieveFilter("siteSettings.featureFlags.adminCheckoutBypass", SIEVE_OP.EQ, "= true") before calling this.
29
29
  */
30
30
  export declare function grantAdminCheckoutBypass(userId: string, addressId: string, bypassingAdminUid: string): Promise<void>;
31
31
  export { userRepository };
@@ -103,7 +103,7 @@ export async function grantCheckoutConsentViaSms(userId, userPhone, addressId) {
103
103
  * `verifiedVia: "admin_bypass"` marker prevents bypass-credit grants.
104
104
  *
105
105
  * Security: callers MUST verify the requesting user is an admin AND that
106
- * `siteSettings.featureFlags.adminCheckoutBypass === true` before calling this.
106
+ * sieveFilter("siteSettings.featureFlags.adminCheckoutBypass", SIEVE_OP.EQ, "= true") before calling this.
107
107
  */
108
108
  export async function grantAdminCheckoutBypass(userId, addressId, bypassingAdminUid) {
109
109
  const address = await findUserAddress(userId, addressId);
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { FilterFacetSection } from "../../filters/FilterFacetSection";
4
4
  import { AsyncFacetSection } from "../../filters/AsyncFacetSection";
5
5
  import { RangeFilter } from "../../filters/RangeFilter";
6
- import { Div } from "../../../ui";
6
+ import { Div, Label } from "../../../ui";
7
7
  const NEGOTIABLE_OPTIONS = [
8
8
  { value: "true", label: "Negotiable only" },
9
9
  ];
@@ -16,5 +16,5 @@ export function ClassifiedFilters({ table, categoryOptions = [], loadCategoryOpt
16
16
  : [];
17
17
  const selectedNegotiable = table.get("negotiable") ? [table.get("negotiable")] : [];
18
18
  const selectedShipping = table.get("acceptsShipping") ? [table.get("acceptsShipping")] : [];
19
- return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs("div", { className: "border-t border-[var(--appkit-color-border)] pt-4 mt-4", children: [_jsx("label", { className: "block text-sm font-medium text-[var(--appkit-color-text)] mb-2", children: "City / Area" }), _jsx("input", { type: "text", value: table.get("city") || "", onChange: (e) => table.set("city", e.target.value), placeholder: "e.g. Mumbai", className: "w-full rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-[var(--appkit-color-text-faint)] focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]" })] }), _jsx(FilterFacetSection, { title: "Negotiable", options: NEGOTIABLE_OPTIONS, selected: selectedNegotiable, onChange: (vals) => table.set("negotiable", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(FilterFacetSection, { title: "Shipping", options: SHIPPING_OPTIONS, selected: selectedShipping, onChange: (vals) => table.set("acceptsShipping", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(RangeFilter, { title: "Asking Price", minValue: table.get("minPrice"), maxValue: table.get("maxPrice"), onMinChange: (v) => table.set("minPrice", v), onMaxChange: (v) => table.set("maxPrice", v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 500000, step: 100, minPlaceholder: "Min price", maxPlaceholder: "Max price", defaultCollapsed: false })] }));
19
+ return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs(Div, { className: "border-t border-[var(--appkit-color-border)] pt-4 mt-4", children: [_jsx(Label, { className: "block text-sm font-medium text-[var(--appkit-color-text)] mb-2", children: "City / Area" }), _jsx("input", { type: "text", value: table.get("city") || "", onChange: (e) => table.set("city", e.target.value), placeholder: "e.g. Mumbai", className: "w-full rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-[var(--appkit-color-text-faint)] focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]" })] }), _jsx(FilterFacetSection, { title: "Negotiable", options: NEGOTIABLE_OPTIONS, selected: selectedNegotiable, onChange: (vals) => table.set("negotiable", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(FilterFacetSection, { title: "Shipping", options: SHIPPING_OPTIONS, selected: selectedShipping, onChange: (vals) => table.set("acceptsShipping", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(RangeFilter, { title: "Asking Price", minValue: table.get("minPrice"), maxValue: table.get("maxPrice"), onMinChange: (v) => table.set("minPrice", v), onMaxChange: (v) => table.set("maxPrice", v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 500000, step: 100, minPlaceholder: "Min price", maxPlaceholder: "Max price", defaultCollapsed: false })] }));
20
20
  }
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback } from "react";
4
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
5
  import { useProducts } from "../../products/hooks/useProducts";
6
- import { BulkActionBar, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text } from "../../../ui";
6
+ import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text } from "../../../ui";
7
7
  import { usePendingTable } from "../../../react/hooks/usePendingTable";
8
8
  import { useAuthGate } from "../../../react/hooks/useAuthGate";
9
9
  import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
@@ -19,6 +19,12 @@ import { ClassifiedFilters } from "./ClassifiedFilters";
19
19
  import { ACTION_ID } from "../../products/constants/action-defs";
20
20
  import { useToast } from "../../../ui";
21
21
  import { useBottomActions } from "../../layout";
22
+ const __P = {
23
+ p3: "p-3",
24
+ };
25
+ const __O = {
26
+ hidden: "overflow-hidden",
27
+ };
22
28
  const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
23
29
  const SORT_OPTIONS = [
24
30
  { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
@@ -105,7 +111,7 @@ export function ClassifiedIndexListing({ initialData }) {
105
111
  }
106
112
  }
107
113
  useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
108
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search classified listings\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
114
+ return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search classified listings\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
109
115
  commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
110
- setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No classified listings found." })) : (_jsx("div", { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.CLASSIFIED_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ClassifiedFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
116
+ setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No classified listings found." })) : (_jsx(Div, { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.CLASSIFIED_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ClassifiedFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
111
117
  }
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
2
3
  import { productRepository } from "../../../repositories";
3
4
  import { Container, Heading, Main, Section } from "../../../ui";
4
5
  import { AdSlot } from "../../homepage/components/AdSlot";
@@ -16,18 +17,18 @@ function buildClassifiedFilters(params) {
16
17
  const minPrice = sp(params, "minPrice");
17
18
  const maxPrice = sp(params, "maxPrice");
18
19
  if (minPrice)
19
- parts.push(`price>=${minPrice}`);
20
+ parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
20
21
  if (maxPrice)
21
- parts.push(`price<=${maxPrice}`);
22
+ parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
22
23
  const city = sp(params, "city");
23
24
  if (city)
24
- parts.push(`classifiedCity==${city}`);
25
+ parts.push(sieveFilter("classifiedCity", SIEVE_OP.EQ, city));
25
26
  const negotiable = sp(params, "negotiable");
26
27
  if (negotiable === "true")
27
- parts.push(`classifiedNegotiable==true`);
28
+ parts.push(sieveFilter("classifiedNegotiable", SIEVE_OP.EQ, "true"));
28
29
  const acceptsShipping = sp(params, "acceptsShipping");
29
30
  if (acceptsShipping === "true")
30
- parts.push(`classifiedAcceptsShipping==true`);
31
+ parts.push(sieveFilter("classifiedAcceptsShipping", SIEVE_OP.EQ, "true"));
31
32
  return parts.join(",");
32
33
  }
33
34
  export async function ClassifiedListView({ searchParams = {} }) {
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Div, Heading, Text, TextLink } from "../../../ui";
3
3
  import { LAYOUT } from "../../../tokens";
4
+ const CLS_PLACEHOLDER = "w-full bg-gradient-to-br from-indigo-100 to-purple-100 dark:from-indigo-900/30 dark:to-purple-900/30";
4
5
  export function CollectionCard({ collection, href }) {
5
- return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`, style: { backgroundImage: `url(${collection.image})` } })) : (_jsx(Div, { className: `${LAYOUT.cardHeight.md} w-full bg-gradient-to-br from-indigo-100 to-purple-100 dark:from-indigo-900/30 dark:to-purple-900/30` })), _jsxs(Div, { surface: "default", padding: "sm", children: [_jsx(Heading, { level: 3, className: "font-semibold text-gray-900 dark:text-zinc-100", children: collection.title }), collection.subtitle && (_jsx(Text, { className: "mt-1 text-sm text-gray-500 dark:text-zinc-400", children: collection.subtitle })), collection.productCount !== undefined && (_jsxs(Text, { className: "mt-2 text-xs text-gray-400 dark:text-zinc-500", children: [collection.productCount, " ", collection.productCount === 1 ? "item" : "items"] }))] })] }));
6
+ return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`, style: { backgroundImage: `url(${collection.image})` } })) : (_jsx(Div, { className: `${LAYOUT.cardHeight.md} ${CLS_PLACEHOLDER}` })), _jsxs(Div, { surface: "default", padding: "sm", children: [_jsx(Heading, { level: 3, className: "font-semibold text-gray-900 dark:text-zinc-100", children: collection.title }), collection.subtitle && (_jsx(Text, { className: "mt-1 text-sm text-gray-500 dark:text-zinc-400", children: collection.subtitle })), collection.productCount !== undefined && (_jsxs(Text, { className: "mt-2 text-xs text-gray-400 dark:text-zinc-500", children: [collection.productCount, " ", collection.productCount === 1 ? "item" : "items"] }))] })] }));
6
7
  }
7
8
  export function CollectionGrid({ collections, getHref }) {
8
9
  return (_jsx(Div, { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: collections.map((c) => (_jsx(CollectionCard, { collection: c, href: getHref(c.slug) }, c.slug))) }));
@@ -2,6 +2,8 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback } from "react";
4
4
  import { Button, Div, Heading, Span, Text, Textarea } from "../../../ui";
5
+ const CLS_FIELD_ERROR = "text-red-500";
6
+ const CLS_ERROR_BANNER = "rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 px-4 py-3 text-sm text-red-700 dark:text-red-300";
5
7
  const INITIAL_FORM = {
6
8
  name: "",
7
9
  email: "",
@@ -51,8 +53,8 @@ export function ContactForm({ onSubmit, labels = {}, className = "", }) {
51
53
  if (submitted) {
52
54
  return (_jsxs(Div, { className: `text-center py-12 ${className}`, children: [_jsx(Div, { className: "text-5xl mb-4", children: "\u2705" }), _jsx(Heading, { level: 2, className: "mb-2", children: labels.successTitle ?? "Message Sent!" }), _jsx(Text, { variant: "secondary", className: "mb-6", children: labels.successDescription ?? "We'll get back to you shortly." }), _jsx(Button, { type: "button", variant: "outline", onClick: () => setSubmitted(false), children: labels.sendAnotherButton ?? "Send another message" })] }));
53
55
  }
54
- const field = (id, label, placeholder, multiline) => (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: label }), multiline ? (_jsx(Textarea, { id: id, value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, rows: 5, className: "w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm outline-none focus:ring-2 ring-primary/20 transition" })) : (_jsx("input", { id: id, type: id === "email" ? "email" : "text", value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, className: "h-10 w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition" })), errors[id] && _jsx(Span, { className: "text-xs text-red-500", children: errors[id] })] }));
55
- return (_jsxs("form", { onSubmit: handleSubmit, noValidate: true, className: `space-y-4 ${className}`, children: [_jsx(Heading, { level: 2, className: "mb-6", children: labels.title ?? "Send us a message" }), submitError && (_jsx(Div, { className: "rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 px-4 py-3 text-sm text-red-700 dark:text-red-300", children: submitError })), field("name", labels.nameLabel ?? "Your Name", labels.namePlaceholder ?? "Enter your name"), field("email", labels.emailLabel ?? "Email", labels.emailPlaceholder ?? "your@email.com"), field("subject", labels.subjectLabel ?? "Subject", labels.subjectPlaceholder ?? "How can we help?"), field("message", labels.messageLabel ?? "Message", labels.messagePlaceholder ?? "Tell us more…", true), _jsx(Button, { type: "submit", variant: "primary", disabled: isSubmitting, className: "w-full sm:w-auto", children: isSubmitting
56
+ const field = (id, label, placeholder, multiline) => (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: label }), multiline ? (_jsx(Textarea, { id: id, value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, rows: 5, className: "w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm outline-none focus:ring-2 ring-primary/20 transition" })) : (_jsx("input", { id: id, type: id === "email" ? "email" : "text", value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, className: "h-10 w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition" })), errors[id] && _jsx(Span, { size: "xs", className: CLS_FIELD_ERROR, children: errors[id] })] }));
57
+ return (_jsxs("form", { onSubmit: handleSubmit, noValidate: true, className: `space-y-4 ${className}`, children: [_jsx(Heading, { level: 2, className: "mb-6", children: labels.title ?? "Send us a message" }), submitError && (_jsx(Div, { className: CLS_ERROR_BANNER, children: submitError })), field("name", labels.nameLabel ?? "Your Name", labels.namePlaceholder ?? "Enter your name"), field("email", labels.emailLabel ?? "Email", labels.emailPlaceholder ?? "your@email.com"), field("subject", labels.subjectLabel ?? "Subject", labels.subjectPlaceholder ?? "How can we help?"), field("message", labels.messageLabel ?? "Message", labels.messagePlaceholder ?? "Tell us more…", true), _jsx(Button, { type: "submit", variant: "primary", disabled: isSubmitting, className: "w-full sm:w-auto", children: isSubmitting
56
58
  ? (labels.submittingButton ?? "Sending…")
57
59
  : (labels.submitButton ?? "Send Message") })] }));
58
60
  }
@@ -1,5 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Div, Heading, Span, Stack, Text } from "../../../ui";
3
+ const __P = {
4
+ p4: "p-4",
5
+ };
3
6
  export function ContactInfoSidebar({ infoItems, labels = {}, renderActions, }) {
4
- return (_jsxs(Stack, { as: "aside", gap: "lg", children: [_jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-4", children: labels.title ?? "Contact Information" }), _jsx(Stack, { gap: "md", children: infoItems.map((item) => (_jsxs(Div, { className: "flex items-start gap-3", children: [_jsx(Span, { className: "text-xl flex-shrink-0 mt-0.5", children: item.icon }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wide mb-0.5", children: item.label }), item.href ? (_jsx("a", { href: item.href, className: "text-sm text-primary-800 dark:text-primary-300 hover:underline", children: item.value })) : (_jsx(Text, { className: "text-sm", children: item.value }))] })] }, item.label))) })] }), (labels.businessHoursLabel || labels.responseTimeLabel) && (_jsxs(Stack, { gap: "sm", className: "rounded-xl border border-neutral-200 dark:border-slate-700 bg-neutral-50 dark:bg-slate-800/60 p-4", children: [labels.businessHoursLabel && labels.businessHoursValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.businessHoursLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.businessHoursValue })] })), labels.responseTimeLabel && labels.responseTimeValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.responseTimeLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.responseTimeValue })] }))] })), renderActions?.()] }));
7
+ return (_jsxs(Stack, { as: "aside", gap: "lg", children: [_jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-4", children: labels.title ?? "Contact Information" }), _jsx(Stack, { gap: "md", children: infoItems.map((item) => (_jsxs(Div, { className: "flex items-start gap-3", children: [_jsx(Span, { size: "xl", className: "flex-shrink-0 mt-0.5", children: item.icon }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wide mb-0.5", children: item.label }), item.href ? (_jsx("a", { href: item.href, className: "text-sm text-primary-800 dark:text-primary-300 hover:underline", children: item.value })) : (_jsx(Text, { className: "text-sm", children: item.value }))] })] }, item.label))) })] }), (labels.businessHoursLabel || labels.responseTimeLabel) && (_jsxs(Stack, { gap: "sm", className: `rounded-xl border border-neutral-200 dark:border-slate-700 bg-neutral-50 dark:bg-slate-800/60 ${__P.p4}`, children: [labels.businessHoursLabel && labels.businessHoursValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.businessHoursLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.businessHoursValue })] })), labels.responseTimeLabel && labels.responseTimeValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.responseTimeLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.responseTimeValue })] }))] })), renderActions?.()] }));
5
8
  }
@@ -6,21 +6,29 @@ import { Alert, Button, Div, Heading, Input, Span, StackedViewShell, Text, } fro
6
6
  import { apiClient } from "../../../http";
7
7
  import { useCopilotChat } from "../hooks/useCopilotChat";
8
8
  import { THEME_CONSTANTS } from "../../../tokens";
9
+ const __P = {
10
+ p3: "p-3",
11
+ p4: "p-4",
12
+ };
13
+ const __O = {
14
+ yAuto: "overflow-y-auto",
15
+ };
9
16
  const LBL_CONVERSATION_ID = "Conversation ID";
17
+ const CLS_ERROR_TEXT = "text-center text-sm text-red-500";
10
18
  function MessageBubble({ msg }) {
11
19
  const isUser = msg.role === "user";
12
20
  return (_jsx(Div, { className: `flex ${isUser ? "justify-end" : "justify-start"}`, children: _jsxs(Div, { className: `max-w-[80%] rounded-2xl px-4 py-2.5 text-sm ${isUser
13
21
  ? "bg-primary text-white rounded-tr-sm"
14
- : "bg-neutral-100 dark:bg-slate-700 text-neutral-900 dark:text-neutral-100 rounded-tl-sm"}`, children: [_jsx(Text, { className: "whitespace-pre-wrap text-sm leading-relaxed", children: msg.content }), msg.durationMs ? (_jsxs(Span, { className: "mt-1 block text-xs opacity-60", children: [(msg.durationMs / 1000).toFixed(1), "s"] })) : null] }) }));
22
+ : "bg-neutral-100 dark:bg-slate-700 text-neutral-900 dark:text-neutral-100 rounded-tl-sm"}`, children: [_jsx(Text, { className: "whitespace-pre-wrap text-sm leading-relaxed", children: msg.content }), msg.durationMs ? (_jsxs(Span, { size: "xs", className: "mt-1 block opacity-60", children: [(msg.durationMs / 1000).toFixed(1), "s"] })) : null] }) }));
15
23
  }
16
24
  function renderCopilotChatPanel(props) {
17
25
  const { messages, conversationId, isLoading, error, input, setInput, labels, messagesEndRef, handleSubmit } = props;
18
- return (_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: "border-b border-neutral-200 dark:border-slate-700 p-3", children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels?.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels?.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels?.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => _jsx(MessageBubble, { msg: msg }, msg.id)), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { className: "text-sm opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? _jsx(Text, { className: "text-center text-sm text-red-500", children: labels?.errorLabel ?? "An error occurred. Please try again." }) : null, _jsx("div", { ref: messagesEndRef })] }), _jsx(Div, { className: "border-t border-neutral-200 dark:border-slate-700 p-3", children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), placeholder: labels?.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels?.sendingButton ?? "Sending..." : labels?.sendButton ?? "Send" })] }) })] }));
26
+ return (_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: `border-b border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels?.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: `flex-1 ${__O.yAuto} ${__P.p4} space-y-4`, children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels?.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels?.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => _jsx(MessageBubble, { msg: msg }, msg.id)), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? _jsx(Text, { className: CLS_ERROR_TEXT, children: labels?.errorLabel ?? "An error occurred. Please try again." }) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { className: `border-t border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), placeholder: labels?.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels?.sendingButton ?? "Sending..." : labels?.sendButton ?? "Send" })] }) })] }));
19
27
  }
20
28
  function renderCopilotHistoryPanel(props) {
21
29
  const { historyQuery, conversationInput, setConversationInput, loadConversation, labels } = props;
22
30
  return (_jsxs(Div, { surface: "card", padding: "sm", className: "space-y-3", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold", children: labels?.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (e) => { e.preventDefault(); if (!conversationInput.trim())
23
- return; loadConversation(conversationInput.trim()); }, children: [_jsx(Input, { label: labels?.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (e) => setConversationInput(e.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels?.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: "max-h-72 overflow-y-auto space-y-2", children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] }));
31
+ return; loadConversation(conversationInput.trim()); }, children: [_jsx(Input, { label: labels?.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (e) => setConversationInput(e.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels?.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: `max-h-72 ${__O.yAuto} space-y-2`, children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] }));
24
32
  }
25
33
  export function AdminCopilotView({ endpoint, historyEndpoint = "/api/copilot/history", renderHeader, labels = {}, className = "", }) {
26
34
  const [input, setInput] = useState("");
@@ -44,11 +52,11 @@ export function AdminCopilotView({ endpoint, historyEndpoint = "/api/copilot/his
44
52
  };
45
53
  return (_jsx(StackedViewShell, { portal: "admin", title: labels.title ?? "AI Copilot", className: className, sections: [
46
54
  renderHeader ? (renderHeader(startNewConversation)) : (_jsxs(Div, { className: "flex items-center justify-between gap-3", children: [_jsx(Heading, { level: 2, children: labels.title ?? "AI Copilot" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: startNewConversation, children: labels.newConversation ?? "New Conversation" })] })),
47
- _jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-[2fr,1fr] gap-4", children: [_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: "border-b border-neutral-200 dark:border-slate-700 p-3", children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => (_jsx(MessageBubble, { msg: msg }, msg.id))), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { className: "text-sm opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? (_jsx(Text, { className: "text-center text-sm text-red-500", children: labels.errorLabel ?? "An error occurred. Please try again." })) : null, _jsx("div", { ref: messagesEndRef })] }), _jsx(Div, { className: "border-t border-neutral-200 dark:border-slate-700 p-3", children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (event) => setInput(event.target.value), placeholder: labels.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels.sendingButton ?? "Sending..." : labels.sendButton ?? "Send" })] }) })] }), _jsxs(Div, { surface: "card", padding: "sm", className: "space-y-3", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold", children: labels.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (event) => {
55
+ _jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-[2fr,1fr] gap-4", children: [_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: `border-b border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: `flex-1 ${__O.yAuto} ${__P.p4} space-y-4`, children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => (_jsx(MessageBubble, { msg: msg }, msg.id))), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? (_jsx(Text, { className: CLS_ERROR_TEXT, children: labels.errorLabel ?? "An error occurred. Please try again." })) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { className: `border-t border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (event) => setInput(event.target.value), placeholder: labels.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels.sendingButton ?? "Sending..." : labels.sendButton ?? "Send" })] }) })] }), _jsxs(Div, { surface: "card", padding: "sm", className: "space-y-3", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold", children: labels.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (event) => {
48
56
  event.preventDefault();
49
57
  if (!conversationInput.trim())
50
58
  return;
51
59
  loadConversation(conversationInput.trim());
52
- }, children: [_jsx(Input, { label: labels.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (event) => setConversationInput(event.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: "max-h-72 overflow-y-auto space-y-2", children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] })] }),
60
+ }, children: [_jsx(Input, { label: labels.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (event) => setConversationInput(event.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: `max-h-72 ${__O.yAuto} space-y-2`, children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] })] }),
53
61
  ] }));
54
62
  }
@@ -3,7 +3,7 @@ import type { IRepository } from "../../../contracts";
3
3
  * Built-in job: Close live auctions whose `endTime` has passed.
4
4
  *
5
5
  * Run interval: every 5 minutes (recommended).
6
- * Requires an `IRepository<AuctionDocument>` injected at registration time.
6
+ * Requires an sieveFilter("IRepository", SIEVE_OP.LT, "AuctionDocument>") injected at registration time.
7
7
  *
8
8
  * @example
9
9
  * ```ts
@@ -23,5 +23,5 @@ interface AuctionDocument {
23
23
  highestBidAmount?: number;
24
24
  closedAt?: string;
25
25
  }
26
- export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("..").CronJobDefinition;
26
+ export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("@mohasinac/appkit").CronJobDefinition;
27
27
  export {};
@@ -1,3 +1,4 @@
1
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
1
2
  import { createCronJob } from "../registry";
2
3
  export function createAuctionExpiryJob(auctionRepo) {
3
4
  return createCronJob({
@@ -9,7 +10,7 @@ export function createAuctionExpiryJob(auctionRepo) {
9
10
  timeoutSeconds: 60,
10
11
  }, async (ctx) => {
11
12
  const result = await auctionRepo.findAll({
12
- filters: `status==live,endTime<=${ctx.scheduleTime}`,
13
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "live"), sieveFilter("endTime", SIEVE_OP.LTE, ctx.scheduleTime)),
13
14
  perPage: 500,
14
15
  });
15
16
  let processed = 0;
@@ -10,5 +10,5 @@ interface PreOrderDocument {
10
10
  status: string;
11
11
  expectedShippingDate?: string;
12
12
  }
13
- export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("..").CronJobDefinition;
13
+ export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("@mohasinac/appkit").CronJobDefinition;
14
14
  export {};
@@ -1,3 +1,4 @@
1
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
1
2
  import { createCronJob } from "../registry";
2
3
  export function createPreOrderReminderJob(preOrderRepo) {
3
4
  const sevenDaysFromNow = () => {
@@ -15,7 +16,7 @@ export function createPreOrderReminderJob(preOrderRepo) {
15
16
  }, async () => {
16
17
  const cutoff = sevenDaysFromNow();
17
18
  const result = await preOrderRepo.findAll({
18
- filters: `status==confirmed,expectedShippingDate<=${cutoff}`,
19
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "confirmed"), sieveFilter("expectedShippingDate", SIEVE_OP.LTE, cutoff)),
19
20
  perPage: 500,
20
21
  });
21
22
  let processed = 0;
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback } from "react";
4
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
5
  import { useProducts } from "../../products/hooks/useProducts";
6
- import { BulkActionBar, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
6
+ import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
7
7
  import { usePendingTable } from "../../../react/hooks/usePendingTable";
8
8
  import { useAuthGate } from "../../../react/hooks/useAuthGate";
9
9
  import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
@@ -18,6 +18,12 @@ import { InteractiveProductCard } from "../../products/components/InteractivePro
18
18
  import { DigitalCodeFilters } from "./DigitalCodeFilters";
19
19
  import { ACTION_ID } from "../../products/constants/action-defs";
20
20
  import { useBottomActions } from "../../layout";
21
+ const __P = {
22
+ p3: "p-3",
23
+ };
24
+ const __O = {
25
+ hidden: "overflow-hidden",
26
+ };
21
27
  const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
22
28
  const SORT_OPTIONS = [
23
29
  { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
@@ -102,7 +108,7 @@ export function DigitalCodesIndexListing({ initialData }) {
102
108
  }
103
109
  }
104
110
  useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
105
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search digital codes\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
111
+ return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search digital codes\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
106
112
  commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
107
- setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No digital code listings found." })) : (_jsx("div", { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.DIGITAL_CODE_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(DigitalCodeFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
113
+ setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No digital code listings found." })) : (_jsx(Div, { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.DIGITAL_CODE_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(DigitalCodeFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
108
114
  }
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
2
3
  import { productRepository } from "../../../repositories";
3
4
  import { Container, Heading, Main, Section } from "../../../ui";
4
5
  import { AdSlot } from "../../homepage/components/AdSlot";
@@ -16,12 +17,12 @@ function buildDigitalCodeFilters(params) {
16
17
  const minPrice = sp(params, "minPrice");
17
18
  const maxPrice = sp(params, "maxPrice");
18
19
  if (minPrice)
19
- parts.push(`price>=${minPrice}`);
20
+ parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
20
21
  if (maxPrice)
21
- parts.push(`price<=${maxPrice}`);
22
+ parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
22
23
  const deliveryMethod = sp(params, "deliveryMethod");
23
24
  if (deliveryMethod)
24
- parts.push(`digitalCodeDelivery==${deliveryMethod}`);
25
+ parts.push(sieveFilter("digitalCodeDelivery", SIEVE_OP.EQ, deliveryMethod));
25
26
  return parts.join(",");
26
27
  }
27
28
  export async function DigitalCodesListView({ searchParams = {} }) {
@@ -4,6 +4,8 @@
4
4
  * Business logic for event CRUD, status changes, entries, and public access.
5
5
  * Auth, rate-limiting, and input validation are handled by the calling server action.
6
6
  */
7
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
8
+ import { sortBy } from "@mohasinac/appkit";
7
9
  import { serverLogger } from "../../../monitoring";
8
10
  import { eventRepository } from "../repository/events.repository";
9
11
  import { eventEntryRepository } from "../repository/event-entry.repository";
@@ -108,13 +110,13 @@ export async function listPublicEvents(params) {
108
110
  if (!filters) {
109
111
  const parts = [];
110
112
  if (sp.has("status"))
111
- parts.push(`status==${sp.get("status")}`);
113
+ parts.push(sieveFilter("status", SIEVE_OP.EQ, sp.get("status")));
112
114
  if (sp.has("type"))
113
- parts.push(`type==${sp.get("type")}`);
115
+ parts.push(sieveFilter("type", SIEVE_OP.EQ, sp.get("type")));
114
116
  if (sp.has("types")) {
115
117
  const types = sp.get("types").split(",");
116
118
  if (types.length === 1)
117
- parts.push(`type==${types[0]}`);
119
+ parts.push(sieveFilter("type", SIEVE_OP.EQ, types[0]));
118
120
  }
119
121
  if (parts.length)
120
122
  filters = parts.join(",");
@@ -157,7 +159,7 @@ export async function adminGetEventById(id) {
157
159
  }
158
160
  export async function adminGetEventEntries(eventId, params) {
159
161
  const result = await eventEntryRepository.listForEvent(eventId, {
160
- sorts: "-createdAt",
162
+ sorts: sortBy("createdAt", "DESC"),
161
163
  page: params?.page ?? 1,
162
164
  pageSize: params?.pageSize ?? 50,
163
165
  });