@mohasinac/appkit 4.1.3 → 4.3.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 (276) hide show
  1. package/dist/_internal/server/features/auth/actions.d.ts +0 -1
  2. package/dist/_internal/server/features/auth/actions.js +0 -1
  3. package/dist/_internal/server/features/bundles/data.d.ts +22 -4
  4. package/dist/_internal/server/features/bundles/data.js +41 -4
  5. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  6. package/dist/_internal/server/features/bundles/index.js +1 -1
  7. package/dist/_internal/server/features/checkout/actions.d.ts +15 -0
  8. package/dist/_internal/server/features/checkout/actions.js +249 -257
  9. package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +5 -16
  10. package/dist/_internal/server/features/checkout/prize-bundle-gates.js +5 -30
  11. package/dist/_internal/server/features/orders/adapters.js +1 -14
  12. package/dist/_internal/server/features/products/actions.js +8 -3
  13. package/dist/_internal/server/features/products/service.d.ts +15 -0
  14. package/dist/_internal/server/features/products/service.js +41 -0
  15. package/dist/_internal/server/functions/firestore.d.ts +3 -1
  16. package/dist/_internal/server/functions/firestore.js +17 -1
  17. package/dist/_internal/server/functions/scheduled.d.ts +3 -5
  18. package/dist/_internal/server/functions/scheduled.js +14 -30
  19. package/dist/_internal/server/jobs/core/bundleStockSync.js +25 -7
  20. package/dist/_internal/server/jobs/core/countersReconcile.js +7 -1
  21. package/dist/_internal/server/jobs/core/index.d.ts +4 -4
  22. package/dist/_internal/server/jobs/core/index.js +4 -4
  23. package/dist/_internal/server/jobs/core/jobRunners.js +10 -0
  24. package/dist/_internal/server/jobs/core/newsletterExport.d.ts +15 -0
  25. package/dist/_internal/server/jobs/core/newsletterExport.js +43 -0
  26. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +2 -0
  27. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +1 -0
  28. package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.d.ts +19 -0
  29. package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.js +30 -0
  30. package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +2 -2
  31. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +3 -2
  32. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +1 -0
  33. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.d.ts +20 -0
  34. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +113 -0
  35. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.d.ts +14 -0
  36. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +74 -0
  37. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.d.ts +22 -0
  38. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +68 -0
  39. package/dist/_internal/server/jobs/core/revenueRollup.d.ts +13 -0
  40. package/dist/_internal/server/jobs/core/revenueRollup.js +22 -0
  41. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +35 -0
  42. package/dist/_internal/server/jobs/core/whatsappNotify.js +82 -0
  43. package/dist/_internal/server/jobs/handlers/index.d.ts +4 -4
  44. package/dist/_internal/server/jobs/handlers/index.js +9 -6
  45. package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.d.ts +3 -0
  46. package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.js +11 -0
  47. package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.d.ts +2 -0
  48. package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.js +2 -0
  49. package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.d.ts +3 -0
  50. package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.js +4 -0
  51. package/dist/_internal/server/jobs/handlers/revenueRollup.d.ts +2 -0
  52. package/dist/_internal/server/jobs/handlers/revenueRollup.js +2 -0
  53. package/dist/_internal/shared/actions/action-registry.js +40 -10
  54. package/dist/_internal/shared/checkout/rules/_defaults.js +1 -2
  55. package/dist/_internal/shared/checkout/rules/_limits.d.ts +3 -0
  56. package/dist/_internal/shared/checkout/rules/_limits.js +3 -0
  57. package/dist/_internal/shared/checkout/rules/_registry.d.ts +2 -1
  58. package/dist/_internal/shared/checkout/rules/_registry.js +2 -2
  59. package/dist/_internal/shared/checkout/rules/classified.rule.js +0 -1
  60. package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
  61. package/dist/_internal/shared/checkout/rules/index.js +1 -1
  62. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +20 -1
  63. package/dist/_internal/shared/checkout/rules/types.d.ts +17 -7
  64. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +2 -0
  65. package/dist/_internal/shared/features/categories/bundle-copy.js +2 -0
  66. package/dist/_internal/shared/features/categories/bundle-pricing.d.ts +23 -0
  67. package/dist/_internal/shared/features/categories/bundle-pricing.js +25 -0
  68. package/dist/_internal/shared/features/checkout/config.d.ts +7 -0
  69. package/dist/_internal/shared/features/checkout/config.js +7 -0
  70. package/dist/_internal/shared/fees/calculator.d.ts +26 -0
  71. package/dist/_internal/shared/fees/calculator.js +25 -0
  72. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  73. package/dist/constants/api-endpoints.d.ts +6 -9
  74. package/dist/constants/api-endpoints.js +5 -5
  75. package/dist/constants/field-names.d.ts +17 -1
  76. package/dist/constants/field-names.js +17 -1
  77. package/dist/features/about/components/FeesView.js +18 -0
  78. package/dist/features/account/hooks/useNotifications.js +5 -0
  79. package/dist/features/admin/actions/admin-actions.js +6 -0
  80. package/dist/features/admin/actions/notification-actions.d.ts +4 -1
  81. package/dist/features/admin/actions/notification-actions.js +57 -12
  82. package/dist/features/admin/components/AdminAdsView.js +1 -1
  83. package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
  84. package/dist/features/admin/components/AdminNewsletterView.js +42 -11
  85. package/dist/features/admin/components/AdminPrizeDrawsView.js +3 -3
  86. package/dist/features/admin/components/AdminSiteSettingsView.js +115 -11
  87. package/dist/features/admin/components/AdminTesterChecklistView.js +74 -22
  88. package/dist/features/admin/hooks/useAdminListing.d.ts +4 -0
  89. package/dist/features/admin/hooks/useAdminListing.js +4 -2
  90. package/dist/features/admin/repository/analytics-rollup.repository.d.ts +25 -0
  91. package/dist/features/admin/repository/analytics-rollup.repository.js +31 -0
  92. package/dist/features/admin/repository/site-settings.repository.js +8 -1
  93. package/dist/features/admin/schemas/firestore.d.ts +54 -5
  94. package/dist/features/admin/schemas/firestore.js +63 -26
  95. package/dist/features/auctions/actions/bid-actions.js +3 -1
  96. package/dist/features/auctions/components/AuctionBidsTable.d.ts +6 -1
  97. package/dist/features/auctions/components/AuctionBidsTable.js +8 -4
  98. package/dist/features/auctions/components/AuctionDetailPageView.js +10 -13
  99. package/dist/features/auctions/components/CollapsibleBidHistory.d.ts +23 -2
  100. package/dist/features/auctions/components/CollapsibleBidHistory.js +21 -3
  101. package/dist/features/auctions/components/LiveBidPrice.d.ts +19 -0
  102. package/dist/features/auctions/components/LiveBidPrice.js +17 -0
  103. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -1
  104. package/dist/features/auctions/components/PlaceBidFormClient.js +16 -1
  105. package/dist/features/auctions/hooks/useBids.d.ts +33 -0
  106. package/dist/features/auctions/hooks/useBids.js +32 -0
  107. package/dist/features/auctions/hooks/useLiveAuctionBid.d.ts +20 -0
  108. package/dist/features/auctions/hooks/useLiveAuctionBid.js +23 -0
  109. package/dist/features/auth/checkout-value-otp.d.ts +7 -10
  110. package/dist/features/auth/checkout-value-otp.js +14 -10
  111. package/dist/features/auth/server.d.ts +0 -1
  112. package/dist/features/auth/server.js +0 -1
  113. package/dist/features/blog/api/[slug]/route.d.ts +5 -0
  114. package/dist/features/blog/api/[slug]/route.js +12 -3
  115. package/dist/features/blog/components/BlogPostView.d.ts +2 -0
  116. package/dist/features/blog/components/BlogPostView.js +5 -4
  117. package/dist/features/blog/hooks/useBlog.d.ts +2 -0
  118. package/dist/features/blog/hooks/useBlog.js +2 -0
  119. package/dist/features/blog/repository/blog.repository.d.ts +7 -0
  120. package/dist/features/blog/repository/blog.repository.js +44 -0
  121. package/dist/features/blog/schemas/firestore.d.ts +3 -0
  122. package/dist/features/blog/schemas/firestore.js +1 -0
  123. package/dist/features/blog/types/index.d.ts +2 -0
  124. package/dist/features/cart/components/index.d.ts +0 -2
  125. package/dist/features/cart/components/index.js +0 -1
  126. package/dist/features/cart/hooks/useCartCount.js +22 -5
  127. package/dist/features/cart/hooks/useGuestCart.js +11 -1
  128. package/dist/features/cart/utils/guest-cart.d.ts +4 -0
  129. package/dist/features/cart/utils/guest-cart.js +10 -0
  130. package/dist/features/cart/utils/pending-ops.d.ts +17 -0
  131. package/dist/features/cart/utils/pending-ops.js +46 -5
  132. package/dist/features/categories/components/BrandDetailPageView.js +6 -2
  133. package/dist/features/categories/components/BundleDetailView.js +4 -2
  134. package/dist/features/categories/components/CategoryDetailPageView.js +10 -2
  135. package/dist/features/categories/schemas/firestore.d.ts +7 -0
  136. package/dist/features/checkout/actions/index.d.ts +0 -1
  137. package/dist/features/checkout/actions/index.js +0 -1
  138. package/dist/features/checkout/schemas/firestore.d.ts +2 -2
  139. package/dist/features/events/actions/event-actions.d.ts +2 -0
  140. package/dist/features/events/actions/event-actions.js +5 -0
  141. package/dist/features/events/components/EventCard.js +1 -2
  142. package/dist/features/events/components/RelatedEventsCarousel.d.ts +15 -0
  143. package/dist/features/events/components/RelatedEventsCarousel.js +13 -0
  144. package/dist/features/events/components/index.d.ts +2 -0
  145. package/dist/features/events/components/index.js +1 -0
  146. package/dist/features/events/repository/events.repository.d.ts +6 -0
  147. package/dist/features/events/repository/events.repository.js +21 -0
  148. package/dist/features/history/repository/user-history.repository.d.ts +1 -1
  149. package/dist/features/history/utils/guest-history.d.ts +1 -1
  150. package/dist/features/homepage/components/FeaturedBundlesSection.js +4 -2
  151. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  152. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  153. package/dist/features/homepage/components/WelcomeSection.js +1 -1
  154. package/dist/features/layout/AppLayoutShell.js +1 -1
  155. package/dist/features/layout/BackToTop.d.ts +9 -5
  156. package/dist/features/layout/BackToTop.js +17 -21
  157. package/dist/features/layout/NavbarLayout.js +1 -1
  158. package/dist/features/layout/TitleBarLayout.js +2 -2
  159. package/dist/features/media/MediaVideo.d.ts +7 -0
  160. package/dist/features/media/MediaVideo.js +36 -5
  161. package/dist/features/orders/actions/refund-actions.js +1 -0
  162. package/dist/features/orders/components/OrdersList.js +1 -5
  163. package/dist/features/orders/schemas/firestore.d.ts +16 -8
  164. package/dist/features/orders/schemas/index.d.ts +3 -32
  165. package/dist/features/orders/schemas/index.js +1 -4
  166. package/dist/features/orders/types/index.d.ts +6 -9
  167. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
  168. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
  169. package/dist/features/products/actions/product-actions.js +13 -10
  170. package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
  171. package/dist/features/products/components/MarketplaceBundleCard.js +7 -4
  172. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  173. package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
  174. package/dist/features/products/components/PrizeDrawWinnerMappingView.d.ts +14 -0
  175. package/dist/features/products/components/PrizeDrawWinnerMappingView.js +37 -0
  176. package/dist/features/products/components/PrizeRevealModal.d.ts +10 -23
  177. package/dist/features/products/components/PrizeRevealModal.js +18 -147
  178. package/dist/features/products/components/ProductDetailPageView.js +72 -30
  179. package/dist/features/products/components/ProductForm.js +7 -14
  180. package/dist/features/products/components/ProductGalleryClient.d.ts +10 -1
  181. package/dist/features/products/components/ProductGalleryClient.js +29 -10
  182. package/dist/features/products/components/ProductsIndexListing.js +2 -1
  183. package/dist/features/products/components/RelatedProductsCarousel.js +2 -2
  184. package/dist/features/products/components/ShowGroupSection.js +2 -2
  185. package/dist/features/products/components/SublistingCarouselSection.js +1 -1
  186. package/dist/features/products/components/index.d.ts +4 -2
  187. package/dist/features/products/components/index.js +1 -0
  188. package/dist/features/products/constants/action-defs.d.ts +28 -4
  189. package/dist/features/products/constants/action-defs.js +76 -3
  190. package/dist/features/products/repository/products.repository.d.ts +6 -0
  191. package/dist/features/products/repository/products.repository.js +20 -1
  192. package/dist/features/products/schemas/firestore.d.ts +26 -2
  193. package/dist/features/products/schemas/index.d.ts +11 -3
  194. package/dist/features/products/schemas/index.js +10 -2
  195. package/dist/features/products/types/index.d.ts +2 -1
  196. package/dist/features/reviews/actions/review-actions.js +1 -0
  197. package/dist/features/reviews/components/ReviewDetailPageView.js +8 -1
  198. package/dist/features/reviews/components/ReviewDetailShell.js +2 -1
  199. package/dist/features/reviews/components/ReviewsList.js +2 -1
  200. package/dist/features/reviews/schemas/firestore.d.ts +3 -0
  201. package/dist/features/reviews/schemas/index.d.ts +6 -0
  202. package/dist/features/reviews/schemas/index.js +2 -0
  203. package/dist/features/reviews/types/index.d.ts +3 -0
  204. package/dist/features/scams/actions/scam-actions.d.ts +3 -0
  205. package/dist/features/scams/actions/scam-actions.js +3 -2
  206. package/dist/features/scams/components/ScamProfileView.d.ts +2 -1
  207. package/dist/features/scams/components/ScamProfileView.js +2 -2
  208. package/dist/features/scams/repository/scammer.repository.d.ts +6 -0
  209. package/dist/features/scams/repository/scammer.repository.js +24 -0
  210. package/dist/features/seller/actions/seller-actions.js +8 -0
  211. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  212. package/dist/features/seller/components/SellerPrizeDrawsView.js +4 -0
  213. package/dist/features/stores/components/StoreDetailLayoutView.js +6 -6
  214. package/dist/features/stores/components/StoreNavTabs.d.ts +10 -1
  215. package/dist/features/stores/components/StoreNavTabs.js +21 -9
  216. package/dist/features/tester/actions/index.d.ts +1 -0
  217. package/dist/features/tester/actions/index.js +1 -0
  218. package/dist/features/tester/actions/leaderboard-actions.d.ts +3 -0
  219. package/dist/features/tester/actions/leaderboard-actions.js +5 -0
  220. package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +26 -4
  221. package/dist/features/tester/components/AdminTesterFeedbackListView.js +13 -0
  222. package/dist/features/tester/components/BugHunterLeaderboardView.d.ts +23 -0
  223. package/dist/features/tester/components/BugHunterLeaderboardView.js +18 -0
  224. package/dist/features/tester/components/index.d.ts +2 -0
  225. package/dist/features/tester/components/index.js +1 -0
  226. package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +12 -1
  227. package/dist/features/tester/repository/tester-checklist-item.repository.js +80 -0
  228. package/dist/features/tester/repository/tester-checklist-response.repository.d.ts +4 -0
  229. package/dist/features/tester/repository/tester-checklist-response.repository.js +4 -0
  230. package/dist/features/tester/schemas/firestore.d.ts +22 -1
  231. package/dist/features/tester/schemas/firestore.js +8 -0
  232. package/dist/features/tester/seed-data/categories-tester-seed-data.js +42 -7
  233. package/dist/features/tester/seed-data/events-tester-seed-data.js +23 -0
  234. package/dist/features/tester/seed-data/orders-tester-seed-data.js +69 -31
  235. package/dist/features/tester/seed-data/products-tester-seed-data.js +152 -8
  236. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +249 -14
  237. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +10 -1
  238. package/dist/features/whatsapp-bot/helpers/whatsapp.js +47 -0
  239. package/dist/features/whatsapp-bot/types/index.d.ts +19 -0
  240. package/dist/features/wishlist/hooks/useGuestWishlist.js +11 -1
  241. package/dist/features/wishlist/hooks/useWishlistCount.js +16 -2
  242. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -0
  243. package/dist/features/wishlist/utils/guest-wishlist.js +11 -0
  244. package/dist/index.d.ts +23 -24
  245. package/dist/index.js +29 -60
  246. package/dist/jobs.d.ts +1 -1
  247. package/dist/jobs.js +2 -2
  248. package/dist/next/routing/route-map.d.ts +4 -0
  249. package/dist/next/routing/route-map.js +2 -0
  250. package/dist/repositories/index.d.ts +2 -0
  251. package/dist/repositories/index.js +1 -0
  252. package/dist/schemas/registry.d.ts +6 -26
  253. package/dist/seed/bids-seed-data.js +14 -2
  254. package/dist/seed/blog-posts-seed-data.js +2 -1
  255. package/dist/seed/categories-seed-data.js +11 -2
  256. package/dist/seed/events-seed-data.js +11 -11
  257. package/dist/seed/faq-seed-data.js +5 -1
  258. package/dist/seed/products-auctions-seed-data.js +2 -2
  259. package/dist/seed/products-preorders-seed-data.d.ts +2 -1
  260. package/dist/seed/products-prize-draws-seed-data.js +56 -10
  261. package/dist/seed/products-standard-seed-data.js +82 -3
  262. package/dist/seed/scammers-seed-data.js +75 -2
  263. package/dist/seed/site-settings-seed-data.js +12 -2
  264. package/dist/server-entry.d.ts +0 -1
  265. package/dist/server-entry.js +0 -1
  266. package/dist/server.d.ts +6 -22
  267. package/dist/server.js +12 -59
  268. package/dist/styles.css +1 -1
  269. package/dist/tailwind-utilities.css +1 -1
  270. package/dist/ui/components/BaseListingCard.js +1 -1
  271. package/dist/ui/components/ImageLightbox.d.ts +9 -0
  272. package/dist/ui/components/ImageLightbox.js +6 -3
  273. package/dist/ui/components/ListingToolbar.d.ts +18 -1
  274. package/dist/ui/components/ListingToolbar.js +5 -2
  275. package/dist/ui/components/StickyToolbar.js +13 -8
  276. package/package.json +1 -1
