@mohasinac/appkit 4.59.0 → 4.60.1

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 (532) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +62 -5
  3. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -2
  4. package/dist/_internal/server/features/brands/actions.js +78 -4
  5. package/dist/_internal/server/features/checkout/actions.d.ts +36 -13
  6. package/dist/_internal/server/features/checkout/actions.js +668 -183
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +18 -1
  8. package/dist/_internal/server/features/gateway-events/index.d.ts +10 -0
  9. package/dist/_internal/server/features/gateway-events/index.js +10 -0
  10. package/dist/_internal/server/features/gateway-events/ingest.d.ts +127 -0
  11. package/dist/_internal/server/features/gateway-events/ingest.js +188 -0
  12. package/dist/_internal/server/features/gateway-events/redact.d.ts +66 -0
  13. package/dist/_internal/server/features/gateway-events/redact.js +151 -0
  14. package/dist/_internal/server/features/grievance/actions.d.ts +63 -0
  15. package/dist/_internal/server/features/grievance/actions.js +173 -0
  16. package/dist/_internal/server/features/grievance/index.d.ts +8 -0
  17. package/dist/_internal/server/features/grievance/index.js +8 -0
  18. package/dist/_internal/server/features/grouped/data.js +28 -3
  19. package/dist/_internal/server/features/lottery/actions.js +99 -4
  20. package/dist/_internal/server/features/order-completion/actions.d.ts +92 -0
  21. package/dist/_internal/server/features/order-completion/actions.js +336 -0
  22. package/dist/_internal/server/features/order-completion/index.d.ts +7 -0
  23. package/dist/_internal/server/features/order-completion/index.js +7 -0
  24. package/dist/_internal/server/features/orders/actions.d.ts +13 -0
  25. package/dist/_internal/server/features/orders/actions.js +56 -2
  26. package/dist/_internal/server/features/orders/adapters.d.ts +20 -2
  27. package/dist/_internal/server/features/orders/adapters.js +44 -0
  28. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
  29. package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
  30. package/dist/_internal/server/features/orders/index.d.ts +2 -1
  31. package/dist/_internal/server/features/orders/index.js +1 -1
  32. package/dist/_internal/server/features/orders/service.d.ts +60 -0
  33. package/dist/_internal/server/features/orders/service.js +74 -0
  34. package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
  35. package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
  36. package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
  37. package/dist/_internal/server/features/payment-cases/index.js +9 -0
  38. package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
  39. package/dist/_internal/server/features/payouts/actions.js +84 -10
  40. package/dist/_internal/server/features/points/adjust.d.ts +61 -0
  41. package/dist/_internal/server/features/points/adjust.js +121 -0
  42. package/dist/_internal/server/features/points/award.d.ts +65 -0
  43. package/dist/_internal/server/features/points/award.js +145 -0
  44. package/dist/_internal/server/features/price-index/market.d.ts +33 -0
  45. package/dist/_internal/server/features/price-index/market.js +54 -1
  46. package/dist/_internal/server/features/products/data.js +40 -22
  47. package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
  48. package/dist/_internal/server/features/protection-claims/actions.js +228 -0
  49. package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
  50. package/dist/_internal/server/features/protection-claims/index.js +8 -0
  51. package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
  52. package/dist/_internal/server/features/refunds/actions.js +259 -17
  53. package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
  54. package/dist/_internal/server/features/refunds/capacity.js +37 -0
  55. package/dist/_internal/server/features/reviews/actions.js +3 -2
  56. package/dist/_internal/server/features/search/index-build/sources.js +20 -1
  57. package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
  58. package/dist/_internal/server/features/shipping/reconcile.js +34 -3
  59. package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
  60. package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
  61. package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
  62. package/dist/_internal/server/features/stores/tabs.js +24 -4
  63. package/dist/_internal/server/functions/https.d.ts +31 -1
  64. package/dist/_internal/server/functions/https.js +52 -1
  65. package/dist/_internal/server/functions/scheduled.d.ts +72 -1
  66. package/dist/_internal/server/functions/scheduled.js +124 -1
  67. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
  68. package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
  69. package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
  70. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
  71. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
  72. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
  73. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  74. package/dist/_internal/server/jobs/core/index.js +2 -0
  75. package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
  76. package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
  77. package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
  78. package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
  79. package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
  80. package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
  81. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
  83. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
  84. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
  85. package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
  86. package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
  87. package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
  88. package/dist/_internal/server/jobs/handlers/index.js +5 -0
  89. package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
  90. package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
  91. package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
  92. package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
  93. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
  94. package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
  95. package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
  96. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  97. package/dist/_internal/shared/actions/action-registry.js +71 -0
  98. package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
  99. package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
  100. package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
  101. package/dist/_internal/shared/checkout/lanes.js +46 -0
  102. package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
  103. package/dist/_internal/shared/checkout/order-math.js +251 -3
  104. package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
  105. package/dist/_internal/shared/checkout/refundable-base.js +122 -0
  106. package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
  107. package/dist/_internal/shared/features/auctions/config.js +30 -1
  108. package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
  109. package/dist/_internal/shared/features/brands/schema.js +18 -0
  110. package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
  111. package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
  112. package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
  113. package/dist/_internal/shared/features/print/label-profiles.js +350 -0
  114. package/dist/_internal/shared/features/products/to-product-item.js +33 -5
  115. package/dist/_internal/shared/fees/calculator.d.ts +31 -2
  116. package/dist/_internal/shared/fees/calculator.js +103 -5
  117. package/dist/_internal/shared/fees/india-states.d.ts +195 -0
  118. package/dist/_internal/shared/fees/india-states.js +190 -0
  119. package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
  120. package/dist/_internal/shared/fees/payout-hold.js +74 -0
  121. package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
  122. package/dist/_internal/shared/obligations/deadlines.js +155 -0
  123. package/dist/_internal/shared/shipping/quote.d.ts +96 -0
  124. package/dist/_internal/shared/shipping/quote.js +67 -0
  125. package/dist/_internal/shared/time/business-days.d.ts +91 -0
  126. package/dist/_internal/shared/time/business-days.js +185 -0
  127. package/dist/cli/index.js +0 -2
  128. package/dist/client.d.ts +10 -4
  129. package/dist/client.js +29 -3
  130. package/dist/configs/tailwind.d.ts +0 -12
  131. package/dist/configs/tailwind.js +28 -15
  132. package/dist/constants/api-endpoints.d.ts +51 -9
  133. package/dist/constants/api-endpoints.js +23 -7
  134. package/dist/constants/index.d.ts +1 -1
  135. package/dist/constants/index.js +1 -1
  136. package/dist/contracts/index.d.ts +1 -1
  137. package/dist/contracts/payment.d.ts +131 -0
  138. package/dist/features/about/components/AboutView.js +1 -1
  139. package/dist/features/about/components/DeveloperView.js +5 -2
  140. package/dist/features/about/components/FAQPageView.js +2 -1
  141. package/dist/features/about/components/FeesView.js +2 -1
  142. package/dist/features/about/components/HelpPageView.js +2 -1
  143. package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
  144. package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
  145. package/dist/features/about/components/HowEmiWorksView.js +2 -1
  146. package/dist/features/about/components/HowOffersWorkView.js +2 -1
  147. package/dist/features/about/components/HowOrdersWorkView.js +2 -1
  148. package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
  149. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
  150. package/dist/features/about/components/HowReviewsWorkView.js +2 -1
  151. package/dist/features/about/components/PolicyPageView.js +2 -1
  152. package/dist/features/about/components/ProseHero.d.ts +73 -0
  153. package/dist/features/about/components/ProseHero.js +18 -0
  154. package/dist/features/about/components/SecurityPrivacyView.js +2 -1
  155. package/dist/features/about/components/ShippingPolicyView.js +2 -1
  156. package/dist/features/about/components/TrackOrderView.js +2 -1
  157. package/dist/features/about/components/UnauthorizedView.js +1 -1
  158. package/dist/features/about/index.d.ts +2 -0
  159. package/dist/features/about/index.js +5 -0
  160. package/dist/features/account/actions/address-actions.d.ts +26 -2
  161. package/dist/features/account/actions/address-actions.js +25 -1
  162. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  163. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  164. package/dist/features/account/components/UserOrdersView.js +17 -0
  165. package/dist/features/account/components/UserSidebar.js +1 -1
  166. package/dist/features/account/hooks/useNotifications.js +29 -0
  167. package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
  168. package/dist/features/admin/components/AdminBeysView.js +2 -2
  169. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  170. package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
  171. package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
  172. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  173. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  174. package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
  175. package/dist/features/admin/components/AdminContactEditorView.js +1 -1
  176. package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
  177. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  178. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  179. package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
  180. package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
  181. package/dist/features/admin/components/AdminGuideHubView.js +1 -1
  182. package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
  183. package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
  184. package/dist/features/admin/components/AdminPartsView.js +2 -2
  185. package/dist/features/admin/components/AdminProductsView.js +75 -4
  186. package/dist/features/admin/components/AdminSidebar.js +2 -2
  187. package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
  188. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
  189. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  190. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  191. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  192. package/dist/features/admin/components/AdminUsersView.js +72 -1
  193. package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
  194. package/dist/features/admin/components/AdminViewCards.js +4 -4
  195. package/dist/features/admin/components/DataListingView.d.ts +28 -0
  196. package/dist/features/admin/components/DataListingView.js +175 -14
  197. package/dist/features/admin/components/DataTable.d.ts +12 -1
  198. package/dist/features/admin/components/DataTable.js +3 -3
  199. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  200. package/dist/features/admin/components/OwnerQuickActions.js +60 -2
  201. package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
  202. package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
  203. package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
  204. package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
  205. package/dist/features/admin/components/index.d.ts +4 -0
  206. package/dist/features/admin/components/index.js +6 -0
  207. package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
  208. package/dist/features/admin/constants/filter-tabs.js +106 -0
  209. package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
  210. package/dist/features/admin/repository/site-settings.repository.js +82 -1
  211. package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
  212. package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
  213. package/dist/features/admin/schemas/firestore.js +5 -1
  214. package/dist/features/admin/schemas/site-settings-form.js +30 -1
  215. package/dist/features/auctions/actions/bid-actions.js +13 -1
  216. package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
  217. package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
  218. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
  219. package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
  220. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
  221. package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
  222. package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
  223. package/dist/features/audit-log/schemas/firestore.js +14 -0
  224. package/dist/features/auth/permissions/constants.d.ts +17 -1
  225. package/dist/features/auth/permissions/constants.js +18 -0
  226. package/dist/features/blog/components/BlogPostView.js +1 -1
  227. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  228. package/dist/features/categories/api/[id]/description-template/route.js +107 -1
  229. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  230. package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
  231. package/dist/features/categories/components/BundleDetailView.js +1 -1
  232. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  233. package/dist/features/categories/components/CategoryForm.js +12 -1
  234. package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
  235. package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
  236. package/dist/features/categories/repository/market-price-index.repository.js +105 -0
  237. package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
  238. package/dist/features/categories/repository/price-observation.repository.js +132 -0
  239. package/dist/features/events/components/EventSaleBanner.js +1 -1
  240. package/dist/features/events/components/EventStatusBadge.js +1 -1
  241. package/dist/features/faq/components/FAQAccordion.js +2 -1
  242. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  243. package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
  244. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  245. package/dist/features/filters/FilterFacetSection.js +1 -1
  246. package/dist/features/filters/SwitchFilter.js +1 -1
  247. package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
  248. package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
  249. package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
  250. package/dist/features/gateway-events/schemas/firestore.js +125 -0
  251. package/dist/features/gateway-events/schemas/index.d.ts +81 -0
  252. package/dist/features/gateway-events/schemas/index.js +79 -0
  253. package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
  254. package/dist/features/homepage/components/AnnouncementBar.js +37 -1
  255. package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
  256. package/dist/features/homepage/components/BrandsSection.js +1 -1
  257. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  258. package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
  259. package/dist/features/homepage/components/HeroCarousel.js +2 -2
  260. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  261. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
  262. package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
  263. package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
  264. package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
  265. package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
  266. package/dist/features/inventory/components/ReceiveStationView.js +413 -0
  267. package/dist/features/inventory/components/operator-message.d.ts +29 -0
  268. package/dist/features/inventory/components/operator-message.js +41 -0
  269. package/dist/features/inventory/index.d.ts +13 -0
  270. package/dist/features/inventory/index.js +28 -0
  271. package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
  272. package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
  273. package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
  274. package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
  275. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
  276. package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
  277. package/dist/features/inventory/schemas/firestore.d.ts +197 -0
  278. package/dist/features/inventory/schemas/firestore.js +159 -0
  279. package/dist/features/layout/AppLayoutShell.d.ts +12 -1
  280. package/dist/features/layout/AppLayoutShell.js +25 -12
  281. package/dist/features/layout/AutoBreadcrumbs.js +162 -3
  282. package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
  283. package/dist/features/layout/BottomNavbar.d.ts +1 -1
  284. package/dist/features/layout/BottomNavbar.js +2 -2
  285. package/dist/features/media/MediaAvatar.js +1 -1
  286. package/dist/features/media/MediaImage.d.ts +24 -4
  287. package/dist/features/media/MediaImage.js +44 -4
  288. package/dist/features/media/MediaLightbox.js +1 -1
  289. package/dist/features/media/modals/ImageCropModal.js +1 -1
  290. package/dist/features/media/modals/ImageEditor.js +1 -1
  291. package/dist/features/media/upload/MediaUploadField.js +91 -3
  292. package/dist/features/obligations/constants/policies.d.ts +92 -0
  293. package/dist/features/obligations/constants/policies.js +378 -0
  294. package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
  295. package/dist/features/obligations/repository/obligations.repository.js +158 -0
  296. package/dist/features/obligations/schemas/firestore.d.ts +160 -0
  297. package/dist/features/obligations/schemas/firestore.js +87 -0
  298. package/dist/features/orders/actions/order-actions.d.ts +43 -4
  299. package/dist/features/orders/actions/order-actions.js +60 -3
  300. package/dist/features/orders/actions/refund-actions.js +70 -10
  301. package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
  302. package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
  303. package/dist/features/orders/components/OrdersList.js +2 -2
  304. package/dist/features/orders/components/RefundHistoryTable.js +3 -1
  305. package/dist/features/orders/components/index.d.ts +2 -0
  306. package/dist/features/orders/components/index.js +6 -0
  307. package/dist/features/orders/constants/transitions.d.ts +59 -0
  308. package/dist/features/orders/constants/transitions.js +104 -0
  309. package/dist/features/orders/repository/orders.repository.d.ts +109 -6
  310. package/dist/features/orders/repository/orders.repository.js +464 -21
  311. package/dist/features/orders/schemas/firestore.d.ts +270 -0
  312. package/dist/features/orders/schemas/firestore.js +24 -0
  313. package/dist/features/orders/schemas/index.d.ts +61 -0
  314. package/dist/features/orders/schemas/index.js +22 -0
  315. package/dist/features/orders/types/index.d.ts +79 -0
  316. package/dist/features/parts/components/PartsIndexPageView.js +8 -1
  317. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
  318. package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
  319. package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
  320. package/dist/features/payment-cases/schemas/firestore.js +105 -0
  321. package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
  322. package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
  323. package/dist/features/payments/repository/payout.repository.d.ts +0 -1
  324. package/dist/features/payments/repository/payout.repository.js +0 -1
  325. package/dist/features/points/repository/points.repository.d.ts +122 -0
  326. package/dist/features/points/repository/points.repository.js +304 -1
  327. package/dist/features/points/schemas/adjust-form.d.ts +58 -0
  328. package/dist/features/points/schemas/adjust-form.js +63 -0
  329. package/dist/features/points/schemas/firestore.d.ts +108 -1
  330. package/dist/features/points/schemas/firestore.js +84 -0
  331. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
  332. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  333. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
  334. package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
  335. package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
  336. package/dist/features/price-index/market-stats.d.ts +82 -0
  337. package/dist/features/price-index/market-stats.js +230 -0
  338. package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
  339. package/dist/features/print/components/BoxLabelPrintView.js +66 -0
  340. package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
  341. package/dist/features/print/components/LabelProfilePicker.js +38 -0
  342. package/dist/features/print/components/labels.d.ts +117 -0
  343. package/dist/features/print/components/labels.js +258 -0
  344. package/dist/features/print/components/labels.style.css +46 -0
  345. package/dist/features/print/index.d.ts +6 -0
  346. package/dist/features/print/index.js +16 -0
  347. package/dist/features/products/columns/productTableColumns.js +5 -4
  348. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  349. package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
  350. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  351. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  352. package/dist/features/products/components/PrizeRevealModal.js +2 -2
  353. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  354. package/dist/features/products/components/ProductForm.js +34 -23
  355. package/dist/features/products/components/ProductGrid.js +86 -62
  356. package/dist/features/products/constants/card-badges.d.ts +97 -0
  357. package/dist/features/products/constants/card-badges.js +100 -0
  358. package/dist/features/products/repository/products.repository.js +34 -1
  359. package/dist/features/products/schemas/firestore.d.ts +46 -3
  360. package/dist/features/products/schemas/firestore.js +21 -0
  361. package/dist/features/promotions/components/PromotionsView.js +1 -1
  362. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
  363. package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
  364. package/dist/features/promotions/schemas/firestore.js +30 -3
  365. package/dist/features/promotions/schemas/index.d.ts +6 -6
  366. package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
  367. package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
  368. package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
  369. package/dist/features/protection-claims/schemas/firestore.js +130 -0
  370. package/dist/features/reviews/actions/review-actions.js +3 -2
  371. package/dist/features/reviews/components/ReviewModal.js +1 -1
  372. package/dist/features/reviews/components/ReviewsList.js +1 -1
  373. package/dist/features/reviews/schemas/firestore.d.ts +20 -1
  374. package/dist/features/scams/constants/scam-types.d.ts +2 -0
  375. package/dist/features/scams/constants/scam-types.js +18 -0
  376. package/dist/features/scams/schemas/report-form.d.ts +3 -3
  377. package/dist/features/scams/schemas/report-form.js +26 -1
  378. package/dist/features/search/components/Search.js +9 -9
  379. package/dist/features/search/components/SearchResultsClient.js +18 -3
  380. package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
  381. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  382. package/dist/features/seller/actions/offer-actions.js +16 -1
  383. package/dist/features/seller/actions/seller-actions.js +14 -3
  384. package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
  385. package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
  386. package/dist/features/seller/components/PrintCenterView.js +41 -30
  387. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  388. package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
  389. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  390. package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
  391. package/dist/features/seller/components/SellerProductShell.js +123 -13
  392. package/dist/features/seller/components/SellerReviewsView.js +4 -2
  393. package/dist/features/seller/components/SellerSidebar.js +1 -1
  394. package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
  395. package/dist/features/seller/schemas/coupon-form.js +27 -0
  396. package/dist/features/seller/schemas/product-form.d.ts +3 -0
  397. package/dist/features/seller/schemas/product-form.js +5 -0
  398. package/dist/features/shell/FormShell.js +2 -2
  399. package/dist/features/shell/QuickFormDrawer.js +14 -0
  400. package/dist/features/shell/SectionForm.d.ts +19 -0
  401. package/dist/features/shell/SectionForm.js +133 -9
  402. package/dist/features/shell/SectionForm.style.css +54 -0
  403. package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
  404. package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
  405. package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
  406. package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
  407. package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
  408. package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
  409. package/dist/features/stores/components/StoreGuideHubView.js +1 -1
  410. package/dist/features/stores/components/StoreHeader.js +1 -1
  411. package/dist/features/support/schemas/firestore.d.ts +73 -2
  412. package/dist/features/support/schemas/firestore.js +59 -0
  413. package/dist/index.d.ts +16 -24
  414. package/dist/index.js +38 -47
  415. package/dist/next/ErrorBoundary.js +1 -1
  416. package/dist/next/routing/route-map.d.ts +24 -0
  417. package/dist/next/routing/route-map.js +40 -0
  418. package/dist/providers/payment-manual/index.d.ts +15 -1
  419. package/dist/providers/payment-manual/index.js +37 -0
  420. package/dist/providers/payment-phonepe/index.d.ts +14 -1
  421. package/dist/providers/payment-phonepe/index.js +36 -0
  422. package/dist/providers/payment-razorpay/index.d.ts +44 -1
  423. package/dist/providers/payment-razorpay/index.js +99 -0
  424. package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
  425. package/dist/providers/shipping-shiprocket/index.js +18 -0
  426. package/dist/schemas/registry.d.ts +44 -11
  427. package/dist/server-entry.d.ts +2 -0
  428. package/dist/server-entry.js +27 -0
  429. package/dist/server.d.ts +43 -0
  430. package/dist/server.js +98 -0
  431. package/dist/styles.css +418 -149
  432. package/dist/tailwind-utilities.css +1 -1
  433. package/dist/tokens/themes/default-dark.js +15 -12
  434. package/dist/tokens/themes/default-light.js +14 -11
  435. package/dist/tokens/tokens.css +106 -23
  436. package/dist/ui/DataTable.style.css +4 -4
  437. package/dist/ui/columns/cell-renderers.d.ts +20 -0
  438. package/dist/ui/columns/cell-renderers.js +26 -1
  439. package/dist/ui/columns/index.d.ts +1 -1
  440. package/dist/ui/columns/index.js +4 -1
  441. package/dist/ui/components/Badge.style.css +1 -1
  442. package/dist/ui/components/Breadcrumb.js +19 -1
  443. package/dist/ui/components/BulkActionBar.style.css +4 -4
  444. package/dist/ui/components/Button.style.css +1 -1
  445. package/dist/ui/components/Checkbox.style.css +1 -1
  446. package/dist/ui/components/FallbackShell.js +1 -1
  447. package/dist/ui/components/Form.d.ts +14 -1
  448. package/dist/ui/components/Form.js +2 -2
  449. package/dist/ui/components/FormField.js +18 -4
  450. package/dist/ui/components/FormField.style.css +43 -3
  451. package/dist/ui/components/GatedPrice.style.css +1 -1
  452. package/dist/ui/components/IconButton.style.css +1 -1
  453. package/dist/ui/components/Input.js +22 -1
  454. package/dist/ui/components/Input.style.css +38 -22
  455. package/dist/ui/components/ListingFilterDrawer.js +1 -1
  456. package/dist/ui/components/ListingToolbar.js +1 -1
  457. package/dist/ui/components/PaginatedSelect.js +0 -0
  458. package/dist/ui/components/Radio.style.css +1 -1
  459. package/dist/ui/components/Repeater.d.ts +53 -0
  460. package/dist/ui/components/Repeater.js +7 -0
  461. package/dist/ui/components/RichTextEditor.d.ts +20 -1
  462. package/dist/ui/components/RichTextEditor.js +23 -2
  463. package/dist/ui/components/Select.style.css +7 -21
  464. package/dist/ui/components/Semantic.js +27 -3
  465. package/dist/ui/components/TagInput.style.css +4 -9
  466. package/dist/ui/components/Textarea.style.css +4 -18
  467. package/dist/ui/components/Toggle.style.css +1 -1
  468. package/dist/ui/components/Typography.d.ts +3 -3
  469. package/dist/ui/components/Typography.js +15 -15
  470. package/dist/ui/components/ViewToggle.style.css +4 -4
  471. package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
  472. package/dist/ui/forms/AddAnotherToggle.js +56 -0
  473. package/dist/ui/forms/ColorPickerField.js +15 -2
  474. package/dist/ui/forms/FieldCheckbox.js +15 -2
  475. package/dist/ui/forms/FieldInput.d.ts +22 -1
  476. package/dist/ui/forms/FieldInput.js +19 -5
  477. package/dist/ui/forms/FieldLabel.d.ts +35 -0
  478. package/dist/ui/forms/FieldLabel.js +70 -0
  479. package/dist/ui/forms/FieldSelect.d.ts +4 -1
  480. package/dist/ui/forms/FieldSelect.js +27 -5
  481. package/dist/ui/forms/FieldTextarea.d.ts +4 -1
  482. package/dist/ui/forms/FieldTextarea.js +22 -5
  483. package/dist/ui/forms/FormShell.d.ts +17 -1
  484. package/dist/ui/forms/FormShell.js +36 -2
  485. package/dist/ui/forms/FormShell.style.css +41 -33
  486. package/dist/ui/forms/index.d.ts +5 -1
  487. package/dist/ui/forms/index.js +2 -0
  488. package/dist/ui/icons/icon-registry.d.ts +1 -0
  489. package/dist/ui/icons/icon-registry.js +17 -1
  490. package/dist/utils/id-generators.d.ts +80 -0
  491. package/dist/utils/id-generators.js +93 -0
  492. package/dist/utils/search-txt-builders.d.ts +12 -0
  493. package/dist/utils/search-txt-builders.js +17 -0
  494. package/package.json +1 -1
  495. package/scripts/seed-cli.mjs +106 -5
  496. package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
  497. package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
  498. package/dist/features/loyalty/api/balance/route.d.ts +0 -12
  499. package/dist/features/loyalty/api/balance/route.js +0 -41
  500. package/dist/features/loyalty/api/earn/route.d.ts +0 -12
  501. package/dist/features/loyalty/api/earn/route.js +0 -38
  502. package/dist/features/loyalty/api/history/route.d.ts +0 -12
  503. package/dist/features/loyalty/api/history/route.js +0 -58
  504. package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
  505. package/dist/features/loyalty/api/redeem/route.js +0 -38
  506. package/dist/features/loyalty/columns/index.d.ts +0 -17
  507. package/dist/features/loyalty/columns/index.js +0 -40
  508. package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
  509. package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
  510. package/dist/features/loyalty/components/index.d.ts +0 -1
  511. package/dist/features/loyalty/components/index.js +0 -1
  512. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
  513. package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
  514. package/dist/features/loyalty/index.d.ts +0 -6
  515. package/dist/features/loyalty/index.js +0 -6
  516. package/dist/features/loyalty/manifest.d.ts +0 -2
  517. package/dist/features/loyalty/manifest.js +0 -16
  518. package/dist/features/loyalty/messages/en.json +0 -19
  519. package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
  520. package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
  521. package/dist/features/loyalty/schemas/index.d.ts +0 -85
  522. package/dist/features/loyalty/schemas/index.js +0 -40
  523. package/dist/features/loyalty/server.d.ts +0 -6
  524. package/dist/features/loyalty/server.js +0 -6
  525. package/dist/features/loyalty/types/index.d.ts +0 -31
  526. package/dist/features/loyalty/types/index.js +0 -1
  527. package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
  528. package/dist/features/loyalty/types/loyalty-config.js +0 -1
  529. package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
  530. package/dist/features/loyalty/types/loyalty-math.js +0 -27
  531. package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
  532. package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ export * from "./firestore";
