@mohasinac/appkit 2.6.3 → 2.6.5

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 (615) hide show
  1. package/dist/_internal/server/features/account/data.js +2 -2
  2. package/dist/_internal/server/features/bundles/data.d.ts +26 -6
  3. package/dist/_internal/server/features/bundles/data.js +41 -6
  4. package/dist/_internal/server/features/bundles/index.d.ts +3 -2
  5. package/dist/_internal/server/features/bundles/index.js +4 -2
  6. package/dist/_internal/server/features/bundles/metadata.d.ts +20 -0
  7. package/dist/_internal/server/features/bundles/metadata.js +46 -0
  8. package/dist/_internal/server/features/bundles/og.d.ts +38 -0
  9. package/dist/_internal/server/features/bundles/og.js +122 -0
  10. package/dist/_internal/server/features/checkout/actions.js +192 -133
  11. package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +57 -0
  12. package/dist/_internal/server/features/checkout/bundle-expansion.js +70 -0
  13. package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +5 -15
  14. package/dist/_internal/server/features/checkout/prize-bundle-gates.js +5 -21
  15. package/dist/_internal/server/features/media/contextGuards.js +15 -1
  16. package/dist/_internal/server/features/payouts/actions.d.ts +19 -0
  17. package/dist/_internal/server/features/payouts/actions.js +38 -0
  18. package/dist/_internal/server/features/products/data.js +1 -2
  19. package/dist/_internal/server/features/raffle/actions.d.ts +11 -0
  20. package/dist/_internal/server/features/raffle/actions.js +31 -0
  21. package/dist/_internal/server/features/refunds/actions.d.ts +31 -0
  22. package/dist/_internal/server/features/refunds/actions.js +77 -0
  23. package/dist/_internal/server/jobs/core/adminAnalytics.d.ts +28 -0
  24. package/dist/_internal/server/jobs/core/adminAnalytics.js +98 -0
  25. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +19 -0
  26. package/dist/_internal/server/jobs/core/assignSpinPrize.js +81 -0
  27. package/dist/_internal/server/jobs/core/auctionSettlement.d.ts +2 -0
  28. package/dist/_internal/server/jobs/core/auctionSettlement.js +70 -0
  29. package/dist/_internal/server/jobs/core/autoPayoutEligibility.d.ts +2 -0
  30. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +109 -0
  31. package/dist/_internal/server/jobs/core/bundleStockSync.d.ts +10 -0
  32. package/dist/_internal/server/jobs/core/bundleStockSync.js +71 -0
  33. package/dist/_internal/server/jobs/core/cartPrune.d.ts +2 -0
  34. package/dist/_internal/server/jobs/core/cartPrune.js +13 -0
  35. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.d.ts +2 -0
  36. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +45 -0
  37. package/dist/_internal/server/jobs/core/countersReconcile.d.ts +2 -0
  38. package/dist/_internal/server/jobs/core/countersReconcile.js +107 -0
  39. package/dist/_internal/server/jobs/core/couponExpiry.d.ts +2 -0
  40. package/dist/_internal/server/jobs/core/couponExpiry.js +13 -0
  41. package/dist/_internal/server/jobs/core/dailyDataCleanup.d.ts +2 -0
  42. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +20 -0
  43. package/dist/_internal/server/jobs/core/index.d.ts +44 -0
  44. package/dist/_internal/server/jobs/core/index.js +47 -0
  45. package/dist/_internal/server/jobs/core/listingProcessor.d.ts +30 -0
  46. package/dist/_internal/server/jobs/core/listingProcessor.js +138 -0
  47. package/dist/_internal/server/jobs/core/mediaTmpCleanup.d.ts +14 -0
  48. package/dist/_internal/server/jobs/core/mediaTmpCleanup.js +68 -0
  49. package/dist/_internal/server/jobs/core/notificationPrune.d.ts +2 -0
  50. package/dist/_internal/server/jobs/core/notificationPrune.js +13 -0
  51. package/dist/_internal/server/jobs/core/offerExpiry.d.ts +2 -0
  52. package/dist/_internal/server/jobs/core/offerExpiry.js +50 -0
  53. package/dist/_internal/server/jobs/core/onBidPlaced.d.ts +15 -0
  54. package/dist/_internal/server/jobs/core/onBidPlaced.js +59 -0
  55. package/dist/_internal/server/jobs/core/onCategoryWrite.d.ts +14 -0
  56. package/dist/_internal/server/jobs/core/onCategoryWrite.js +134 -0
  57. package/dist/_internal/server/jobs/core/onOrderCreate.d.ts +18 -0
  58. package/dist/_internal/server/jobs/core/onOrderCreate.js +78 -0
  59. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +19 -0
  60. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +139 -0
  61. package/dist/_internal/server/jobs/core/onProductStockChange.d.ts +23 -0
  62. package/dist/_internal/server/jobs/core/onProductStockChange.js +130 -0
  63. package/dist/_internal/server/jobs/core/onProductWrite.d.ts +12 -0
  64. package/dist/_internal/server/jobs/core/onProductWrite.js +94 -0
  65. package/dist/_internal/server/jobs/core/onReviewWrite.d.ts +7 -0
  66. package/dist/_internal/server/jobs/core/onReviewWrite.js +49 -0
  67. package/dist/_internal/server/jobs/core/onStoreWrite.d.ts +12 -0
  68. package/dist/_internal/server/jobs/core/onStoreWrite.js +7 -0
  69. package/dist/_internal/server/jobs/core/payoutBatch.d.ts +8 -0
  70. package/dist/_internal/server/jobs/core/payoutBatch.js +102 -0
  71. package/dist/_internal/server/jobs/core/pendingOrderTimeout.d.ts +2 -0
  72. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +27 -0
  73. package/dist/_internal/server/jobs/core/positionsReconcile.d.ts +7 -0
  74. package/dist/_internal/server/jobs/core/positionsReconcile.js +87 -0
  75. package/dist/_internal/server/jobs/core/prizeRevealClose.d.ts +2 -0
  76. package/dist/_internal/server/jobs/core/prizeRevealClose.js +22 -0
  77. package/dist/_internal/server/jobs/core/prizeRevealExpiry.d.ts +2 -0
  78. package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +50 -0
  79. package/dist/_internal/server/jobs/core/prizeRevealOpen.d.ts +2 -0
  80. package/dist/_internal/server/jobs/core/prizeRevealOpen.js +56 -0
  81. package/dist/_internal/server/jobs/core/prizeRevealReminder.d.ts +2 -0
  82. package/dist/_internal/server/jobs/core/prizeRevealReminder.js +38 -0
  83. package/dist/_internal/server/jobs/core/productStatsSync.d.ts +8 -0
  84. package/dist/_internal/server/jobs/core/productStatsSync.js +36 -0
  85. package/dist/_internal/server/jobs/core/promotions.d.ts +12 -0
  86. package/dist/_internal/server/jobs/core/promotions.js +43 -0
  87. package/dist/_internal/server/jobs/core/storeAnalytics.d.ts +30 -0
  88. package/dist/_internal/server/jobs/core/storeAnalytics.js +109 -0
  89. package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +19 -0
  90. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +86 -0
  91. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.d.ts +6 -0
  92. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +85 -0
  93. package/dist/_internal/server/jobs/handlers/adminAnalytics.d.ts +2 -26
  94. package/dist/_internal/server/jobs/handlers/adminAnalytics.js +2 -98
  95. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +1 -22
  96. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +2 -86
  97. package/dist/_internal/server/jobs/handlers/auctionSettlement.js +2 -70
  98. package/dist/_internal/server/jobs/handlers/autoPayoutEligibility.js +2 -110
  99. package/dist/_internal/server/jobs/handlers/bundleStockSync.d.ts +0 -16
  100. package/dist/_internal/server/jobs/handlers/bundleStockSync.js +2 -80
  101. package/dist/_internal/server/jobs/handlers/cartPrune.js +2 -13
  102. package/dist/_internal/server/jobs/handlers/cleanupRtdbEvents.js +2 -45
  103. package/dist/_internal/server/jobs/handlers/countersReconcile.js +2 -109
  104. package/dist/_internal/server/jobs/handlers/couponExpiry.js +2 -13
  105. package/dist/_internal/server/jobs/handlers/dailyDataCleanup.js +2 -20
  106. package/dist/_internal/server/jobs/handlers/listingProcessor.d.ts +3 -28
  107. package/dist/_internal/server/jobs/handlers/listingProcessor.js +3 -138
  108. package/dist/_internal/server/jobs/handlers/mediaTmpCleanup.d.ts +0 -12
  109. package/dist/_internal/server/jobs/handlers/mediaTmpCleanup.js +2 -69
  110. package/dist/_internal/server/jobs/handlers/notificationPrune.js +2 -13
  111. package/dist/_internal/server/jobs/handlers/offerExpiry.js +2 -50
  112. package/dist/_internal/server/jobs/handlers/onBidPlaced.d.ts +1 -10
  113. package/dist/_internal/server/jobs/handlers/onBidPlaced.js +2 -56
  114. package/dist/_internal/server/jobs/handlers/onCategoryWrite.d.ts +1 -8
  115. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +6 -134
  116. package/dist/_internal/server/jobs/handlers/onOrderCreate.d.ts +1 -12
  117. package/dist/_internal/server/jobs/handlers/onOrderCreate.js +2 -76
  118. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.d.ts +1 -12
  119. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +2 -139
  120. package/dist/_internal/server/jobs/handlers/onProductStockChange.d.ts +0 -13
  121. package/dist/_internal/server/jobs/handlers/onProductStockChange.js +7 -134
  122. package/dist/_internal/server/jobs/handlers/onProductWrite.d.ts +1 -6
  123. package/dist/_internal/server/jobs/handlers/onProductWrite.js +6 -106
  124. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +2 -49
  125. package/dist/_internal/server/jobs/handlers/onStoreWrite.d.ts +1 -8
  126. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +7 -8
  127. package/dist/_internal/server/jobs/handlers/payoutBatch.d.ts +0 -9
  128. package/dist/_internal/server/jobs/handlers/payoutBatch.js +2 -104
  129. package/dist/_internal/server/jobs/handlers/pendingOrderTimeout.d.ts +0 -6
  130. package/dist/_internal/server/jobs/handlers/pendingOrderTimeout.js +2 -33
  131. package/dist/_internal/server/jobs/handlers/positionsReconcile.d.ts +0 -5
  132. package/dist/_internal/server/jobs/handlers/positionsReconcile.js +2 -87
  133. package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +0 -7
  134. package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +2 -29
  135. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +0 -8
  136. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +2 -58
  137. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +0 -8
  138. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +2 -65
  139. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +0 -7
  140. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +2 -45
  141. package/dist/_internal/server/jobs/handlers/productStatsSync.d.ts +0 -6
  142. package/dist/_internal/server/jobs/handlers/productStatsSync.js +2 -36
  143. package/dist/_internal/server/jobs/handlers/promotions.d.ts +2 -10
  144. package/dist/_internal/server/jobs/handlers/promotions.js +2 -43
  145. package/dist/_internal/server/jobs/handlers/storeAnalytics.d.ts +2 -28
  146. package/dist/_internal/server/jobs/handlers/storeAnalytics.js +2 -109
  147. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +1 -28
  148. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +2 -94
  149. package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.d.ts +0 -6
  150. package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +2 -87
  151. package/dist/_internal/server/jobs/index.d.ts +1 -0
  152. package/dist/_internal/server/jobs/index.js +1 -0
  153. package/dist/_internal/server/jobs/runtime/adapters/firebase.js +21 -0
  154. package/dist/_internal/shared/actions/action-registry.d.ts +84 -0
  155. package/dist/_internal/shared/actions/action-registry.js +160 -0
  156. package/dist/_internal/shared/checkout/rules/_defaults.d.ts +3 -0
  157. package/dist/_internal/shared/checkout/rules/_defaults.js +22 -0
  158. package/dist/_internal/shared/checkout/rules/_limits.d.ts +19 -0
  159. package/dist/_internal/shared/checkout/rules/_limits.js +19 -0
  160. package/dist/_internal/shared/checkout/rules/_registry.d.ts +44 -0
  161. package/dist/_internal/shared/checkout/rules/_registry.js +87 -0
  162. package/dist/_internal/shared/checkout/rules/auction.rule.d.ts +2 -0
  163. package/dist/_internal/shared/checkout/rules/auction.rule.js +10 -0
  164. package/dist/_internal/shared/checkout/rules/bundle.rule.d.ts +11 -0
  165. package/dist/_internal/shared/checkout/rules/bundle.rule.js +6 -0
  166. package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -0
  167. package/dist/_internal/shared/checkout/rules/classified.rule.js +9 -0
  168. package/dist/_internal/shared/checkout/rules/digital-code.rule.d.ts +8 -0
  169. package/dist/_internal/shared/checkout/rules/digital-code.rule.js +6 -0
  170. package/dist/_internal/shared/checkout/rules/index.d.ts +12 -0
  171. package/dist/_internal/shared/checkout/rules/index.js +12 -0
  172. package/dist/_internal/shared/checkout/rules/live.rule.d.ts +10 -0
  173. package/dist/_internal/shared/checkout/rules/live.rule.js +6 -0
  174. package/dist/_internal/shared/checkout/rules/offer.rule.d.ts +2 -0
  175. package/dist/_internal/shared/checkout/rules/offer.rule.js +9 -0
  176. package/dist/_internal/shared/checkout/rules/preorder.rule.d.ts +2 -0
  177. package/dist/_internal/shared/checkout/rules/preorder.rule.js +28 -0
  178. package/dist/_internal/shared/checkout/rules/prize-draw.rule.d.ts +2 -0
  179. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +65 -0
  180. package/dist/_internal/shared/checkout/rules/standard.rule.d.ts +2 -0
  181. package/dist/_internal/shared/checkout/rules/standard.rule.js +5 -0
  182. package/dist/_internal/shared/checkout/rules/types.d.ts +125 -0
  183. package/dist/_internal/shared/checkout/rules/types.js +13 -0
  184. package/dist/_internal/shared/features/cart/schema.d.ts +6 -6
  185. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +123 -0
  186. package/dist/_internal/shared/features/categories/bundle-copy.js +134 -0
  187. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +318 -0
  188. package/dist/_internal/shared/features/categories/bundle-schemas.js +55 -0
  189. package/dist/_internal/shared/features/events/schema.d.ts +4 -4
  190. package/dist/_internal/shared/features/orders/refund-copy.d.ts +36 -0
  191. package/dist/_internal/shared/features/orders/refund-copy.js +40 -0
  192. package/dist/_internal/shared/features/orders/schema.d.ts +4 -4
  193. package/dist/_internal/shared/features/products/schema.d.ts +8 -8
  194. package/dist/_internal/shared/listing-types/_registry.d.ts +27 -0
  195. package/dist/_internal/shared/listing-types/_registry.js +8 -0
  196. package/dist/_internal/shared/listing-types/action-tracker.d.ts +41 -0
  197. package/dist/_internal/shared/listing-types/action-tracker.js +70 -0
  198. package/dist/_internal/shared/listing-types/capabilities.js +25 -0
  199. package/dist/_internal/shared/listing-types/cart-shipping.d.ts +37 -0
  200. package/dist/_internal/shared/listing-types/cart-shipping.js +46 -0
  201. package/dist/_internal/shared/listing-types/classified/config.d.ts +7 -0
  202. package/dist/_internal/shared/listing-types/classified/config.js +8 -0
  203. package/dist/_internal/shared/listing-types/classified/ctas.d.ts +1 -0
  204. package/dist/_internal/shared/listing-types/classified/ctas.js +3 -0
  205. package/dist/_internal/shared/listing-types/classified/og.d.ts +1 -0
  206. package/dist/_internal/shared/listing-types/classified/og.js +1 -0
  207. package/dist/_internal/shared/listing-types/classified/schema.d.ts +1 -0
  208. package/dist/_internal/shared/listing-types/classified/schema.js +1 -0
  209. package/dist/_internal/shared/listing-types/classified/seed-factory.d.ts +1 -0
  210. package/dist/_internal/shared/listing-types/classified/seed-factory.js +1 -0
  211. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +7 -0
  212. package/dist/_internal/shared/listing-types/digital-code/config.js +8 -0
  213. package/dist/_internal/shared/listing-types/digital-code/ctas.d.ts +1 -0
  214. package/dist/_internal/shared/listing-types/digital-code/ctas.js +3 -0
  215. package/dist/_internal/shared/listing-types/digital-code/og.d.ts +1 -0
  216. package/dist/_internal/shared/listing-types/digital-code/og.js +1 -0
  217. package/dist/_internal/shared/listing-types/digital-code/schema.d.ts +1 -0
  218. package/dist/_internal/shared/listing-types/digital-code/schema.js +1 -0
  219. package/dist/_internal/shared/listing-types/digital-code/seed-factory.d.ts +1 -0
  220. package/dist/_internal/shared/listing-types/digital-code/seed-factory.js +1 -0
  221. package/dist/_internal/shared/listing-types/feature-flags.d.ts +34 -0
  222. package/dist/_internal/shared/listing-types/feature-flags.js +45 -0
  223. package/dist/_internal/shared/listing-types/live/config.d.ts +7 -0
  224. package/dist/_internal/shared/listing-types/live/config.js +8 -0
  225. package/dist/_internal/shared/listing-types/live/ctas.d.ts +1 -0
  226. package/dist/_internal/shared/listing-types/live/ctas.js +3 -0
  227. package/dist/_internal/shared/listing-types/live/og.d.ts +1 -0
  228. package/dist/_internal/shared/listing-types/live/og.js +1 -0
  229. package/dist/_internal/shared/listing-types/live/schema.d.ts +1 -0
  230. package/dist/_internal/shared/listing-types/live/schema.js +1 -0
  231. package/dist/_internal/shared/listing-types/live/seed-factory.d.ts +1 -0
  232. package/dist/_internal/shared/listing-types/live/seed-factory.js +1 -0
  233. package/dist/_internal/shared/media/limits.js +8 -0
  234. package/dist/client.d.ts +10 -5
  235. package/dist/client.js +16 -3
  236. package/dist/configs/next.js +7 -0
  237. package/dist/constants/api-endpoints.d.ts +6 -0
  238. package/dist/constants/api-endpoints.js +4 -0
  239. package/dist/core/hooks/useSyncManager.js +13 -1
  240. package/dist/core/unit-of-work.d.ts +1 -1
  241. package/dist/core/unit-of-work.js +2 -2
  242. package/dist/features/account/actions/address-actions.d.ts +1 -1
  243. package/dist/features/account/actions/address-actions.js +15 -7
  244. package/dist/features/account/schemas/firestore.d.ts +8 -43
  245. package/dist/features/account/schemas/firestore.js +8 -54
  246. package/dist/features/account/schemas/index.d.ts +6 -6
  247. package/dist/features/account/server.d.ts +1 -1
  248. package/dist/features/account/server.js +3 -1
  249. package/dist/features/addresses/index.d.ts +2 -0
  250. package/dist/features/addresses/index.js +2 -0
  251. package/dist/features/addresses/repository/addresses.repository.d.ts +29 -0
  252. package/dist/features/addresses/repository/addresses.repository.js +157 -0
  253. package/dist/features/addresses/schemas/firestore.d.ts +53 -0
  254. package/dist/features/addresses/schemas/firestore.js +68 -0
  255. package/dist/features/{bundles → addresses}/schemas/index.d.ts +0 -1
  256. package/dist/features/{bundles → addresses}/schemas/index.js +0 -1
  257. package/dist/features/addresses/server.d.ts +2 -0
  258. package/dist/features/addresses/server.js +2 -0
  259. package/dist/features/admin/components/AdminAllEventEntriesView.js +4 -3
  260. package/dist/features/admin/components/AdminBidsView.js +4 -3
  261. package/dist/features/admin/components/AdminBlogView.js +8 -3
  262. package/dist/features/admin/components/AdminBundleEditorView.d.ts +9 -0
  263. package/dist/features/admin/components/AdminBundleEditorView.js +209 -0
  264. package/dist/features/admin/components/AdminBundlesView.d.ts +9 -0
  265. package/dist/features/admin/components/AdminBundlesView.js +59 -0
  266. package/dist/features/admin/components/AdminCartsView.js +13 -3
  267. package/dist/features/admin/components/AdminContactView.js +4 -3
  268. package/dist/features/admin/components/AdminCouponsView.js +32 -13
  269. package/dist/features/admin/components/AdminNewsletterView.js +4 -3
  270. package/dist/features/admin/components/AdminOrdersView.js +15 -7
  271. package/dist/features/admin/components/AdminPayoutsView.js +4 -3
  272. package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +4 -0
  273. package/dist/features/admin/components/AdminPrizeDrawsView.js +135 -0
  274. package/dist/features/admin/components/AdminProductsView.js +6 -5
  275. package/dist/features/admin/components/AdminReviewsView.js +5 -4
  276. package/dist/features/admin/components/AdminStoresView.js +4 -3
  277. package/dist/features/admin/components/AdminUsersView.js +15 -5
  278. package/dist/features/admin/components/AdminWishlistsView.js +10 -1
  279. package/dist/features/admin/components/DataTable.d.ts +5 -1
  280. package/dist/features/admin/components/DataTable.js +24 -20
  281. package/dist/features/admin/components/index.d.ts +6 -0
  282. package/dist/features/admin/components/index.js +5 -0
  283. package/dist/features/admin/constants/filter-tabs.d.ts +435 -0
  284. package/dist/features/admin/constants/filter-tabs.js +216 -0
  285. package/dist/features/admin/hooks/useAdminListingData.d.ts +1 -0
  286. package/dist/features/admin/hooks/useAdminListingData.js +1 -0
  287. package/dist/features/admin/schemas/firestore.d.ts +15 -0
  288. package/dist/features/admin/schemas/firestore.js +18 -0
  289. package/dist/features/admin/types/product.types.d.ts +2 -2
  290. package/dist/features/auctions/components/AuctionCard.d.ts +4 -1
  291. package/dist/features/auctions/components/AuctionCard.js +5 -3
  292. package/dist/features/auctions/components/AuctionDetailPageView.js +1 -1
  293. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +2 -2
  294. package/dist/features/auctions/components/PlaceBidFormClient.js +12 -2
  295. package/dist/features/auctions/schemas/index.d.ts +2 -2
  296. package/dist/features/auth/index.d.ts +1 -0
  297. package/dist/features/auth/index.js +1 -0
  298. package/dist/features/auth/role-predicates.d.ts +16 -0
  299. package/dist/features/auth/role-predicates.js +15 -0
  300. package/dist/features/blog/components/BlogFeaturedCard.d.ts +4 -1
  301. package/dist/features/blog/components/BlogFeaturedCard.js +5 -3
  302. package/dist/features/cart/actions/cart-actions.d.ts +1 -0
  303. package/dist/features/cart/actions/cart-actions.js +16 -0
  304. package/dist/features/cart/components/CartView.d.ts +19 -1
  305. package/dist/features/cart/components/CartView.js +2 -2
  306. package/dist/features/cart/components/ShippingPicker.d.ts +13 -0
  307. package/dist/features/cart/components/ShippingPicker.js +48 -0
  308. package/dist/features/cart/components/index.d.ts +3 -1
  309. package/dist/features/cart/components/index.js +1 -0
  310. package/dist/features/cart/hooks/useCartCount.js +7 -1
  311. package/dist/features/cart/repository/cart.repository.d.ts +1 -0
  312. package/dist/features/cart/repository/cart.repository.js +35 -0
  313. package/dist/features/cart/schemas/firestore.d.ts +27 -2
  314. package/dist/features/categories/components/BundleAddToCartCta.d.ts +16 -0
  315. package/dist/features/categories/components/BundleAddToCartCta.js +54 -0
  316. package/dist/features/categories/components/BundleBuyNowCta.d.ts +8 -0
  317. package/dist/features/categories/components/BundleBuyNowCta.js +37 -0
  318. package/dist/features/categories/components/BundleDetailView.d.ts +22 -0
  319. package/dist/features/categories/components/BundleDetailView.js +31 -0
  320. package/dist/features/categories/components/BundleDynamicRuleEditor.d.ts +18 -0
  321. package/dist/features/categories/components/BundleDynamicRuleEditor.js +60 -0
  322. package/dist/features/categories/components/BundleItemsPicker.d.ts +26 -0
  323. package/dist/features/categories/components/BundleItemsPicker.js +135 -0
  324. package/dist/features/categories/components/BundlesListView.d.ts +13 -0
  325. package/dist/features/categories/components/BundlesListView.js +27 -0
  326. package/dist/features/categories/components/index.d.ts +12 -0
  327. package/dist/features/categories/components/index.js +9 -0
  328. package/dist/features/checkout/actions/checkout-actions.js +10 -3
  329. package/dist/features/events/components/AdminEventEditorView.js +108 -2
  330. package/dist/features/events/components/AdminEventsView.js +16 -4
  331. package/dist/features/events/components/EventCard.d.ts +4 -1
  332. package/dist/features/events/components/EventCard.js +7 -3
  333. package/dist/features/events/components/EventRaffleWinnerView.d.ts +21 -0
  334. package/dist/features/events/components/EventRaffleWinnerView.js +18 -0
  335. package/dist/features/events/components/SpinWheelView.d.ts +27 -0
  336. package/dist/features/events/components/SpinWheelView.js +64 -0
  337. package/dist/features/events/components/index.d.ts +4 -0
  338. package/dist/features/events/components/index.js +2 -0
  339. package/dist/features/events/schemas/firestore.d.ts +27 -1
  340. package/dist/features/events/schemas/firestore.js +7 -0
  341. package/dist/features/events/types/index.d.ts +27 -1
  342. package/dist/features/homepage/components/FeaturedBundlesSection.d.ts +16 -0
  343. package/dist/features/homepage/components/FeaturedBundlesSection.js +24 -0
  344. package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -1
  345. package/dist/features/homepage/components/WhatsAppCommunitySection.js +2 -2
  346. package/dist/features/homepage/lib/section-renderer.d.ts +2 -0
  347. package/dist/features/homepage/lib/section-renderer.js +5 -5
  348. package/dist/features/layout/NavbarLayout.d.ts +3 -1
  349. package/dist/features/layout/NavbarLayout.js +32 -3
  350. package/dist/features/layout/TitleBarLayout.d.ts +6 -3
  351. package/dist/features/layout/TitleBarLayout.js +22 -7
  352. package/dist/features/media/upload/MediaUploadField.d.ts +15 -1
  353. package/dist/features/media/upload/MediaUploadField.js +22 -1
  354. package/dist/features/orders/components/MarketplaceOrderCard.js +4 -2
  355. package/dist/features/orders/components/OrderSiblingPayments.d.ts +8 -0
  356. package/dist/features/orders/components/OrderSiblingPayments.js +16 -0
  357. package/dist/features/orders/components/RefundHistoryTable.d.ts +6 -0
  358. package/dist/features/orders/components/RefundHistoryTable.js +23 -0
  359. package/dist/features/orders/components/RefundRequestView.d.ts +8 -0
  360. package/dist/features/orders/components/RefundRequestView.js +42 -0
  361. package/dist/features/orders/components/index.d.ts +6 -0
  362. package/dist/features/orders/components/index.js +3 -0
  363. package/dist/features/orders/index.d.ts +1 -0
  364. package/dist/features/orders/index.js +2 -0
  365. package/dist/features/orders/repository/orders.repository.d.ts +20 -1
  366. package/dist/features/orders/repository/orders.repository.js +30 -1
  367. package/dist/features/orders/schemas/firestore.d.ts +63 -13
  368. package/dist/features/orders/schemas/firestore.js +5 -5
  369. package/dist/features/orders/schemas/index.d.ts +4 -4
  370. package/dist/features/orders/types/index.d.ts +12 -2
  371. package/dist/features/orders/utils/bundle-grouping.d.ts +48 -0
  372. package/dist/features/orders/utils/bundle-grouping.js +54 -0
  373. package/dist/features/orders/utils/order-splitter.d.ts +9 -10
  374. package/dist/features/orders/utils/order-splitter.js +24 -30
  375. package/dist/features/payments/repository/payout.repository.d.ts +17 -1
  376. package/dist/features/payments/repository/payout.repository.js +47 -0
  377. package/dist/features/payments/schemas/firestore.d.ts +26 -0
  378. package/dist/features/pre-orders/components/PreorderCard.d.ts +4 -1
  379. package/dist/features/pre-orders/components/PreorderCard.js +8 -6
  380. package/dist/features/products/actions/product-actions.d.ts +1 -1
  381. package/dist/features/products/actions/product-actions.js +1 -1
  382. package/dist/features/products/components/CompareOverlay.d.ts +2 -2
  383. package/dist/features/products/components/CompareOverlay.js +4 -4
  384. package/dist/features/products/components/InteractiveProductCard.js +7 -12
  385. package/dist/features/products/components/NonRefundableConsentModal.d.ts +1 -1
  386. package/dist/features/products/components/NonRefundableConsentModal.js +0 -10
  387. package/dist/features/products/components/ProductGrid.js +28 -12
  388. package/dist/features/products/components/ShowGroupSection.js +3 -3
  389. package/dist/features/products/components/SublistingCarouselSection.js +2 -2
  390. package/dist/features/products/components/index.d.ts +0 -4
  391. package/dist/features/products/components/index.js +5 -2
  392. package/dist/features/products/index.d.ts +1 -1
  393. package/dist/features/products/index.js +3 -1
  394. package/dist/features/products/repository/products.repository.js +4 -0
  395. package/dist/features/products/schemas/catalog-product.d.ts +70 -0
  396. package/dist/features/products/schemas/catalog-product.js +50 -0
  397. package/dist/features/products/schemas/firestore.d.ts +110 -2
  398. package/dist/features/products/schemas/firestore.js +30 -0
  399. package/dist/features/products/schemas/index.d.ts +8 -8
  400. package/dist/features/products/types/index.d.ts +1 -1
  401. package/dist/features/products/utils/listing-type.d.ts +9 -0
  402. package/dist/features/products/utils/listing-type.js +4 -0
  403. package/dist/features/promotions/actions/coupon-actions.d.ts +2 -2
  404. package/dist/features/promotions/actions/coupon-actions.js +1 -1
  405. package/dist/features/promotions/components/CouponCard.d.ts +28 -10
  406. package/dist/features/promotions/components/CouponCard.js +116 -14
  407. package/dist/features/promotions/hooks/useCouponValidate.d.ts +1 -1
  408. package/dist/features/promotions/repository/coupons.repository.d.ts +1 -1
  409. package/dist/features/reviews/schemas/index.d.ts +2 -2
  410. package/dist/features/search/schemas/index.d.ts +2 -2
  411. package/dist/features/search/types/index.d.ts +2 -2
  412. package/dist/features/seller/components/SellerAuctionsView.js +4 -5
  413. package/dist/features/seller/components/SellerBidsView.js +5 -13
  414. package/dist/features/seller/components/SellerCouponsView.js +31 -67
  415. package/dist/features/seller/components/SellerOffersView.js +4 -5
  416. package/dist/features/seller/components/SellerOrdersView.js +4 -5
  417. package/dist/features/seller/components/SellerPayoutsView.js +4 -5
  418. package/dist/features/seller/components/SellerPreOrdersView.d.ts +4 -0
  419. package/dist/features/seller/components/SellerPreOrdersView.js +141 -0
  420. package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +4 -0
  421. package/dist/features/seller/components/SellerPrizeDrawsView.js +138 -0
  422. package/dist/features/seller/components/SellerProductsView.js +4 -8
  423. package/dist/features/seller/components/index.d.ts +4 -0
  424. package/dist/features/seller/components/index.js +2 -0
  425. package/dist/features/seller/schemas/index.d.ts +2 -2
  426. package/dist/features/stores/actions/store-address-actions.d.ts +10 -6
  427. package/dist/features/stores/actions/store-address-actions.js +8 -7
  428. package/dist/features/stores/components/InteractiveStoreCard.js +3 -10
  429. package/dist/features/stores/components/StoreDetailLayoutView.js +20 -5
  430. package/dist/features/stores/schemas/firestore.d.ts +45 -38
  431. package/dist/features/stores/schemas/firestore.js +2 -49
  432. package/dist/features/stores/server.d.ts +0 -1
  433. package/dist/features/stores/server.js +2 -1
  434. package/dist/features/wishlist/hooks/useWishlistCount.d.ts +7 -9
  435. package/dist/features/wishlist/hooks/useWishlistCount.js +67 -86
  436. package/dist/features/wishlist/types/index.d.ts +1 -1
  437. package/dist/index.d.ts +56 -9
  438. package/dist/index.js +66 -11
  439. package/dist/next/routing/route-map.d.ts +6 -0
  440. package/dist/next/routing/route-map.js +4 -0
  441. package/dist/providers/db-firebase/admin.d.ts +6 -2
  442. package/dist/providers/db-firebase/admin.js +23 -0
  443. package/dist/repositories/index.d.ts +1 -2
  444. package/dist/repositories/index.js +5 -2
  445. package/dist/security/authorization.d.ts +2 -1
  446. package/dist/security/authorization.js +3 -2
  447. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  448. package/dist/seed/bids-seed-data.d.ts +2 -2
  449. package/dist/seed/bids-seed-data.js +77 -2
  450. package/dist/seed/cart-seed-data.d.ts +10 -10
  451. package/dist/seed/cart-seed-data.js +15 -15
  452. package/dist/seed/events-seed-data.js +77 -0
  453. package/dist/seed/manifest.js +16 -8
  454. package/dist/seed/orders-seed-data.js +41 -2
  455. package/dist/seed/payouts-seed-data.js +18 -2
  456. package/dist/seed/stores-seed-data.js +55 -0
  457. package/dist/server-entry.d.ts +1 -0
  458. package/dist/server-entry.js +2 -0
  459. package/dist/server.d.ts +4 -0
  460. package/dist/server.js +8 -0
  461. package/dist/tailwind-utilities.css +1 -1
  462. package/dist/ui/components/FilterChipGroup.d.ts +39 -0
  463. package/dist/ui/components/FilterChipGroup.js +15 -0
  464. package/dist/ui/components/HorizontalScroller.js +32 -7
  465. package/dist/ui/components/HorizontalScroller.style.css +6 -0
  466. package/dist/ui/components/SiteLogo.js +1 -1
  467. package/dist/ui/index.d.ts +2 -0
  468. package/dist/ui/index.js +2 -0
  469. package/dist/utils/id-generators.d.ts +11 -0
  470. package/dist/utils/id-generators.js +16 -0
  471. package/package.json +1 -1
  472. package/dist/_internal/shared/features/bundles/config.d.ts +0 -6
  473. package/dist/_internal/shared/features/bundles/config.js +0 -6
  474. package/dist/_internal/shared/schema-versions.d.ts +0 -76
  475. package/dist/_internal/shared/schema-versions.js +0 -82
  476. package/dist/features/account/migrations.d.ts +0 -2
  477. package/dist/features/account/migrations.js +0 -10
  478. package/dist/features/admin/migrations.d.ts +0 -2
  479. package/dist/features/admin/migrations.js +0 -10
  480. package/dist/features/auctions/migrations.d.ts +0 -2
  481. package/dist/features/auctions/migrations.js +0 -10
  482. package/dist/features/auth/migrations.d.ts +0 -2
  483. package/dist/features/auth/migrations.js +0 -10
  484. package/dist/features/blog/migrations.d.ts +0 -2
  485. package/dist/features/blog/migrations.js +0 -10
  486. package/dist/features/brands/actions/brand-actions.d.ts +0 -2
  487. package/dist/features/brands/actions/brand-actions.js +0 -5
  488. package/dist/features/brands/index.d.ts +0 -3
  489. package/dist/features/brands/index.js +0 -3
  490. package/dist/features/brands/migrations.d.ts +0 -2
  491. package/dist/features/brands/migrations.js +0 -10
  492. package/dist/features/brands/repository/brands.repository.d.ts +0 -13
  493. package/dist/features/brands/repository/brands.repository.js +0 -60
  494. package/dist/features/brands/schemas/index.d.ts +0 -33
  495. package/dist/features/brands/schemas/index.js +0 -15
  496. package/dist/features/brands/server.d.ts +0 -7
  497. package/dist/features/brands/server.js +0 -7
  498. package/dist/features/bundles/components/AdminBundleEditorView.d.ts +0 -8
  499. package/dist/features/bundles/components/AdminBundleEditorView.js +0 -7
  500. package/dist/features/bundles/components/BundleDetailPageView.d.ts +0 -9
  501. package/dist/features/bundles/components/BundleDetailPageView.js +0 -45
  502. package/dist/features/bundles/components/BundleForm.d.ts +0 -12
  503. package/dist/features/bundles/components/BundleForm.js +0 -126
  504. package/dist/features/bundles/components/BundleItemsPicker.d.ts +0 -9
  505. package/dist/features/bundles/components/BundleItemsPicker.js +0 -77
  506. package/dist/features/bundles/components/BundlesByCategoryListing.d.ts +0 -6
  507. package/dist/features/bundles/components/BundlesByCategoryListing.js +0 -50
  508. package/dist/features/bundles/components/BundlesListingView.d.ts +0 -17
  509. package/dist/features/bundles/components/BundlesListingView.js +0 -50
  510. package/dist/features/bundles/components/FeaturedBundlesSection.d.ts +0 -5
  511. package/dist/features/bundles/components/FeaturedBundlesSection.js +0 -55
  512. package/dist/features/bundles/components/SellerBundleCreateView.d.ts +0 -8
  513. package/dist/features/bundles/components/SellerBundleCreateView.js +0 -7
  514. package/dist/features/bundles/components/SellerBundleEditView.d.ts +0 -9
  515. package/dist/features/bundles/components/SellerBundleEditView.js +0 -7
  516. package/dist/features/bundles/components/index.d.ts +0 -18
  517. package/dist/features/bundles/components/index.js +0 -9
  518. package/dist/features/bundles/constants/index.d.ts +0 -32
  519. package/dist/features/bundles/constants/index.js +0 -35
  520. package/dist/features/bundles/index.d.ts +0 -2
  521. package/dist/features/bundles/index.js +0 -2
  522. package/dist/features/bundles/migrations.d.ts +0 -2
  523. package/dist/features/bundles/migrations.js +0 -10
  524. package/dist/features/bundles/repository/bundles.repository.d.ts +0 -36
  525. package/dist/features/bundles/repository/bundles.repository.js +0 -148
  526. package/dist/features/bundles/repository/index.d.ts +0 -1
  527. package/dist/features/bundles/repository/index.js +0 -1
  528. package/dist/features/bundles/schemas/firestore.d.ts +0 -88
  529. package/dist/features/bundles/schemas/firestore.js +0 -29
  530. package/dist/features/bundles/schemas/zod.d.ts +0 -377
  531. package/dist/features/bundles/schemas/zod.js +0 -71
  532. package/dist/features/cart/migrations.d.ts +0 -2
  533. package/dist/features/cart/migrations.js +0 -10
  534. package/dist/features/categories/migrations.d.ts +0 -2
  535. package/dist/features/categories/migrations.js +0 -10
  536. package/dist/features/events/migrations.d.ts +0 -2
  537. package/dist/features/events/migrations.js +0 -10
  538. package/dist/features/faq/migrations.d.ts +0 -2
  539. package/dist/features/faq/migrations.js +0 -10
  540. package/dist/features/grouped/migrations.d.ts +0 -2
  541. package/dist/features/grouped/migrations.js +0 -10
  542. package/dist/features/history/migrations.d.ts +0 -2
  543. package/dist/features/history/migrations.js +0 -10
  544. package/dist/features/messages/migrations.d.ts +0 -2
  545. package/dist/features/messages/migrations.js +0 -10
  546. package/dist/features/orders/migrations.d.ts +0 -2
  547. package/dist/features/orders/migrations.js +0 -10
  548. package/dist/features/payments/migrations.d.ts +0 -2
  549. package/dist/features/payments/migrations.js +0 -10
  550. package/dist/features/products/migrations.d.ts +0 -2
  551. package/dist/features/products/migrations.js +0 -10
  552. package/dist/features/products/repository/sublisting-categories.repository.d.ts +0 -16
  553. package/dist/features/products/repository/sublisting-categories.repository.js +0 -126
  554. package/dist/features/products/schemas/sublisting-categories.d.ts +0 -45
  555. package/dist/features/products/schemas/sublisting-categories.js +0 -16
  556. package/dist/features/promotions/migrations.d.ts +0 -2
  557. package/dist/features/promotions/migrations.js +0 -10
  558. package/dist/features/reviews/migrations.d.ts +0 -2
  559. package/dist/features/reviews/migrations.js +0 -10
  560. package/dist/features/scams/migrations.d.ts +0 -2
  561. package/dist/features/scams/migrations.js +0 -10
  562. package/dist/features/seller/migrations.d.ts +0 -2
  563. package/dist/features/seller/migrations.js +0 -10
  564. package/dist/features/stores/migrations.d.ts +0 -2
  565. package/dist/features/stores/migrations.js +0 -10
  566. package/dist/features/sublisting/migrations.d.ts +0 -2
  567. package/dist/features/sublisting/migrations.js +0 -10
  568. package/dist/features/sublisting/schemas/firestore.d.ts +0 -32
  569. package/dist/features/sublisting/schemas/firestore.js +0 -19
  570. package/dist/features/support/migrations.d.ts +0 -2
  571. package/dist/features/support/migrations.js +0 -10
  572. package/dist/features/wishlist/migrations.d.ts +0 -2
  573. package/dist/features/wishlist/migrations.js +0 -10
  574. package/dist/seed/_bundle-constants.d.ts +0 -14
  575. package/dist/seed/_bundle-constants.js +0 -14
  576. package/dist/seed/anime-figures-seed-data.d.ts +0 -8
  577. package/dist/seed/anime-figures-seed-data.js +0 -1033
  578. package/dist/seed/beyblade-seed-data.d.ts +0 -7
  579. package/dist/seed/beyblade-seed-data.js +0 -1129
  580. package/dist/seed/brands-seed-data.d.ts +0 -7
  581. package/dist/seed/brands-seed-data.js +0 -410
  582. package/dist/seed/bundles-seed-data.d.ts +0 -13
  583. package/dist/seed/bundles-seed-data.js +0 -229
  584. package/dist/seed/cosplay-accessories-seed-data.d.ts +0 -8
  585. package/dist/seed/cosplay-accessories-seed-data.js +0 -647
  586. package/dist/seed/hot-wheels-seed-data.d.ts +0 -7
  587. package/dist/seed/hot-wheels-seed-data.js +0 -1612
  588. package/dist/seed/letitrip-official-seed-data.d.ts +0 -8
  589. package/dist/seed/letitrip-official-seed-data.js +0 -399
  590. package/dist/seed/pokemon-carousel-slides-seed-data.d.ts +0 -8
  591. package/dist/seed/pokemon-carousel-slides-seed-data.js +0 -322
  592. package/dist/seed/pokemon-categories-seed-data.d.ts +0 -24
  593. package/dist/seed/pokemon-categories-seed-data.js +0 -547
  594. package/dist/seed/pokemon-coupons-seed-data.d.ts +0 -6
  595. package/dist/seed/pokemon-coupons-seed-data.js +0 -465
  596. package/dist/seed/pokemon-homepage-sections-seed-data.d.ts +0 -7
  597. package/dist/seed/pokemon-homepage-sections-seed-data.js +0 -241
  598. package/dist/seed/pokemon-products-seed-data.d.ts +0 -9
  599. package/dist/seed/pokemon-products-seed-data.js +0 -1791
  600. package/dist/seed/pokemon-seed-bundle.d.ts +0 -47
  601. package/dist/seed/pokemon-seed-bundle.js +0 -71
  602. package/dist/seed/pokemon-stores-seed-data.d.ts +0 -6
  603. package/dist/seed/pokemon-stores-seed-data.js +0 -179
  604. package/dist/seed/pokemon-users-seed-data.d.ts +0 -6
  605. package/dist/seed/pokemon-users-seed-data.js +0 -521
  606. package/dist/seed/products-seed-data.d.ts +0 -6
  607. package/dist/seed/products-seed-data.js +0 -2530
  608. package/dist/seed/retro-gaming-seed-data.d.ts +0 -8
  609. package/dist/seed/retro-gaming-seed-data.js +0 -801
  610. package/dist/seed/server.d.ts +0 -2
  611. package/dist/seed/server.js +0 -7
  612. package/dist/seed/sublisting-categories-seed-data.d.ts +0 -7
  613. package/dist/seed/sublisting-categories-seed-data.js +0 -159
  614. package/dist/seed/transformers-seed-data.d.ts +0 -7
  615. package/dist/seed/transformers-seed-data.js +0 -530
