@mohasinac/appkit 4.13.1 → 4.15.0

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 (493) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +14 -5
  2. package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +3 -0
  3. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +6 -0
  4. package/dist/_internal/client/features/lottery/LotteryDetailView.d.ts +8 -0
  5. package/dist/_internal/client/features/lottery/LotteryDetailView.js +4 -1
  6. package/dist/_internal/client/features/lottery/LotteryListView.d.ts +7 -0
  7. package/dist/_internal/client/features/lottery/LotteryListView.js +1 -1
  8. package/dist/_internal/client/features/lottery/PrizeDrawLotteryDetailView.js +4 -1
  9. package/dist/_internal/client/features/lottery/slot-collage-items.d.ts +15 -0
  10. package/dist/_internal/client/features/lottery/slot-collage-items.js +13 -0
  11. package/dist/_internal/server/features/auctions/actions.js +8 -2
  12. package/dist/_internal/server/features/bundles/data.d.ts +16 -0
  13. package/dist/_internal/server/features/bundles/data.js +26 -0
  14. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  15. package/dist/_internal/server/features/bundles/index.js +1 -1
  16. package/dist/_internal/server/features/cart/service.d.ts +3 -3
  17. package/dist/_internal/server/features/checkout/actions.js +25 -0
  18. package/dist/_internal/server/features/checkout/locked-lines.d.ts +38 -0
  19. package/dist/_internal/server/features/checkout/locked-lines.js +171 -0
  20. package/dist/_internal/server/features/checkout/source-context.d.ts +5 -0
  21. package/dist/_internal/server/features/checkout/source-context.js +157 -0
  22. package/dist/_internal/server/features/homepage/index.d.ts +0 -1
  23. package/dist/_internal/server/features/homepage/index.js +7 -1
  24. package/dist/_internal/server/features/lottery/adapters.js +4 -0
  25. package/dist/_internal/server/features/offers/adapters.d.ts +103 -0
  26. package/dist/_internal/server/features/offers/adapters.js +88 -0
  27. package/dist/_internal/server/features/offers/index.d.ts +2 -0
  28. package/dist/_internal/server/features/offers/index.js +1 -0
  29. package/dist/_internal/server/features/orders/adapters.js +24 -0
  30. package/dist/_internal/server/features/products/data.js +15 -37
  31. package/dist/_internal/server/features/products/index.d.ts +1 -1
  32. package/dist/_internal/server/features/products/index.js +1 -1
  33. package/dist/_internal/server/features/products/list-public.d.ts +46 -20
  34. package/dist/_internal/server/features/products/list-public.js +266 -90
  35. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +44 -0
  36. package/dist/_internal/server/features/products/listing-tab-counts.js +97 -0
  37. package/dist/_internal/server/features/site-settings/adapters.d.ts +51 -0
  38. package/dist/_internal/server/features/site-settings/adapters.js +75 -0
  39. package/dist/_internal/server/features/site-settings/index.d.ts +1 -0
  40. package/dist/_internal/server/features/site-settings/index.js +1 -0
  41. package/dist/_internal/server/features/stores/adapters.d.ts +56 -0
  42. package/dist/_internal/server/features/stores/adapters.js +91 -0
  43. package/dist/_internal/server/features/stores/index.d.ts +1 -0
  44. package/dist/_internal/server/features/stores/index.js +1 -0
  45. package/dist/_internal/server/jobs/core/auctionSettlement.js +56 -2
  46. package/dist/_internal/server/jobs/core/offerExpiry.js +55 -19
  47. package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +5 -0
  48. package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +33 -1
  49. package/dist/_internal/server/jobs/handlers/messages.d.ts +7 -0
  50. package/dist/_internal/server/jobs/handlers/messages.js +10 -0
  51. package/dist/_internal/shared/actions/action-registry.js +17 -1
  52. package/dist/_internal/shared/checkout/lanes.d.ts +25 -0
  53. package/dist/_internal/shared/checkout/lanes.js +26 -0
  54. package/dist/_internal/shared/features/auctions/config.d.ts +27 -0
  55. package/dist/_internal/shared/features/auctions/config.js +27 -0
  56. package/dist/_internal/shared/features/auctions/schema.d.ts +14 -2
  57. package/dist/_internal/shared/features/auctions/schema.js +13 -1
  58. package/dist/_internal/shared/features/blog/schema.d.ts +2 -2
  59. package/dist/_internal/shared/features/cart/schema.d.ts +20 -15
  60. package/dist/_internal/shared/features/cart/schema.js +15 -0
  61. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +32 -32
  62. package/dist/_internal/shared/features/emi/schedule.d.ts +24 -3
  63. package/dist/_internal/shared/features/emi/schedule.js +20 -5
  64. package/dist/_internal/shared/features/events/schema.d.ts +2 -2
  65. package/dist/_internal/shared/features/homepage/section-gate.d.ts +14 -0
  66. package/dist/_internal/shared/features/homepage/section-gate.js +51 -0
  67. package/dist/_internal/shared/features/offers/config.d.ts +30 -0
  68. package/dist/_internal/shared/features/offers/config.js +59 -0
  69. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  70. package/dist/_internal/shared/features/products/schema.d.ts +30 -30
  71. package/dist/_internal/shared/features/products/to-product-item.js +6 -0
  72. package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
  73. package/dist/_internal/shared/features/site-settings/fees.d.ts +60 -0
  74. package/dist/_internal/shared/features/site-settings/fees.js +39 -0
  75. package/dist/_internal/shared/features/site-settings/types.d.ts +40 -0
  76. package/dist/_internal/shared/features/site-settings/types.js +1 -0
  77. package/dist/_internal/shared/history/history.d.ts +88 -0
  78. package/dist/_internal/shared/history/history.js +198 -0
  79. package/dist/_internal/shared/history/index.d.ts +4 -0
  80. package/dist/_internal/shared/history/index.js +2 -0
  81. package/dist/_internal/shared/history/types.d.ts +61 -0
  82. package/dist/_internal/shared/history/types.js +6 -0
  83. package/dist/_internal/shared/listing-types/_registry.d.ts +54 -1
  84. package/dist/_internal/shared/listing-types/_registry.js +67 -0
  85. package/dist/_internal/shared/listing-types/art/config.d.ts +3 -0
  86. package/dist/_internal/shared/listing-types/art/config.js +5 -0
  87. package/dist/_internal/shared/listing-types/auction/config.d.ts +13 -0
  88. package/dist/_internal/shared/listing-types/auction/config.js +21 -0
  89. package/dist/_internal/shared/listing-types/availability.d.ts +79 -0
  90. package/dist/_internal/shared/listing-types/availability.js +104 -0
  91. package/dist/_internal/shared/listing-types/capabilities.d.ts +15 -0
  92. package/dist/_internal/shared/listing-types/capabilities.js +12 -0
  93. package/dist/_internal/shared/listing-types/classified/config.d.ts +3 -0
  94. package/dist/_internal/shared/listing-types/classified/config.js +5 -0
  95. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +11 -0
  96. package/dist/_internal/shared/listing-types/digital-code/config.js +22 -2
  97. package/dist/_internal/shared/listing-types/live/config.d.ts +3 -0
  98. package/dist/_internal/shared/listing-types/live/config.js +5 -0
  99. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +3 -0
  100. package/dist/_internal/shared/listing-types/pre-order/config.js +19 -0
  101. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +11 -0
  102. package/dist/_internal/shared/listing-types/prize-draw/config.js +15 -0
  103. package/dist/_internal/shared/listing-types/standard/config.d.ts +3 -0
  104. package/dist/_internal/shared/listing-types/standard/config.js +5 -0
  105. package/dist/_internal/shared/listing-types/stickers/config.d.ts +3 -0
  106. package/dist/_internal/shared/listing-types/stickers/config.js +5 -0
  107. package/dist/client.d.ts +20 -7
  108. package/dist/client.js +22 -4
  109. package/dist/constants/api-endpoints.d.ts +6 -0
  110. package/dist/constants/api-endpoints.js +2 -0
  111. package/dist/constants/field-names.d.ts +57 -8
  112. package/dist/constants/field-names.js +101 -8
  113. package/dist/constants/table-keys.d.ts +17 -0
  114. package/dist/constants/table-keys.js +17 -0
  115. package/dist/errors/error-codes.d.ts +13 -1
  116. package/dist/errors/error-codes.js +13 -1
  117. package/dist/errors/error-display-map.js +12 -3
  118. package/dist/errors/messages.d.ts +10 -2
  119. package/dist/errors/messages.js +10 -2
  120. package/dist/features/about/components/AboutView.d.ts +3 -0
  121. package/dist/features/about/components/AboutView.js +3 -2
  122. package/dist/features/about/components/PolicyPageView.d.ts +2 -1
  123. package/dist/features/about/components/PolicyPageView.js +61 -23
  124. package/dist/features/about/components/PublicProfileView.js +5 -0
  125. package/dist/features/about/schemas/firestore.d.ts +3 -0
  126. package/dist/features/account/components/UserBidsView.js +12 -4
  127. package/dist/features/account/components/UserOrdersView.js +7 -0
  128. package/dist/features/account/components/UserReturnsView.d.ts +3 -0
  129. package/dist/features/account/components/UserReturnsView.js +17 -1
  130. package/dist/features/account/components/index.d.ts +0 -2
  131. package/dist/features/account/components/index.js +0 -1
  132. package/dist/features/account/schemas/index.d.ts +2 -2
  133. package/dist/features/account/types/index.d.ts +21 -2
  134. package/dist/features/addresses/schemas/index.d.ts +4 -4
  135. package/dist/features/admin/components/AdminArtView.js +8 -3
  136. package/dist/features/admin/components/AdminAuditLogView.js +1 -0
  137. package/dist/features/admin/components/AdminBidsView.js +15 -2
  138. package/dist/features/admin/components/AdminBlogEditorView.js +65 -33
  139. package/dist/features/admin/components/AdminClassifiedView.js +8 -3
  140. package/dist/features/admin/components/AdminDigitalCodesView.js +8 -3
  141. package/dist/features/admin/components/AdminFeatureEditorView.js +35 -6
  142. package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -0
  143. package/dist/features/admin/components/AdminLiveView.js +8 -3
  144. package/dist/features/admin/components/AdminNavEditorView.js +15 -5
  145. package/dist/features/admin/components/AdminNewsletterView.js +18 -2
  146. package/dist/features/admin/components/AdminOffersView.d.ts +4 -0
  147. package/dist/features/admin/components/AdminOffersView.js +230 -0
  148. package/dist/features/admin/components/AdminOrdersView.js +10 -1
  149. package/dist/features/admin/components/AdminPaymentMethodsView.js +24 -4
  150. package/dist/features/admin/components/AdminPrizeDrawsView.js +5 -0
  151. package/dist/features/admin/components/AdminProductsView.js +16 -29
  152. package/dist/features/admin/components/AdminScammerEditorView.d.ts +2 -1
  153. package/dist/features/admin/components/AdminScammerEditorView.js +3 -13
  154. package/dist/features/admin/components/AdminScammersView.js +3 -8
  155. package/dist/features/admin/components/AdminSectionsView.js +32 -23
  156. package/dist/features/admin/components/AdminSessionsView.js +17 -2
  157. package/dist/features/admin/components/AdminSiteSettingsView.js +31 -13
  158. package/dist/features/admin/components/AdminSiteView.js +6 -2
  159. package/dist/features/admin/components/AdminStickersView.js +8 -3
  160. package/dist/features/admin/components/ViewAuditLogEntryModal.js +1 -0
  161. package/dist/features/admin/components/index.d.ts +2 -0
  162. package/dist/features/admin/components/index.js +1 -0
  163. package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -2
  164. package/dist/features/admin/components/sections/adminSectionsTypes.js +45 -27
  165. package/dist/features/admin/constants/filter-tabs.d.ts +89 -0
  166. package/dist/features/admin/constants/filter-tabs.js +56 -0
  167. package/dist/features/admin/schemas/firestore.d.ts +122 -3
  168. package/dist/features/admin/schemas/firestore.js +1 -0
  169. package/dist/features/admin/schemas/homepage-section-form.d.ts +22 -0
  170. package/dist/features/admin/schemas/homepage-section-form.js +68 -0
  171. package/dist/features/admin/schemas/nav-item-form.d.ts +74 -0
  172. package/dist/features/admin/schemas/nav-item-form.js +72 -0
  173. package/dist/features/auctions/actions/bid-actions.d.ts +20 -5
  174. package/dist/features/auctions/actions/bid-actions.js +93 -20
  175. package/dist/features/auctions/components/AuctionBidsTable.d.ts +10 -1
  176. package/dist/features/auctions/components/AuctionBidsTable.js +22 -4
  177. package/dist/features/auctions/components/AuctionDetailPageView.js +11 -6
  178. package/dist/features/auctions/components/AuctionsListView.js +5 -6
  179. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +7 -0
  180. package/dist/features/auctions/components/MarketplaceAuctionCard.js +19 -2
  181. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -2
  182. package/dist/features/auctions/components/PlaceBidFormClient.js +8 -4
  183. package/dist/features/auctions/components/bid-detail-fields.d.ts +29 -0
  184. package/dist/features/auctions/components/bid-detail-fields.js +103 -0
  185. package/dist/features/auctions/repository/bid.repository.d.ts +13 -0
  186. package/dist/features/auctions/repository/bid.repository.js +23 -0
  187. package/dist/features/auctions/schemas/firestore.d.ts +17 -0
  188. package/dist/features/auctions/schemas/index.d.ts +12 -12
  189. package/dist/features/audit-log/schemas/firestore.d.ts +14 -0
  190. package/dist/features/audit-log/schemas/firestore.js +7 -0
  191. package/dist/features/auth/permissions/constants.d.ts +1 -1
  192. package/dist/features/auth/permissions/constants.js +10 -1
  193. package/dist/features/blog/actions/blog-actions.d.ts +7 -7
  194. package/dist/features/blog/schemas/blog-form.d.ts +80 -0
  195. package/dist/features/blog/schemas/blog-form.js +100 -0
  196. package/dist/features/blog/schemas/index.d.ts +6 -6
  197. package/dist/features/cart/repository/cart.repository.js +1 -0
  198. package/dist/features/cart/schemas/firestore.d.ts +15 -0
  199. package/dist/features/catalogue/schemas/validation.d.ts +4 -4
  200. package/dist/features/categories/components/BrandDetailPageView.js +23 -40
  201. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -7
  202. package/dist/features/categories/components/BrandDetailTabs.js +8 -12
  203. package/dist/features/categories/components/BundleCollage.js +1 -1
  204. package/dist/features/categories/components/CategoryDetailPageView.js +53 -57
  205. package/dist/features/categories/components/CategoryDetailTabs.d.ts +10 -8
  206. package/dist/features/categories/components/CategoryDetailTabs.js +11 -16
  207. package/dist/features/categories/components/CategoryProductsListing.js +11 -1
  208. package/dist/features/categories/components/ConcernCard.js +7 -1
  209. package/dist/features/categories/schemas/firestore.d.ts +13 -0
  210. package/dist/features/categories/schemas/index.d.ts +26 -26
  211. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +16 -1
  212. package/dist/features/classified/components/ClassifiedDetailPageView.js +23 -3
  213. package/dist/features/events/components/AdminEventEditorView.js +32 -54
  214. package/dist/features/events/components/AdminEventEntriesView.js +22 -3
  215. package/dist/features/events/components/AdminEventsView.js +15 -11
  216. package/dist/features/events/components/EventFilters.d.ts +9 -1
  217. package/dist/features/events/components/EventFilters.js +45 -21
  218. package/dist/features/events/components/EventsIndexListing.d.ts +6 -1
  219. package/dist/features/events/components/EventsIndexListing.js +2 -2
  220. package/dist/features/events/components/EventsListPageView.js +13 -4
  221. package/dist/features/events/repository/events.repository.d.ts +17 -0
  222. package/dist/features/events/repository/events.repository.js +27 -0
  223. package/dist/features/events/schemas/event-form.d.ts +113 -0
  224. package/dist/features/events/schemas/event-form.js +82 -0
  225. package/dist/features/events/schemas/firestore.d.ts +12 -0
  226. package/dist/features/events/schemas/firestore.js +12 -0
  227. package/dist/features/events/schemas/index.d.ts +50 -50
  228. package/dist/features/events/types/index.d.ts +11 -0
  229. package/dist/features/events/types/index.js +57 -1
  230. package/dist/features/faq/actions/faq-actions.d.ts +12 -12
  231. package/dist/features/faq/schemas/index.d.ts +8 -8
  232. package/dist/features/filters/FilterFacetSection.d.ts +7 -1
  233. package/dist/features/filters/FilterFacetSection.js +11 -3
  234. package/dist/features/grouped/schemas/grouped-listing-form.d.ts +101 -0
  235. package/dist/features/grouped/schemas/grouped-listing-form.js +89 -0
  236. package/dist/features/grouped/schemas/index.d.ts +4 -4
  237. package/dist/features/homepage/actions/homepage-section-actions.d.ts +11 -3
  238. package/dist/features/homepage/actions/homepage-section-actions.js +33 -1
  239. package/dist/features/homepage/components/AnnouncementBar.d.ts +7 -1
  240. package/dist/features/homepage/components/AnnouncementBar.js +3 -3
  241. package/dist/features/homepage/components/MarketplaceHomepageView.js +20 -6
  242. package/dist/features/homepage/hooks/homepage-query.d.ts +16 -0
  243. package/dist/features/homepage/hooks/homepage-query.js +45 -0
  244. package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +10 -0
  245. package/dist/features/homepage/hooks/useFeaturedAuctions.js +28 -8
  246. package/dist/features/homepage/hooks/useFeaturedPreOrders.js +17 -8
  247. package/dist/features/homepage/hooks/useFeaturedProducts.js +15 -8
  248. package/dist/features/homepage/schemas/index.d.ts +33 -2
  249. package/dist/features/homepage/schemas/index.js +24 -0
  250. package/dist/features/layout/AppLayoutShell.d.ts +11 -1
  251. package/dist/features/layout/AppLayoutShell.js +15 -14
  252. package/dist/features/layout/BackToTop.d.ts +9 -0
  253. package/dist/features/layout/BackToTop.js +10 -1
  254. package/dist/features/layout/BottomActions.js +28 -25
  255. package/dist/features/layout/BottomChrome.d.ts +34 -0
  256. package/dist/features/layout/BottomChrome.js +55 -0
  257. package/dist/features/layout/BottomNavLayout.d.ts +6 -0
  258. package/dist/features/layout/BottomNavLayout.js +7 -1
  259. package/dist/features/layout/BottomNavbar.js +15 -2
  260. package/dist/features/layout/FooterLayout.js +11 -1
  261. package/dist/features/layout/NavbarLayout.js +1 -1
  262. package/dist/features/layout/TitleBarLayout.d.ts +7 -0
  263. package/dist/features/layout/TitleBarLayout.js +28 -5
  264. package/dist/features/layout/index.d.ts +2 -0
  265. package/dist/features/layout/index.js +1 -0
  266. package/dist/features/lottery/types/index.d.ts +3 -0
  267. package/dist/features/media/MediaPickerModal.js +5 -1
  268. package/dist/features/messages/schemas/index.d.ts +2 -2
  269. package/dist/features/orders/components/OrderScopeTabs.d.ts +20 -0
  270. package/dist/features/orders/components/OrderScopeTabs.js +31 -0
  271. package/dist/features/orders/components/OrderStatusTimeline.d.ts +5 -1
  272. package/dist/features/orders/components/OrderStatusTimeline.js +39 -20
  273. package/dist/features/orders/constants/order-scope.d.ts +48 -0
  274. package/dist/features/orders/constants/order-scope.js +111 -0
  275. package/dist/features/orders/repository/orders.repository.d.ts +54 -7
  276. package/dist/features/orders/repository/orders.repository.js +121 -22
  277. package/dist/features/orders/schemas/firestore.d.ts +152 -0
  278. package/dist/features/orders/schemas/firestore.js +30 -0
  279. package/dist/features/orders/schemas/index.d.ts +18 -18
  280. package/dist/features/orders/types/index.d.ts +35 -7
  281. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +14 -9
  282. package/dist/features/pre-orders/components/PreOrdersListView.js +6 -5
  283. package/dist/features/pre-orders/schemas/index.d.ts +1 -1
  284. package/dist/features/products/actions/product-actions.d.ts +14 -0
  285. package/dist/features/products/actions/product-actions.js +49 -11
  286. package/dist/features/products/api/route.d.ts +12 -0
  287. package/dist/features/products/api/route.js +42 -100
  288. package/dist/features/products/components/ArtStickersListView.js +2 -2
  289. package/dist/features/products/components/AuctionsIndexListing.js +13 -11
  290. package/dist/features/products/components/AvailabilityTabs.d.ts +11 -0
  291. package/dist/features/products/components/AvailabilityTabs.js +47 -0
  292. package/dist/features/products/components/GroupSettingsPanel.js +5 -1
  293. package/dist/features/products/components/MakeOfferButton.js +48 -49
  294. package/dist/features/products/components/PrizeDrawCollage.d.ts +20 -4
  295. package/dist/features/products/components/PrizeDrawCollage.js +9 -1
  296. package/dist/features/products/components/PrizeDrawsIndexListing.js +14 -12
  297. package/dist/features/products/components/PrizeDrawsListingView.js +2 -2
  298. package/dist/features/products/components/PrizeDrawsSection.d.ts +7 -1
  299. package/dist/features/products/components/PrizeDrawsSection.js +23 -18
  300. package/dist/features/products/components/ProductDetailPageView.d.ts +4 -1
  301. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  302. package/dist/features/products/components/ProductForm.js +5 -2
  303. package/dist/features/products/components/ProductGrid.js +6 -1
  304. package/dist/features/products/components/ProductsIndexListing.js +22 -32
  305. package/dist/features/products/components/ProductsIndexPageView.js +6 -9
  306. package/dist/features/products/components/index.d.ts +2 -2
  307. package/dist/features/products/components/index.js +1 -1
  308. package/dist/features/products/config/listing-type-listing-config.d.ts +20 -0
  309. package/dist/features/products/config/listing-type-listing-config.js +22 -10
  310. package/dist/features/products/constants/action-defs.d.ts +2 -0
  311. package/dist/features/products/constants/action-defs.js +6 -0
  312. package/dist/features/products/hooks/useAvailabilityScope.d.ts +13 -0
  313. package/dist/features/products/hooks/useAvailabilityScope.js +19 -0
  314. package/dist/features/products/hooks/useProducts.d.ts +5 -0
  315. package/dist/features/products/hooks/useProducts.js +13 -2
  316. package/dist/features/products/repository/products.repository.d.ts +31 -2
  317. package/dist/features/products/repository/products.repository.js +53 -21
  318. package/dist/features/products/schemas/firestore.d.ts +17 -3
  319. package/dist/features/products/schemas/firestore.js +7 -2
  320. package/dist/features/products/schemas/index.d.ts +64 -64
  321. package/dist/features/products/schemas/product-features.validators.d.ts +79 -6
  322. package/dist/features/products/schemas/product-features.validators.js +63 -0
  323. package/dist/features/products/types/index.d.ts +16 -1
  324. package/dist/features/promotions/schemas/index.d.ts +2 -2
  325. package/dist/features/reviews/schemas/index.d.ts +16 -16
  326. package/dist/features/scams/constants/scammer-status-display.d.ts +28 -0
  327. package/dist/features/scams/constants/scammer-status-display.js +79 -0
  328. package/dist/features/search/schemas/index.d.ts +4 -4
  329. package/dist/features/seller/actions/offer-actions.js +57 -4
  330. package/dist/features/seller/components/OfferPhaseTimeline.d.ts +59 -0
  331. package/dist/features/seller/components/OfferPhaseTimeline.js +107 -0
  332. package/dist/features/seller/components/SellerArtView.js +5 -0
  333. package/dist/features/seller/components/SellerAuctionsView.js +13 -15
  334. package/dist/features/seller/components/SellerBidsView.js +11 -4
  335. package/dist/features/seller/components/SellerClassifiedView.js +5 -0
  336. package/dist/features/seller/components/SellerCouponEditorView.js +17 -17
  337. package/dist/features/seller/components/SellerDigitalCodesView.js +5 -0
  338. package/dist/features/seller/components/SellerLiveView.js +5 -0
  339. package/dist/features/seller/components/SellerOffersView.js +2 -1
  340. package/dist/features/seller/components/SellerOrdersView.js +31 -9
  341. package/dist/features/seller/components/SellerPayoutSettingsView.js +56 -31
  342. package/dist/features/seller/components/SellerPreOrdersView.js +5 -0
  343. package/dist/features/seller/components/SellerPrizeDrawsView.js +14 -16
  344. package/dist/features/seller/components/SellerProductShell.js +7 -1
  345. package/dist/features/seller/components/SellerProductsView.js +11 -8
  346. package/dist/features/seller/components/SellerStickersView.js +5 -0
  347. package/dist/features/seller/components/index.d.ts +0 -2
  348. package/dist/features/seller/components/index.js +0 -1
  349. package/dist/features/seller/repository/offer.repository.d.ts +142 -24
  350. package/dist/features/seller/repository/offer.repository.js +165 -26
  351. package/dist/features/seller/schemas/coupon-form.d.ts +72 -0
  352. package/dist/features/seller/schemas/coupon-form.js +116 -0
  353. package/dist/features/seller/schemas/firestore.d.ts +56 -2
  354. package/dist/features/seller/schemas/firestore.js +27 -0
  355. package/dist/features/seller/schemas/index.d.ts +2 -2
  356. package/dist/features/seller/schemas/offer-forms.d.ts +46 -0
  357. package/dist/features/seller/schemas/offer-forms.js +42 -0
  358. package/dist/features/seller/server.d.ts +0 -1
  359. package/dist/features/seller/server.js +0 -1
  360. package/dist/features/shell/SectionForm.d.ts +99 -0
  361. package/dist/features/shell/SectionForm.js +128 -0
  362. package/dist/features/shell/build-sections.d.ts +63 -0
  363. package/dist/features/shell/build-sections.js +207 -0
  364. package/dist/features/shell/entity-form.d.ts +109 -0
  365. package/dist/features/shell/entity-form.js +96 -0
  366. package/dist/features/shell/field-ui-meta.d.ts +115 -0
  367. package/dist/features/shell/field-ui-meta.js +324 -0
  368. package/dist/features/shell/index.d.ts +8 -0
  369. package/dist/features/shell/index.js +4 -0
  370. package/dist/features/status-history/components/StatusTimeline.d.ts +74 -0
  371. package/dist/features/status-history/components/StatusTimeline.js +46 -0
  372. package/dist/features/status-history/index.d.ts +11 -0
  373. package/dist/features/status-history/index.js +10 -0
  374. package/dist/features/store-extensions/components/ReviewDecisionModal.d.ts +27 -0
  375. package/dist/features/store-extensions/components/ReviewDecisionModal.js +82 -0
  376. package/dist/features/store-extensions/index.d.ts +12 -0
  377. package/dist/features/store-extensions/index.js +12 -0
  378. package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +36 -0
  379. package/dist/features/store-extensions/schemas/admin-notification-form.js +114 -0
  380. package/dist/features/store-extensions/schemas/analytics-forms.d.ts +57 -0
  381. package/dist/features/store-extensions/schemas/analytics-forms.js +158 -0
  382. package/dist/features/store-extensions/schemas/custom-role-form.d.ts +85 -0
  383. package/dist/features/store-extensions/schemas/custom-role-form.js +118 -0
  384. package/dist/features/store-extensions/schemas/firestore.d.ts +21 -1
  385. package/dist/features/store-extensions/schemas/firestore.js +60 -0
  386. package/dist/features/store-extensions/schemas/google-config-form.d.ts +53 -0
  387. package/dist/features/store-extensions/schemas/google-config-form.js +105 -0
  388. package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +28 -0
  389. package/dist/features/store-extensions/schemas/item-request-create-form.js +80 -0
  390. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +78 -0
  391. package/dist/features/store-extensions/schemas/listing-template-form.js +87 -0
  392. package/dist/features/store-extensions/schemas/moderation-review-form.d.ts +49 -0
  393. package/dist/features/store-extensions/schemas/moderation-review-form.js +101 -0
  394. package/dist/features/store-extensions/schemas/payout-method-form.d.ts +153 -0
  395. package/dist/features/store-extensions/schemas/payout-method-form.js +155 -0
  396. package/dist/features/store-extensions/schemas/report-create-form.d.ts +25 -0
  397. package/dist/features/store-extensions/schemas/report-create-form.js +79 -0
  398. package/dist/features/store-extensions/schemas/report-review-form.d.ts +47 -0
  399. package/dist/features/store-extensions/schemas/report-review-form.js +111 -0
  400. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +148 -0
  401. package/dist/features/store-extensions/schemas/shipping-config-form.js +104 -0
  402. package/dist/features/store-extensions/schemas/store-category-form.d.ts +54 -0
  403. package/dist/features/store-extensions/schemas/store-category-form.js +73 -0
  404. package/dist/features/stores/api/[storeSlug]/route.js +2 -25
  405. package/dist/features/stores/components/StoreAuctionsListing.js +15 -1
  406. package/dist/features/stores/components/StoreClassifiedsListing.js +12 -2
  407. package/dist/features/stores/components/StoreDetailLayoutView.js +24 -71
  408. package/dist/features/stores/components/StoreDigitalCodesListing.js +12 -2
  409. package/dist/features/stores/components/StoreLiveItemsListing.js +12 -2
  410. package/dist/features/stores/components/StorePreOrdersListing.js +12 -1
  411. package/dist/features/stores/components/StoreProductsListing.js +11 -1
  412. package/dist/features/stores/repository/store.repository.js +6 -0
  413. package/dist/features/stores/schemas/index.d.ts +6 -6
  414. package/dist/features/support/schemas/index.d.ts +4 -4
  415. package/dist/features/tester/actions/checklist-item-actions.d.ts +4 -4
  416. package/dist/features/tester/seed-data/offers-tester-seed-data.js +119 -3
  417. package/dist/features/tester/seed-data/products-tester-seed-data.js +131 -1
  418. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +431 -1
  419. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  420. package/dist/index.d.ts +25 -12
  421. package/dist/index.js +26 -11
  422. package/dist/next/routing/route-map.d.ts +23 -3
  423. package/dist/next/routing/route-map.js +14 -2
  424. package/dist/providers/db-firebase/base.repository.d.ts +30 -0
  425. package/dist/providers/db-firebase/base.repository.js +50 -1
  426. package/dist/providers/db-firebase/index.d.ts +1 -1
  427. package/dist/providers/db-firebase/index.js +1 -1
  428. package/dist/providers/db-firebase/sieve.d.ts +25 -0
  429. package/dist/providers/db-firebase/sieve.js +52 -18
  430. package/dist/react/hooks/useUrlTable.js +10 -1
  431. package/dist/schemas/firestore-value.d.ts +8 -0
  432. package/dist/schemas/firestore-value.js +44 -0
  433. package/dist/schemas/index.d.ts +1 -1
  434. package/dist/schemas/index.js +1 -1
  435. package/dist/schemas/registry.d.ts +702 -69
  436. package/dist/schemas/registry.js +64 -1
  437. package/dist/seed/_helpers/category-forest.d.ts +2 -0
  438. package/dist/seed/_helpers/category-forest.js +309 -0
  439. package/dist/seed/_helpers/category-tree.d.ts +27 -0
  440. package/dist/seed/_helpers/category-tree.js +103 -0
  441. package/dist/seed/bids-seed-data.js +30 -0
  442. package/dist/seed/catalogue-seed-data.js +12 -12
  443. package/dist/seed/categories-seed-data.js +177 -162
  444. package/dist/seed/events-seed-data.js +61 -10
  445. package/dist/seed/homepage-sections-seed-data.js +5 -1
  446. package/dist/seed/offers-seed-data.js +244 -34
  447. package/dist/seed/orders-seed-data.js +336 -1
  448. package/dist/seed/products-art-seed-data.js +50 -12
  449. package/dist/seed/products-auctions-seed-data.js +138 -18
  450. package/dist/seed/products-classifieds-seed-data.js +80 -16
  451. package/dist/seed/products-digital-codes-seed-data.js +66 -18
  452. package/dist/seed/products-live-items-seed-data.js +64 -13
  453. package/dist/seed/products-preorders-seed-data.d.ts +0 -1
  454. package/dist/seed/products-preorders-seed-data.js +52 -13
  455. package/dist/seed/products-prize-draws-seed-data.js +63 -14
  456. package/dist/seed/products-standard-seed-data.js +99 -26
  457. package/dist/seed/products-stickers-seed-data.js +47 -12
  458. package/dist/seed/reviews-seed-data.js +6 -1
  459. package/dist/seed/site-settings-seed-data.d.ts +1 -38
  460. package/dist/seed/site-settings-seed-data.js +38 -76
  461. package/dist/seed/stores-seed-data.js +71 -1
  462. package/dist/seed/users-seed-data.js +15 -5
  463. package/dist/server-entry.d.ts +1 -2
  464. package/dist/server-entry.js +4 -3
  465. package/dist/server.d.ts +6 -3
  466. package/dist/server.js +13 -4
  467. package/dist/styles.css +78 -12
  468. package/dist/tailwind-utilities.css +1 -1
  469. package/dist/ui/components/Button.style.css +19 -4
  470. package/dist/ui/components/CollapsibleSection.d.ts +17 -1
  471. package/dist/ui/components/CollapsibleSection.js +6 -2
  472. package/dist/ui/components/FilterChipGroup.d.ts +25 -1
  473. package/dist/ui/components/FilterChipGroup.js +21 -4
  474. package/dist/ui/components/HandMode.style.css +47 -0
  475. package/dist/ui/components/Layout.d.ts +9 -2
  476. package/dist/ui/components/Layout.js +1 -1
  477. package/dist/ui/components/ListingLayout.js +8 -8
  478. package/dist/ui/components/ListingLayout.style.css +8 -7
  479. package/dist/ui/components/RecordDetailModal.d.ts +10 -1
  480. package/dist/ui/components/RecordDetailModal.js +2 -2
  481. package/dist/ui/components/StickyToolbar.d.ts +3 -1
  482. package/dist/ui/components/StickyToolbar.js +62 -20
  483. package/dist/ui/components/bottom-chrome-slot.d.ts +21 -0
  484. package/dist/ui/components/bottom-chrome-slot.js +29 -0
  485. package/dist/ui/components/index.style.css +3 -0
  486. package/dist/ui/forms/FormShell.d.ts +43 -13
  487. package/dist/ui/forms/FormShell.js +22 -11
  488. package/dist/ui/forms/index.d.ts +1 -1
  489. package/dist/ui/index.d.ts +1 -1
  490. package/package.json +2 -1
  491. package/scripts/node-esm-loader.mjs +65 -0
  492. package/scripts/seed-cli-loader.mjs +6 -49
  493. package/scripts/seed-cli.mjs +1 -1