3
+ export declare const gatewayEventKindSchema: z.ZodEnum<["paid", "failed", "dispute", "refund", "other"]>;
4
+ export declare const gatewayEventStatusSchema: z.ZodEnum<["received", "processing", "processed", "ignored", "conflict", "failed"]>;
5
+ export declare const gatewayEventFirestoreSchema: z.ZodObject<{
6
+ id: z.ZodString;
7
+ gateway: z.ZodString;
8
+ rawEvent: z.ZodString;
9
+ kind: z.ZodEnum<["paid", "failed", "dispute", "refund", "other"]>;
10
+ status: z.ZodEnum<["received", "processing", "processed", "ignored", "conflict", "failed"]>;
11
+ terminal: z.ZodOptional<z.ZodBoolean>;
12
+ providerEventId: z.ZodOptional<z.ZodString>;
13
+ bodySha256: z.ZodString;
14
+ gatewayOrderId: z.ZodOptional<z.ZodString>;
15
+ gatewayPaymentId: z.ZodOptional<z.ZodString>;
16
+ amount: z.ZodOptional<z.ZodNumber>;
17
+ orderIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
18
+ receivedAt: z.ZodDate;
19
+ claimedAt: z.ZodDate;
20
+ leaseExpiresAt: z.ZodDate;
21
+ processedAt: z.ZodOptional<z.ZodDate>;
22
+ attempts: z.ZodNumber;
23
+ lastError: z.ZodOptional<z.ZodString>;
24
+ expiresAt: z.ZodDate;
25
+ payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, z.ZodTypeDef, unknown>>>;
26
+ payloadTruncated: z.ZodOptional<z.ZodBoolean>;
27
+ createdAt: z.ZodDate;
28
+ updatedAt: z.ZodDate;
29
+ seedPurpose: z.ZodOptional<z.ZodString>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ status: "received" | "failed" | "processed" | "processing" | "conflict" | "ignored";
32
+ id: string;
33
+ kind: "other" | "paid" | "failed" | "dispute" | "refund";
34
+ createdAt: Date;
35
+ updatedAt: Date;
36
+ expiresAt: Date;
37
+ gateway: string;
38
+ receivedAt: Date;
39
+ attempts: number;
40
+ bodySha256: string;
41
+ leaseExpiresAt: Date;
42
+ claimedAt: Date;
43
+ rawEvent: string;
44
+ terminal?: boolean | undefined;
45
+ amount?: number | undefined;
46
+ seedPurpose?: string | undefined;
47
+ orderIds?: string[] | undefined;
48
+ processedAt?: Date | undefined;
49
+ gatewayPaymentId?: string | undefined;
50
+ gatewayOrderId?: string | undefined;
51
+ providerEventId?: string | undefined;
52
+ lastError?: string | undefined;
53
+ payload?: Record<string, unknown> | undefined;
54
+ payloadTruncated?: boolean | undefined;
55
+ }, {
56
+ status: "received" | "failed" | "processed" | "processing" | "conflict" | "ignored";
57
+ id: string;
58
+ kind: "other" | "paid" | "failed" | "dispute" | "refund";
59
+ createdAt: Date;
60
+ updatedAt: Date;
61
+ expiresAt: Date;
62
+ gateway: string;
63
+ receivedAt: Date;
64
+ attempts: number;
65
+ bodySha256: string;
66
+ leaseExpiresAt: Date;
67
+ claimedAt: Date;
68
+ rawEvent: string;
69
+ terminal?: boolean | undefined;
70
+ amount?: number | undefined;
71
+ seedPurpose?: string | undefined;
72
+ orderIds?: string[] | undefined;
73
+ processedAt?: Date | undefined;
74
+ gatewayPaymentId?: string | undefined;
75
+ gatewayOrderId?: string | undefined;
76
+ providerEventId?: string | undefined;
77
+ lastError?: string | undefined;
78
+ payload?: Record<string, unknown> | undefined;
79
+ payloadTruncated?: boolean | undefined;
80
+ }>;
81
+ export type GatewayEventFromSchema = z.infer<typeof gatewayEventFirestoreSchema>;
@@ -0,0 +1,79 @@
1
+ // [SCHEMA] gateway-events feature — Firestore document schema.
2
+ //
3
+ // Mirrors GatewayEventDocument in ./firestore.ts.
4
+ //
5
+ // 🛑 THE MIRROR MUST BE COMPLETE, and that is not a style point. `z.object()`
6
+ // STRIPS unknown keys, so a field present on the interface and absent here is
7
+ // silently DELETED by any parse — which is precisely what
8
+ // `orderRefundEventSchema` was doing to `reasonCode` and `razorpayRefundId`
9
+ // (the schema written to validate a gateway refund reference discarded it), and
10
+ // what `serverErrorFirestoreSchema` was doing to `cause`, `entityType` and
11
+ // `entityId`. Both were found by reading the two files side by side, which is
12
+ // the only way this class of drift is ever found.
13
+ //
14
+ // So: a field added to `GatewayEventDocument` is added here in the same edit.
15
+ import { z } from "zod";
16
+ export * from "./firestore.js";
17
+ export const gatewayEventKindSchema = z.enum([
18
+ "paid",
19
+ "failed",
20
+ "dispute",
21
+ "refund",
22
+ "other",
23
+ ]);
24
+ export const gatewayEventStatusSchema = z.enum([
25
+ "received",
26
+ "processing",
27
+ "processed",
28
+ "ignored",
29
+ "conflict",
30
+ "failed",
31
+ ]);
32
+ /**
33
+ * The redacted payload, as a recursive JSON-ish value.
34
+ *
35
+ * `z.record(z.unknown())` would accept anything and assert nothing; this at
36
+ * least pins the shape to serialisable data, which is the property that matters
37
+ * for a field written to Firestore and read back into an admin table.
38
+ */
39
+ const jsonValueSchema = z.lazy(() => z.union([
40
+ z.string(),
41
+ z.number(),
42
+ z.boolean(),
43
+ z.null(),
44
+ z.array(jsonValueSchema),
45
+ z.record(jsonValueSchema),
46
+ ]));
47
+ export const gatewayEventFirestoreSchema = z.object({
48
+ id: z.string(),
49
+ gateway: z.string(),
50
+ rawEvent: z.string(),
51
+ kind: gatewayEventKindSchema,
52
+ status: gatewayEventStatusSchema,
53
+ terminal: z.boolean().optional(),
54
+ providerEventId: z.string().optional(),
55
+ bodySha256: z.string(),
56
+ gatewayOrderId: z.string().optional(),
57
+ gatewayPaymentId: z.string().optional(),
58
+ /*
59
+ * No `.int()`. The amount is decimal RUPEES, so a legitimate ₹1,499.50 must
60
+ * parse — `audit-money-units`' INT_ON_MONEY_FIELD rule exists because that
61
+ * constraint survived the subunit→rupee migration on six money fields and
62
+ * rejected real values.
63
+ */
64
+ amount: z.number().optional(),
65
+ orderIds: z.array(z.string()).optional(),
66
+ receivedAt: z.date(),
67
+ claimedAt: z.date(),
68
+ leaseExpiresAt: z.date(),
69
+ processedAt: z.date().optional(),
70
+ attempts: z.number(),
71
+ lastError: z.string().optional(),
72
+ expiresAt: z.date(),
73
+ payload: z.record(jsonValueSchema).optional(),
74
+ payloadTruncated: z.boolean().optional(),
75
+ // BaseDocument
76
+ createdAt: z.date(),
77
+ updatedAt: z.date(),
78
+ seedPurpose: z.string().optional(),
79
+ });
@@ -15,7 +15,7 @@ const THEME_LABEL = {
15
15
  generic: "Grouped listing",
16
16
  };