@@ -0,0 +1,48 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * ShippingPicker — buyer-facing shipping provider selector.
5
+ *
6
+ * Renders the store's configured shipping providers as a radio list.
7
+ * The selected provider's id + calculated fee are surfaced via the
8
+ * `onPickProvider` callback so the parent can persist them to the cart item.
9
+ */
10
+ import { useState } from "react";
11
+ import { Button, Div, Row, Stack, Text } from "../../../ui";
12
+ import { formatCurrency } from "../../../utils/number.formatter";
13
+ import { REFUND_COPY } from "../../../_internal/shared/features/orders/refund-copy";
14
+ /** Resolve the effective flat fee for a provider given the current subtotal. */
15
+ function resolveProviderFee(p, subtotalInPaise) {
16
+ const { fee } = p;
17
+ if (fee.freeAboveInPaise !== undefined && subtotalInPaise >= fee.freeAboveInPaise)
18
+ return 0;
19
+ let total = fee.flatInPaise ?? 0;
20
+ if (fee.percentOfOrder !== undefined) {
21
+ total += Math.round((fee.percentOfOrder / 100) * subtotalInPaise);
22
+ }
23
+ if (fee.minInPaise !== undefined)
24
+ total = Math.max(total, fee.minInPaise);
25
+ return total;
26
+ }
27
+ export function ShippingPicker({ providers, selectedProviderId, subtotalInPaise = 0, onPickProvider, isLoading = false, className = "", }) {
28
+ const [pending, setPending] = useState(false);
29
+ if (providers.length === 0) {
30
+ return (_jsx(Text, { size: "sm", color: "muted", className: className, children: REFUND_COPY.shipping.noOptions }));
31
+ }
32
+ const handleSelect = async (p) => {
33
+ const fee = resolveProviderFee(p, subtotalInPaise);
34
+ setPending(true);
35
+ try {
36
+ await onPickProvider(p.providerId, fee);
37
+ }
38
+ finally {
39
+ setPending(false);
40
+ }
41
+ };
42
+ return (_jsx(Stack, { gap: "xs", className: className, role: "radiogroup", "aria-label": "Shipping options", children: providers.map((p) => {
43
+ const fee = resolveProviderFee(p, subtotalInPaise);
44
+ const selected = p.providerId === selectedProviderId;
45
+ const disabled = isLoading || pending;
46
+ return (_jsx(Button, { type: "button", variant: selected ? "primary" : "outline", size: "sm", disabled: disabled, onClick: () => handleSelect(p), "aria-checked": selected, role: "radio", className: "w-full justify-start text-left", children: _jsxs(Row, { gap: "sm", className: "w-full flex-wrap", align: "center", children: [_jsxs(Div, { className: "flex-1", children: [_jsx(Text, { size: "sm", weight: selected ? "semibold" : "normal", children: p.label }), _jsx(Text, { size: "xs", color: "muted", children: REFUND_COPY.shipping.etaFormat(p.etaDaysMin, p.etaDaysMax) })] }), _jsx(Text, { size: "sm", weight: "semibold", children: fee === 0 ? REFUND_COPY.shipping.freeLabel : formatCurrency(fee / 100, "INR") })] }) }, p.providerId));
47
+ }) }));
48
+ }
@@ -1,6 +1,6 @@
1
1
  export { CartItemRow, CartDrawer } from "./CartDrawer";