@@ -11,6 +11,7 @@ import { useAuthGate } from "../../../react/hooks/useAuthGate";
11
11
  import { ACTION_ID, ACTION_META, COMPARE_MAX_ITEMS } from "../constants/action-defs";
12
12
  import { CompareOverlay } from "./CompareOverlay";
13
13
  import { ROUTES } from "../../../next";
14
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
14
15
  import { ProductGrid, ProductFilters, PRODUCT_PUBLIC_SORT_OPTIONS } from ".";
15
16
  import { useGuestCart } from "../../cart/hooks/useGuestCart";
16
17
  import { useGuestWishlist } from "../../wishlist/hooks/useGuestWishlist";
@@ -241,7 +242,7 @@ export function ProductsIndexListing({ initialData, listingTypes = GENERIC_PRODU
241
242
  setCompareIds(ids);
242
243
  },
243
244
  },
244
- ] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "4", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view === "grid" ? "card" : "list", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart, onBuyNow: handleBuyNow, selectionMode: selection.isSelecting, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "product", onClose: () => {
245
+ ] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "4", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => pluginFor(p.listingType ?? "standard").detailRoute(p.slug || p.id), view: view === "grid" ? "card" : "list", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart, onBuyNow: handleBuyNow, selectionMode: selection.isSelecting, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "product", onClose: () => {
245
246
  setCompareIds([]);
246
247
  selection.clearSelection();
247
248
  }, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions, featureOptions: featureOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { ROUTES } from "../../../next";