17
17
  export function GroupedListingDetailView({ group, members }) {
18
- return (_jsx(Section, { padding: "section", children: _jsx(Container, { children: _jsxs(Stack, { gap: "comfortable", children: [group.coverImage && (_jsx(Div, { className: `relative h-48 w-full md:h-64 ${__O.hidden}`, rounded: "xl", surface: "muted", children: _jsx(MediaImage, { src: group.coverImage, alt: group.title, size: "banner" }) })), _jsxs(Stack, { gap: "xs", children: [_jsx(Span, { size: "xs", color: "muted", transform: "uppercase", weight: "semibold", children: THEME_LABEL[group.groupTheme] }), _jsx(RecordOwnerQuickActions, { resource: "GROUP", recordId: String(group.id), placement: "detail", recordLabel: String(group.title), storeId: group.storeId ? String(group.storeId) : undefined }), _jsx(Heading, { level: 1, children: group.title }), group.description && (_jsx(Text, { color: "muted", children: group.description })), _jsxs(Text, { size: "sm", color: "muted", children: [members.length, " item", members.length === 1 ? "" : "s", " in this group"] })] }), members.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "lg", children: "Pick what you want" }), _jsx(Text, { size: "sm", color: "muted", children: "Choose a quantity for each item \u2014 they'll go into your cart as a single line you can edit later." }), _jsx(GroupMemberPicker, { groupId: group.id, groupSource: "grouped-listing", members: members,
18
+ return (_jsx(Section, { padding: "section", children: _jsx(Container, { children: _jsxs(Stack, { gap: "comfortable", children: [group.coverImage && (_jsx(Div, { className: `relative h-48 w-full md:h-64 ${__O.hidden}`, rounded: "xl", surface: "muted", children: _jsx(MediaImage, { src: group.coverImage, alt: group.title, size: "banner" }) })), _jsxs(Stack, { gap: "xs", children: [_jsx(Span, { size: "xs", color: "muted", transform: "uppercase", weight: "semibold", children: THEME_LABEL[group.groupTheme] }), _jsx(Heading, { level: 1, children: group.title }), _jsx(RecordOwnerQuickActions, { resource: "GROUP", recordId: String(group.id), placement: "detail", recordLabel: String(group.title), storeId: group.storeId ? String(group.storeId) : undefined }), group.description && (_jsx(Text, { color: "muted", children: group.description })), _jsxs(Text, { size: "sm", color: "muted", children: [members.length, " item", members.length === 1 ? "" : "s", " in this group"] })] }), members.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "lg", children: "Pick what you want" }), _jsx(Text, { size: "sm", color: "muted", children: "Choose a quantity for each item \u2014 they'll go into your cart as a single line you can edit later." }), _jsx(GroupMemberPicker, { groupId: group.id, groupSource: "grouped-listing", members: members,
19
19
  /*
20
20
  * Off the group document this view already loaded. The picker
21
21
  * and `addGroupLineToCart` run the SAME `checkGroupRules`, so
@@ -55,6 +55,42 @@ export function AnnouncementBar({ message, link, className = "", onDismiss }) {
55
55
  }, [message, userAlreadyDismissed]);
56
56
  if (dismissed)
57
57
  return null;
58
+ /*
59
+ * ── THE CLS STORY, AND WHY THIS CLASS EXISTS ──────────────────────────────
60
+ *
61
+ * 🛑 THIS COMPONENT USED TO CAUSE A TOP-OF-PAGE LAYOUT SHIFT ON EVERY
62
+ * RETURNING VISIT, and a shift at the top of the document moves everything
63
+ * below it — so it counts against CLS at close to full weight. The mobile
64
+ * homepage measured 0.822 against a 0.1 "good" threshold.
65
+ *
66
+ * The mechanism: `dismissed` starts `false` for anyone without a resolved
67
+ * session, so the server and the first client frame BOTH render the bar at
68
+ * full height — at `opacity-0`, because `mounted` is also false. Then the
69
+ * effect above reads `localStorage`, finds a dismissal, and returns `null`.
70
+ * The bar's whole height disappears after paint and the page jumps upward.
71
+ * The visitor saw a coloured strip they could not read, which then vanished.
72
+ *
73
+ * It cannot be fixed from inside this component. The dismissal is in
74
+ * `localStorage`, which does not exist during the server render, and the
75
+ * root locale layout must stay STATIC (Root Cause #82) so it cannot read a
76
+ * cookie instead. Something has to decide before React runs.
77
+ *
78
+ * So `src/app/layout.tsx` carries a pre-paint inline script — the same
79
+ * mechanism already used there for theme, font and hand mode — which sets
80
+ * `data-banner-dismissed="1"` on `<html>`. This class is what that attribute
81
+ * acts on: `display: none` from the first frame, so the bar reserves nothing
82
+ * and there is nothing to collapse.
83
+ *
84
+ * 🛑 THE CLASS STAYS ON EVEN AFTER MOUNT. Removing it once React knows
85
+ * better would re-introduce the shift for the exact visitor it protects. The
86
+ * component's own `dismissed` state unmounts the bar in the same frame, so
87
+ * the two agree; the attribute is the pre-React half of one decision, not a
88
+ * guess to be corrected.
89
+ *
90
+ * The `opacity` transition is kept for the OTHER case — a visitor with no
91
+ * dismissal, where the bar is genuinely shown and fading it in avoids a hard
92
+ * pop. That case reserves its space on the server and does not shift.
93
+ */
58
94
  /*
59
95
  * 🛑 THE `overlay` PROP IS GONE — DO NOT REINTRODUCE IT.
60
96
  *
@@ -76,7 +112,7 @@ export function AnnouncementBar({ message, link, className = "", onDismiss }) {
76
112
  * every width, so there is nothing to overlap and no breakpoint to tune.
77
113
  */
78
114
  const positionCls = "relative w-full bg-primary-700";
79
- return (_jsx(Div, { className: `${positionCls} transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: _jsxs(Row, { textWeight: "medium", textSize: "sm", className: "relative text-left text-white", padding: "y-xs", align: "center", justify: "start", children: [link ? (_jsx(TextLink, { href: link, className: "text-white underline", children: message })) : (_jsx(Span, { children: message })), _jsx(IconButton, { type: "button", onClick: () => {
115
+ return (_jsx(Div, { className: `appkit-announcement-bar ${positionCls} transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: _jsxs(Row, { textWeight: "medium", textSize: "sm", className: "relative text-left text-white", padding: "y-xs", align: "center", justify: "start", children: [link ? (_jsx(TextLink, { href: link, className: "text-white underline", children: message })) : (_jsx(Span, { children: message })), _jsx(IconButton, { type: "button", onClick: () => {
80
116
  saveLocalDismissal(message);
81
117
  onDismiss?.(bannerHash);
82
118
  setDismissed(true);
@@ -0,0 +1,30 @@
1
+ /*
2
+ * The announcement bar's pre-paint suppression.
3
+ *
4
+ * 🛑 THE SELECTOR IS A CONTRACT WITH AN INLINE SCRIPT IN `src/app/layout.tsx`.
5
+ * That script reads `localStorage['letitrip:announcement-dismissed']` before
6
+ * the first paint and sets `data-banner-dismissed="1"` on `<html>`; this rule
7
+ * is the half that acts on it.
8
+ *
9
+ * Why it has to be CSS and not React: the bar renders at full height on the
10
+ * server (nothing has told it the visitor dismissed it), so by the time a
11
+ * `useEffect` can read `localStorage` the space is already painted — and
12
+ * removing it then is a top-of-page layout shift that moves the whole
13
+ * document. Mobile homepage CLS measured 0.822 against a 0.1 threshold.
14
+ *
15
+ * 🛑 `display: none`, NOT `visibility: hidden` or `opacity: 0`. The point is
16
+ * to reserve NO SPACE. The previous behaviour was effectively `opacity: 0`
17
+ * while still occupying its height, which is the worst of both: an unreadable
18
+ * coloured strip that then collapsed.
19
+ *
20
+ * 🛑 NOT scoped to a media query. The shift happens at every width; it is
21
+ * merely worst on a phone, where the bar wraps to two lines and the viewport
22
+ * is short enough that its height is a large fraction of the fold.
23
+ *
24
+ * @tag domain:homepage
25
+ * @tag layer:feature
26
+ */
27
+
28
+ :root[data-banner-dismissed="1"] .appkit-announcement-bar {
29
+ display: none;
30
+ }
@@ -29,7 +29,7 @@ function BrandLogo({ brand }) {
29
29
  const iconSrc = brand.display?.icon;
30
30
  const coverImage = brand.display?.coverImage;
31
31
  const initial = brand.name[0]?.toUpperCase() ?? "?";
32
- return (_jsxs(Link, { href: ROUTES.PUBLIC.CATEGORY_DETAIL(brand.slug), className: "flex h-32 w-36 flex-col items-center justify-center gap-[var(--appkit-space-2)] rounded-xl border bg-[var(--appkit-color-surface)] p-[var(--appkit-space-3)] shadow-sm transition-all hover:border-primary-300 hover:shadow-md border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] md:h-40", children: [iconSrc || coverImage ? (_jsx(Image, { src: resolveMediaUrl(iconSrc ?? coverImage), alt: brand.name, width: 64, height: 64, className: "h-16 w-16 rounded object-contain" })) : (_jsx(Row, { textWeight: "bold", textSize: "sm", className: "h-16 w-16 bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300", align: "center", justify: "center", rounded: "lg", children: initial })), _jsx(Text, { className: "w-full truncate", color: "muted", size: "xs", weight: "medium", align: "start", children: brand.name })] }));
32
+ return (_jsxs(Link, { href: ROUTES.PUBLIC.CATEGORY_DETAIL(brand.slug), className: "flex h-32 w-36 flex-col items-center justify-center gap-[var(--appkit-space-2)] rounded-xl border p-[var(--appkit-space-3)] shadow-sm transition-all hover:border-primary-300 hover:shadow-md border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] md:h-40", children: [iconSrc || coverImage ? (_jsx(Image, { src: resolveMediaUrl(iconSrc ?? coverImage), alt: brand.name, width: 64, height: 64, className: "h-16 w-16 rounded object-contain" })) : (_jsx(Row, { textWeight: "bold", textSize: "sm", className: "h-16 w-16 bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300", align: "center", justify: "center", rounded: "lg", children: initial })), _jsx(Text, { className: "w-full truncate", color: "muted", size: "xs", weight: "medium", align: "start", children: brand.name })] }));
33
33
  }
34
34
  export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "All brands →", className = "", initialItems, cta, filters, autoScroll = true, scrollInterval = 4000, loop = true, }) {
35
35
  const themed = { textPrimary: THEMED_TEXT_PRIMARY };
@@ -24,5 +24,5 @@ export function CTABannerSection({ title = SECTION_TITLE.banner, eyebrow = SECTI
24
24
  // Pairs with SECTION_COPY.bannerSecondaryCta — see the note there for why
25
25
  // this banner must not default to /auctions.
26
26
  secondaryHref = String(ROUTES.PUBLIC.CATEGORIES), height = "md", backgroundImage, className = "", }) {
27
- return (_jsxs(Section, { tone: "accent-banner", className: `relative ${className}`, overflow: "hidden", paddingY: HEIGHT_PADDING_Y[height], paddingX: "x-md", children: [backgroundImage && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "absolute inset-0", children: _jsx(MediaImage, { src: backgroundImage, alt: "", size: "banner", objectFit: "cover" }) }), _jsx(Scrim, { direction: "left-to-right", intensity: "strong", className: "absolute inset-0" })] })), _jsxs(Div, { className: "relative mx-auto max-w-3xl text-left", children: [_jsxs(Div, { layout: "inline-flex", align: "center", gap: "2", surface: "frost", rounded: "full", padding: "x-sm", className: "mb-4 py-[var(--appkit-space-1-5)] backdrop-blur-sm", children: [_jsx(Icon, { name: "deals", size: "sm", tone: "on-solid" }), _jsx(Span, { color: "inverse", size: "xs", weight: "semibold", transform: "uppercase", className: "tracking-[0.18em]", children: eyebrow })] }), _jsx(Heading, { color: "inverse", level: 2, mdSize: "3xl", lgSize: "4xl", size: "2xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { color: "inverse-muted", className: "mt-3", size: "base", children: subtitle })), description && (_jsx(Text, { color: "inverse-muted", className: "mt-2 max-w-2xl", size: "sm", children: description })), _jsxs(Row, { className: "mt-8", align: "center", justify: "start", gap: "md", wrap: true, children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-[var(--appkit-space-8)] py-[var(--appkit-space-3)] text-[length:var(--appkit-text-sm)] font-semibold text-primary-700 shadow-sm transition-all hover:bg-surface-hover hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-[var(--appkit-space-8)] py-[var(--appkit-space-3)] text-[length:var(--appkit-text-sm)] font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] })] }));
27
+ return (_jsxs(Section, { tone: "accent-banner", className: `relative ${className}`, overflow: "hidden", paddingY: HEIGHT_PADDING_Y[height], paddingX: "x-md", children: [backgroundImage && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "absolute inset-0", children: _jsx(MediaImage, { src: backgroundImage, alt: "", size: "banner", objectFit: "cover", fill: true }) }), _jsx(Scrim, { direction: "left-to-right", intensity: "strong", className: "absolute inset-0" })] })), _jsxs(Div, { className: "relative mx-auto max-w-3xl text-left", children: [_jsxs(Div, { layout: "inline-flex", align: "center", gap: "2", surface: "frost", rounded: "full", padding: "x-sm", className: "mb-4 py-[var(--appkit-space-1-5)] backdrop-blur-sm", children: [_jsx(Icon, { name: "deals", size: "sm", tone: "on-solid" }), _jsx(Span, { color: "inverse", size: "xs", weight: "semibold", transform: "uppercase", className: "tracking-[0.18em]", children: eyebrow })] }), _jsx(Heading, { color: "inverse", level: 2, mdSize: "3xl", lgSize: "4xl", size: "2xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { color: "inverse-muted", className: "mt-3", size: "base", children: subtitle })), description && (_jsx(Text, { color: "inverse-muted", className: "mt-2 max-w-2xl", size: "sm", children: description })), _jsxs(Row, { className: "mt-8", align: "center", justify: "start", gap: "md", wrap: true, children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-[var(--appkit-space-8)] py-[var(--appkit-space-3)] text-[length:var(--appkit-text-sm)] font-semibold text-primary-700 shadow-sm transition-all hover:bg-surface-hover hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-[var(--appkit-space-8)] py-[var(--appkit-space-3)] text-[length:var(--appkit-text-sm)] font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] })] }));
28
28
  }
@@ -9,36 +9,26 @@
9
9
  "use client";
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  import Link from "next/link.js";
12
- import { Badge, Div, GatedPrice, Grid, Heading, PricesOnly, Row, Section, Stack, Text } from "../../../ui/index.js";
13
- import { MediaImage } from "../../media/MediaImage.js";
12
+ /*
13
+ * 🛑 The import list shrank with the card. Badge, GatedPrice, PricesOnly,
14
+ * MediaImage, Div, formatCurrency, BUNDLE_STOCK_VARIANT,
15
+ * computeBundleDiscount, the two className constants and the placeholder
16
+ * emoji were ALL only reachable from the deleted `FeaturedBundleCard`.
17
+ * `tsc` does not flag an unused import, so leaving them would have kept a
18
+ * card's worth of dependencies on a file that no longer draws a card — and
19
+ * `MarketplaceBundleCard` owns every one of those concerns now.
20
+ */
21
+ import { Grid, Heading, Row, Section, Stack, Text } from "../../../ui/index.js";
14
22
  import { ROUTES } from "../../../next/routing/route-map.js";
15
- import { formatCurrency } from "../../../utils/number.formatter.js";
16
- import { BUNDLE_COPY, BUNDLE_STOCK_VARIANT, } from "../../../_internal/shared/features/categories/bundle-copy.js";
17
- import { computeBundleDiscount } from "../../../_internal/shared/features/categories/bundle-pricing.js";
18
- import { useHandMode } from "../../../_internal/client/hand-mode/index.js";
23
+ import { BUNDLE_COPY } from "../../../_internal/shared/features/categories/bundle-copy.js";
24
+ import { MarketplaceBundleCard } from "../../products/components/MarketplaceBundleCard.js";
19
25
  import { BundleBuyNowCta } from "../../categories/components/BundleBuyNowCta.js";
20
- const __P = {
21
- p3: "p-[var(--appkit-space-3)]",
22
- };
23
- const __O = {
24
- hidden: "overflow-hidden",
25
- };
26
- const PLACEHOLDER_EMOJI = "📦";
26
+ import { useHandMode } from "../../../_internal/client/hand-mode/index.js";
27
27
  export function FeaturedBundlesSection({ title = BUNDLE_COPY.featuredDefaultTitle, description, initialItems = [], maxItems, showSavingsBadge = true, viewMoreLabel = BUNDLE_COPY.featured.viewAll, className = "", onBuyNow, }) {
28
28
  const { hand } = useHandMode();
29
29
  const bundles = initialItems.filter((c) => c.categoryType === "bundle");
30
30
  const items = maxItems && maxItems > 0 ? bundles.slice(0, maxItems) : bundles;
31
31
  if (items.length === 0)
32
32
  return null;
33
- return (_jsx(Section, { className: `${className}`, padding: "y-2xl", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", wrap: true, reverse: hand === "left", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, size: "2xl", weight: "semibold", color: "primary", children: title }), description && (_jsx(Text, { size: "sm", color: "muted", children: description }))] }), _jsx(Link, { href: String(ROUTES.PUBLIC.BUNDLES), className: "inline-flex items-center gap-[0.375rem] rounded-[var(--appkit-radius-md)] px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-sm)] font-semibold transition-colors bg-primary text-white hover:bg-primary-600", children: viewMoreLabel })] }), _jsx(Grid, { cols: "cards", gap: "3", children: items.map((bundle) => (_jsx(FeaturedBundleCard, { bundle: bundle, showSavingsBadge: showSavingsBadge, onBuyNow: onBuyNow }, bundle.id))) })] }) }));
34
- }
35
- function FeaturedBundleCard({ bundle, showSavingsBadge = true, onBuyNow, }) {
36
- const stock = bundle.bundleStockStatus ?? "in_stock";
37
- const memberCount = bundle.bundleProductIds?.length ?? 0;
38
- const cover = bundle.display?.coverImage;
39
- const href = String(ROUTES.PUBLIC.BUNDLE_DETAIL?.(bundle.slug) ?? "#");
40
- const discount = computeBundleDiscount(bundle.bundlePrice, bundle.bundleOriginalTotal);
41
- return (_jsxs(Stack, { gap: "none", surface: "default", rounded: "xl", border: "default", children: [_jsxs(Link, { href: href, className: "group block p-[var(--appkit-space-3)] hover:no-underline", children: [_jsxs(Div, { className: `relative mb-2 aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: [cover ? (_jsx(MediaImage, { src: cover, alt: bundle.name, size: "card", className: "transition-transform group-hover:scale-105" })) : (_jsx(Row, { textSize: "3xl", className: "h-full w-full", align: "center", justify: "center", children: PLACEHOLDER_EMOJI })), showSavingsBadge && discount && (_jsx(PricesOnly, { children: _jsx(Badge, { variant: "success", className: "absolute left-2 top-2", children: BUNDLE_COPY.detail.discountBadge(discount.percent) }) }))] }), _jsx(Text, { className: "line-clamp-2", size: "sm", weight: "semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1", wrap: true, children: [_jsx(Text, { size: "sm", weight: "bold", children: _jsx(GatedPrice, { label: "Sign in to see the bundle price", children: bundle.bundlePrice
42
- ? formatCurrency(bundle.bundlePrice, "INR")
43
- : BUNDLE_COPY.featured.priceFallback }) }), discount && (_jsx(PricesOnly, { children: _jsx(Text, { size: "xs", color: "muted", className: "line-through", children: formatCurrency(discount.originalTotal, "INR") }) })), _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.featured.itemCount(memberCount)] }), stock !== "in_stock" && (_jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: BUNDLE_COPY.stockBadge.listVariantOutOfStock }))] })] }), onBuyNow && (_jsx(Div, { border: "subtle", className: `border-t ${__P.p3}`, padding: "t-xs", children: _jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow, compact: true }) }))] }));
33
+ return (_jsx(Section, { className: `${className}`, padding: "y-2xl", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "sm", align: "center", justify: "between", wrap: true, reverse: hand === "left", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, size: "2xl", weight: "semibold", color: "primary", children: title }), description && (_jsx(Text, { size: "sm", color: "muted", children: description }))] }), _jsx(Link, { href: String(ROUTES.PUBLIC.BUNDLES), className: "inline-flex items-center gap-[0.375rem] rounded-[var(--appkit-radius-md)] px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-sm)] font-semibold transition-colors bg-primary text-white hover:bg-primary-600", children: viewMoreLabel })] }), _jsx(Grid, { cols: "cards", gap: "3", children: items.map((bundle) => (_jsxs(Stack, { children: [_jsx(MarketplaceBundleCard, { bundle: bundle }), onBuyNow && (_jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: bundle.bundleStockStatus === "out_of_stock", onBuyNow: onBuyNow, compact: true }))] }, bundle.id))) })] }) }));
44
34
  }
@@ -90,7 +90,7 @@ function SlideBackground({ bg, legacy, mobileLegacy, isMobile, priority, }) {
90
90
  if (effectiveBg.type === "video") {
91
91
  return (_jsxs(_Fragment, { children: [_jsx(MediaVideo, { src: src, thumbnailUrl: effectiveBg.thumbnail ?? legacy?.thumbnail, alt: "", autoPlayMuted: true, loop: true, controls: false }), effectiveBg.dimOverlay?.enabled && (_jsx(Div, { className: POSITION_FILL, style: { backgroundColor: `rgba(0,0,0,${(effectiveBg.dimOverlay.opacity ?? 0) / 100})` } }))] }));
92
92
  }
93
- return (_jsxs(_Fragment, { children: [_jsx(MediaImage, { src: src, alt: "", size: "hero", objectFit: "cover", priority: priority, fetchPriority: priority ? "high" : "low" }), effectiveBg.dimOverlay?.enabled && (_jsx(Div, { className: POSITION_FILL, style: { backgroundColor: `rgba(0,0,0,${(effectiveBg.dimOverlay.opacity ?? 0) / 100})` } }))] }));
93
+ return (_jsxs(_Fragment, { children: [_jsx(MediaImage, { src: src, alt: "", size: "hero", objectFit: "cover", fill: true, priority: priority, fetchPriority: priority ? "high" : "low" }), effectiveBg.dimOverlay?.enabled && (_jsx(Div, { className: POSITION_FILL, style: { backgroundColor: `rgba(0,0,0,${(effectiveBg.dimOverlay.opacity ?? 0) / 100})` } }))] }));
94
94
  }
95
95
  /** Renders the background of a card (image, video, color, gradient). */
96
96
  function CardBackground({ bg }) {
@@ -106,7 +106,7 @@ function CardBackground({ bg }) {
106
106
  if (bg.type === "image" && bg.url) {
107
107
  // `cover` for the same reason as the slide backdrop above — this sits
108
108
  // behind the card's eyebrow/title/description, not beside them.
109
- return _jsx(MediaImage, { src: bg.url, alt: "", size: "card", objectFit: "cover" });
109
+ return _jsx(MediaImage, { src: bg.url, alt: "", size: "card", objectFit: "cover", fill: true });
110
110
  }
111
111
  return null;
112
112
  }
@@ -54,5 +54,5 @@ export function SocialPostCard({ post, showCaption = true, showStats = true }) {
54
54
  return _jsx(YouTubeCard, { post: post, showCaption: showCaption });
55
55
  }
56
56
  const meta = PLATFORM_META[post.platform];
57
- return (_jsxs(Anchor, { href: post.permalink, tone: "none", underline: "none", rounded: "xl", className: "group relative block aspect-square overflow-hidden bg-[var(--appkit-color-surface)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--appkit-color-primary)] bg-[var(--appkit-color-surface-elevated)]", "aria-label": post.caption ?? `View on ${meta.label}`, children: [post.imageUrl ? (_jsx(MediaImage, { src: post.imageUrl, alt: post.caption ?? `${meta.label} post`, size: "card", className: "transition-transform duration-300 group-hover:scale-105" })) : (_jsx(Row, { className: "h-full w-full", surface: "subtle", align: "center", justify: "center", children: _jsx(Span, { size: "sm", color: "faint", children: "No preview" }) })), post.mediaType === "video" && (_jsx(Row, { className: "pointer-events-none absolute inset-0", align: "center", justify: "center", children: _jsx(Row, { surface: "overlay-sm", className: "h-12 w-12 backdrop-blur-sm", align: "center", justify: "center", rounded: "full", children: _jsx("svg", { className: "ml-1 h-5 w-5 text-white", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M8 5v14l11-7z" }) }) }) })), post.mediaType === "carousel" && (_jsx(Div, { className: "pointer-events-none absolute right-2 top-2", children: _jsx(Row, { surface: "overlay-sm", className: "h-6 w-6 backdrop-blur-sm", rounded: "default", align: "center", justify: "center", children: _jsxs("svg", { className: "h-3.5 w-3.5 text-white", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "2", y: "3", width: "15", height: "15", rx: "2" }), _jsx("path", { d: "M7 8h14M7 12h14M7 16h14" })] }) }) })), _jsxs(Row, { textWeight: "medium", textSize: "xs", className: `absolute left-2 top-2 px-[0.375rem] text-white ${meta.colorClass}`, padding: "y-2xs", align: "center", gap: "xs", rounded: "default", children: [meta.icon, _jsx(Span, { className: "hidden sm:inline", children: meta.label })] }), _jsxs(Stack, { justify: "end", surface: "overlay-xl", className: `pointer-events-none absolute inset-0 ${__P.p3} opacity-0 transition-opacity duration-200 group-hover:opacity-100`, children: [showCaption && post.caption && (_jsx(Text, { color: "inverse", className: "mb-2 line-clamp-3", size: "xs", children: post.caption })), showStats && (_jsxs(Row, { textSize: "xs", className: "text-white/80", align: "center", gap: "3", children: [post.stats.likes != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" }) }), formatCount(post.stats.likes)] })), post.stats.views != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" }) }), formatCount(post.stats.views)] })), post.stats.comments != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }), formatCount(post.stats.comments)] }))] }))] })] }));
57
+ return (_jsxs(Anchor, { href: post.permalink, tone: "none", underline: "none", rounded: "xl", className: "group relative block aspect-square overflow-hidden focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--appkit-color-primary)] bg-[var(--appkit-color-surface-elevated)]", "aria-label": post.caption ?? `View on ${meta.label}`, children: [post.imageUrl ? (_jsx(MediaImage, { src: post.imageUrl, alt: post.caption ?? `${meta.label} post`, size: "card", className: "transition-transform duration-300 group-hover:scale-105" })) : (_jsx(Row, { className: "h-full w-full", surface: "subtle", align: "center", justify: "center", children: _jsx(Span, { size: "sm", color: "faint", children: "No preview" }) })), post.mediaType === "video" && (_jsx(Row, { className: "pointer-events-none absolute inset-0", align: "center", justify: "center", children: _jsx(Row, { surface: "overlay-sm", className: "h-12 w-12 backdrop-blur-sm", align: "center", justify: "center", rounded: "full", children: _jsx("svg", { className: "ml-1 h-5 w-5 text-white", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M8 5v14l11-7z" }) }) }) })), post.mediaType === "carousel" && (_jsx(Div, { className: "pointer-events-none absolute right-2 top-2", children: _jsx(Row, { surface: "overlay-sm", className: "h-6 w-6 backdrop-blur-sm", rounded: "default", align: "center", justify: "center", children: _jsxs("svg", { className: "h-3.5 w-3.5 text-white", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "2", y: "3", width: "15", height: "15", rx: "2" }), _jsx("path", { d: "M7 8h14M7 12h14M7 16h14" })] }) }) })), _jsxs(Row, { textWeight: "medium", textSize: "xs", className: `absolute left-2 top-2 px-[0.375rem] text-white ${meta.colorClass}`, padding: "y-2xs", align: "center", gap: "xs", rounded: "default", children: [meta.icon, _jsx(Span, { className: "hidden sm:inline", children: meta.label })] }), _jsxs(Stack, { justify: "end", surface: "overlay-xl", className: `pointer-events-none absolute inset-0 ${__P.p3} opacity-0 transition-opacity duration-200 group-hover:opacity-100`, children: [showCaption && post.caption && (_jsx(Text, { color: "inverse", className: "mb-2 line-clamp-3", size: "xs", children: post.caption })), showStats && (_jsxs(Row, { textSize: "xs", className: "text-white/80", align: "center", gap: "3", children: [post.stats.likes != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" }) }), formatCount(post.stats.likes)] })), post.stats.views != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" }) }), formatCount(post.stats.views)] })), post.stats.comments != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }), formatCount(post.stats.comments)] }))] }))] })] }));
58
58
  }
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export declare function AdminMoveLedgerView(): React.JSX.Element;
3
+ /** The kind chips, derived from the union so a sixth kind cannot be missed. */
4
+ export declare const MOVEMENT_KIND_TABS: {
5
+ id: "move" | "receive" | "pick" | "adjust" | "audit";
6
+ label: string;
7
+ }[];
@@ -0,0 +1,157 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /*
4
+ * WHY: The ledger is the only thing that can answer "where did this go", and
5
+ * an append-only log is useless if nobody can read it.
6
+ * WHAT: The movement listing. READ ONLY — there is no row action, because a
7
+ * movement cannot be edited or deleted.
8
+ *
9
+ * @tag domain:inventory
10
+ * @tag layer:feature
11
+ * @tag access:client
12
+ */
13
+ import React from "react";
14
+ import { DataListingView, } from "../../admin/components/DataListingView.js";
15
+ import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints.js";
16
+ import { sortBy } from "../../../constants/sort.js";
17
+ import { sieveFilter, SIEVE_OP } from "../../../utils/sieve-builder.js";
18
+ import { RecordDetailModal } from "../../../ui/components/RecordDetailModal.js";
19
+ import { statusLabel } from "../../../ui/columns/cell-renderers.js";
20
+ import { MovementKindValues, } from "../schemas/firestore.js";
21
+ /**
22
+ * `AC60-01 → AC60-04`, or `→ AC60-04` for a receive.
23
+ *
24
+ * 🛑 Reads the DENORMALISED codes on the row, not the live box documents, and
25
+ * that is correct rather than lazy: a movement records what things were
26
+ * CALLED at the time. Resolving the current code would rewrite history to
27
+ * match the present, which is the one thing a historical record must not do.
28
+ */
29
+ function endpoints(m) {
30
+ const from = m.fromBoxCode ?? m.fromBoxId;
31
+ const to = m.toBoxCode ?? m.toBoxId;
32
+ if (from && to)
33
+ return `${from} → ${to}`;
34
+ if (to)
35
+ return `→ ${to}`;
36
+ if (from)
37
+ return `${from} →`;
38
+ return "—";
39
+ }
40
+ export function AdminMoveLedgerView() {
41
+ /*
42
+ * 🛑 Declared BEFORE the `useMemo` that closes over `setSelected`. The memo
43
+ * factory runs during this render, so a `useState` below it would leave the
44
+ * setter in its temporal dead zone and throw `ReferenceError` on first
45
+ * paint — a `const` is hoisted but not initialised.
46
+ */
47
+ const [selected, setSelected] = React.useState(null);
48
+ const config = React.useMemo(() => ({
49
+ portal: "admin",
50
+ title: "Move Ledger",
51
+ subtitle: "Every stock movement, newest first. Append-only — a movement that should not have happened is corrected with an adjustment, never edited.",
52
+ /*
53
+ * 🛑 NO SEARCH BOX. `inventoryMovements` has no `searchTxt` and the
54
+ * repository indexes equality-plus-date, so a box here would accept
55
+ * typing, send the term and change nothing — which is the ~39 dead
56
+ * boxes `DataListingView`'s own `searchPlaceholder` note is about.
57
+ * Scoping is done by the kind chips and by arriving from a box or a
58
+ * product page, both of which pass a real filter.
59
+ */
60
+ emptyLabel: "No stock has moved yet",
61
+ filterKeys: ["kind"],
62
+ /*
63
+ * 🛑 REQUIRED, and its absence was not a missing filter — it CRASHED
64
+ * THE PAGE. `useAdminListing` calls `buildFilters(currentFilterState)`
65
+ * unconditionally (its optional sibling one line below is spelled
66
+ * `buildExtraParams?.(…)`), so with none supplied the render threw
67
+ * `TypeError: buildFilters is not a function` and
68
+ * `/admin/inventory/movements` never painted at all.
69
+ *
70
+ * This view and `AdminStorageBoxesView` were the only two of ~84
71
+ * `ListingViewConfig` declarations in the repo missing it — both mine,
72
+ * both from Phase 5, and both among the four screens flagged as
73
+ * "built without a browser". Opening either one once would have found
74
+ * this instantly; reading the source did not, because the field is
75
+ * required by a type that was only checked after a separate syntax
76
+ * error stopped masking it.
77
+ */
78
+ buildFilters: (state) => state.kind ? sieveFilter("kind", SIEVE_OP.EQ, state.kind) : undefined,
79
+ defaultSort: sortBy("occurredAt", "DESC"),
80
+ sortOptions: [
81
+ { value: sortBy("occurredAt", "DESC"), label: "Newest" },
82
+ { value: sortBy("occurredAt", "ASC"), label: "Oldest" },
83
+ { value: sortBy("quantity", "DESC"), label: "Largest quantity" },
84
+ ],
85
+ queryKey: ["admin", "inventory", "movements"],
86
+ endpoint: ADMIN_ENDPOINTS.INVENTORY_MOVEMENTS,
87
+ mapRows: (response) => (response.items ?? []).map((m) => ({
88
+ id: m.id,
89
+ primary: `${m.quantity} × ${m.productTitle ?? m.productId}`,
90
+ secondary: [
91
+ endpoints(m),
92
+ /*
93
+ * The reason, which is REQUIRED on an adjust — a variance
94
+ * nobody explained is indistinguishable from a typo three
95
+ * weeks later, and the row cannot be amended to add one.
96
+ */
97
+ m.reason,
98
+ m.shipmentId ? `shipment ${m.shipmentId}` : undefined,
99
+ ]
100
+ .filter(Boolean)
101
+ .join(" · "),
102
+ status: statusLabel(m.kind),
103
+ updatedAt: m.occurredAt ? String(m.occurredAt) : "",
104
+ doc: m,
105
+ })),
106
+ /*
107
+ * 🛑 Still no `renderRowActions`, no `renderEditor`, no
108
+ * `rowHrefTemplate` — so these rows get NO EDIT affordance, which is
109
+ * the honest output for a collection whose repository throws on
110
+ * `update` and `delete`. A pencil here would be a control that cannot
111
+ * work, which is the defect the row-affordance work exists to remove
112
+ * rather than to spread.
113
+ *
114
+ * 🛑 But READ is a different question, and the original version of
115
+ * this comment answered the edit one and stopped — which is why
116
+ * `audit-listing-detail-affordance` flagged this view as 1 of 64
117
+ * dead ends and was RIGHT to. `onRowClick` opens a read-only modal;
118
+ * it mutates nothing and so does not contradict any of the above.
119
+ */
120
+ onRowClick: (row) => setSelected(row),
121
+ }), []);
122
+ const m = selected?.doc;
123
+ return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(RecordDetailModal, { isOpen: selected !== null, onClose: () => setSelected(null), title: selected?.primary ?? "Movement", description: m
124
+ ? `${statusLabel(m.kind)} · ${endpoints(m)}`
125
+ : undefined, fields: m
126
+ ? [
127
+ /*
128
+ * `actorUid` first — it is the field the row cannot show and
129
+ * the only reason this modal exists. A uid rather than a
130
+ * name on purpose: resolving it would cost a user read per
131
+ * row, and the ledger's job is to be unambiguous about WHICH
132
+ * account acted, which a uid is and a display name is not.
133
+ */
134
+ { label: "Moved by", value: m.actorUid || "—" },
135
+ { label: "Kind", value: statusLabel(m.kind) },
136
+ { label: "Quantity", value: String(m.quantity) },
137
+ {
138
+ label: "Product",
139
+ value: m.productTitle ?? m.productId,
140
+ },
141
+ { label: "From", value: m.fromBoxCode ?? m.fromBoxId ?? "—" },
142
+ { label: "To", value: m.toBoxCode ?? m.toBoxId ?? "—" },
143
+ {
144
+ label: "Occurred",
145
+ value: m.occurredAt ? String(m.occurredAt) : "—",
146
+ },
147
+ { label: "Reason", value: m.reason || "—" },
148
+ { label: "Shipment", value: m.shipmentId || "—" },
149
+ { label: "Movement id", value: m.id },
150
+ ]
151
+ : undefined })] }));
152
+ }
153
+ /** The kind chips, derived from the union so a sixth kind cannot be missed. */
154
+ export const MOVEMENT_KIND_TABS = MovementKindValues.map((k) => ({
155
+ id: k,
156
+ label: statusLabel(k),
157
+ }));
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ /**
3
+ * The register-a-box form.
4
+ *
5
+ * Exported because it is a PAGE now, not a drawer — see the note on
6
+ * `primaryAction` below for why create could not share the row affordance.
7
+ */
8
+ export declare function RegisterBoxForm({ onCreated }: {
9
+ onCreated: () => void;
10
+ }): React.JSX.Element;
11
+ export declare function AdminStorageBoxesView(): React.JSX.Element;