2
2
  export { CartView } from "./CartView";
3
- export type { CartViewProps } from "./CartView";
3
+ export type { CartViewProps, CartOrderGroup } from "./CartView";
4
4
  export { CartSummary } from "./CartSummary";
5
5
  export type { CartSummaryProps } from "./CartSummary";
6
6
  export { CheckoutView } from "./CheckoutView";
@@ -11,3 +11,5 @@ export { CheckoutOtpModal } from "./CheckoutOtpModal";
11
11
  export type { CheckoutOtpModalProps } from "./CheckoutOtpModal";
12
12
  export { CheckoutSuccessView } from "./CheckoutSuccessView";
13
13
  export type { CheckoutSuccessViewProps } from "./CheckoutSuccessView";
14
+ export { ShippingPicker } from "./ShippingPicker";
15
+ export type { ShippingPickerProps } from "./ShippingPicker";
@@ -5,3 +5,4 @@ export { CheckoutView } from "./CheckoutView";
5
5
  export { CheckoutAddressStep } from "./CheckoutAddressStep";
6
6
  export { CheckoutOtpModal } from "./CheckoutOtpModal";
7
7
  export { CheckoutSuccessView } from "./CheckoutSuccessView";
8
+ export { ShippingPicker } from "./ShippingPicker";
@@ -16,5 +16,11 @@ export function useCartCount(enabled = false) {
16
16
  queryFn: () => apiClient.get(CART_ENDPOINTS.GET),
17
17
  enabled,
18
18
  });