3
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
4
4
  import { SectionCarousel } from "../../homepage/components/SectionCarousel";
5
5
  import { ProductCard } from "./ProductGrid";
6
6
  import { CAROUSEL_PER_VIEW } from "../../homepage/constants/carousel-per-view";
7
7
  export function RelatedProductsCarousel({ items, title = "You might also like", }) {
8
8
  if (items.length === 0)
9
9
  return null;
10
- return (_jsx(SectionCarousel, { title: title, pillLabel: "Related Products", headingVariant: "editorial", items: items, isLoading: false, perView: CAROUSEL_PER_VIEW.standard, keyExtractor: (item) => item.id, renderItem: (item) => (_jsx(ProductCard, { product: item, href: item.slug || item.id ? String(ROUTES.PUBLIC.PRODUCT_DETAIL(item.slug || item.id)) : undefined })) }));
10
+ return (_jsx(SectionCarousel, { title: title, pillLabel: "Related Products", headingVariant: "editorial", items: items, isLoading: false, perView: CAROUSEL_PER_VIEW.standard, keyExtractor: (item) => item.id, renderItem: (item) => (_jsx(ProductCard, { product: item, href: item.slug || item.id ? pluginFor(item.listingType ?? "standard").detailRoute(item.slug || item.id) : undefined })) }));
11
11
  }
@@ -28,7 +28,7 @@ function GroupTableRow({ member }) {
28
28
  const href = memberHref(member);
29
29
  const price = formatCurrency(member.price, member.currency ?? "INR");
30
30
  const image = member.images?.[0] ?? "";
31
- return (_jsxs(Tr, { className: "last:border-0", border: "subtle", children: [_jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Div, { className: `w-10 h-10 ${__O.hidden}`, rounded: "full", border: "default", children: _jsx(MediaImage, { src: image, alt: member.title, size: "thumbnail" }) }) }), _jsxs(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: [_jsx(Text, { className: "line-clamp-2", color: "primary", size: "sm", weight: "medium", children: member.title }), member.isGroupParent && (_jsx(Span, { weight: "semibold", className: "text-[10px] text-[var(--appkit-color-primary)]", children: "Parent" }))] }), _jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Text, { size: "sm", color: "muted", children: price }) }), _jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Text, { size: "xs", transform: "capitalize", color: "muted", children: member.condition ?? "—" }) }), _jsx(Td, { padding: "xs-tall", children: _jsx(Link, { href: href, className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline", children: "View \u00E2\u2020\u2019" }) })] }));
31
+ return (_jsxs(Tr, { className: "last:border-0", border: "subtle", children: [_jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Div, { className: `w-10 h-10 ${__O.hidden}`, rounded: "full", border: "default", children: _jsx(MediaImage, { src: image, alt: member.title, size: "thumbnail" }) }) }), _jsxs(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: [_jsx(Text, { className: "line-clamp-2", color: "primary", size: "sm", weight: "medium", children: member.title }), member.isGroupParent && (_jsx(Span, { weight: "semibold", className: "text-[10px] text-[var(--appkit-color-primary)]", children: "Parent" }))] }), _jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Text, { size: "sm", color: "muted", children: price }) }), _jsx(Td, { paddingSide: "pr-sm", padding: "xs-tall", children: _jsx(Text, { size: "xs", transform: "capitalize", color: "muted", children: member.condition ?? "—" }) }), _jsx(Td, { padding: "xs-tall", children: _jsx(Link, { href: href, className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline", children: "View \u2192" }) })] }));
32
32
  }
33
33
  export function ShowGroupSection({ groupId, currentSlug, isParent, groupTitle }) {
34
34
  const [open, setOpen] = useState(false);
@@ -54,7 +54,7 @@ export function ShowGroupSection({ groupId, currentSlug, isParent, groupTitle })
54
54
  return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: `${__O.hidden}`, surface: "muted", rounded: "xl", border: "default", children: [_jsxs(Row, { role: "button", tabIndex: 0, onClick: () => setOpen((v) => !v), onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") {
55
55
  e.preventDefault();
56
56
  setOpen((v) => !v);
57
- } }, justify: "between", paddingX: "x-md", paddingY: "y-sm", className: "w-full cursor-pointer text-left hover:bg-[var(--appkit-color-surface-elevated)]/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "mr-1", color: "faint", children: open ? "â–¼" : "â–¶" }), _jsx(Text, { size: "sm", weight: "medium", color: "primary", children: parentLabel }), _jsx(Span, { size: "xs", className: "ml-1", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: members.length })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: (e) => { e.stopPropagation(); setShowAll(true); }, className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline ml-3 flex-shrink-0", children: "View whole group \u00E2\u2020\u2019" })] }), open && (_jsx(Div, { className: `pb-[1rem] pt-[0.25rem] ${__O.xAuto}`, padding: "x-md", children: _jsx(Row, { gap: "3", className: "min-w-0", children: [...members]
57
+ } }, justify: "between", paddingX: "x-md", paddingY: "y-sm", className: "w-full cursor-pointer text-left hover:bg-[var(--appkit-color-surface-elevated)]/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "mr-1", color: "faint", children: open ? "" : "" }), _jsx(Text, { size: "sm", weight: "medium", color: "primary", children: parentLabel }), _jsx(Span, { size: "xs", className: "ml-1", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: members.length })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: (e) => { e.stopPropagation(); setShowAll(true); }, className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline ml-3 flex-shrink-0", children: "View whole group \u2192" })] }), open && (_jsx(Div, { className: `pb-[1rem] pt-[0.25rem] ${__O.xAuto}`, padding: "x-md", children: _jsx(Row, { gap: "3", className: "min-w-0", children: [...members]
58
58
  .sort((a, b) => (b.isGroupParent ? 1 : 0) - (a.isGroupParent ? 1 : 0))
59
59
  .map((m) => (_jsx(MemberThumb, { member: m, isCurrent: m.slug === currentSlug || m.id === currentSlug }, m.id))) }) }))] }), useDrawer ? (_jsx(SideDrawer, { isOpen: showAll, onClose: () => setShowAll(false), title: label, children: tableContent })) : (_jsx(Modal, { open: showAll, onClose: () => setShowAll(false), title: label, children: tableContent }))] }));
60
60
  }