@@ -5,22 +5,26 @@ import { sortBy } from "@mohasinac/appkit/client";
5
5
  import React from "react";
6
6
  import { FilterChipGroup, ListingLayout } from "../../../ui";
7
7
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
8
- import { ADMIN_EVENT_STATUS_TABS } from "../../admin/constants/filter-tabs";
8
+ import { ADMIN_EVENT_STATUS_TABS, ALL_TAB } from "../../admin/constants/filter-tabs";
9
+ import { ALL_EVENT_TYPES, EVENT_TYPE_LABELS } from "../types";
9
10
  import { toRecordArray, toRelativeDate, toStringValue, } from "../../admin/hooks/useAdminListingData";
10
11
  import { DataListingView } from "../../admin/components/DataListingView";
11
12
  import { AdminEventEditorView } from "./AdminEventEditorView";
12
13
  import { ADMIN_BULK_ACTIONS, ROW_ACTION_META } from "../../products/constants/action-defs";
13
- // TODO(events): TYPE_OPTIONS list pre-dates the SB9 EventType union refresh
14
- // (sale|offer|poll|survey|feedback|raffle|spin_wheel). Keep current values to
15
- // avoid silently breaking saved-filter URLs — sync in a dedicated follow-up.
14
+ /**
15
+ * Derived from the `EventType` union (2026-08-24).
16
+ *
17
+ * The hand-written list this replaces offered `contest`, `giveaway` and
18
+ * `flash-sale` — none of which are `EventType` values, so each was fed straight
19
+ * into `sieveFilter("type", EQ, id)` and matched zero rows forever — while
20
+ * omitting five real types (`offer`, `feedback`, `raffle`, `spin_wheel`,
21
+ * `lottery`). It carried a TODO deferring the fix on the grounds of "avoid
22
+ * silently breaking saved-filter URLs"; that reasoning didn't hold, since a URL
23
+ * naming a dead id was already returning nothing (Root Cause #33 + #61).
24
+ */
16
25
  const TYPE_OPTIONS = [
17
- { id: "All", label: "All" },
18
- { id: "contest", label: "Contest" },
19
- { id: "giveaway", label: "Giveaway" },
20
- { id: "sale", label: "Sale" },
21
- { id: "poll", label: "Poll" },
22
- { id: "survey", label: "Survey" },
23
- { id: "flash-sale", label: "Flash Sale" },
26
+ ALL_TAB,
27
+ ...ALL_EVENT_TYPES.map((type) => ({ id: type, label: EVENT_TYPE_LABELS[type] })),
24
28
  ];