19
- return data?.itemCount ?? guestCount;
19
+ // When authenticated, the server is authoritative — never mix in the guest
20
+ // count, otherwise stale localStorage entries leak into the badge after
21
+ // login (the cart-merge clears the local store but `useGuestCart`'s React
22
+ // state holds the pre-clear snapshot until remount).
23
+ if (enabled)
24
+ return data?.itemCount ?? 0;
25
+ return guestCount;
20
26
  }
@@ -16,6 +16,7 @@ export declare class CartRepository extends BaseRepository<CartDocument> {
16
16
  getSubtotal(cart: CartDocument): number;
17
17
  addCoupon(userId: string, coupon: CartAppliedCoupon): Promise<void>;
18
18
  removeCoupon(userId: string, code: string): Promise<void>;
19
+ updateItemShipping(userId: string, itemId: string, providerId: string, feeInPaise: number): Promise<CartDocument>;
19
20
  clearAllCoupons(userId: string): Promise<void>;
20
21
  setSelectedItems(userId: string, itemIds: string[] | null): Promise<void>;
21
22
  /**
@@ -84,6 +84,13 @@ export class CartRepository extends BaseRepository {
84
84
  ...(input.lockedPrice !== undefined && {
85
85
  lockedPrice: input.lockedPrice,
86
86
  }),
87
+ // SB-UNI-4 2026-05-13 — propagate bundle identifiers when present.
88
+ ...(input.bundleCategorySlug !== undefined && {
89
+ bundleCategorySlug: input.bundleCategorySlug,
90
+ }),
91
+ ...(input.bundleProductIds !== undefined && {
92
+ bundleProductIds: input.bundleProductIds,
93
+ }),
87
94
  addedAt: new Date(),
88
95
  updatedAt: new Date(),
89
96
  };
@@ -209,6 +216,34 @@ export class CartRepository extends BaseRepository {
209
216
  .doc(userId)
210
217
  .set({ appliedCoupons: updated, updatedAt: new Date() }, { merge: true });
211
218
  }
219
+ async updateItemShipping(userId, itemId, providerId, feeInPaise) {
220
+ try {
221
+ const cart = await this.findByUserId(userId);
222
+ if (!cart)
223
+ throw new NotFoundError("Cart not found");
224
+ const itemIndex = cart.items.findIndex((item) => item.itemId === itemId);
225
+ if (itemIndex < 0)
226
+ throw new NotFoundError("Cart item not found");
227
+ const items = [...cart.items];
228
+ items[itemIndex] = {
229
+ ...items[itemIndex],
230
+ chosenShippingProviderId: providerId,
231
+ chosenShippingFeeInPaise: feeInPaise,
232
+ updatedAt: new Date(),
233
+ };
234
+ const updatedCart = { ...cart, items, updatedAt: new Date() };
235
+ await this.db
236
+ .collection(this.collection)
237
+ .doc(userId)
238
+ .set(prepareForFirestore(updatedCart));
239
+ return updatedCart;
240
+ }
241
+ catch (error) {
242
+ if (error instanceof DatabaseError || error instanceof NotFoundError)
243
+ throw error;
244
+ throw new DatabaseError("Failed to update cart item shipping", error);
245
+ }
246
+ }
212
247
  async clearAllCoupons(userId) {
213
248
  await this.db
214
249
  .collection(this.collection)
@@ -21,12 +21,33 @@ export interface CartItemDocument {
21
21
  * carts) and cart-side UI badges. Replaces the legacy `isAuction`/`isPreOrder`
22
22
  * pair on the cart item.
23
23
  */
24
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
24
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
25
25
  /** True when item was added from an accepted Make-an-Offer */
26
26
  isOffer?: boolean;
27
27
  offerId?: string;
28
28
  /** Locked offer price — overrides normal product price at checkout */
29
29
  lockedPrice?: number;
30
+ /**
31
+ * SB-UNI-4 2026-05-13 — bundle identifier when this cart line represents a
32
+ * bundle (categoryType:"bundle" row on the categories collection). When set,
33
+ * `productId` points at the bundle category's id, `price` is the locked
34
+ * bundlePriceInPaise, and `bundleProductIds` snapshots the member product
35
+ * ids at add-to-cart time. Order-side fan-out into per-product OrderItem
36
+ * entries lands in S-SBUNI-5 (checkout-side stock decrement + per-store
37
+ * grouping); until then the foundation is here but BundleDetailView keeps
38
+ * the "Add to cart coming soon" notice up.
39
+ */
40
+ bundleCategorySlug?: string;
41
+ /** Snapshot of `bundle.bundleProductIds` at add-to-cart time. */
42
+ bundleProductIds?: string[];
43
+ /**
44
+ * S-SBUNI-RULES 2026-05-13 — buyer's chosen shipping provider for this
45
+ * item, snapshotted at cart time. Locked at checkout; the per-tab
46
+ * ShippingPicker writes this when the buyer selects a provider.
47
+ */
48
+ chosenShippingProviderId?: string;
49
+ /** Fee in paise for the chosen provider, snapshotted at cart time. */
50
+ chosenShippingFeeInPaise?: number;
30
51
  addedAt: Date;
31
52
  updatedAt: Date;
32
53
  }