@@ -54,5 +54,5 @@ export function SublistingCarouselSection({ sublistingCategoryId, currentListing
54
54
  return (_jsxs(Div, { className: `${__O.hidden}`, surface: "muted", rounded: "xl", border: "default", children: [_jsxs(Row, { role: "button", tabIndex: 0, onClick: () => setOpen((v) => !v), onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") {
55
55
  e.preventDefault();
56
56
  setOpen((v) => !v);
57
- } }, justify: "between", paddingX: "x-md", paddingY: "y-sm", className: "w-full cursor-pointer text-left hover:bg-[var(--appkit-color-surface-elevated)]/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "mr-1", color: "faint", children: open ? "â–¼" : "â–¶" }), _jsxs(Text, { size: "sm", weight: "medium", color: "primary", children: ["More listings like this:", " ", _jsx(Span, { className: "text-[var(--appkit-color-primary)]", children: label })] }), _jsx(Span, { size: "xs", className: "ml-1", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: listings.length })] }), category && (_jsx(Link, { href: String(ROUTES.PUBLIC.SUBLISTING_CATEGORY(category.slug)), onClick: (e) => e.stopPropagation(), className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline ml-3 flex-shrink-0", children: "View all \u00E2\u2020\u2019" }))] }), open && (_jsx(Div, { className: `pb-[1rem] pt-[0.25rem] ${__O.xAuto}`, padding: "x-md", children: _jsx(Row, { gap: "3", className: "min-w-0", children: listings.map((listing) => (_jsx(ListingThumb, { listing: listing, isCurrent: listing.id === currentListingId }, listing.id))) }) }))] }));
57
+ } }, justify: "between", paddingX: "x-md", paddingY: "y-sm", className: "w-full cursor-pointer text-left hover:bg-[var(--appkit-color-surface-elevated)]/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "mr-1", color: "faint", children: open ? "â–¼" : "â–¶" }), _jsxs(Text, { size: "sm", weight: "medium", color: "primary", children: ["More listings like this:", " ", _jsx(Span, { className: "text-[var(--appkit-color-primary)]", children: label })] }), _jsx(Span, { size: "xs", className: "ml-1", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: listings.length })] }), category && (_jsx(Link, { href: String(ROUTES.PUBLIC.SUBLISTING_CATEGORY(category.slug)), onClick: (e) => e.stopPropagation(), className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-primary)] hover:underline ml-3 flex-shrink-0", children: "View all \u2192" }))] }), open && (_jsx(Div, { className: `pb-[1rem] pt-[0.25rem] ${__O.xAuto}`, padding: "x-md", children: _jsx(Row, { gap: "3", className: "min-w-0", children: listings.map((listing) => (_jsx(ListingThumb, { listing: listing, isCurrent: listing.id === currentListingId }, listing.id))) }) }))] }));
58
58
  }
@@ -12,7 +12,9 @@ export type { PrizeDrawItemsEditorProps } from "./PrizeDrawItemsEditor";
12
12
  export { PrizeDrawCollage } from "./PrizeDrawCollage";
13
13
  export type { PrizeDrawCollageProps } from "./PrizeDrawCollage";
14
14
  export { PrizeRevealModal } from "./PrizeRevealModal";
15
- export type { PrizeRevealModalProps, PrizeRevealResponse, } from "./PrizeRevealModal";
15
+ export type { PrizeRevealModalProps, PrizeRevealResult, } from "./PrizeRevealModal";
16
+ export { PrizeDrawWinnerMappingView } from "./PrizeDrawWinnerMappingView";
17
+ export type { PrizeDrawWinnerMappingViewProps, PrizeDrawWinnerMappingRow, } from "./PrizeDrawWinnerMappingView";
16
18
  export { MarketplacePrizeDrawCard } from "./MarketplacePrizeDrawCard";
17
19
  export type { MarketplacePrizeDrawCardProps, MarketplacePrizeDrawCardData, MarketplacePrizeDrawCardLabels, } from "./MarketplacePrizeDrawCard";
18
20
  export { MarketplaceBundleCard } from "./MarketplaceBundleCard";
@@ -51,7 +53,7 @@ export type { MakeOfferButtonProps } from "./MakeOfferButton";
51
53
  export { RelatedProducts } from "./RelatedProducts";
52
54
  export type { RelatedProductsProps } from "./RelatedProducts";
53
55
  export { ProductGalleryClient } from "./ProductGalleryClient";
54
- export type { ProductGalleryClientProps } from "./ProductGalleryClient";
56
+ export type { ProductGalleryClientProps, ProductGalleryVideo } from "./ProductGalleryClient";
55
57
  export { ProductTabsShell } from "./ProductTabsShell";
56
58
  export type { ProductTabsShellProps, CustomTabDef } from "./ProductTabsShell";
57
59
  export { ProductGradingTab } from "./ProductGradingTab";
@@ -6,6 +6,7 @@ export { NonRefundableConsentModal } from "./NonRefundableConsentModal";
6
6
  export { PrizeDrawItemsEditor } from "./PrizeDrawItemsEditor";
7
7
  export { PrizeDrawCollage } from "./PrizeDrawCollage";
8
8
  export { PrizeRevealModal } from "./PrizeRevealModal";
9
+ export { PrizeDrawWinnerMappingView } from "./PrizeDrawWinnerMappingView";
9
10
  export { MarketplacePrizeDrawCard } from "./MarketplacePrizeDrawCard";
10
11
  export { MarketplaceBundleCard } from "./MarketplaceBundleCard";
11
12
  export { PrizeDrawsIndexListing } from "./PrizeDrawsIndexListing";