25
29
  export function AdminEventsView({ children, ...props }) {
26
30
  if (React.Children.count(children) > 0) {
@@ -104,5 +104,13 @@ export declare function getEventSortOptions(variant: EventFilterVariant): Readon
104
104
  export interface EventFiltersProps {
105
105
  table: UrlTable;
106
106
  variant?: EventFilterVariant;
107
+ /**
108
+ * Matching-row counts keyed by event type AND status value. Optional — when
109
+ * absent every facet renders uncounted and nothing is hidden, which is the
110
+ * pre-existing behaviour.
111
+ */
112
+ counts?: Record<string, number | undefined>;
113
+ /** Drop facets whose count is 0. Requires `counts`. */
114
+ hideEmpty?: boolean;
107
115
  }
108
- export declare function EventFilters({ table, variant }: EventFiltersProps): import("react").JSX.Element;
116
+ export declare function EventFilters({ table, variant, counts, hideEmpty, }: EventFiltersProps): import("react").JSX.Element;
@@ -8,6 +8,25 @@ import { Div } from "../../../ui";
8
8
  import { TABLE_KEYS } from "../../../constants/table-keys";
9
9
  import { EVENT_FIELDS } from "../../../constants/field-names";
10
10
  import { sortBy } from "../../../constants/sort";
11
+ import { ALL_EVENT_STATUSES, ALL_EVENT_TYPES, } from "../types";
12
+ /**
13
+ * `sale` -> `eventTypeSale`, `spin_wheel` -> `eventTypeSpinWheel`.
14
+ *
15
+ * Derived rather than a lookup map so a new union member cannot be silently
16
+ * label-less; a missing i18n key surfaces as the key itself, which is loud.
17
+ */
18
+ function pascal(value) {
19
+ return value
20
+ .split("_")
21
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
22
+ .join("");
23
+ }
24
+ function eventTypeLabelKey(value) {
25
+ return `eventType${pascal(value)}`;
26
+ }
27
+ function eventStatusLabelKey(value) {
28
+ return `eventStatus${pascal(value)}`;
29
+ }
11
30
  export const EVENT_FILTER_KEYS = {
12
31
  admin: ["type", TABLE_KEYS.STATUS, TABLE_KEYS.DATE_FROM, TABLE_KEYS.DATE_TO],
13
32
  seller: ["type", TABLE_KEYS.STATUS, TABLE_KEYS.DATE_FROM, TABLE_KEYS.DATE_TO],
@@ -48,27 +67,32 @@ export function getEventSortOptions(variant) {
48
67
  return EVENT_PUBLIC_SORT_OPTIONS;
49
68
  }
50
69
  }
51
- export function EventFilters({ table, variant = "admin" }) {
70
+ export function EventFilters({ table, variant = "admin", counts, hideEmpty = false, }) {
52
71
  const t = useTranslations("filters");
53
- const typeOptions = [
54
- { value: "sale", label: t("eventTypeSale") },
55
- { value: "offer", label: t("eventTypeOffer") },
56
- { value: "poll", label: t("eventTypePoll") },
57
- { value: "survey", label: t("eventTypeSurvey") },
58
- { value: "feedback", label: t("eventTypeFeedback") },
59
- { value: "raffle", label: t("eventTypeRaffle") },
60
- { value: "spin_wheel", label: t("eventTypeSpinWheel") },
61
- ];
62
- const adminStatusOptions = [
63
- { value: "draft", label: t("eventStatusDraft") },
64
- { value: "active", label: t("eventStatusActive") },
65
- { value: "paused", label: t("eventStatusPaused") },
66
- { value: "ended", label: t("eventStatusEnded") },
67
- ];
68
- const publicStatusOptions = [
69
- { value: "active", label: t("eventStatusActive") },
70
- { value: "ended", label: t("eventStatusEnded") },
71
- ];
72
+ // Derived from the unions, not hand-listed. The previous literals were
73
+ // missing `lottery` (type) and `cancelled` (admin status) — a facet that
74
+ // doesn't exist can never be selected, so those events were unfilterable
75
+ // (Root Cause #61).
76
+ const typeOptions = ALL_EVENT_TYPES.map((value) => ({
77
+ value,
78
+ label: t(eventTypeLabelKey(value)),
79
+ count: counts?.[value],
80
+ }));
81
+ const adminStatusOptions = ALL_EVENT_STATUSES.map((value) => ({
82
+ value,
83
+ label: t(eventStatusLabelKey(value)),
84
+ count: counts?.[value],
85
+ }));
86
+ // Deliberately narrower than the union: a shopper has no use for draft,
87
+ // paused or cancelled events, and the public list query only ever returns
88
+ // active ones anyway. Kept as an explicit subset of ALL_EVENT_STATUSES so it
89
+ // is a documented omission rather than another drifted literal.
90
+ const PUBLIC_STATUSES = ["active", "ended"];
91
+ const publicStatusOptions = PUBLIC_STATUSES.map((value) => ({
92
+ value,
93
+ label: t(eventStatusLabelKey(value)),
94
+ count: counts?.[value],
95
+ }));
72
96
  const statusOptions = variant === "public" ? publicStatusOptions : adminStatusOptions;
73
97
  const selectedType = table.get("type")
74
98
  ? table.get("type").split("|").filter(Boolean)
@@ -76,5 +100,5 @@ export function EventFilters({ table, variant = "admin" }) {
76
100
  const selectedStatus = table.get("status")
77
101
  ? table.get("status").split("|").filter(Boolean)
78
102
  : [];
79
- return (_jsxs(Div, { children: [_jsx(FilterFacetSection, { title: t("type"), options: typeOptions, selected: selectedType, onChange: (vals) => table.set("type", vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(FilterFacetSection, { title: t("status"), options: statusOptions, selected: selectedStatus, onChange: (vals) => table.set("status", vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(RangeFilter, { title: t("dateRange"), type: "date", minValue: table.get("dateFrom"), maxValue: table.get("dateTo"), onMinChange: (v) => table.set("dateFrom", v), onMaxChange: (v) => table.set("dateTo", v), minPlaceholder: t("minDate"), maxPlaceholder: t("maxDate"), defaultCollapsed: true }), _jsx(SwitchFilter, { title: t("expired"), label: t("showExpiredOnly"), checked: table.get("showExpired") === "true", onChange: (v) => table.set("showExpired", v ? "true" : "") })] }));
103
+ return (_jsxs(Div, { children: [_jsx(FilterFacetSection, { title: t("type"), options: typeOptions, selected: selectedType, onChange: (vals) => table.set("type", vals.join("|")), searchable: false, defaultCollapsed: false, hideEmpty: hideEmpty }), _jsx(FilterFacetSection, { title: t("status"), options: statusOptions, selected: selectedStatus, onChange: (vals) => table.set("status", vals.join("|")), hideEmpty: hideEmpty, searchable: false, defaultCollapsed: false }), _jsx(RangeFilter, { title: t("dateRange"), type: "date", minValue: table.get("dateFrom"), maxValue: table.get("dateTo"), onMinChange: (v) => table.set("dateFrom", v), onMaxChange: (v) => table.set("dateTo", v), minPlaceholder: t("minDate"), maxPlaceholder: t("maxDate"), defaultCollapsed: true }), _jsx(SwitchFilter, { title: t("expired"), label: t("showExpiredOnly"), checked: table.get("showExpired") === "true", onChange: (v) => table.set("showExpired", v ? "true" : "") })] }));
80
104
  }
@@ -1,5 +1,10 @@
1
1
  import React from "react";
2
2
  export interface EventsIndexListingProps {
3
+ /**
4
+ * Event counts keyed by type AND status value, resolved server-side. Drives
5
+ * both the facet count badges and hiding facets that would return nothing.
6
+ */
7
+ facetCounts?: Record<string, number | undefined>;
3
8
  initialData?: any;
4
9
  }
5
- export declare function EventsIndexListing({ initialData }: EventsIndexListingProps): React.JSX.Element;
10
+ export declare function EventsIndexListing({ initialData, facetCounts }: EventsIndexListingProps): React.JSX.Element;
@@ -18,7 +18,7 @@ const __O = {
18
18
  };
19
19
  const PAGE_SIZE = 24;
20
20
  const FILTER_KEYS = [TABLE_KEYS.TYPE, TABLE_KEYS.STATUS, TABLE_KEYS.DATE_FROM, TABLE_KEYS.DATE_TO, TABLE_KEYS.SHOW_EXPIRED];
21
- export function EventsIndexListing({ initialData }) {
21
+ export function EventsIndexListing({ initialData, facetCounts }) {
22
22
  const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: sortBy(EVENT_FIELDS.STARTS_AT, "ASC") } });
23
23
  const [searchInput, setSearchInput] = useState(table.get(TABLE_KEYS.QUERY) || "");
24
24
  const [filterOpen, setFilterOpen] = useState(false);
@@ -123,5 +123,5 @@ export function EventsIndexListing({ initialData }) {
123
123
  }, [searchInput, table]);
124
124
  return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search events...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || sortBy(EVENT_FIELDS.STARTS_AT, "ASC"), sortOptions: EVENT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState, toggles: [
125
125
  { label: "Show expired", active: showExpired, onChange: (next) => table.set(TABLE_KEYS.SHOW_EXPIRED, next ? "true" : "") },
126
- ] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-video", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p4}`, gap: "sm", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8 mt-2", surface: "subtle", rounded: "default" })] })] }, i))) })) : events.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No events found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) : (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(EventFilters, { table: pendingTable, variant: "public" }) })] }));
126
+ ] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-video", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p4}`, gap: "sm", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8 mt-2", surface: "subtle", rounded: "default" })] })] }, i))) })) : events.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No events found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) : (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(EventFilters, { table: pendingTable, variant: "public", counts: facetCounts, hideEmpty: Boolean(facetCounts) }) })] }));
127
127
  }