@@ -89,10 +110,14 @@ export type AddToCartInput = {
89
110
  /** Store slug (= storeId = store.id) */
90
111
  storeId: string;
91
112
  storeName: string;
92
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
113
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
93
114
  isOffer?: boolean;
94
115
  offerId?: string;
95
116
  lockedPrice?: number;
117
+ /** SB-UNI-4 2026-05-13 — bundle identifier when the line is a bundle. */
118
+ bundleCategorySlug?: string;
119
+ /** Snapshot of bundle members at add-to-cart time. */
120
+ bundleProductIds?: string[];
96
121
  };
97
122
  export type UpdateCartItemInput = {
98
123
  quantity: number;
@@ -0,0 +1,16 @@
1
+ export interface BundleAddToCartCtaProps {
2
+ /** Bundle slug — `categories/{bundle-...}` row. */
3
+ bundleSlug: string;
4
+ /** True when bundleStockStatus === "out_of_stock". Renders disabled CTA. */
5
+ outOfStock?: boolean;
6
+ /**
7
+ * Server-action callback. Returning successfully marks the toast as success;
8
+ * any thrown error surfaces inline + as an error toast. Typed as a generic
9
+ * async fn so consumers can wrap the underlying action however they like.
10
+ */
11
+ onAddToCart: (input: {
12
+ bundleSlug: string;
13
+ quantity: number;
14
+ }) => Promise<unknown>;
15
+ }
16
+ export declare function BundleAddToCartCta({ bundleSlug, outOfStock, onAddToCart, }: BundleAddToCartCtaProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * BundleAddToCartCta — S-SBUNI-5 2026-05-13.
5
+ *
6
+ * Client island for the bundle detail page CTA. Replaces the "coming soon"
7
+ * disabled-CTA notice from S-SBUNI-3 + S-SBUNI-4 now that the cart-line
8
+ * foundation + per-member stock decrement at checkout are wired.
9
+ *
10
+ * Receives the bundle slug + an `onAddToCart` callback (typically the
11
+ * `addBundleToCartAction` server action from the consumer app). Renders
12
+ * a qty input + Add button + inline error / toast feedback.
13
+ *
14
+ * Out-of-stock bundles render a disabled button with `ctaOutOfStock` text.
15
+ */
16
+ import { useState, useCallback } from "react";
17
+ import { Button, Input, Row, Stack, Text } from "../../../ui";
18
+ import { useToast } from "../../../ui";
19
+ import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
20
+ const MIN_QTY = 1;
21
+ const MAX_QTY = 10;
22
+ export function BundleAddToCartCta({ bundleSlug, outOfStock = false, onAddToCart, }) {
23
+ const { showToast } = useToast();
24
+ const [quantity, setQuantity] = useState(MIN_QTY);
25
+ const [submitting, setSubmitting] = useState(false);
26
+ const [error, setError] = useState(null);
27
+ const handleClick = useCallback(async () => {
28
+ setError(null);
29
+ setSubmitting(true);
30
+ try {
31
+ await onAddToCart({ bundleSlug, quantity });
32
+ showToast(BUNDLE_COPY.detail.ctaSuccess, "success");
33
+ }
34
+ catch (err) {
35
+ const message = err instanceof Error ? err.message : BUNDLE_COPY.detail.ctaErrorFallback;
36
+ setError(message);
37
+ showToast(message, "error");
38
+ }
39
+ finally {
40
+ setSubmitting(false);
41
+ }
42
+ }, [bundleSlug, quantity, onAddToCart, showToast]);
43
+ if (outOfStock) {
44
+ return (_jsxs(Stack, { gap: "xs", "aria-live": "polite", children: [_jsx(Button, { variant: "primary", disabled: true, "aria-disabled": true, children: BUNDLE_COPY.detail.ctaOutOfStock }), _jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }));
45
+ }
46
+ return (_jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", align: "center", className: "flex-wrap", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.detail.qtyLabel }), _jsx(Input, { type: "number", inputMode: "numeric", min: MIN_QTY, max: MAX_QTY, step: 1, value: String(quantity), "aria-label": BUNDLE_COPY.detail.qtyAriaLabel, onChange: (e) => {
47
+ const next = Number(e.target.value);
48
+ if (Number.isFinite(next)) {
49
+ setQuantity(Math.min(Math.max(MIN_QTY, Math.floor(next)), MAX_QTY));
50
+ }
51
+ }, disabled: submitting, className: "w-20" })] }), _jsx(Button, { variant: "primary", onClick: handleClick, disabled: submitting, "aria-busy": submitting, children: submitting
52
+ ? BUNDLE_COPY.detail.ctaAdding
53
+ : BUNDLE_COPY.detail.ctaAddToCart })] }), error && (_jsx(Text, { size: "sm", color: "danger", role: "alert", children: error }))] }));
54
+ }
@@ -0,0 +1,8 @@
1
+ export interface BundleBuyNowCtaProps {
2
+ bundleSlug: string;
3
+ outOfStock?: boolean;
4
+ onBuyNow: (input: {
5
+ bundleSlug: string;
6
+ }) => Promise<unknown>;
7
+ }
8
+ export declare function BundleBuyNowCta({ bundleSlug, outOfStock, onBuyNow, }: BundleBuyNowCtaProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * BundleBuyNowCta — direct-checkout CTA for bundle detail pages.
5
+ *
6
+ * Replaces BundleAddToCartCta (deleted). Bundles bypass the cart and go
7
+ * straight to checkout via the `directBundleCheckoutAction` server action.
8
+ * No qty input — bundles are always qty=1 per checkout.
9
+ */
10
+ import { useState, useCallback } from "react";
11
+ import { Button, Stack, Text } from "../../../ui";
12
+ import { useToast } from "../../../ui";
13
+ import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
14
+ export function BundleBuyNowCta({ bundleSlug, outOfStock = false, onBuyNow, }) {
15
+ const { showToast } = useToast();
16
+ const [submitting, setSubmitting] = useState(false);
17
+ const [error, setError] = useState(null);
18
+ const handleClick = useCallback(async () => {
19
+ setError(null);
20
+ setSubmitting(true);
21
+ try {
22
+ await onBuyNow({ bundleSlug });
23
+ }
24
+ catch (err) {
25
+ const message = err instanceof Error ? err.message : BUNDLE_COPY.detail.ctaErrorFallback;
26
+ setError(message);
27
+ showToast(message, "error");
28
+ }
29
+ finally {
30
+ setSubmitting(false);
31
+ }
32
+ }, [bundleSlug, onBuyNow, showToast]);
33
+ if (outOfStock) {
34
+ return (_jsxs(Stack, { gap: "xs", "aria-live": "polite", children: [_jsx(Button, { variant: "primary", disabled: true, "aria-disabled": true, children: BUNDLE_COPY.detail.ctaOutOfStock }), _jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }));
35
+ }
36
+ return (_jsxs(Stack, { gap: "sm", children: [_jsx(Button, { variant: "primary", onClick: handleClick, disabled: submitting, "aria-busy": submitting, children: submitting ? BUNDLE_COPY.detail.ctaAdding : BUNDLE_COPY.detail.ctaBuyNow }), error && (_jsx(Text, { size: "sm", color: "danger", role: "alert", children: error }))] }));
37
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * BundleDetailView — public detail page for a bundle (categoryType:"bundle"
3
+ * row on the categories collection). Rebuilt in S-SBUNI-3 2026-05-13 after
4
+ * the SB-UNI-V deletion. Slot-shell pattern: parent passes the doc + the
5
+ * resolved product members; this view stays presentational.
6
+ *
7
+ * Members rendered as a simple grid of product cards (links to PDPs). The
8
+ * "Buy bundle" CTA + non-refundable consent modal are intentionally NOT
9
+ * wired yet — bundle add-to-cart needs the SB-UNI-3 carry-over cohort
10
+ * (cart line `{bundleCategorySlug, qty}` + N-line checkout expansion).
11
+ */
12
+ import type { CategoryDocument } from "../schemas";
13
+ import type { ProductDocument } from "../../products/schemas/firestore";
14
+ export interface BundleDetailViewProps {
15
+ bundle: CategoryDocument;
16
+ members?: ProductDocument[];
17
+ /** Direct-checkout callback (S-SBUNI-RULES). When supplied, renders the "Buy now" CTA. */
18
+ onBuyNow?: (input: {
19
+ bundleSlug: string;
20
+ }) => Promise<unknown>;
21
+ }
22
+ export declare function BundleDetailView({ bundle, members, onBuyNow, }: BundleDetailViewProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Link from "next/link";
3
+ import { Badge, Container, Div, Heading, Main, Row, Section, Stack, Text, } from "../../../ui";
4
+ import { ROUTES } from "../../../next/routing/route-map";
5
+ import { formatCurrency } from "../../../utils/number.formatter";
6
+ import { BUNDLE_COPY, BUNDLE_STOCK_VARIANT, } from "../../../_internal/shared/features/categories/bundle-copy";
7
+ import { BundleBuyNowCta } from "./BundleBuyNowCta";
8
+ const STOCK_BADGE_TEXT = {
9
+ in_stock: BUNDLE_COPY.stockBadge.in_stock,
10
+ partial: BUNDLE_COPY.stockBadge.partial,
11
+ out_of_stock: BUNDLE_COPY.stockBadge.out_of_stock,
12
+ };
13
+ const PLACEHOLDER_EMOJI = "📦";
14
+ export function BundleDetailView({ bundle, members = [], onBuyNow, }) {
15
+ const memberCount = members.length || bundle.bundleProductIds?.length || 0;
16
+ const stock = bundle.bundleStockStatus ?? "in_stock";
17
+ const cover = bundle.display?.coverImage;
18
+ const priceLabel = bundle.bundlePriceInPaise
19
+ ? formatCurrency(bundle.bundlePriceInPaise / 100, "INR")
20
+ : BUNDLE_COPY.detail.priceFallback;
21
+ return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "lg", children: [_jsxs(Row, { gap: "lg", align: "start", className: "flex-col md:flex-row", children: [_jsx(Div, { className: "aspect-video w-full overflow-hidden rounded-2xl bg-zinc-100 md:w-1/2 dark:bg-zinc-800", children: cover ? (
22
+ // eslint-disable-next-line @next/next/no-img-element, lir/no-raw-media-elements
23
+ _jsx("img", { src: cover, alt: bundle.name, className: "h-full w-full object-cover" })) : (_jsx(Div, { className: "flex h-full w-full items-center justify-center text-6xl", children: PLACEHOLDER_EMOJI })) }), _jsxs(Stack, { gap: "md", className: "flex-1", children: [_jsx(Heading, { level: 1, className: "text-3xl font-semibold text-zinc-900 dark:text-zinc-100", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "lg", weight: "bold", children: priceLabel }), _jsxs(Text, { size: "sm", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.detail.itemCount(memberCount)] }), _jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: STOCK_BADGE_TEXT[stock] })] }), bundle.description && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-sm font-semibold text-[var(--appkit-color-text-muted)]", children: BUNDLE_COPY.detailDescriptionHeading }), _jsx(Text, { className: "whitespace-pre-line", children: bundle.description })] })), onBuyNow ? (_jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow })) : (_jsxs(Div, { className: "rounded-xl border border-dashed border-zinc-300 bg-zinc-50 p-4 text-sm dark:border-zinc-700 dark:bg-zinc-900", "aria-live": "polite", children: [_jsx(Text, { weight: "semibold", className: "mb-1 block", children: BUNDLE_COPY.detail.ctaDisabled }), _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }))] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 2, className: "text-xl font-semibold text-zinc-900 dark:text-zinc-100", children: BUNDLE_COPY.detailItemsHeading }), members.length === 0 ? (_jsx(Text, { color: "muted", children: BUNDLE_COPY.detail.emptyMembers })) : (_jsx(Div, { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4", children: members.map((p) => (_jsx(BundleMemberCard, { product: p }, p.id))) }))] })] }) }) }) }));
24
+ }
25
+ function BundleMemberCard({ product }) {
26
+ const href = String(ROUTES.PUBLIC.PRODUCT_DETAIL?.(product.slug ?? product.id) ?? "#");
27
+ const cover = product.mainImage ?? product.images?.[0];
28
+ return (_jsxs(Link, { href: href, className: "group rounded-xl border border-zinc-200 bg-white p-2 transition-colors hover:border-zinc-300 dark:border-zinc-800 dark:bg-zinc-900 dark:hover:border-zinc-700", children: [_jsx(Div, { className: "mb-2 aspect-square overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800", children: cover ? (
29
+ // eslint-disable-next-line @next/next/no-img-element, lir/no-raw-media-elements
30
+ _jsx("img", { src: cover, alt: product.title, className: "h-full w-full object-cover transition-transform group-hover:scale-105", loading: "lazy" })) : (_jsx(Div, { className: "flex h-full w-full items-center justify-center text-3xl", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2 text-sm font-medium", children: product.title }), _jsx(Text, { size: "xs", color: "muted", className: "mt-1", children: formatCurrency((product.price ?? 0) / 100, product.currency ?? "INR") })] }));
31
+ }
@@ -0,0 +1,18 @@
1
+ type DynamicRule = {
2
+ type: "dynamic";
3
+ filter: {
4
+ categorySlug?: string;
5
+ brandSlug?: string;
6
+ tags?: string[];
7
+ listingType?: "standard" | "pre-order";
8
+ };
9
+ orderBy?: "price-asc" | "price-desc" | "createdAt-desc";
10
+ limit: number;
11
+ };
12
+ export interface BundleDynamicRuleEditorProps {
13
+ value: DynamicRule | null;
14
+ onChange: (next: DynamicRule) => void;
15
+ disabled?: boolean;
16
+ }
17
+ export declare function BundleDynamicRuleEditor({ value, onChange, disabled, }: BundleDynamicRuleEditorProps): import("react/jsx-runtime").JSX.Element;
18
+ export {};
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * BundleDynamicRuleEditor — S-SBUNI-5 2026-05-13.
5
+ *
6
+ * Dynamic-rule companion to BundleItemsPicker. When an admin picks "dynamic"
7
+ * as the bundle's query-rule type, this view collects:
8
+ * - filter: categorySlug? · brandSlug? · tags? · listingType?
9
+ * - orderBy: price-asc | price-desc | createdAt-desc
10
+ * - limit (1..BUNDLE_MAX_ITEMS)
11
+ *
12
+ * The resolved member ids are computed by the `onProductStockChange` Firebase
13
+ * Function + a scheduled job, cached on `bundleProductIds[]` with a
14
+ * `bundleQueryResolvedAt` timestamp. This editor only writes the rule.
15
+ */
16
+ import { useCallback } from "react";
17
+ import { Div, Input, Row, Select, Stack, Text } from "../../../ui";
18
+ import { BUNDLE_MAX_ITEMS } from "../../../_internal/shared/features/categories/bundle-config";
19
+ import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
20
+ const DEFAULT_DYNAMIC_RULE = {
21
+ type: "dynamic",
22
+ filter: {},
23
+ orderBy: "createdAt-desc",
24
+ limit: 6,
25
+ };
26
+ const ORDER_BY_OPTIONS = [
27
+ { label: "Newest first", value: "createdAt-desc" },
28
+ { label: "Price (low → high)", value: "price-asc" },
29
+ { label: "Price (high → low)", value: "price-desc" },
30
+ ];
31
+ const LISTING_TYPE_OPTIONS = [
32
+ { label: "Any (standard + pre-order)", value: "" },
33
+ { label: "Standard only", value: "standard" },
34
+ { label: "Pre-order only", value: "pre-order" },
35
+ ];
36
+ export function BundleDynamicRuleEditor({ value, onChange, disabled = false, }) {
37
+ const rule = value ?? DEFAULT_DYNAMIC_RULE;
38
+ const patch = useCallback((next) => onChange({ ...rule, ...next }), [rule, onChange]);
39
+ const patchFilter = useCallback((next) => onChange({ ...rule, filter: { ...rule.filter, ...next } }), [rule, onChange]);
40
+ const tagsValue = (rule.filter.tags ?? []).join(", ");
41
+ return (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", className: "flex-wrap", children: [_jsx(Text, { size: "sm", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.title }), _jsx(Text, { size: "xs", color: "muted", children: BUNDLE_COPY.adminEditor.dynamic.hint })] }), _jsxs(Div, { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.categorySlug }), _jsx(Input, { type: "text", value: rule.filter.categorySlug ?? "", onChange: (e) => patchFilter({ categorySlug: e.target.value.trim() || undefined }), placeholder: "category-action-figures", disabled: disabled })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.brandSlug }), _jsx(Input, { type: "text", value: rule.filter.brandSlug ?? "", onChange: (e) => patchFilter({ brandSlug: e.target.value.trim() || undefined }), placeholder: "brand-bandai", disabled: disabled })] })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.tags }), _jsx(Input, { type: "text", value: tagsValue, onChange: (e) => {
42
+ const parsed = e.target.value
43
+ .split(",")
44
+ .map((t) => t.trim())
45
+ .filter(Boolean);
46
+ patchFilter({ tags: parsed.length ? parsed : undefined });
47
+ }, placeholder: "pokemon, starter-deck", disabled: disabled })] }), _jsxs(Div, { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.listingType }), _jsx(Select, { options: LISTING_TYPE_OPTIONS, value: rule.filter.listingType ?? "", onValueChange: (next) => patchFilter({
48
+ listingType: next === "" ? undefined : next,
49
+ }), disabled: disabled, "aria-label": BUNDLE_COPY.adminEditor.dynamic.fields.listingType })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.orderBy }), _jsx(Select, { options: ORDER_BY_OPTIONS.map((o) => ({
50
+ label: o.label,
51
+ value: o.value,
52
+ })), value: (rule.orderBy ?? "createdAt-desc"), onValueChange: (next) => patch({ orderBy: next }), disabled: disabled, "aria-label": BUNDLE_COPY.adminEditor.dynamic.fields.orderBy })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "semibold", children: BUNDLE_COPY.adminEditor.dynamic.fields.limit }), _jsx(Input, { type: "number", inputMode: "numeric", min: 1, max: BUNDLE_MAX_ITEMS, step: 1, value: String(rule.limit), onChange: (e) => {
53
+ const next = Number(e.target.value);
54
+ if (Number.isFinite(next)) {
55
+ patch({
56
+ limit: Math.min(Math.max(1, Math.floor(next)), BUNDLE_MAX_ITEMS),
57
+ });
58
+ }
59
+ }, disabled: disabled })] })] })] }));
60
+ }
@@ -0,0 +1,26 @@
1
+ export interface BundleItemSearchResult {
2
+ id: string;
3
+ title: string;
4
+ image?: string;
5
+ priceInPaise?: number;
6
+ storeId?: string;
7
+ }
8
+ export interface BundleItemsPickerProps {
9
+ /** Currently selected product ids. Source of truth lives in the parent form. */
10
+ value: string[];
11
+ /** Mutator called with the next ids list whenever a row is added or removed. */
12
+ onChange: (next: string[]) => void;
13
+ /** Async fetcher for search results. Receives debounced query. */
14
+ fetchProducts: (query: string) => Promise<BundleItemSearchResult[]>;
15
+ /** Optional override on min/max bounds (defaults to BUNDLE_MIN_ITEMS / BUNDLE_MAX_ITEMS). */
16
+ minItems?: number;
17
+ maxItems?: number;
18
+ /** Optional initial chip metadata so already-selected ids show titles, not raw ids. */
19
+ initialMetadata?: Record<string, BundleItemSearchResult>;
20
+ }
21
+ export declare function BundleItemsPicker({ value, onChange, fetchProducts, minItems, maxItems, initialMetadata, }: BundleItemsPickerProps): import("react/jsx-runtime").JSX.Element;
22
+ /**
23
+ * Default fetcher hitting the public /api/products endpoint. Consumers can
24
+ * pass this directly to BundleItemsPicker's `fetchProducts` prop.
25
+ */
26
+ export declare function defaultBundleItemsFetch(query: string): Promise<BundleItemSearchResult[]>;
@@ -0,0 +1,135 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * BundleItemsPicker — S-SBUNI-4 2026-05-13.
5
+ *
6
+ * Multi-select picker for bundle member products. Selected ids render as
7
+ * chips above the picker; a debounced search input queries the public
8
+ * /api/products endpoint and renders matches as checkbox rows. Enforces the
9
+ * BUNDLE_MIN_ITEMS / BUNDLE_MAX_ITEMS bounds at the UI level.
10
+ *
11
+ * The consumer passes a `fetchProducts(query)` prop so this component stays
12
+ * appkit-internal and the wire shape lives in the host app. A default
13
+ * implementation that hits `/api/products` is exported as
14
+ * `defaultBundleItemsFetch`.
15
+ */
16
+ import { useCallback, useEffect, useMemo, useState } from "react";
17
+ import { Badge, Button, Checkbox, Div, Input, Row, Stack, Text } from "../../../ui";
18
+ import { BUNDLE_MAX_ITEMS, BUNDLE_MIN_ITEMS, } from "../../../_internal/shared/features/categories/bundle-config";
19
+ import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy";
20
+ const SEARCH_DEBOUNCE_MS = 250;
21
+ export function BundleItemsPicker({ value, onChange, fetchProducts, minItems = BUNDLE_MIN_ITEMS, maxItems = BUNDLE_MAX_ITEMS, initialMetadata = {}, }) {
22
+ const [query, setQuery] = useState("");
23
+ const [debouncedQuery, setDebouncedQuery] = useState("");
24
+ const [results, setResults] = useState([]);
25
+ const [isSearching, setIsSearching] = useState(false);
26
+ const [searchError, setSearchError] = useState(null);
27
+ const [metadata, setMetadata] = useState(initialMetadata);
28
+ // Debounce query
29
+ useEffect(() => {
30
+ const t = setTimeout(() => setDebouncedQuery(query.trim()), SEARCH_DEBOUNCE_MS);
31
+ return () => clearTimeout(t);
32
+ }, [query]);
33
+ // Fetch on debounced query change
34
+ useEffect(() => {
35
+ let cancelled = false;
36
+ if (debouncedQuery.length < 2) {
37
+ setResults([]);
38
+ setSearchError(null);
39
+ return;
40
+ }
41
+ setIsSearching(true);
42
+ setSearchError(null);
43
+ fetchProducts(debouncedQuery)
44
+ .then((rows) => {
45
+ if (cancelled)
46
+ return;
47
+ setResults(rows);
48
+ setMetadata((prev) => {
49
+ const next = { ...prev };
50
+ for (const r of rows)
51
+ next[r.id] = r;
52
+ return next;
53
+ });
54
+ })
55
+ .catch((err) => {
56
+ if (cancelled)
57
+ return;
58
+ const msg = err instanceof Error ? err.message : "Search failed";
59
+ setSearchError(msg);
60
+ setResults([]);
61
+ })
62
+ .finally(() => {
63
+ if (!cancelled)
64
+ setIsSearching(false);
65
+ });
66
+ return () => {
67
+ cancelled = true;
68
+ };
69
+ }, [debouncedQuery, fetchProducts]);
70
+ const selectedSet = useMemo(() => new Set(value), [value]);
71
+ const toggle = useCallback((id) => {
72
+ if (selectedSet.has(id)) {
73
+ onChange(value.filter((v) => v !== id));
74
+ return;
75
+ }
76
+ if (value.length >= maxItems) {
77
+ return;
78
+ }
79
+ onChange([...value, id]);
80
+ }, [selectedSet, value, onChange, maxItems]);
81
+ const remove = useCallback((id) => onChange(value.filter((v) => v !== id)), [value, onChange]);
82
+ const tooFew = value.length < minItems;
83
+ const tooMany = value.length > maxItems;
84
+ const countLabel = BUNDLE_COPY.picker.selectedCount(value.length, minItems, maxItems);
85
+ const countVariant = tooFew || tooMany ? "warning" : "success";
86
+ return (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", className: "flex-wrap", children: [_jsx(Text, { size: "sm", weight: "semibold", children: BUNDLE_COPY.picker.title }), _jsx(Badge, { variant: countVariant, children: countLabel })] }), value.length > 0 && (_jsx(Div, { className: "flex flex-wrap gap-2 rounded-lg border border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-700 dark:bg-zinc-900", children: value.map((id) => {
87
+ const meta = metadata[id];
88
+ const label = meta?.title ?? id;
89
+ return (_jsxs(Row, { gap: "xs", align: "center", className: "rounded-full border border-zinc-300 bg-white px-3 py-1 text-xs dark:border-zinc-600 dark:bg-zinc-800", children: [_jsx(Text, { size: "xs", className: "max-w-[200px] truncate", children: label }), _jsx(Button, { variant: "ghost", size: "sm", "aria-label": BUNDLE_COPY.picker.removeAria(label), onClick: () => remove(id), children: "\u00D7" })] }, id));
90
+ }) })), _jsxs(Stack, { gap: "sm", children: [_jsx(Input, { type: "search", placeholder: BUNDLE_COPY.picker.searchPlaceholder, value: query, onChange: (e) => setQuery(e.target.value), "aria-label": BUNDLE_COPY.picker.searchAriaLabel }), searchError && (_jsx(Text, { size: "sm", color: "danger", children: searchError })), isSearching && (_jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.searchingHint })), !isSearching &&
91
+ debouncedQuery.length >= 2 &&
92
+ results.length === 0 &&
93
+ !searchError && (_jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.picker.noMatches(debouncedQuery) })), results.length > 0 && (_jsx(Div, { className: "max-h-72 overflow-y-auto rounded-lg border border-zinc-200 dark:border-zinc-700", children: results.map((r) => {
94
+ const isSelected = selectedSet.has(r.id);
95
+ const atCap = !isSelected && value.length >= maxItems;
96
+ return (_jsxs(Row, { gap: "sm", align: "center", className: `border-b border-zinc-100 px-3 py-2 last:border-b-0 dark:border-zinc-800 ${isSelected ? "bg-blue-50 dark:bg-blue-950" : ""} ${atCap ? "opacity-50" : ""}`, children: [_jsx(Checkbox, { checked: isSelected, disabled: atCap, onChange: () => toggle(r.id), "aria-label": BUNDLE_COPY.picker.toggleAria(r.title) }), _jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsx(Text, { size: "sm", weight: "medium", children: r.title }), _jsxs(Row, { gap: "sm", children: [_jsx(Text, { size: "xs", color: "muted", children: r.id }), typeof r.priceInPaise === "number" && (_jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 \u20B9", Math.round(r.priceInPaise / 100).toLocaleString("en-IN")] }))] })] })] }, r.id));
97
+ }) }))] })] }));
98
+ }
99
+ /**
100
+ * Default fetcher hitting the public /api/products endpoint. Consumers can
101
+ * pass this directly to BundleItemsPicker's `fetchProducts` prop.
102
+ */
103
+ export async function defaultBundleItemsFetch(query) {
104
+ const url = `/api/products?q=${encodeURIComponent(query)}&pageSize=20`;
105
+ const res = await fetch(url, { method: "GET" });
106
+ if (!res.ok) {
107
+ throw new Error(`Search failed: ${res.status}`);
108
+ }
109
+ const data = (await res.json());
110
+ const rawItems = data?.data?.items ?? data?.items ?? [];
111
+ return rawItems
112
+ .map((r) => {
113
+ const rec = r;
114
+ const id = typeof rec.id === "string" ? rec.id : null;
115
+ const title = typeof rec.title === "string"
116
+ ? rec.title
117
+ : typeof rec.name === "string"
118
+ ? rec.name
119
+ : null;
120
+ if (!id || !title)
121
+ return null;
122
+ return {
123
+ id,
124
+ title,
125
+ image: typeof rec.mainImage === "string"
126
+ ? rec.mainImage
127
+ : Array.isArray(rec.images) && typeof rec.images[0] === "string"
128
+ ? rec.images[0]
129
+ : undefined,
130
+ priceInPaise: typeof rec.price === "number" ? rec.price : undefined,
131
+ storeId: typeof rec.storeId === "string" ? rec.storeId : undefined,
132
+ };
133
+ })
134
+ .filter((r) => r !== null);
135
+ }
@@ -0,0 +1,13 @@
1
+ type SearchParams = Record<string, string | string[]>;
2
+ export interface BundlesListViewProps {
3
+ searchParams?: SearchParams;
4
+ }
5
+ /**
6
+ * Public `/bundles` index. Bundles live as `categoryType:"bundle"` rows on
7
+ * the categories collection (SB-UNI-D + V), so this fetches via
8
+ * `categoriesRepository.listByType("bundle", …)` instead of `productRepository`.
9
+ * Optional `?storeId=…` post-filters to a single seller's bundles.
10
+ * Sort UI is owned by `CategoryBundlesListing` (client).
11
+ */
12
+ export declare function BundlesListView({ searchParams, }: BundlesListViewProps): Promise<import("react/jsx-runtime").JSX.Element>;
13
+ export {};