@@ -32,7 +32,6 @@ export declare const ACTION_ID: {
32
32
  readonly CANCEL_RESERVATION: "cancel-reservation";
33
33
  readonly CHECKOUT: "checkout";
34
34
  readonly CONTINUE_TO_VERIFY: "continue-to-verification";
35
- readonly SEND_OTP: "send-otp";
36
35
  readonly VERIFY_OTP: "verify-otp";
37
36
  readonly PAY_ONLINE: "pay-online";
38
37
  readonly PAY_COD: "pay-cod";
@@ -280,15 +279,40 @@ export declare const DASHBOARD_QUICK_ACTION_ID: {
280
279
  readonly ADMIN_ADD_BLOG: "dqa-admin-add-blog";
281
280
  readonly ADMIN_ADD_FAQ: "dqa-admin-add-faq";
282
281
  readonly ADMIN_SETTINGS: "dqa-admin-settings";
282
+ readonly ADMIN_STORES: "dqa-admin-stores";
283
+ readonly ADMIN_ORDERS: "dqa-admin-orders";
284
+ readonly ADMIN_PAYOUTS: "dqa-admin-payouts";
285
+ readonly ADMIN_ANALYTICS: "dqa-admin-analytics";
286
+ readonly ADMIN_EVENTS: "dqa-admin-events";
287
+ readonly ADMIN_SUPPORT: "dqa-admin-support";
288
+ readonly ADMIN_MODERATION: "dqa-admin-moderation";
289
+ readonly ADMIN_INTEGRATION_GUIDES: "dqa-admin-integration-guides";
290
+ readonly ADMIN_USERS: "dqa-admin-users";
291
+ readonly ADMIN_CATEGORIES: "dqa-admin-categories";
292
+ readonly ADMIN_REVIEWS: "dqa-admin-reviews";
293
+ readonly ADMIN_FAQS: "dqa-admin-faqs";
294
+ readonly ADMIN_CAROUSEL: "dqa-admin-carousel";
295
+ readonly ADMIN_SECTIONS: "dqa-admin-sections";
283
296
  readonly SELLER_ADD_PRODUCT: "dqa-seller-add-product";
284
297
  readonly SELLER_ADD_COUPON: "dqa-seller-add-coupon";
285
298
  readonly SELLER_VIEW_ORDERS: "dqa-seller-view-orders";
286
299
  readonly SELLER_PAYOUT_REQ: "dqa-seller-payout-request";
287
300
  readonly SELLER_SETTINGS: "dqa-seller-settings";
301
+ readonly SELLER_AUCTIONS: "dqa-seller-auctions";
302
+ readonly SELLER_SHIPPING: "dqa-seller-shipping";
303
+ readonly SELLER_MESSAGES: "dqa-seller-messages";
304
+ readonly SELLER_WHATSAPP: "dqa-seller-whatsapp";
305
+ readonly SELLER_REVIEWS: "dqa-seller-reviews";
306
+ readonly SELLER_PRODUCTS: "dqa-seller-products";
307
+ readonly SELLER_STOREFRONT: "dqa-seller-storefront";
308
+ readonly SELLER_ANALYTICS: "dqa-seller-analytics";
288
309
  readonly USER_VIEW_ORDERS: "dqa-user-view-orders";
289
310
  readonly USER_VIEW_WISHLIST: "dqa-user-view-wishlist";
290
311
  readonly USER_EDIT_PROFILE: "dqa-user-edit-profile";
291
312
  readonly USER_ADD_ADDRESS: "dqa-user-add-address";
313
+ readonly USER_RECENTLY_VIEWED: "dqa-user-recently-viewed";
314
+ readonly USER_MY_CATALOGUE: "dqa-user-my-catalogue";
315
+ readonly USER_MY_COUPONS: "dqa-user-my-coupons";
292
316
  };
293
317
  export type DashboardQuickActionId = (typeof DASHBOARD_QUICK_ACTION_ID)[keyof typeof DASHBOARD_QUICK_ACTION_ID];
294
318
  export interface DashboardQuickActionMeta {
@@ -309,9 +333,9 @@ export interface DashboardQuickActionMeta {
309
333
  }
310
334
  export declare const DASHBOARD_QUICK_ACTION_META: Record<DashboardQuickActionId, DashboardQuickActionMeta>;
311
335
  export declare const DASHBOARD_QUICK_ACTIONS: {
312
- readonly admin: readonly ["dqa-admin-add-product", "dqa-admin-add-user", "dqa-admin-add-store", "dqa-admin-add-coupon", "dqa-admin-add-event", "dqa-admin-add-blog", "dqa-admin-settings"];
313
- readonly seller: readonly ["dqa-seller-add-product", "dqa-seller-add-coupon", "dqa-seller-view-orders", "dqa-seller-payout-request", "dqa-seller-settings"];
314
- readonly user: readonly ["dqa-user-view-orders", "dqa-user-view-wishlist", "dqa-user-edit-profile", "dqa-user-add-address"];
336
+ readonly admin: readonly ["dqa-admin-add-product", "dqa-admin-add-user", "dqa-admin-add-store", "dqa-admin-add-coupon", "dqa-admin-add-event", "dqa-admin-add-blog", "dqa-admin-users", "dqa-admin-stores", "dqa-admin-orders", "dqa-admin-payouts", "dqa-admin-analytics", "dqa-admin-categories", "dqa-admin-reviews", "dqa-admin-events", "dqa-admin-faqs", "dqa-admin-carousel", "dqa-admin-sections", "dqa-admin-support", "dqa-admin-moderation", "dqa-admin-integration-guides", "dqa-admin-settings"];
337
+ readonly seller: readonly ["dqa-seller-add-product", "dqa-seller-products", "dqa-seller-view-orders", "dqa-seller-analytics", "dqa-seller-add-coupon", "dqa-seller-auctions", "dqa-seller-payout-request", "dqa-seller-shipping", "dqa-seller-messages", "dqa-seller-whatsapp", "dqa-seller-reviews", "dqa-seller-storefront", "dqa-seller-settings"];
338
+ readonly user: readonly ["dqa-user-view-orders", "dqa-user-view-wishlist", "dqa-user-edit-profile", "dqa-user-add-address", "dqa-user-recently-viewed", "dqa-user-my-catalogue", "dqa-user-my-coupons"];
315
339
  };
316
340
  export declare const ADMIN_BULK_ACTIONS: {
317
341
  readonly users: readonly ["row-manage", "row-suspend", "row-restore", "row-delete"];
@@ -53,7 +53,6 @@ export const ACTION_ID = {
53
53
  // ── Checkout / navigation CTAs ───────────────────────────────────────────
54
54
  CHECKOUT: "checkout",
55
55
  CONTINUE_TO_VERIFY: "continue-to-verification",
56
- SEND_OTP: "send-otp",
57
56
  VERIFY_OTP: "verify-otp",
58
57
  PAY_ONLINE: "pay-online",
59
58
  PAY_COD: "pay-cod",
@@ -99,7 +98,6 @@ export const ACTION_META = {
99
98
  // ── Checkout / navigation CTAs ────────────────────────────────────────────
100
99
  [ACTION_ID.CHECKOUT]: { id: ACTION_ID.CHECKOUT, label: regLabel("CART", "checkout", "Checkout"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
101
100
  [ACTION_ID.CONTINUE_TO_VERIFY]: { id: ACTION_ID.CONTINUE_TO_VERIFY, label: regLabel("CHECKOUT", "continue-to-verification", "Continue"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
102
- [ACTION_ID.SEND_OTP]: { id: ACTION_ID.SEND_OTP, label: regLabel("CHECKOUT", "send-otp", "Send Code"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
103
101
  [ACTION_ID.VERIFY_OTP]: { id: ACTION_ID.VERIFY_OTP, label: regLabel("CHECKOUT", "verify-otp", "Verify & Continue"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
104
102
  [ACTION_ID.PAY_ONLINE]: { id: ACTION_ID.PAY_ONLINE, label: regLabel("CHECKOUT", "pay-online", "Pay Online"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
105
103
  [ACTION_ID.PAY_COD]: { id: ACTION_ID.PAY_COD, label: regLabel("CHECKOUT", "pay-cod", "Cash on Delivery"), variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
@@ -351,17 +349,42 @@ export const DASHBOARD_QUICK_ACTION_ID = {
351
349
  ADMIN_ADD_BLOG: "dqa-admin-add-blog",
352
350
  ADMIN_ADD_FAQ: "dqa-admin-add-faq",
353
351
  ADMIN_SETTINGS: "dqa-admin-settings",
352
+ ADMIN_STORES: "dqa-admin-stores",
353
+ ADMIN_ORDERS: "dqa-admin-orders",
354
+ ADMIN_PAYOUTS: "dqa-admin-payouts",
355
+ ADMIN_ANALYTICS: "dqa-admin-analytics",
356
+ ADMIN_EVENTS: "dqa-admin-events",
357
+ ADMIN_SUPPORT: "dqa-admin-support",
358
+ ADMIN_MODERATION: "dqa-admin-moderation",
359
+ ADMIN_INTEGRATION_GUIDES: "dqa-admin-integration-guides",
360
+ ADMIN_USERS: "dqa-admin-users",
361
+ ADMIN_CATEGORIES: "dqa-admin-categories",
362
+ ADMIN_REVIEWS: "dqa-admin-reviews",
363
+ ADMIN_FAQS: "dqa-admin-faqs",
364
+ ADMIN_CAROUSEL: "dqa-admin-carousel",
365
+ ADMIN_SECTIONS: "dqa-admin-sections",
354
366
  // Seller / Store
355
367
  SELLER_ADD_PRODUCT: "dqa-seller-add-product",
356
368
  SELLER_ADD_COUPON: "dqa-seller-add-coupon",
357
369
  SELLER_VIEW_ORDERS: "dqa-seller-view-orders",
358
370
  SELLER_PAYOUT_REQ: "dqa-seller-payout-request",
359
371
  SELLER_SETTINGS: "dqa-seller-settings",
372
+ SELLER_AUCTIONS: "dqa-seller-auctions",
373
+ SELLER_SHIPPING: "dqa-seller-shipping",
374
+ SELLER_MESSAGES: "dqa-seller-messages",
375
+ SELLER_WHATSAPP: "dqa-seller-whatsapp",
376
+ SELLER_REVIEWS: "dqa-seller-reviews",
377
+ SELLER_PRODUCTS: "dqa-seller-products",
378
+ SELLER_STOREFRONT: "dqa-seller-storefront",
379
+ SELLER_ANALYTICS: "dqa-seller-analytics",
360
380
  // User / Buyer
361
381
  USER_VIEW_ORDERS: "dqa-user-view-orders",
362
382
  USER_VIEW_WISHLIST: "dqa-user-view-wishlist",
363
383
  USER_EDIT_PROFILE: "dqa-user-edit-profile",
364
384
  USER_ADD_ADDRESS: "dqa-user-add-address",
385
+ USER_RECENTLY_VIEWED: "dqa-user-recently-viewed",
386
+ USER_MY_CATALOGUE: "dqa-user-my-catalogue",
387
+ USER_MY_COUPONS: "dqa-user-my-coupons",
365
388
  };
366
389
  export const DASHBOARD_QUICK_ACTION_META = {
367
390
  [DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_PRODUCT]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_PRODUCT, label: "Add Product", variant: "primary", iconName: "Plus", requiresAuth: true, requiredRole: "admin", requiredPermission: "products.create" },
@@ -372,15 +395,40 @@ export const DASHBOARD_QUICK_ACTION_META = {
372
395
  [DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_BLOG]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_BLOG, label: "New Post", variant: "outline", iconName: "FileText", requiresAuth: true, requiredRole: "admin", requiredPermission: "blog.create" },
373
396
  [DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_FAQ]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_FAQ, label: "Add FAQ", variant: "outline", iconName: "HelpCircle", requiresAuth: true, requiredRole: "admin", requiredPermission: "faqs.create" },
374
397
  [DASHBOARD_QUICK_ACTION_ID.ADMIN_SETTINGS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_SETTINGS, label: "Settings", variant: "ghost", iconName: "Settings", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.settings.read" },
398
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_STORES]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_STORES, label: "Stores", variant: "outline", iconName: "Store", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.stores.read" },
399
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_ORDERS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_ORDERS, label: "Orders", variant: "outline", iconName: "ShoppingBag", requiresAuth: true, requiredRole: "admin", requiredPermission: "orders.read" },
400
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_PAYOUTS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_PAYOUTS, label: "Payouts", variant: "outline", iconName: "Banknote", requiresAuth: true, requiredRole: "admin", requiredPermission: "payouts.read" },
401
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_ANALYTICS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_ANALYTICS, label: "Analytics", variant: "outline", iconName: "BarChart", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.analytics.read" },
402
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_EVENTS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_EVENTS, label: "Events", variant: "outline", iconName: "Calendar", requiresAuth: true, requiredRole: "admin", requiredPermission: "events.read" },
403
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT, label: "Support Tickets", variant: "outline", iconName: "LifeBuoy", requiresAuth: true, requiredRole: "admin", requiredPermission: "support.read" },
404
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION, label: "Moderation", variant: "outline", iconName: "ShieldAlert", requiresAuth: true, requiredRole: "admin", requiredPermission: "moderation.read" },
405
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES, label: "Integration Guides", variant: "ghost", iconName: "BookOpen", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin:site:read" },
406
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_USERS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_USERS, label: "Users", variant: "outline", iconName: "Users", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.users.read" },
407
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_CATEGORIES]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_CATEGORIES, label: "Categories", variant: "outline", iconName: "Tag", requiresAuth: true, requiredRole: "admin", requiredPermission: "categories.read" },
408
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_REVIEWS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_REVIEWS, label: "Reviews", variant: "outline", iconName: "Star", requiresAuth: true, requiredRole: "admin", requiredPermission: "reviews.read" },
409
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_FAQS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_FAQS, label: "FAQs", variant: "outline", iconName: "HelpCircle", requiresAuth: true, requiredRole: "admin", requiredPermission: "faqs.read" },
410
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_CAROUSEL]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_CAROUSEL, label: "Carousel", variant: "outline", iconName: "Layout", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.settings.read" },
411
+ [DASHBOARD_QUICK_ACTION_ID.ADMIN_SECTIONS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_SECTIONS, label: "Sections", variant: "outline", iconName: "Layers", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.settings.read" },
375
412
  [DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_PRODUCT]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_PRODUCT, label: "List a Product", variant: "primary", iconName: "Plus", requiresAuth: true, requiredRole: "seller", requiredPermission: "products.create" },
376
413
  [DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_COUPON]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_COUPON, label: "New Coupon", variant: "outline", iconName: "Tag", requiresAuth: true, requiredRole: "seller", requiredPermission: "coupons.create" },
377
414
  [DASHBOARD_QUICK_ACTION_ID.SELLER_VIEW_ORDERS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_VIEW_ORDERS, label: "Orders", variant: "outline", iconName: "ShoppingBag", requiresAuth: true, requiredRole: "seller" },
378
415
  [DASHBOARD_QUICK_ACTION_ID.SELLER_PAYOUT_REQ]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_PAYOUT_REQ, label: "Request Payout", variant: "outline", iconName: "Banknote", requiresAuth: true, requiredRole: "seller", requiredPermission: "seller.payouts.request" },
379
416
  [DASHBOARD_QUICK_ACTION_ID.SELLER_SETTINGS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_SETTINGS, label: "Store Settings", variant: "ghost", iconName: "Settings", requiresAuth: true, requiredRole: "seller" },
417
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_AUCTIONS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_AUCTIONS, label: "Auctions", variant: "outline", iconName: "Gavel", requiresAuth: true, requiredRole: "seller" },
418
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_SHIPPING]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_SHIPPING, label: "Shipping", variant: "outline", iconName: "Truck", requiresAuth: true, requiredRole: "seller" },
419
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_MESSAGES]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_MESSAGES, label: "Messages", variant: "outline", iconName: "MessageCircle", requiresAuth: true, requiredRole: "seller" },
420
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_WHATSAPP]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_WHATSAPP, label: "WhatsApp", variant: "outline", iconName: "Phone", requiresAuth: true, requiredRole: "seller" },
421
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_REVIEWS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_REVIEWS, label: "Reviews", variant: "outline", iconName: "Star", requiresAuth: true, requiredRole: "seller" },
422
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_PRODUCTS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_PRODUCTS, label: "My Products", variant: "outline", iconName: "Package", requiresAuth: true, requiredRole: "seller" },
423
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_STOREFRONT]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_STOREFRONT, label: "My Storefront", variant: "outline", iconName: "Store", requiresAuth: true, requiredRole: "seller" },
424
+ [DASHBOARD_QUICK_ACTION_ID.SELLER_ANALYTICS]: { id: DASHBOARD_QUICK_ACTION_ID.SELLER_ANALYTICS, label: "Analytics", variant: "outline", iconName: "BarChart", requiresAuth: true, requiredRole: "seller" },
380
425
  [DASHBOARD_QUICK_ACTION_ID.USER_VIEW_ORDERS]: { id: DASHBOARD_QUICK_ACTION_ID.USER_VIEW_ORDERS, label: "My Orders", variant: "outline", iconName: "Package", requiresAuth: true, requiredRole: "user" },