@@ -45,8 +45,17 @@ export async function EventsListPageView({ searchParams = {} }) {
45
45
  const page = Number(sp(searchParams, "page")) || 1;
46
46
  const pageSize = Number(sp(searchParams, "pageSize")) || 24;
47
47
  const filters = buildEventFilters(searchParams);
48
- const result = await eventRepository
49
- .list({ filters, sorts: sort, page, pageSize })
50
- .catch(() => null);
51
- return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "mb-8", color: "primary", size: "3xl", weight: "semibold", children: "Events" }), _jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-6" }), _jsx(EventsIndexListing, { initialData: result }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] }) }) }));
48
+ const [result, facetCounts] = await Promise.all([
49
+ eventRepository
50
+ .list({ filters, sorts: sort, page, pageSize })
51
+ .catch(() => null),
52
+ // Facet counts are deliberately NOT narrowed by the shopper's own type or
53
+ // status selection: a count that shrank to zero as you ticked boxes would
54
+ // hide the very facet you'd need to untick. They answer "does this kind of
55
+ // event exist at all", which is the question that decides visibility.
56
+ eventRepository
57
+ .facetCountsForTypesAndStatuses()
58
+ .catch(() => ({})),
59
+ ]);
60
+ return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "mb-8", color: "primary", size: "3xl", weight: "semibold", children: "Events" }), _jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-6" }), _jsx(EventsIndexListing, { initialData: result, facetCounts: facetCounts }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] }) }) }));
52
61
  }