381
426
  [DASHBOARD_QUICK_ACTION_ID.USER_VIEW_WISHLIST]: { id: DASHBOARD_QUICK_ACTION_ID.USER_VIEW_WISHLIST, label: "Wishlist", variant: "outline", iconName: "Heart", requiresAuth: true, requiredRole: "user" },
382
427
  [DASHBOARD_QUICK_ACTION_ID.USER_EDIT_PROFILE]: { id: DASHBOARD_QUICK_ACTION_ID.USER_EDIT_PROFILE, label: "Edit Profile", variant: "outline", iconName: "User", requiresAuth: true, requiredRole: "user" },
383
428
  [DASHBOARD_QUICK_ACTION_ID.USER_ADD_ADDRESS]: { id: DASHBOARD_QUICK_ACTION_ID.USER_ADD_ADDRESS, label: "Add Address", variant: "outline", iconName: "MapPin", requiresAuth: true, requiredRole: "user" },
429
+ [DASHBOARD_QUICK_ACTION_ID.USER_RECENTLY_VIEWED]: { id: DASHBOARD_QUICK_ACTION_ID.USER_RECENTLY_VIEWED, label: "Recently Viewed", variant: "outline", iconName: "Clock", requiresAuth: true, requiredRole: "user" },
430
+ [DASHBOARD_QUICK_ACTION_ID.USER_MY_CATALOGUE]: { id: DASHBOARD_QUICK_ACTION_ID.USER_MY_CATALOGUE, label: "My Catalogue", variant: "outline", iconName: "Archive", requiresAuth: true, requiredRole: "user" },
431
+ [DASHBOARD_QUICK_ACTION_ID.USER_MY_COUPONS]: { id: DASHBOARD_QUICK_ACTION_ID.USER_MY_COUPONS, label: "My Coupons", variant: "outline", iconName: "Ticket", requiresAuth: true, requiredRole: "user" },
384
432
  };
385
433
  // Quick action groups — ordered left-to-right in the top shortcut bar
386
434
  export const DASHBOARD_QUICK_ACTIONS = {
@@ -391,13 +439,35 @@ export const DASHBOARD_QUICK_ACTIONS = {
391
439
  DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_COUPON,
392
440
  DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_EVENT,
393
441
  DASHBOARD_QUICK_ACTION_ID.ADMIN_ADD_BLOG,
442
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_USERS,
443
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_STORES,
444
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_ORDERS,
445
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_PAYOUTS,
446
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_ANALYTICS,
447
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_CATEGORIES,
448
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_REVIEWS,
449
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_EVENTS,
450
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_FAQS,
451
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_CAROUSEL,
452
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_SECTIONS,
453
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT,
454
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION,
455
+ DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES,
394
456
  DASHBOARD_QUICK_ACTION_ID.ADMIN_SETTINGS,
395
457
  ],
396
458
  seller: [
397
459
  DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_PRODUCT,
398
- DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_COUPON,
460
+ DASHBOARD_QUICK_ACTION_ID.SELLER_PRODUCTS,
399
461
  DASHBOARD_QUICK_ACTION_ID.SELLER_VIEW_ORDERS,
462
+ DASHBOARD_QUICK_ACTION_ID.SELLER_ANALYTICS,
463
+ DASHBOARD_QUICK_ACTION_ID.SELLER_ADD_COUPON,
464
+ DASHBOARD_QUICK_ACTION_ID.SELLER_AUCTIONS,
400
465
  DASHBOARD_QUICK_ACTION_ID.SELLER_PAYOUT_REQ,
466
+ DASHBOARD_QUICK_ACTION_ID.SELLER_SHIPPING,
467
+ DASHBOARD_QUICK_ACTION_ID.SELLER_MESSAGES,
468
+ DASHBOARD_QUICK_ACTION_ID.SELLER_WHATSAPP,
469
+ DASHBOARD_QUICK_ACTION_ID.SELLER_REVIEWS,
470
+ DASHBOARD_QUICK_ACTION_ID.SELLER_STOREFRONT,
401
471
  DASHBOARD_QUICK_ACTION_ID.SELLER_SETTINGS,
402
472
  ],
403
473
  user: [
@@ -405,6 +475,9 @@ export const DASHBOARD_QUICK_ACTIONS = {
405
475
  DASHBOARD_QUICK_ACTION_ID.USER_VIEW_WISHLIST,
406
476
  DASHBOARD_QUICK_ACTION_ID.USER_EDIT_PROFILE,
407
477
  DASHBOARD_QUICK_ACTION_ID.USER_ADD_ADDRESS,
478
+ DASHBOARD_QUICK_ACTION_ID.USER_RECENTLY_VIEWED,
479
+ DASHBOARD_QUICK_ACTION_ID.USER_MY_CATALOGUE,
480
+ DASHBOARD_QUICK_ACTION_ID.USER_MY_COUPONS,
408
481
  ],
409
482
  };
410
483
  // Admin bulk actions per listing entity — used in BulkActionsBar on admin tables
@@ -18,6 +18,12 @@ export declare class ProductRepository extends BaseRepository<ProductDocument> {
18
18
  findByStatus(status: ProductStatus): Promise<ProductDocument[]>;
19
19
  findFeatured(): Promise<ProductDocument[]>;
20
20
  findByCategory(category: string): Promise<ProductDocument[]>;
21
+ /**
22
+ * Published products sharing at least one tag with the given list — "you
23
+ * might also like" style discovery. `array-contains-any` caps at 10 values,
24
+ * so only the first 10 tags are used.
25
+ */
26
+ findByTagsOverlap(tags: string[], limit?: number): Promise<ProductDocument[]>;
21
27
  findByBarcodeId(barcodeId: string): Promise<ProductDocument | null>;
22
28
  findBySlug(slug: string): Promise<ProductDocument | undefined>;
23
29
  findByIdOrSlug(idOrSlug: string): Promise<ProductDocument | undefined>;
@@ -145,6 +145,21 @@ export class ProductRepository extends BaseRepository {
145
145
  .get();
146
146
  return snap.docs.map((d) => this.mapDoc(d));
147
147
  }
148
+ /**
149
+ * Published products sharing at least one tag with the given list — "you
150
+ * might also like" style discovery. `array-contains-any` caps at 10 values,
151
+ * so only the first 10 tags are used.
152
+ */
153
+ async findByTagsOverlap(tags, limit = 8) {
154
+ if (tags.length === 0)
155
+ return [];
156
+ const snap = await this.getCollection()
157
+ .where(PRODUCT_FIELDS.STATUS, "==", ProductStatusValues.PUBLISHED)
158
+ .where(PRODUCT_FIELDS.TAGS, "array-contains-any", tags.slice(0, 10))
159
+ .limit(limit)
160
+ .get();
161
+ return snap.docs.map((d) => this.mapDoc(d));
162
+ }
148
163
  async findByBarcodeId(barcodeId) {
149
164
  const docs = await this.findBy("barcodeId", barcodeId);
150
165
  return docs[0] ?? null;
@@ -226,10 +241,14 @@ export class ProductRepository extends BaseRepository {
226
241
  return snapshot.docs.map((doc) => this.mapDoc(doc));
227
242
  }
228
243
  async findByGroupId(groupId) {
244
+ // Tier GP: groups may mix standard products + pre-orders (never auctions).
229
245
  const snapshot = await this.db
230
246
  .collection(this.collection)
231
247
  .where("groupId", "==", groupId)
232
- .where(PRODUCT_FIELDS.LISTING_TYPE, "==", LISTING_TYPE_VALUES.STANDARD)
248
+ .where(PRODUCT_FIELDS.LISTING_TYPE, "in", [
249
+ LISTING_TYPE_VALUES.STANDARD,
250
+ LISTING_TYPE_VALUES.PRE_ORDER,
251
+ ])
233
252
  .get();
234
253
  return snapshot.docs.map((doc) => this.mapDoc(doc));
235
254
  }
@@ -263,18 +263,40 @@ export interface ProductDocument extends BaseDocument {
263
263
  pricePerEntry?: number;
264
264
  prizeMaxEntries?: number;
265
265
  prizeCurrentEntries?: number;
266
+ /**
267
+ * Draw start, set once at creation (= createdAt) — never seller-edited.
268
+ * `prizeRevealWindowEnd` is derived from this + `prizeDrawDurationDays`.
269
+ */
266
270
  prizeRevealWindowStart?: Date;
271
+ /** Hard expiry — `prizeRevealWindowStart` + `prizeDrawDurationDays` days. */
267
272
  prizeRevealWindowEnd?: Date;
273
+ /**
274
+ * "pending" is legacy-only (no longer written by new listings — reveal is
275
+ * fully automatic, there's no seller-facing delayed-start concept anymore;
276
+ * draft→published is how a seller holds a draw back). New listings go
277
+ * straight to "open"; "closed" once every eligible order has been revealed.
278
+ */
268
279
  prizeRevealStatus?: "pending" | "open" | "closed";
269
- prizeRevealDeadlineDays?: number;
280
+ /**
281
+ * Seller-facing duration input, 1–15 days (PRIZE_DRAW_DURATION_DAYS_MIN/MAX
282
+ * in checkout/rules/_limits.ts). Drives `prizeRevealWindowEnd` at creation.
283
+ */
284
+ prizeDrawDurationDays?: number;
270
285
  /** Public proof-of-fairness file (commit-reveal scheme). */
271
286
  prizeGithubFileUrl?: string;
272
287
  /**
273
288
  * Draw mode for prize-draw listings.
274
- * "reveal" = classic buyer-reveal flow (default, backward-compat).
289
+ * "reveal" = classic automatic-reveal flow (default, backward-compat).
275
290
  * "lottery" = user self-pull with weighted random slot assignment.
276
291
  */
277
292
  prizeDrawMode?: "reveal" | "lottery";
293
+ /**
294
+ * Reveal trigger for "reveal" mode draws (irrelevant for "lottery" mode).
295
+ * "instant" — winner assigned the moment the order's payment is confirmed.
296
+ * "scheduled" — winner assigned automatically at whichever comes first:
297
+ * `prizeRevealWindowEnd` or full sellout (`prizeCurrentEntries === prizeMaxEntries`).
298
+ */
299
+ prizeRevealMode?: "instant" | "scheduled";
278
300
  /**
279
301
  * Full lottery config. Only set when prizeDrawMode === "lottery".
280
302
  * Includes server-only price/weight fields — stripped by adapter before any client response.
@@ -333,6 +355,8 @@ export interface PrizeDrawItem {
333
355
  /** Per-slot price in decimal rupees for lottery mode. Lower price = higher weight = higher chance. */
334
356
  prizeSlotPrice?: number;
335
357
  isWon: boolean;
358
+ /** Order id this item was assigned to — set alongside isWon:true. Admin/seller-only mapping (never public) so the seller knows which physical item ships to which order. */
359
+ wonByOrderId?: string;
336
360
  }
337
361
  /** Runtime-accessible product status values — use instead of bare string literals. */
338
362
  export declare const ProductStatusValues: {
@@ -149,6 +149,7 @@ export declare const productItemSchema: z.ZodObject<{
149
149
  condition: z.ZodString;
150
150
  estimatedValue: z.ZodOptional<z.ZodNumber>;
151
151
  isWon: z.ZodBoolean;
152
+ wonByOrderId: z.ZodOptional<z.ZodString>;
152
153
  }, "strip", z.ZodTypeAny, {
153
154
  title: string;
154
155
  images: string[];
@@ -161,6 +162,7 @@ export declare const productItemSchema: z.ZodObject<{
161
162
  } | undefined;
162
163
  description?: string | undefined;
163
164
  estimatedValue?: number | undefined;
165
+ wonByOrderId?: string | undefined;
164
166
  }, {
165
167
  title: string;
166
168
  images: string[];
@@ -173,6 +175,7 @@ export declare const productItemSchema: z.ZodObject<{
173
175
  } | undefined;
174
176
  description?: string | undefined;
175
177
  estimatedValue?: number | undefined;
178
+ wonByOrderId?: string | undefined;
176
179
  }>, "many">>;
177
180
  pricePerEntry: z.ZodOptional<z.ZodNumber>;
178
181
  prizeMaxEntries: z.ZodOptional<z.ZodNumber>;
@@ -180,7 +183,8 @@ export declare const productItemSchema: z.ZodObject<{
180
183
  prizeRevealWindowStart: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodDate]>>;
181
184
  prizeRevealWindowEnd: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodDate]>>;
182
185
  prizeRevealStatus: z.ZodOptional<z.ZodEnum<["pending", "open", "closed"]>>;
183
- prizeRevealDeadlineDays: z.ZodOptional<z.ZodNumber>;
186
+ prizeDrawDurationDays: z.ZodOptional<z.ZodNumber>;
187
+ prizeRevealMode: z.ZodOptional<z.ZodEnum<["instant", "scheduled"]>>;
184
188
  prizeGithubFileUrl: z.ZodOptional<z.ZodString>;
185
189
  inStock: z.ZodOptional<z.ZodBoolean>;
186
190
  stockCount: z.ZodOptional<z.ZodNumber>;
@@ -423,6 +427,7 @@ export declare const productItemSchema: z.ZodObject<{
423
427
  } | undefined;
424
428
  description?: string | undefined;
425
429
  estimatedValue?: number | undefined;
430
+ wonByOrderId?: string | undefined;
426
431
  }[] | undefined;
427
432
  pricePerEntry?: number | undefined;
428
433
  prizeMaxEntries?: number | undefined;
@@ -430,8 +435,9 @@ export declare const productItemSchema: z.ZodObject<{
430
435
  prizeRevealWindowStart?: string | Date | undefined;
431
436
  prizeRevealWindowEnd?: string | Date | undefined;
432
437
  prizeRevealStatus?: "closed" | "open" | "pending" | undefined;
433
- prizeRevealDeadlineDays?: number | undefined;
438
+ prizeDrawDurationDays?: number | undefined;
434
439
  prizeGithubFileUrl?: string | undefined;
440
+ prizeRevealMode?: "instant" | "scheduled" | undefined;
435
441
  media?: {
436
442
  type: "video" | "image" | "file";
437
443
  url: string;
@@ -559,6 +565,7 @@ export declare const productItemSchema: z.ZodObject<{
559
565
  } | undefined;
560
566
  description?: string | undefined;
561
567
  estimatedValue?: number | undefined;
568
+ wonByOrderId?: string | undefined;
562
569
  }[] | undefined;
563
570
  pricePerEntry?: number | undefined;
564
571
  prizeMaxEntries?: number | undefined;
@@ -566,8 +573,9 @@ export declare const productItemSchema: z.ZodObject<{
566
573
  prizeRevealWindowStart?: string | Date | undefined;
567
574
  prizeRevealWindowEnd?: string | Date | undefined;
568
575
  prizeRevealStatus?: "closed" | "open" | "pending" | undefined;
569
- prizeRevealDeadlineDays?: number | undefined;
576
+ prizeDrawDurationDays?: number | undefined;
570
577
  prizeGithubFileUrl?: string | undefined;
578
+ prizeRevealMode?: "instant" | "scheduled" | undefined;
571
579
  media?: {
572
580
  type: "video" | "image" | "file";
573
581
  url: string;
@@ -1,6 +1,7 @@
1
1
  export * from "./firestore";
2
2
  import { z } from "zod";
3
3
  import { mediaFieldSchema } from "../../media/types/index";
4
+ import { PRIZE_DRAW_DURATION_DAYS_MIN, PRIZE_DRAW_DURATION_DAYS_MAX, } from "../../../_internal/shared/checkout/rules/_limits";
4
5
  // --- Sub-schemas --------------------------------------------------------------
5
6
  export const productImageSchema = z.object({
6
7
  url: z.string(),
@@ -96,8 +97,9 @@ export const productItemSchema = z.object({
96
97
  condition: z.string(),
97
98
  estimatedValue: z.number().optional(),
98
99
  isWon: z.boolean(),
100
+ wonByOrderId: z.string().optional(),
99
101
  }))
100
- .min(3)
102
+ .min(2)
101
103
  .max(16)
102
104
  .optional(),
103
105
  pricePerEntry: z.number().positive().optional(),
@@ -106,7 +108,13 @@ export const productItemSchema = z.object({
106
108
  prizeRevealWindowStart: z.union([z.string(), z.date()]).optional(),
107
109
  prizeRevealWindowEnd: z.union([z.string(), z.date()]).optional(),
108
110
  prizeRevealStatus: z.enum(["pending", "open", "closed"]).optional(),
109
- prizeRevealDeadlineDays: z.number().int().positive().optional(),
111
+ prizeDrawDurationDays: z
112
+ .number()
113
+ .int()
114
+ .min(PRIZE_DRAW_DURATION_DAYS_MIN)
115
+ .max(PRIZE_DRAW_DURATION_DAYS_MAX)
116
+ .optional(),
117
+ prizeRevealMode: z.enum(["instant", "scheduled"]).optional(),
110
118
  prizeGithubFileUrl: z.string().url().optional(),
111
119
  inStock: z.boolean().optional(),
112
120
  stockCount: z.number().optional(),
@@ -136,7 +136,8 @@ export interface ProductItem {
136
136
  prizeRevealWindowStart?: string | Date;
137
137
  prizeRevealWindowEnd?: string | Date;
138
138
  prizeRevealStatus?: "pending" | "open" | "closed";
139
- prizeRevealDeadlineDays?: number;
139
+ prizeDrawDurationDays?: number;
140
+ prizeRevealMode?: "instant" | "scheduled";
140
141
  prizeGithubFileUrl?: string;
141
142
  maxPerUser?: number;
142
143
  /** Winner's display name for ended auctions — shown masked in public UI */
@@ -31,6 +31,7 @@ export async function createReview(userId, input) {
31
31
  return reviewRepository.create({
32
32
  productId: input.productId,
33
33
  productTitle: product.title,
34
+ listingType: product.listingType,
34
35
  storeId: product.storeId,
35
36
  storeName: product.storeName,
36
37
  userId,
@@ -4,6 +4,7 @@ import { reviewRepository } from "../../../repositories";
4
4
  import { Container, Div, Heading, Main, Nav, Section, Span, Text } from "../../../ui";
5
5
  import { ROUTES } from "../../../next";
6
6
  import { ReviewDetailShell } from "./ReviewDetailShell";
7
+ import { ReviewCard } from "./ReviewsList";
7
8
  export async function ReviewDetailPageView({ id }) {
8
9
  const doc = await reviewRepository.findById(id).catch(() => null);
9
10
  const review = doc;
@@ -12,5 +13,11 @@ export async function ReviewDetailPageView({ id }) {
12
13
  if (!review || review.status !== "approved") {
13
14
  return (_jsx(Main, { children: _jsx(Section, { padding: "y-6xl", children: _jsx(Container, { size: "sm", children: _jsxs(Div, { className: "text-left", children: [_jsx(Text, { className: "mb-4", size: "5xl", "aria-hidden": "true", children: "\uD83D\uDD0D" }), _jsx(Heading, { color: "inverse", level: 1, className: "text-[var(--appkit-color-text)] dark: mb-2", size: "2xl", weight: "bold", children: "Review not found" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)] mb-6", size: "sm", children: "This review may have been removed or is no longer available." }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "inline-flex items-center gap-[var(--appkit-space-2)] rounded-lg bg-primary px-[var(--appkit-space-5)] py-[var(--appkit-space-2-5)] text-[length:var(--appkit-text-sm)] font-medium text-white hover:bg-primary-600 transition-colors", children: "\u2190 Back to Reviews" })] }) }) }) }));
14
15
  }
15
- return (_jsxs(Main, { children: [_jsx(Div, { paddingY: "y-xs-tall", className: "border-b border-neutral-100 bg-neutral-50", padding: "x-md", children: _jsxs(Nav, { layout: "flex", gap: "2xs", textSize: "xs", color: "faint", className: "mx-auto max-w-3xl", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary transition-colors", children: "Home" }), _jsx(Span, { children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "hover:text-primary transition-colors", children: "Reviews" }), _jsx(Span, { children: "/" }), _jsx(Span, { className: "text-neutral-700 truncate max-w-[200px]", children: review.title ?? review.id })] }) }), _jsx(ReviewDetailShell, { review: review, storeHref: storeSlug ? String(ROUTES.PUBLIC.STORE_DETAIL(storeSlug)) : null })] }));
16
+ const [sameProductDocs, sameStoreDocs] = await Promise.all([
17
+ reviewRepository.findApprovedByProduct(review.productId).catch(() => []),
18
+ storeSlug ? reviewRepository.findApprovedByStore(storeSlug).catch(() => []) : Promise.resolve([]),
19
+ ]);
20
+ const sameProductReviews = sameProductDocs.filter((r) => r.id !== review.id).slice(0, 6);
21
+ const sameStoreReviews = sameStoreDocs.filter((r) => r.id !== review.id).slice(0, 6);
22
+ return (_jsxs(Main, { children: [_jsx(Div, { paddingY: "y-xs-tall", className: "border-b border-neutral-100 bg-neutral-50", padding: "x-md", children: _jsxs(Nav, { layout: "flex", gap: "2xs", textSize: "xs", color: "faint", className: "mx-auto max-w-3xl", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary transition-colors", children: "Home" }), _jsx(Span, { children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "hover:text-primary transition-colors", children: "Reviews" }), _jsx(Span, { children: "/" }), _jsx(Span, { className: "text-neutral-700 truncate max-w-[200px]", children: review.title ?? review.id })] }) }), _jsx(ReviewDetailShell, { review: review, storeHref: storeSlug ? String(ROUTES.PUBLIC.STORE_DETAIL(storeSlug)) : null }), sameProductReviews.length > 0 && (_jsx(Section, { padding: "y-lg", border: "subtle", className: "border-t", children: _jsxs(Container, { size: "sm", children: [_jsxs(Heading, { level: 2, className: "mb-4", size: "lg", weight: "semibold", children: ["More reviews for ", review.productTitle ?? "this product"] }), _jsx(Div, { layout: "grid", gap: "4", className: "sm:grid-cols-2", children: sameProductReviews.map((r) => (_jsx(ReviewCard, { review: r, context: "listing" }, r.id))) })] }) })), sameStoreReviews.length > 0 && (_jsx(Section, { padding: "y-lg", border: "subtle", className: "border-t", children: _jsxs(Container, { size: "sm", children: [_jsxs(Heading, { level: 2, className: "mb-4", size: "lg", weight: "semibold", children: ["More reviews for ", review.storeName ?? "this store"] }), _jsx(Div, { layout: "grid", gap: "4", className: "sm:grid-cols-2", children: sameStoreReviews.map((r) => (_jsx(ReviewCard, { review: r, context: "store" }, r.id))) })] }) }))] }));
16
23
  }
@@ -24,6 +24,7 @@ import { maskName } from "../../../security";
24
24
  import { getDefaultLocale } from "../../../core/baseline-resolver";
25
25
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
26
26
  import { ROUTES } from "../../../next";
27
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
27
28
  import { apiClient } from "../../../http";
28
29
  import { REVIEW_ENDPOINTS } from "../../../constants/api-endpoints";
29
30
  export function ReviewDetailShell({ review, storeHref }) {
@@ -84,7 +85,7 @@ export function ReviewDetailShell({ review, storeHref }) {
84
85
  };
85
86
  // ── Links ───────────────────────────────────────────────────────────────────
86
87
  const productHref = review.productId
87
- ? String(ROUTES.PUBLIC.PRODUCT_DETAIL(review.productId))
88
+ ? pluginFor(review.listingType ?? "standard").detailRoute(review.productId)
88
89
  : null;
89
90
  const sellerHref = storeHref ?? null;
90
91
  const reviewerProfileId = review.userSlug ?? review.userId;