@@ -5,6 +5,23 @@ declare class EventRepository extends BaseRepository<EventDocument> {
5
5
  static readonly SIEVE_FIELDS: FirebaseSieveFields;
6
6
  constructor();
7
7
  list(model: SieveModel): Promise<FirebaseSieveResult<EventDocument>>;
8
+ /**
9
+ * How many events exist per `type` and per `status` — the numbers behind the
10
+ * facet checkboxes, and what lets a type with no events disappear from the
11
+ * filter instead of offering a guaranteed-empty result.
12
+ *
13
+ * Events carry no store/category/brand FK (verified against `EventDocument`),
14
+ * so these counts are global by nature; `baseFilters` narrows them only when
15
+ * a surface wants a subset (e.g. the public page counting active events).
16
+ *
17
+ * Both fields are counted in ONE parallel batch — 13 `.count()` aggregations,
18
+ * no document reads.
19
+ */
20
+ facetCountsForTypesAndStatuses(opts?: {
21
+ types?: readonly string[];
22
+ statuses?: readonly string[];
23
+ baseFilters?: string;
24
+ }): Promise<Record<string, number | undefined>>;
8
25
  findBySlug(slug: string): Promise<EventDocument | null>;
9
26
  findByIdOrSlug(idOrSlug: string): Promise<EventDocument | null>;
10
27
  /**
@@ -1,6 +1,7 @@
1
1
  import { DatabaseError } from "../../../errors";
2
2
  import { serverLogger } from "../../../monitoring";
3
3
  import { slugify } from "../../../utils";
4
+ import { ALL_EVENT_STATUSES, ALL_EVENT_TYPES } from "../types";
4
5
  import { normalizeError } from "../../../errors/normalize";
5
6
  import { BaseRepository, prepareForFirestore, parseSieveDateValue, } from "../../../providers/db-firebase";
6
7
  import { EVENT_FIELDS, EVENTS_COLLECTION, } from "../schemas";
@@ -12,6 +13,32 @@ class EventRepository extends BaseRepository {
12
13
  async list(model) {
13
14
  return this.sieveQuery(model, EventRepository.SIEVE_FIELDS);
14
15
  }
16
+ /**
17
+ * How many events exist per `type` and per `status` — the numbers behind the
18
+ * facet checkboxes, and what lets a type with no events disappear from the
19
+ * filter instead of offering a guaranteed-empty result.
20
+ *
21
+ * Events carry no store/category/brand FK (verified against `EventDocument`),
22
+ * so these counts are global by nature; `baseFilters` narrows them only when
23
+ * a surface wants a subset (e.g. the public page counting active events).
24
+ *
25
+ * Both fields are counted in ONE parallel batch — 13 `.count()` aggregations,
26
+ * no document reads.
27
+ */
28
+ async facetCountsForTypesAndStatuses(opts) {
29
+ const types = opts?.types ?? ALL_EVENT_TYPES;
30
+ const statuses = opts?.statuses ?? ALL_EVENT_STATUSES;
31
+ const [typeCounts, statusCounts] = await Promise.all([
32
+ this.facetCounts(EVENT_FIELDS.TYPE, types, EventRepository.SIEVE_FIELDS, {
33
+ baseFilters: opts?.baseFilters,
34
+ }),
35
+ this.facetCounts(EVENT_FIELDS.STATUS, statuses, EventRepository.SIEVE_FIELDS, { baseFilters: opts?.baseFilters }),
36
+ ]);
37
+ // Type and status values are disjoint, so one flat map is unambiguous and
38
+ // lets the filter component look either up by value without knowing which
39
+ // field it came from.
40
+ return { ...typeCounts, ...statusCounts };
41
+ }
15
42
  async findBySlug(slug) {
16
43
  return this.findOneBy(EVENT_FIELDS.SLUG, slug);
17
44
  }
@@ -0,0 +1,113 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * ## `.passthrough()` STAYS here, deliberately
4
+ *
5
+ * `EventDraft` carries ~40 fields; this schema names seven. The blog form's
6
+ * equivalent was safe to tighten because its draft had fourteen fields and all
7
+ * fourteen could be named in one sitting. This one cannot: most of its fields
8
+ * are per-event-type (poll options, survey fields, spin prizes, raffle config)
9
+ * and only apply under a `type` discriminator, so naming them correctly means
10
+ * modelling the discriminated union rather than listing keys.
11
+ *
12
+ * Tightening it blind is the single most dangerous edit available in this
13
+ * codebase — `z.object()` strips unknown keys, so every field this schema
14
+ * failed to name would vanish from the draft the moment passthrough came off.
15
+ * That is exactly how `productBaseSchema` came to eat every `classified*` /
16
+ * `digitalCode*` / `liveItem*` / `prize*` field.
17
+ *
18
+ * The wire payload is NOT at risk either way: it is built explicitly below
19
+ * (`type`, `title`, `slug`, … plus `buildEventTypeConfig` /
20
+ * `buildEventRaffleFields`), never by spreading the draft.
21
+ *
22
+ * Prerequisite for removing it: a FULL-collection `roundtrip-diff --entity
23
+ * event --full`, not a sample — per the data-integrity protocol.
24
+ *
25
+ * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
26
+ * by schema instance and every zod wrapper returns a new one.
27
+ */
28
+ export declare const eventDraftSchema: z.ZodEffects<z.ZodObject<{
29
+ type: z.ZodString;
30
+ title: z.ZodString;
31
+ startsAt: z.ZodString;
32
+ endsAt: z.ZodString;
33
+ couponId: z.ZodString;
34
+ displayCode: z.ZodString;
35
+ pollOptions: z.ZodArray<z.ZodObject<{
36
+ id: z.ZodString;
37
+ label: z.ZodString;
38
+ }, "strip", z.ZodTypeAny, {
39
+ id: string;
40
+ label: string;
41
+ }, {
42
+ id: string;
43
+ label: string;
44
+ }>, "many">;
45
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
46
+ type: z.ZodString;
47
+ title: z.ZodString;
48
+ startsAt: z.ZodString;
49
+ endsAt: z.ZodString;
50
+ couponId: z.ZodString;
51
+ displayCode: z.ZodString;
52
+ pollOptions: z.ZodArray<z.ZodObject<{
53
+ id: z.ZodString;
54
+ label: z.ZodString;
55
+ }, "strip", z.ZodTypeAny, {
56
+ id: string;
57
+ label: string;
58
+ }, {
59
+ id: string;
60
+ label: string;
61
+ }>, "many">;
62
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
63
+ type: z.ZodString;
64
+ title: z.ZodString;
65
+ startsAt: z.ZodString;
66
+ endsAt: z.ZodString;
67
+ couponId: z.ZodString;
68
+ displayCode: z.ZodString;
69
+ pollOptions: z.ZodArray<z.ZodObject<{
70
+ id: z.ZodString;
71
+ label: z.ZodString;
72
+ }, "strip", z.ZodTypeAny, {
73
+ id: string;
74
+ label: string;
75
+ }, {
76
+ id: string;
77
+ label: string;
78
+ }>, "many">;
79
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
80
+ type: z.ZodString;
81
+ title: z.ZodString;
82
+ startsAt: z.ZodString;
83
+ endsAt: z.ZodString;
84
+ couponId: z.ZodString;
85
+ displayCode: z.ZodString;
86
+ pollOptions: z.ZodArray<z.ZodObject<{
87
+ id: z.ZodString;
88
+ label: z.ZodString;
89
+ }, "strip", z.ZodTypeAny, {
90
+ id: string;
91
+ label: string;
92
+ }, {
93
+ id: string;
94
+ label: string;
95
+ }>, "many">;
96
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
97
+ type: z.ZodString;
98
+ title: z.ZodString;
99
+ startsAt: z.ZodString;
100
+ endsAt: z.ZodString;
101
+ couponId: z.ZodString;
102
+ displayCode: z.ZodString;
103
+ pollOptions: z.ZodArray<z.ZodObject<{
104
+ id: z.ZodString;
105
+ label: z.ZodString;
106
+ }, "strip", z.ZodTypeAny, {
107
+ id: string;
108
+ label: string;
109
+ }, {
110
+ id: string;
111
+ label: string;
112
+ }>, "many">;
113
+ }, z.ZodTypeAny, "passthrough">>;
@@ -0,0 +1,82 @@
1
+ /*
2
+ * WHY: Same reason as the blog form schema — keeping it in the `.tsx` view
3
+ * would have dragged a React component tree into every API route through
4
+ * `SCHEMAS` -> `routeHandler`.
5
+ * WHAT: The event editor's form schema, with its UI metadata.
6
+ *
7
+ * EXPORTS:
8
+ * eventDraftSchema
9
+ *
10
+ * @tag domain:events
11
+ * @tag layer:schema
12
+ * @tag pattern:none
13
+ * @tag access:isomorphic
14
+ * @tag consumers:AdminEventEditorView,SCHEMAS.forms
15
+ * @tag sideEffects:none
16
+ */
17
+ import { z } from "zod";
18
+ import { annotate } from "../../shell/field-ui-meta";
19
+ /**
20
+ * ## `.passthrough()` STAYS here, deliberately
21
+ *
22
+ * `EventDraft` carries ~40 fields; this schema names seven. The blog form's
23
+ * equivalent was safe to tighten because its draft had fourteen fields and all
24
+ * fourteen could be named in one sitting. This one cannot: most of its fields
25
+ * are per-event-type (poll options, survey fields, spin prizes, raffle config)
26
+ * and only apply under a `type` discriminator, so naming them correctly means
27
+ * modelling the discriminated union rather than listing keys.
28
+ *
29
+ * Tightening it blind is the single most dangerous edit available in this
30
+ * codebase — `z.object()` strips unknown keys, so every field this schema
31
+ * failed to name would vanish from the draft the moment passthrough came off.
32
+ * That is exactly how `productBaseSchema` came to eat every `classified*` /
33
+ * `digitalCode*` / `liveItem*` / `prize*` field.
34
+ *
35
+ * The wire payload is NOT at risk either way: it is built explicitly below
36
+ * (`type`, `title`, `slug`, … plus `buildEventTypeConfig` /
37
+ * `buildEventRaffleFields`), never by spreading the draft.
38
+ *
39
+ * Prerequisite for removing it: a FULL-collection `roundtrip-diff --entity
40
+ * event --full`, not a sample — per the data-integrity protocol.
41
+ *
42
+ * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
43
+ * by schema instance and every zod wrapper returns a new one.
44
+ */
45
+ export const eventDraftSchema = z.object({
46
+ type: annotate(z.string(), {
47
+ section: "details", sectionLabel: "Details", sectionRequired: true,
48
+ quick: true, order: 1, row: "pair", kind: "select",
49
+ }),
50
+ title: annotate(z.string().min(1, "Title is required"), {
51
+ section: "details", quick: true, order: 2, row: "full",
52
+ }),
53
+ startsAt: annotate(z.string().min(1, "Start date is required"), {
54
+ section: "details", quick: true, order: 3, row: "pair", kind: "date",
55
+ }),
56
+ endsAt: annotate(z.string().min(1, "End date is required"), {
57
+ section: "details", quick: true, order: 4, row: "pair", kind: "date",
58
+ }),
59
+ couponId: annotate(z.string(), {
60
+ section: "settings", sectionLabel: "Settings", order: 1, row: "pair",
61
+ help: "Required for offer events.",
62
+ }),
63
+ displayCode: annotate(z.string(), {
64
+ section: "settings", order: 2, row: "pair",
65
+ help: "Required for offer events.",
66
+ }),
67
+ pollOptions: annotate(z.array(z.object({ id: z.string(), label: z.string() })), {
68
+ section: "settings", order: 3, row: "full", kind: "list",
69
+ }),
70
+ }).passthrough().superRefine((v, ctx) => {
71
+ if (v.type === "offer") {
72
+ if (!v.couponId.trim()) {
73
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["couponId"], message: "Coupon is required for offer events" });
74
+ }
75
+ if (!v.displayCode.trim()) {
76
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["displayCode"], message: "Display code is required for offer events" });
77
+ }
78
+ }
79
+ if (v.type === "poll" && v.pollOptions.filter((o) => o.label.trim()).length < 2) {
80
+ ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["pollOptions"], message: "Poll events require at least 2 options" });
81
+ }
82
+ });
@@ -128,6 +128,17 @@ export declare const EVENT_FIELDS: {
128
128
  readonly ENDED: EventStatus;
129
129
  readonly CANCELLED: EventStatus;
130
130
  };
131
+ /**
132
+ * Every `EventType`. `LOTTERY` was missing until 2026-08-24, which is why
133
+ * `events-seed-data.ts` — which imports EVENT_FIELDS from HERE, not from
134
+ * `constants/field-names.ts` — had to write `type: "lottery"` as a raw string
135
+ * literal while every other row used this map.
136
+ *
137
+ * NB. there are two `EVENT_FIELDS` constants (this one and the one in
138
+ * `constants/field-names.ts`) and they drifted independently. Same shape as
139
+ * the two competing `OrderStatus` types in Root Cause #36. Keep both in step
140
+ * with the `EventType` / `EventStatus` unions until one of them is retired.
141
+ */
131
142
  readonly TYPE_VALUES: {
132
143
  readonly SALE: EventType;
133
144
  readonly OFFER: EventType;
@@ -136,6 +147,7 @@ export declare const EVENT_FIELDS: {
136
147
  readonly FEEDBACK: EventType;
137
148
  readonly RAFFLE: EventType;
138
149
  readonly SPIN_WHEEL: EventType;
150
+ readonly LOTTERY: EventType;
139
151
  };
140
152
  readonly STATS: {
141
153
  readonly TOTAL_ENTRIES: "stats.totalEntries";
@@ -46,6 +46,17 @@ export const EVENT_FIELDS = {
46
46
  ENDED: "ended",
47
47
  CANCELLED: "cancelled",
48
48
  },
49
+ /**
50
+ * Every `EventType`. `LOTTERY` was missing until 2026-08-24, which is why
51
+ * `events-seed-data.ts` — which imports EVENT_FIELDS from HERE, not from
52
+ * `constants/field-names.ts` — had to write `type: "lottery"` as a raw string
53
+ * literal while every other row used this map.
54
+ *
55
+ * NB. there are two `EVENT_FIELDS` constants (this one and the one in
56
+ * `constants/field-names.ts`) and they drifted independently. Same shape as
57
+ * the two competing `OrderStatus` types in Root Cause #36. Keep both in step
58
+ * with the `EventType` / `EventStatus` unions until one of them is retired.
59
+ */
49
60
  TYPE_VALUES: {
50
61
  SALE: "sale",
51
62
  OFFER: "offer",
@@ -54,6 +65,7 @@ export const EVENT_FIELDS = {
54
65
  FEEDBACK: "feedback",
55
66
  RAFFLE: "raffle",
56
67
  SPIN_WHEEL: "spin_wheel",
68
+ LOTTERY: "lottery",
57
69
  },
58
70
  STATS: {
59
71
  TOTAL_ENTRIES: "stats.totalEntries",