@mohasinac/appkit 4.62.0 → 4.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +8 -29
  3. package/dist/_internal/client/features/layout/filterNavItems.d.ts +28 -0
  4. package/dist/_internal/client/features/layout/filterNavItems.js +35 -0
  5. package/dist/_internal/server/features/ads/booking.d.ts +118 -0
  6. package/dist/_internal/server/features/ads/booking.js +326 -0
  7. package/dist/_internal/server/features/checkout/actions.d.ts +129 -9
  8. package/dist/_internal/server/features/checkout/actions.js +850 -79
  9. package/dist/_internal/server/features/checkout/expand-order-items.d.ts +1 -2
  10. package/dist/_internal/server/features/checkout/expand-order-items.js +32 -0
  11. package/dist/_internal/server/features/checkout/freeze-parts.d.ts +50 -0
  12. package/dist/_internal/server/features/checkout/freeze-parts.js +94 -0
  13. package/dist/_internal/server/features/checkout/value-otp-gate.d.ts +55 -0
  14. package/dist/_internal/server/features/checkout/value-otp-gate.js +60 -0
  15. package/dist/_internal/server/features/dashboard/attention.d.ts +128 -0
  16. package/dist/_internal/server/features/dashboard/attention.js +183 -0
  17. package/dist/_internal/server/features/dashboard/data.d.ts +47 -0
  18. package/dist/_internal/server/features/dashboard/data.js +82 -0
  19. package/dist/_internal/server/features/inventory/reservations.d.ts +99 -0
  20. package/dist/_internal/server/features/inventory/reservations.js +273 -0
  21. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  22. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  23. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  24. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  25. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  26. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  27. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  28. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  29. package/dist/_internal/server/features/offers/destinations.d.ts +40 -0
  30. package/dist/_internal/server/features/offers/destinations.js +65 -0
  31. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  32. package/dist/_internal/server/features/orders/actions.js +81 -8
  33. package/dist/_internal/server/features/orders/adapters.js +54 -0
  34. package/dist/_internal/server/features/orders/amend-delivery.d.ts +56 -0
  35. package/dist/_internal/server/features/orders/amend-delivery.js +124 -0
  36. package/dist/_internal/server/features/orders/balance.d.ts +89 -0
  37. package/dist/_internal/server/features/orders/balance.js +256 -0
  38. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  39. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  40. package/dist/_internal/server/features/points/award.js +46 -4
  41. package/dist/_internal/server/features/pricing/actions.d.ts +58 -0
  42. package/dist/_internal/server/features/pricing/actions.js +144 -0
  43. package/dist/_internal/server/features/refunds/actions.js +26 -0
  44. package/dist/_internal/server/features/shipping/book-split.d.ts +86 -0
  45. package/dist/_internal/server/features/shipping/book-split.js +130 -0
  46. package/dist/_internal/server/features/shipping/book.d.ts +61 -0
  47. package/dist/_internal/server/features/shipping/book.js +176 -0
  48. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  49. package/dist/_internal/server/features/shipping/courier-block.js +264 -0
  50. package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
  51. package/dist/_internal/server/features/site-settings/adapters.js +29 -0
  52. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  53. package/dist/_internal/server/features/stores/adapters.js +65 -0
  54. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  55. package/dist/_internal/server/functions/scheduled.js +95 -2
  56. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +11 -2
  57. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  58. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  59. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  60. package/dist/_internal/server/jobs/core/index.js +2 -1
  61. package/dist/_internal/server/jobs/core/jobRunners.js +45 -0
  62. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  63. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  64. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  65. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +65 -0
  66. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  67. package/dist/_internal/server/jobs/core/reservationExpiry.d.ts +17 -0
  68. package/dist/_internal/server/jobs/core/reservationExpiry.js +40 -0
  69. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  70. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  71. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +25 -2
  72. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  73. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  74. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  75. package/dist/_internal/server/jobs/handlers/reservationExpiry.d.ts +2 -0
  76. package/dist/_internal/server/jobs/handlers/reservationExpiry.js +2 -0
  77. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  78. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  79. package/dist/_internal/shared/actions/action-registry.js +296 -0
  80. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  81. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  82. package/dist/_internal/shared/checkout/order-math.d.ts +174 -0
  83. package/dist/_internal/shared/checkout/order-math.js +159 -0
  84. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  85. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  86. package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
  87. package/dist/_internal/shared/checkout/rules/index.js +1 -1
  88. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +18 -0
  89. package/dist/_internal/shared/checkout/rules/payment-gate.js +25 -0
  90. package/dist/_internal/shared/checkout/split.d.ts +75 -0
  91. package/dist/_internal/shared/checkout/split.js +120 -0
  92. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  93. package/dist/_internal/shared/content/disclaimers.js +217 -0
  94. package/dist/_internal/shared/content/published-values.d.ts +93 -0
  95. package/dist/_internal/shared/content/published-values.js +206 -0
  96. package/dist/_internal/shared/features/admin/integrations.d.ts +139 -0
  97. package/dist/_internal/shared/features/admin/integrations.js +263 -0
  98. package/dist/_internal/shared/features/dashboard/hub-sections.d.ts +72 -0
  99. package/dist/_internal/shared/features/dashboard/hub-sections.js +75 -0
  100. package/dist/_internal/shared/features/emi/choice.d.ts +98 -0
  101. package/dist/_internal/shared/features/emi/choice.js +69 -0
  102. package/dist/_internal/shared/features/emi/group.d.ts +84 -0
  103. package/dist/_internal/shared/features/emi/group.js +126 -0
  104. package/dist/_internal/shared/features/ledger/posting.d.ts +107 -0
  105. package/dist/_internal/shared/features/ledger/posting.js +165 -0
  106. package/dist/_internal/shared/features/ledger/reports.d.ts +76 -0
  107. package/dist/_internal/shared/features/ledger/reports.js +127 -0
  108. package/dist/_internal/shared/features/ledger/rules.d.ts +170 -0
  109. package/dist/_internal/shared/features/ledger/rules.js +221 -0
  110. package/dist/_internal/shared/features/offers/coordination.d.ts +122 -0
  111. package/dist/_internal/shared/features/offers/coordination.js +80 -0
  112. package/dist/_internal/shared/features/orders/delivery-snapshot.d.ts +114 -0
  113. package/dist/_internal/shared/features/orders/delivery-snapshot.js +116 -0
  114. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  115. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  116. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  117. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  118. package/dist/_internal/shared/features/payouts/pay-period.d.ts +91 -0
  119. package/dist/_internal/shared/features/payouts/pay-period.js +104 -0
  120. package/dist/_internal/shared/features/points/accepts.d.ts +29 -0
  121. package/dist/_internal/shared/features/points/accepts.js +49 -0
  122. package/dist/_internal/shared/features/pricing/rate-registry.d.ts +150 -0
  123. package/dist/_internal/shared/features/pricing/rate-registry.js +246 -0
  124. package/dist/_internal/shared/features/shipping/parcel.d.ts +123 -0
  125. package/dist/_internal/shared/features/shipping/parcel.js +139 -0
  126. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  127. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  128. package/dist/_internal/shared/features/site-settings/fees.d.ts +16 -8
  129. package/dist/_internal/shared/features/site-settings/fees.js +12 -8
  130. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  131. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  132. package/dist/_internal/shared/fees/calculator.js +32 -2
  133. package/dist/_internal/shared/fees/explain.d.ts +81 -0
  134. package/dist/_internal/shared/fees/explain.js +101 -0
  135. package/dist/_internal/shared/history/index.d.ts +1 -1
  136. package/dist/_internal/shared/history/index.js +1 -1
  137. package/dist/_internal/shared/history/types.d.ts +7 -1
  138. package/dist/_internal/shared/history/types.js +25 -0
  139. package/dist/client.d.ts +21 -0
  140. package/dist/client.js +43 -0
  141. package/dist/constants/api-endpoints.d.ts +114 -0
  142. package/dist/constants/api-endpoints.js +55 -0
  143. package/dist/constants/field-names.d.ts +42 -0
  144. package/dist/constants/field-names.js +52 -0
  145. package/dist/contracts/index.d.ts +1 -1
  146. package/dist/contracts/shipping.d.ts +45 -0
  147. package/dist/contracts/shipping.js +15 -0
  148. package/dist/features/about/components/AboutView.js +1 -1
  149. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  150. package/dist/features/account/components/UserOrdersView.js +47 -35
  151. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  152. package/dist/features/admin/components/AdminIntegrationsView.d.ts +55 -0
  153. package/dist/features/admin/components/AdminIntegrationsView.js +74 -0
  154. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  155. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  156. package/dist/features/admin/components/AdminOrderEditorView.d.ts +33 -1
  157. package/dist/features/admin/components/AdminOrderEditorView.js +81 -3
  158. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  159. package/dist/features/admin/components/AdminOrdersView.js +86 -5
  160. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  161. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  162. package/dist/features/admin/constants/filter-tabs.js +6 -0
  163. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  164. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  165. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  166. package/dist/features/admin/schemas/firestore.d.ts +62 -0
  167. package/dist/features/admin/schemas/firestore.js +5 -0
  168. package/dist/features/ads/schemas/booking-write.d.ts +120 -0
  169. package/dist/features/ads/schemas/booking-write.js +75 -0
  170. package/dist/features/ads/schemas/creative-form.d.ts +18 -0
  171. package/dist/features/ads/schemas/creative-form.js +51 -0
  172. package/dist/features/ads/schemas/firestore.d.ts +140 -0
  173. package/dist/features/ads/schemas/firestore.js +109 -0
  174. package/dist/features/auctions/repository/bid.repository.js +3 -1
  175. package/dist/features/audit-log/schemas/firestore.d.ts +140 -0
  176. package/dist/features/audit-log/schemas/firestore.js +89 -0
  177. package/dist/features/auth/actions/profile-actions.d.ts +69 -1
  178. package/dist/features/auth/actions/profile-actions.js +62 -1
  179. package/dist/features/auth/permissions/constants.js +13 -0
  180. package/dist/features/auth/schemas/firestore.d.ts +16 -2
  181. package/dist/features/auth/schemas/firestore.js +2 -1
  182. package/dist/features/blog/actions/blog-actions.d.ts +6 -0
  183. package/dist/features/blog/actions/blog-actions.js +17 -2
  184. package/dist/features/blog/api/route.js +4 -1
  185. package/dist/features/blog/columns/index.js +5 -0
  186. package/dist/features/blog/components/BlogIndexPageView.js +2 -1
  187. package/dist/features/blog/repository/blog.repository.d.ts +4 -0
  188. package/dist/features/blog/repository/blog.repository.js +5 -0
  189. package/dist/features/blog/schemas/blog-form.d.ts +3 -0
  190. package/dist/features/blog/schemas/blog-form.js +1 -0
  191. package/dist/features/blog/schemas/firestore.d.ts +38 -1
  192. package/dist/features/blog/schemas/firestore.js +23 -0
  193. package/dist/features/blog/schemas/index.d.ts +6 -0
  194. package/dist/features/blog/schemas/index.js +2 -0
  195. package/dist/features/blog/types/index.d.ts +2 -0
  196. package/dist/features/cart/components/CartPriceBreakdown.d.ts +25 -1
  197. package/dist/features/cart/components/CartPriceBreakdown.js +29 -6
  198. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  199. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  200. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  201. package/dist/features/cart/components/index.d.ts +2 -0
  202. package/dist/features/cart/components/index.js +1 -0
  203. package/dist/features/cart/repository/cart.repository.d.ts +33 -0
  204. package/dist/features/cart/repository/cart.repository.js +47 -0
  205. package/dist/features/cart/schemas/firestore.d.ts +116 -0
  206. package/dist/features/contact/email.d.ts +27 -10
  207. package/dist/features/contact/email.js +20 -3
  208. package/dist/features/dashboard/components/DashboardHubView.d.ts +83 -0
  209. package/dist/features/dashboard/components/DashboardHubView.js +56 -0
  210. package/dist/features/dashboard/components/DashboardSectionsClient.d.ts +23 -0
  211. package/dist/features/dashboard/components/DashboardSectionsClient.js +66 -0
  212. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.d.ts +55 -0
  213. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +175 -0
  214. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +62 -0
  215. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +108 -0
  216. package/dist/features/dispute-reasons/schemas/firestore.d.ts +62 -0
  217. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  218. package/dist/features/events/components/EventSaleBanner.js +1 -1
  219. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  220. package/dist/features/faq/components/FAQAccordion.js +29 -4
  221. package/dist/features/faq/components/FAQPageContent.js +2 -2
  222. package/dist/features/gateway-events/schemas/index.d.ts +2 -2
  223. package/dist/features/homepage/schemas/index.d.ts +8 -8
  224. package/dist/features/inventory/schemas/stock-reservation.d.ts +114 -0
  225. package/dist/features/inventory/schemas/stock-reservation.js +103 -0
  226. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  227. package/dist/features/invoicing/schemas/firestore.js +45 -0
  228. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  229. package/dist/features/invoicing/utils/financial-year.js +53 -0
  230. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  231. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  232. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  233. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  234. package/dist/features/jobs/schemas/firestore.js +37 -0
  235. package/dist/features/layout/AppLayoutShell.d.ts +9 -1
  236. package/dist/features/layout/AppLayoutShell.js +12 -4
  237. package/dist/features/layout/BottomActions.js +2 -1
  238. package/dist/features/layout/BottomNavbar.d.ts +10 -2
  239. package/dist/features/layout/SideActionDock.js +52 -2
  240. package/dist/features/layout/TitleBarLayout.js +13 -4
  241. package/dist/features/layout/TitleBarLayout.style.css +59 -0
  242. package/dist/features/layout/useCtaReveal.d.ts +16 -1
  243. package/dist/features/layout/useCtaReveal.js +17 -26
  244. package/dist/features/ledger/repository/journal.repository.d.ts +110 -0
  245. package/dist/features/ledger/repository/journal.repository.js +312 -0
  246. package/dist/features/ledger/schemas/expenses.d.ts +87 -0
  247. package/dist/features/ledger/schemas/expenses.js +27 -0
  248. package/dist/features/ledger/schemas/firestore.d.ts +183 -0
  249. package/dist/features/ledger/schemas/firestore.js +69 -0
  250. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  251. package/dist/features/media/MediaImage.js +22 -1
  252. package/dist/features/media/upload/ImageUpload.js +1 -1
  253. package/dist/features/obligations/constants/policies.js +24 -1
  254. package/dist/features/orders/components/BalancePaymentPanel.d.ts +12 -0
  255. package/dist/features/orders/components/BalancePaymentPanel.js +94 -0
  256. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  257. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  258. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  259. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  260. package/dist/features/orders/components/RaiseDisputeForm.js +119 -0
  261. package/dist/features/orders/components/RefundRequestView.js +19 -1
  262. package/dist/features/orders/components/index.d.ts +4 -0
  263. package/dist/features/orders/components/index.js +2 -0
  264. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  265. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  266. package/dist/features/orders/repository/orders.repository.d.ts +85 -1
  267. package/dist/features/orders/repository/orders.repository.js +205 -6
  268. package/dist/features/orders/schemas/balance.d.ts +40 -0
  269. package/dist/features/orders/schemas/balance.js +47 -0
  270. package/dist/features/orders/schemas/firestore.d.ts +398 -1
  271. package/dist/features/orders/schemas/firestore.js +43 -0
  272. package/dist/features/orders/schemas/index.d.ts +56 -8
  273. package/dist/features/orders/schemas/index.js +12 -0
  274. package/dist/features/orders/types/index.d.ts +47 -0
  275. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  276. package/dist/features/orders/utils/courier-block.js +23 -0
  277. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  278. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  279. package/dist/features/payments/repository/payout.repository.js +3 -2
  280. package/dist/features/payments/schemas/firestore.d.ts +92 -1
  281. package/dist/features/payments/schemas/firestore.js +23 -0
  282. package/dist/features/pricing/components/AdminPricingView.d.ts +13 -0
  283. package/dist/features/pricing/components/AdminPricingView.js +157 -0
  284. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  285. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  286. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  287. package/dist/features/products/schemas/firestore.d.ts +26 -1
  288. package/dist/features/products/schemas/firestore.js +2 -0
  289. package/dist/features/products/schemas/index.d.ts +2 -2
  290. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  291. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  292. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  293. package/dist/features/promotions/components/CouponCard.js +13 -0
  294. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  295. package/dist/features/promotions/constants/coupon-help.js +9 -1
  296. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  297. package/dist/features/promotions/schemas/firestore.js +4 -0
  298. package/dist/features/promotions/types/index.d.ts +19 -1
  299. package/dist/features/reviews/repository/reviews.repository.d.ts +14 -0
  300. package/dist/features/reviews/repository/reviews.repository.js +16 -0
  301. package/dist/features/scams/components/ScamProfileView.js +2 -2
  302. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  303. package/dist/features/scams/repository/scammer.repository.js +2 -1
  304. package/dist/features/scams/schemas/firestore.d.ts +2 -1
  305. package/dist/features/scams/schemas/firestore.js +2 -1
  306. package/dist/features/search/action-index/tab-entries.js +1 -1
  307. package/dist/features/seller/actions/offer-actions.js +56 -0
  308. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  309. package/dist/features/seller/actions/seller-actions.js +37 -3
  310. package/dist/features/seller/components/DispatchForm.d.ts +11 -0
  311. package/dist/features/seller/components/DispatchForm.js +190 -0
  312. package/dist/features/seller/components/SellerOrdersView.js +221 -27
  313. package/dist/features/seller/components/index.d.ts +1 -0
  314. package/dist/features/seller/components/index.js +1 -0
  315. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  316. package/dist/features/seller/repository/offer.repository.js +4 -3
  317. package/dist/features/seller/schemas/firestore.d.ts +23 -2
  318. package/dist/features/seller/schemas/firestore.js +3 -2
  319. package/dist/features/seller/schemas/index.d.ts +4 -4
  320. package/dist/features/seller/schemas/order-forms.d.ts +61 -4
  321. package/dist/features/seller/schemas/order-forms.js +41 -8
  322. package/dist/features/shipments/schemas/firestore.d.ts +25 -0
  323. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  324. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +82 -0
  325. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +145 -0
  326. package/dist/features/shipping-boxes/schemas/firestore.d.ts +80 -0
  327. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  328. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  329. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  330. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  331. package/dist/features/stores/repository/store.repository.d.ts +18 -0
  332. package/dist/features/stores/repository/store.repository.js +27 -1
  333. package/dist/features/stores/schemas/firestore.d.ts +112 -0
  334. package/dist/features/stores/schemas/firestore.js +20 -0
  335. package/dist/features/stores/schemas/index.d.ts +6 -6
  336. package/dist/features/stores/types/index.d.ts +19 -0
  337. package/dist/features/support/repository/support.repository.js +72 -6
  338. package/dist/features/support/schemas/firestore.d.ts +17 -0
  339. package/dist/features/support/schemas/index.d.ts +8 -8
  340. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  341. package/dist/index.d.ts +11 -1
  342. package/dist/index.js +33 -1
  343. package/dist/next/routing/route-map.d.ts +112 -0
  344. package/dist/next/routing/route-map.js +63 -0
  345. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  346. package/dist/providers/shipping-shiprocket/index.js +84 -1
  347. package/dist/react/contexts/SessionContext.d.ts +17 -1
  348. package/dist/schemas/registry.d.ts +69 -34
  349. package/dist/schemas/sieve.d.ts +2 -2
  350. package/dist/security/pii-schemas.d.ts +1 -1
  351. package/dist/security/pii-schemas.js +45 -0
  352. package/dist/server-entry.d.ts +2 -2
  353. package/dist/server-entry.js +8 -1
  354. package/dist/server.d.ts +36 -1
  355. package/dist/server.js +183 -1
  356. package/dist/styles.css +412 -80
  357. package/dist/tailwind-utilities.css +1 -1
  358. package/dist/tokens/themes/default-dark.js +1 -0
  359. package/dist/tokens/themes/default-light.js +1 -0
  360. package/dist/tokens/themes/required.d.ts +1 -1
  361. package/dist/tokens/themes/required.js +1 -0
  362. package/dist/tokens/tokens.css +15 -0
  363. package/dist/ui/components/Button.d.ts +10 -1
  364. package/dist/ui/components/Button.js +25 -3
  365. package/dist/ui/components/Chart.d.ts +63 -0
  366. package/dist/ui/components/Chart.js +169 -0
  367. package/dist/ui/components/Chart.style.css +214 -0
  368. package/dist/ui/components/Disclaimer.d.ts +19 -0
  369. package/dist/ui/components/Disclaimer.js +83 -0
  370. package/dist/ui/components/OverflowRow.js +54 -2
  371. package/dist/ui/components/OverflowRow.style.css +38 -0
  372. package/dist/ui/components/RichTextEditor.js +99 -8
  373. package/dist/ui/components/chart-spec.d.ts +68 -0
  374. package/dist/ui/components/chart-spec.js +140 -0
  375. package/dist/ui/components/index.style.css +1 -0
  376. package/dist/ui/components/surface-tokens.d.ts +1 -1
  377. package/dist/ui/components/surface-tokens.js +9 -0
  378. package/dist/ui/components/tabs-overflow.js +64 -11
  379. package/dist/ui/components/toolbar-collapse.d.ts +13 -0
  380. package/dist/ui/components/toolbar-collapse.js +10 -1
  381. package/dist/ui/index.d.ts +8 -0
  382. package/dist/ui/index.js +9 -0
  383. package/dist/ui/rich-text/RichText.d.ts +10 -1
  384. package/dist/ui/rich-text/RichText.js +33 -2
  385. package/dist/ui/rich-text/RichText.style.css +83 -79
  386. package/dist/ui/rich-text/RichTextRenderer.d.ts +30 -1
  387. package/dist/ui/rich-text/RichTextRenderer.js +34 -2
  388. package/dist/ui/rich-text/chart-blocks.d.ts +62 -0
  389. package/dist/ui/rich-text/chart-blocks.js +87 -0
  390. package/package.json +1 -1
  391. package/scripts/seed-cli.mjs +1834 -1822
@@ -0,0 +1,183 @@
1
+ /**
2
+ * `chartOfAccounts` + `journalEntries` — Part 4's double-entry books.
3
+ *
4
+ * ## 🛑 THE LEDGER IS A PROJECTION. Orders, payouts and expenses are truth.
5
+ *
6
+ * The same split `obligations` takes, and for the same reason. An order says
7
+ * what was sold; a journal entry is an accounting *statement about* that
8
+ * order. So: **never read a balance to make an operational decision.** Do not
9
+ * gate a payout on a ledger figure, do not refuse a refund because an account
10
+ * looks short — read the payout and the order. A projection that starts
11
+ * making decisions becomes a second source of truth, and then the two
12
+ * disagree with no way to say which is wrong.
13
+ *
14
+ * ## 🛑 Every entry is MACHINE-GENERATED from a business event
15
+ *
16
+ * This is the one constraint that makes the whole thing safe. If a human has
17
+ * to remember that a gateway fee is `Dr Bank Charges / Cr Bank`, it will
18
+ * eventually be posted the other way round; if the settlement ingest posts
19
+ * it, it cannot be. `sourceEvent` is REQUIRED and names the event, not the
20
+ * person — a hand-posted adjustment uses `"manual-journal"`, which is a
21
+ * distinguishable value precisely so the exception stays countable.
22
+ *
23
+ * ## 🛑 A correction is a REVERSING ENTRY, never an edit
24
+ *
25
+ * The invoice/credit-note rule, applied to the books. `journalEntries` rows
26
+ * are append-only: `reverse()` writes a NEW entry with the legs swapped and
27
+ * the two pointed at each other. An edit would silently rewrite a period a
28
+ * GST return has already been filed for, and nothing downstream could tell.
29
+ *
30
+ * ## 🛑 Money is DECIMAL RUPEES, matching every other money field here
31
+ *
32
+ * Rupees with two decimal places, like every other money field here. The
33
+ * 2026-05 migration moved the whole codebase off minor units and
34
+ * `audit-money-units` enforces it; a ledger in minor units would be the one
35
+ * place a reader has to remember a different scale, which is how a 100×
36
+ * error gets written (Root Cause #31).
37
+ */
38
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
39
+ export declare const CHART_OF_ACCOUNTS_COLLECTION = "chartOfAccounts";
40
+ export declare const JOURNAL_ENTRIES_COLLECTION = "journalEntries";
41
+ export declare const ACCOUNTING_PERIODS_COLLECTION = "accountingPeriods";
42
+ /**
43
+ * The five classical account types.
44
+ *
45
+ * Carried on the ACCOUNT rather than inferred from its code, because the
46
+ * normal-balance side and every report's sign convention derive from it —
47
+ * and a report that guesses the type from a code prefix breaks the first time
48
+ * somebody adds an account out of range.
49
+ */
50
+ export type AccountType = "asset" | "liability" | "equity" | "income" | "expense";
51
+ /**
52
+ * Which side INCREASES this account.
53
+ *
54
+ * Derived from `AccountType` by `normalBalanceFor`, never stored — a stored
55
+ * copy is a mirror that drifts the first time somebody types the wrong one
56
+ * (Root Cause #42), and the mapping is a fact about accounting rather than
57
+ * about this business.
58
+ */
59
+ export type NormalBalance = "debit" | "credit";
60
+ export declare function normalBalanceFor(type: AccountType): NormalBalance;
61
+ export interface ChartAccountDocument extends BaseDocument {
62
+ /**
63
+ * Stable numeric code, e.g. `"1100"`. The id is `account-{code}`.
64
+ *
65
+ * 🛑 Codes are grouped by type in the conventional Indian small-business
66
+ * ranges (1xxx asset, 2xxx liability, 3xxx equity, 4xxx income, 5xxx
67
+ * expense) **so a CA can map them to Tally at a glance** — that is the
68
+ * entire reason for a numeric code rather than a slug. It is a convention
69
+ * for humans; nothing in the code derives `type` from the range, because a
70
+ * derivation would make adding an account outside it silently wrong.
71
+ */
72
+ code: string;
73
+ name: string;
74
+ type: AccountType;
75
+ /** A one-line note for whoever has to reconcile this against a bank statement. */
76
+ description?: string;
77
+ /**
78
+ * A closed account refuses new postings but keeps its history.
79
+ *
80
+ * Deliberately not a delete: an account with entries against it cannot be
81
+ * removed without orphaning them, and a closed row still has to appear in
82
+ * last year's trial balance.
83
+ */
84
+ isActive: boolean;
85
+ }
86
+ /**
87
+ * One side of one entry.
88
+ *
89
+ * 🛑 `debit` and `credit` are SEPARATE non-negative fields rather than one
90
+ * signed amount. A signed amount needs a sign convention, the convention
91
+ * differs per account type, and a reader then has to know the account's type
92
+ * to interpret the number — which is how a credit gets read as a debit. Two
93
+ * fields are unambiguous at the point of reading, which is where it matters.
94
+ *
95
+ * Exactly one of them is non-zero on any line; `assertBalanced` refuses both.
96
+ */
97
+ export interface JournalLine {
98
+ accountCode: string;
99
+ debit: number;
100
+ credit: number;
101
+ /** Why this leg exists, for a human reading the entry a year later. */
102
+ memo?: string;
103
+ /**
104
+ * Who this leg is ABOUT, when that is a specific counterparty — a store for
105
+ * a seller payable, a vendor for a bill.
106
+ *
107
+ * Optional because most legs (bank, GST, sales) have no counterparty. Where
108
+ * it exists it is what makes a per-seller payable ageing possible without a
109
+ * separate ledger per store.
110
+ */
111
+ counterpartyId?: string;
112
+ }
113
+ /**
114
+ * What caused this entry. REQUIRED, and the closed list is the point.
115
+ *
116
+ * 🛑 `manual-journal` is a real member and must stay one. The alternative —
117
+ * letting a hand-posted entry claim an automated source — is how the "every
118
+ * entry is machine-generated" constraint stops being checkable. With it
119
+ * declared, "how many of our entries were typed by a person" is one query.
120
+ */
121
+ export type JournalSourceEvent = "order-placed" | "order-delivered" | "order-refunded" | "payout-paid" | "settlement-ingest" | "expense-recorded" | "asset-purchased" | "opening-balance" | "manual-journal" | "reversal";
122
+ export interface JournalEntryDocument extends BaseDocument {
123
+ /**
124
+ * The date the entry BELONGS TO, which is not when it was written.
125
+ *
126
+ * A settlement ingested on the 3rd for transactions on the 31st posts to
127
+ * the 31st. `createdAt` records when we learned; this records when it
128
+ * happened, and every report and the period lock read this one.
129
+ */
130
+ entryDate: Date;
131
+ /** `YYYY-MM`, derived from `entryDate` — the lock and the rollups key on it. */
132
+ period: string;
133
+ sourceEvent: JournalSourceEvent;
134
+ /**
135
+ * The record that caused this — an order id, a payout id, an expense id.
136
+ *
137
+ * Absent only for `opening-balance` and `manual-journal`, which have no
138
+ * causing record by definition. `verify-posting-rules` checks that pairing
139
+ * rather than trusting it.
140
+ */
141
+ sourceId?: string;
142
+ narration: string;
143
+ lines: JournalLine[];
144
+ /**
145
+ * Both totals, stored.
146
+ *
147
+ * 🛑 Redundant with `lines` ON PURPOSE, and this is the one place a mirror
148
+ * is right: a trial balance that had to sum every line of every entry is an
149
+ * unbounded read, and these two are written inside the same transaction
150
+ * that validated them. They cannot drift, because nothing can write an
151
+ * entry without going through `assertBalanced`.
152
+ */
153
+ totalDebit: number;
154
+ totalCredit: number;
155
+ /** Set on the entry this one reverses, and on the reversal, pointing both ways. */
156
+ reversedByEntryId?: string;
157
+ reversesEntryId?: string;
158
+ }
159
+ /**
160
+ * A period, and whether it is closed.
161
+ *
162
+ * Id is the period itself (`period-2026-10`), so the lock check is a single
163
+ * `get` by a key the caller already has — not a query.
164
+ */
165
+ export interface AccountingPeriodDocument extends BaseDocument {
166
+ /** `YYYY-MM`. */
167
+ period: string;
168
+ status: "open" | "locked";
169
+ /** Set when locked — which GST return this period was filed under. */
170
+ lockedReason?: string;
171
+ lockedAt?: Date;
172
+ lockedByUid?: string;
173
+ }
174
+ export declare const LEDGER_FIELDS: {
175
+ readonly CODE: "code";
176
+ readonly TYPE: "type";
177
+ readonly IS_ACTIVE: "isActive";
178
+ readonly ENTRY_DATE: "entryDate";
179
+ readonly PERIOD: "period";
180
+ readonly SOURCE_EVENT: "sourceEvent";
181
+ readonly SOURCE_ID: "sourceId";
182
+ readonly STATUS: "status";
183
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * `chartOfAccounts` + `journalEntries` — Part 4's double-entry books.
3
+ *
4
+ * ## 🛑 THE LEDGER IS A PROJECTION. Orders, payouts and expenses are truth.
5
+ *
6
+ * The same split `obligations` takes, and for the same reason. An order says
7
+ * what was sold; a journal entry is an accounting *statement about* that
8
+ * order. So: **never read a balance to make an operational decision.** Do not
9
+ * gate a payout on a ledger figure, do not refuse a refund because an account
10
+ * looks short — read the payout and the order. A projection that starts
11
+ * making decisions becomes a second source of truth, and then the two
12
+ * disagree with no way to say which is wrong.
13
+ *
14
+ * ## 🛑 Every entry is MACHINE-GENERATED from a business event
15
+ *
16
+ * This is the one constraint that makes the whole thing safe. If a human has
17
+ * to remember that a gateway fee is `Dr Bank Charges / Cr Bank`, it will
18
+ * eventually be posted the other way round; if the settlement ingest posts
19
+ * it, it cannot be. `sourceEvent` is REQUIRED and names the event, not the
20
+ * person — a hand-posted adjustment uses `"manual-journal"`, which is a
21
+ * distinguishable value precisely so the exception stays countable.
22
+ *
23
+ * ## 🛑 A correction is a REVERSING ENTRY, never an edit
24
+ *
25
+ * The invoice/credit-note rule, applied to the books. `journalEntries` rows
26
+ * are append-only: `reverse()` writes a NEW entry with the legs swapped and
27
+ * the two pointed at each other. An edit would silently rewrite a period a
28
+ * GST return has already been filed for, and nothing downstream could tell.
29
+ *
30
+ * ## 🛑 Money is DECIMAL RUPEES, matching every other money field here
31
+ *
32
+ * Rupees with two decimal places, like every other money field here. The
33
+ * 2026-05 migration moved the whole codebase off minor units and
34
+ * `audit-money-units` enforces it; a ledger in minor units would be the one
35
+ * place a reader has to remember a different scale, which is how a 100×
36
+ * error gets written (Root Cause #31).
37
+ */
38
+ export const CHART_OF_ACCOUNTS_COLLECTION = "chartOfAccounts";
39
+ export const JOURNAL_ENTRIES_COLLECTION = "journalEntries";
40
+ export const ACCOUNTING_PERIODS_COLLECTION = "accountingPeriods";
41
+ export function normalBalanceFor(type) {
42
+ return type === "asset" || type === "expense" ? "debit" : "credit";
43
+ }
44
+ export const LEDGER_FIELDS = {
45
+ CODE: "code",
46
+ TYPE: "type",
47
+ IS_ACTIVE: "isActive",
48
+ ENTRY_DATE: "entryDate",
49
+ PERIOD: "period",
50
+ SOURCE_EVENT: "sourceEvent",
51
+ SOURCE_ID: "sourceId",
52
+ STATUS: "status",
53
+ };
54
+ /*
55
+ * 🛑 `periodOf` LIVES IN `_internal/shared/features/ledger/posting.ts`, not
56
+ * here, and the reason is mechanical rather than taxonomic.
57
+ *
58
+ * `verify-posting-rules.mjs` imports the posting rules directly via Node's
59
+ * `--experimental-strip-types` so it exercises the shipped source rather
60
+ * than a build artefact (Root Cause #105). Type stripping erases
61
+ * `import type` entirely but cannot RESOLVE a runtime import — appkit source
62
+ * is written extensionless and the build adds `.js` — so a single runtime
63
+ * import in that file would make it unloadable and the audit would be a
64
+ * load-failure instead of a check.
65
+ *
66
+ * Deciding which period an entry belongs to is a posting rule anyway, and it
67
+ * is the one the audit most needs to exercise: a UTC derivation files every
68
+ * IST evening sale in the previous GST return.
69
+ */
@@ -42,12 +42,12 @@ export declare const reopenLotterySlotSchema: z.ZodObject<{
42
42
  adminUserId: z.ZodString;
43
43
  }, "strip", z.ZodTypeAny, {
44
44
  slotNumber: number;
45
- sourceType: "event" | "product";
45
+ sourceType: "product" | "event";
46
46
  sourceId: string;
47
47
  adminUserId: string;
48
48
  }, {
49
49
  slotNumber: number;
50
- sourceType: "event" | "product";
50
+ sourceType: "product" | "event";
51
51
  sourceId: string;
52
52
  adminUserId: string;
53
53
  }>;
@@ -68,7 +68,7 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
68
68
  }, "strip", z.ZodTypeAny, {
69
69
  userId: string;
70
70
  transactionId: string;
71
- sourceType: "event" | "product";
71
+ sourceType: "product" | "event";
72
72
  paymentTime: string;
73
73
  purchasedItemNumber: number;
74
74
  userPhone: string;
@@ -79,7 +79,7 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
79
79
  }, {
80
80
  userId: string;
81
81
  transactionId: string;
82
- sourceType: "event" | "product";
82
+ sourceType: "product" | "event";
83
83
  paymentTime: string;
84
84
  purchasedItemNumber: number;
85
85
  userPhone: string;
@@ -90,7 +90,7 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
90
90
  }>, {
91
91
  userId: string;
92
92
  transactionId: string;
93
- sourceType: "event" | "product";
93
+ sourceType: "product" | "event";
94
94
  paymentTime: string;
95
95
  purchasedItemNumber: number;
96
96
  userPhone: string;
@@ -101,7 +101,7 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
101
101
  }, {
102
102
  userId: string;
103
103
  transactionId: string;
104
- sourceType: "event" | "product";
104
+ sourceType: "product" | "event";
105
105
  paymentTime: string;
106
106
  purchasedItemNumber: number;
107
107
  userPhone: string;
@@ -113,8 +113,29 @@ export function MediaImage({ src, alt, size = "card", priority = false, loading,
113
113
  * the placeholder, the `<picture>` and the plain `<Image>` cannot disagree
114
114
  * about their dimensions — a fallback that occupies a different box from the
115
115
  * image it replaces makes a grid jump as things load.
116
+ *
117
+ * 🛑 `max-h-full` IS THE OTHER HALF OF SIZE_BOX, added 2026-10-23. SIZE_BOX
118
+ * alone fixed the auto-height parent and broke the ALREADY-SIZED one: a
119
+ * parent that is 320x128 got a 320x320 box, so `overflow-hidden` cropped it
120
+ * to the top 40% of a letterboxed square. Measured 89 of 143 call sites in
121
+ * that shape — every image preview on the review, document and site-settings
122
+ * surfaces. `max-height:100%` resolves to `none` against an auto-height
123
+ * parent, so it clamps ONLY in the broken case.
124
+ *
125
+ * Measured in a browser (box for each parent shape), not argued:
126
+ *
127
+ * parent w-full aspect +max-h-full +h-full
128
+ * 320x128 definite 320x320 ✗ 320x128 ✓ 320x128 ✓
129
+ * h128, width shrink 320x320 ✗ 320x128 ✓ 320x128 ✓
130
+ * width 200, h AUTO 200x200 ✓ 200x200 ✓ 200x784 ✗
131
+ * 64px thumb stretched
132
+ * by a flex row 64x64 ✓ 64x64 ✓ 64x90 ✗
133
+ *
134
+ * So `h-full` is NOT the fix — it wins over `aspect-ratio` whenever the
135
+ * parent's height is definite, including the height a flex/grid row hands a
136
+ * thumbnail by stretching it. That is why this is a MAX and not a height.
116
137
  */
117
- const boxClass = fill ? "h-full" : SIZE_BOX[size];
138
+ const boxClass = fill ? "h-full" : `${SIZE_BOX[size]} max-h-full`;
118
139
  // Reset error/load/retry state whenever the resolved src actually changes.
119
140
  // Without this, a component instance that hit a load failure once (e.g.
120
141
  // lost the post-upload propagation race above) latches hasError forever,
@@ -222,7 +222,7 @@ accept = IMAGE_ACCEPT_ATTR, maxSizeMB = MAX_IMAGE_BYTES / MEGABYTE, label = "Upl
222
222
  fileInputRef.current.value = "";
223
223
  onChange?.("");
224
224
  };
225
- return (_jsxs(Stack, { gap: "3", children: [label && (_jsx(Label, { className: "block", color: "muted", size: "sm", weight: "medium", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { className: `relative h-32 max-w-xs mx-auto ${__O.hidden}`, rounded: "lg", border: "default", children: [_jsx(MediaImage, { src: preview, alt: "Preview", size: "card" }), uploading && progress > 0 && (_jsx(Div, { className: "absolute inset-x-0 bottom-0", children: _jsx(Progress, { value: progress, size: "sm" }) }))] }), !uploading && (_jsxs(Row, { wrap: true, gap: "sm", children: [(enableCrop || enableAdvancedCrop) && (_jsx(Button, { type: "button", onClick: () => openEditor(preview), variant: "secondary", size: "sm", children: tMediaEditor("editImage") })), _jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), variant: "outline", size: "sm", children: tUpload("change") }), _jsx(Button, { type: "button", onClick: handleRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] })) : (_jsxs(_Fragment, { children: [showCamera && isCameraSupported && (_jsx(CameraCapture, { mode: "photo", facingMode: "environment", onCapture: handleCameraCapture, onError: setError })), !showCamera && (_jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", wrap: true, children: [showFileInput && (_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), disabled: uploading, variant: "outline", size: "sm", children: uploading ? tUpload("uploading") : tUpload("clickToUpload") })), captureSource !== "file-only" && isCameraSupported && (_jsx(Button, { type: "button", onClick: () => setCaptureMode("camera"), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") })), captureSource !== "file-only" && !isCameraSupported && (_jsx(Button, { type: "button", onClick: () => mobileCaptureRef.current?.click(), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") }))] }), _jsxs(Text, { size: "xs", variant: "secondary", children: [accept === "image/*"
225
+ return (_jsxs(Stack, { gap: "3", children: [label && (_jsx(Label, { className: "block", color: "muted", size: "sm", weight: "medium", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { className: `relative w-full h-32 max-w-xs mx-auto ${__O.hidden}`, rounded: "lg", border: "default", children: [_jsx(MediaImage, { src: preview, alt: "Preview", size: "card" }), uploading && progress > 0 && (_jsx(Div, { className: "absolute inset-x-0 bottom-0", children: _jsx(Progress, { value: progress, size: "sm" }) }))] }), !uploading && (_jsxs(Row, { wrap: true, gap: "sm", children: [(enableCrop || enableAdvancedCrop) && (_jsx(Button, { type: "button", onClick: () => openEditor(preview), variant: "secondary", size: "sm", children: tMediaEditor("editImage") })), _jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), variant: "outline", size: "sm", children: tUpload("change") }), _jsx(Button, { type: "button", onClick: handleRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] })) : (_jsxs(_Fragment, { children: [showCamera && isCameraSupported && (_jsx(CameraCapture, { mode: "photo", facingMode: "environment", onCapture: handleCameraCapture, onError: setError })), !showCamera && (_jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", wrap: true, children: [showFileInput && (_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), disabled: uploading, variant: "outline", size: "sm", children: uploading ? tUpload("uploading") : tUpload("clickToUpload") })), captureSource !== "file-only" && isCameraSupported && (_jsx(Button, { type: "button", onClick: () => setCaptureMode("camera"), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") })), captureSource !== "file-only" && !isCameraSupported && (_jsx(Button, { type: "button", onClick: () => mobileCaptureRef.current?.click(), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") }))] }), _jsxs(Text, { size: "xs", variant: "secondary", children: [accept === "image/*"
226
226
  ? `JPG PNG GIF WebP`
227
227
  : accept.split(",").map((a) => a.split("/")[1]?.toUpperCase() ?? a).join(" "), " ", "\u2014 max ", maxSizeMB, "MB"] })] }))] })) }), _jsx("input", { ref: fileInputRef, type: "file", accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-input" }), showCamera && !isCameraSupported && (_jsx("input", { ref: mobileCaptureRef, type: "file", accept: IMAGE_ACCEPT_ATTR, capture: "environment", onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-capture-input" })), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error }), uploading && (_jsxs(Row, { gap: "sm", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: tUpload("uploadingProgress", { progress }) })] })), cropPreviewUrl && !enableAdvancedCrop && (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: cropPreviewUrl, onClose: handleCropClose, onSave: handleCropSave })), cropPreviewUrl && enableAdvancedCrop && (_jsx(ImageEditor, { isOpen: showAdvancedEditor, imageUrl: cropPreviewUrl, onClose: handleAdvancedEditorClose, onSave: handleAdvancedEditorSave, aspectRatio: cropAspectRatio }))] }));
228
228
  }
@@ -37,6 +37,7 @@
37
37
  import { ORDER_RETURN_WINDOW_DAYS, ORDER_AUTO_CONFIRM_DAYS, } from "../../../_internal/shared/features/orders/config.js";
38
38
  import { PROTECTION_CLAIM_WINDOW_HOURS } from "../../../_internal/shared/features/shipping/protections.js";
39
39
  import { PAYMENT_WINDOW_MINUTES } from "../../orders/constants/payment-window.js";
40
+ import { hasOpenCourierBlock } from "../../orders/utils/courier-block.js";
40
41
  const isPaid = (o) => o.paymentStatus === "paid";
41
42
  const notTerminal = (o) => o.status !== "cancelled" && o.status !== "refunded";
42
43
  /**
@@ -87,7 +88,29 @@ export const OBLIGATION_POLICIES = {
87
88
  anchor: (o) => o.acceptedAt,
88
89
  duration: { value: 2, unit: "days", calendar: "business" },
89
90
  warnAt: [{ value: 8, unit: "hours", calendar: "calendar" }],
90
- precondition: (o) => isPaid(o) && notTerminal(o) && !hasDispatched(o),
91
+ /*
92
+ * 🛑 `!hasOpenCourierBlock(o)` — DO NOT REMOVE, and do not "simplify" it
93
+ * into the stored field.
94
+ *
95
+ * This is `onDue: "act"`, so firing cancels the order and refunds the
96
+ * buyer with the seller recorded as having failed to dispatch. When the
97
+ * platform's own courier wallet is empty, nothing the seller can do makes
98
+ * the booking succeed — so without this guard our funding state cancels a
99
+ * paid order and blames them for it.
100
+ *
101
+ * The engine re-evaluates `precondition` at fire time and closes
102
+ * `superseded` when it returns false, so the clock PAUSES while blocked and
103
+ * resumes when the block clears. No new mechanism, no stored timer.
104
+ *
105
+ * 🛑 This is the ONLY `onDue: "act"` policy that needs the guard, and the
106
+ * others were checked rather than assumed: `hasDispatched` is
107
+ * `Boolean(o.shippingDate)`, so `delivery-confirm` (which REQUIRES
108
+ * `hasDispatched`) and everything post-delivery can never fire on an order
109
+ * that was never booked. `seller-accept` requires `!o.acceptedAt`, and a
110
+ * booking is only attempted after acceptance. Adding the guard there too
111
+ * would be redundant and would imply nobody traced it.
112
+ */
113
+ precondition: (o) => isPaid(o) && notTerminal(o) && !hasDispatched(o) && !hasOpenCourierBlock(o),
91
114
  blockedBy: ["seller-accept"],
92
115
  onDue: "act",
93
116
  publishedCopyKey: "obligations.sellerDispatch",
@@ -0,0 +1,12 @@
1
+ import type { Order } from "../types";
2
+ export interface BalancePaymentPanelProps {
3
+ order: Pick<Order, "id" | "balance" | "currency">;
4
+ /** Uploads one file and resolves to the stored `/media/…` slug. */
5
+ onUpload: (file: File) => Promise<string>;
6
+ /** POSTs to `/api/orders/{id}/balance-proof`. Throws on failure. */
7
+ onSubmit: (input: {
8
+ proofUrl: string;
9
+ transactionId: string;
10
+ }) => Promise<void>;
11
+ }
12
+ export declare function BalancePaymentPanel({ order, onUpload, onSubmit }: BalancePaymentPanelProps): import("react").JSX.Element | null;
@@ -0,0 +1,94 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * D55 — the buyer's panel for paying a pre-order balance.
5
+ *
6
+ * ## 🛑 This exists because the figure was already on screen
7
+ *
8
+ * `OrderProvenanceCard` has printed "Balance due ₹X" on every pre-order since
9
+ * Part 2, and nothing in the product could accept that money. A buyer who
10
+ * reads an amount owed and finds no control does not conclude "the feature is
11
+ * coming" — they conclude the site is broken, and the seller waiting on the
12
+ * money has no way to chase it.
13
+ *
14
+ * ## Why it is NOT a second page
15
+ *
16
+ * The deposit's proof upload is its own route (`/user/orders/[id]/payment`)
17
+ * because it runs against a 15-minute window with a countdown, a UPI address
18
+ * to copy and a fraud declaration — a task with its own screen. The balance
19
+ * has a 7-day window and no countdown, so sending the buyer somewhere else to
20
+ * fill in two fields would add a navigation and a back button for nothing.
21
+ *
22
+ * ## The four states
23
+ *
24
+ * | `balance.status` | What the buyer sees |
25
+ * |---|---|
26
+ * | absent | NOTHING — the seller has not opened collection; the goods do not exist yet |
27
+ * | `awaiting` / `rejected` | the form, with the rejection note when there is one |
28
+ * | `submitted` | "under review", no form |
29
+ * | `paid` | a confirmation line and the reference |
30
+ *
31
+ * 🛑 The absent case rendering nothing is the load-bearing one. A pre-order's
32
+ * premise is that the item has not been made yet, so a payable-looking balance
33
+ * before the seller opens it would be asking the buyer to fund inventory.
34
+ */
35
+ import { useState } from "react";
36
+ import { Button } from "../../../ui/components/Button.js";
37
+ import { Row, Stack } from "../../../ui/components/Layout.js";
38
+ import { Div } from "../../../ui/components/Div.js";
39
+ import { Text, Span } from "../../../ui/components/Typography.js";
40
+ import { Form } from "../../../ui/components/Form.js";
41
+ import { FieldInput } from "../../../ui/forms/FieldInput.js";
42
+ import { FormErrorSummary } from "../../../ui/forms/FormErrorSummary.js";
43
+ import { MediaUploadField } from "../../media/upload/MediaUploadField.js";
44
+ import { balanceProofSchema } from "../schemas/balance.js";
45
+ import { formatCurrency } from "../../../utils/number.formatter.js";
46
+ function dueText(dueBy) {
47
+ if (!dueBy)
48
+ return "";
49
+ const d = new Date(dueBy);
50
+ if (Number.isNaN(d.getTime()))
51
+ return "";
52
+ return ` Due by ${d.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" })}.`;
53
+ }
54
+ export function BalancePaymentPanel({ order, onUpload, onSubmit }) {
55
+ const [proofUrl, setProofUrl] = useState("");
56
+ const [transactionId, setTransactionId] = useState("");
57
+ const [isPending, setIsPending] = useState(false);
58
+ const balance = order.balance;
59
+ // Nothing to collect yet — see the header. Not an empty card, no card.
60
+ if (!balance)
61
+ return null;
62
+ const amount = formatCurrency(balance.amount, order.currency);
63
+ if (balance.status === "paid") {
64
+ return (_jsxs(Div, { surface: "card", padding: "md", className: "mt-4", children: [_jsx(Span, { layout: "inline-flex", color: "success", surface: "success-surface", weight: "semibold", className: "text-[10px]", rounded: "full", padding: "pill-xs", children: "Balance paid" }), _jsxs(Text, { className: "mt-1", color: "muted", size: "xs", children: [amount, " received. This order is ready to ship.", balance.transactionId ? ` Reference: ${balance.transactionId}` : ""] })] }));
65
+ }
66
+ if (balance.status === "submitted") {
67
+ return (_jsxs(Div, { surface: "card", padding: "md", className: "mt-4", children: [_jsx(Span, { layout: "inline-flex", color: "info", surface: "info-surface", weight: "semibold", className: "text-[10px]", rounded: "full", padding: "pill-xs", children: "Balance under review" }), _jsxs(Text, { className: "mt-1", color: "muted", size: "xs", children: ["We have your proof for ", amount, ". Our team checks it against the reference you gave, and the order ships once it clears."] })] }));
68
+ }
69
+ const rejected = balance.status === "rejected";
70
+ const handleSubmit = async () => {
71
+ setIsPending(true);
72
+ try {
73
+ await onSubmit({ proofUrl, transactionId: transactionId.trim() });
74
+ }
75
+ finally {
76
+ /*
77
+ * Cleared even on failure. The caller surfaces the error; leaving the
78
+ * button spinning forever is how a recoverable 400 reads as a hang.
79
+ */
80
+ setIsPending(false);
81
+ }
82
+ };
83
+ return (_jsx(Div, { surface: "card", padding: "md", className: "mt-4", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Div, { children: [_jsx(Span, { layout: "inline-flex", color: rejected ? "error" : "warning", surface: rejected ? "danger-surface" : "warning-surface", weight: "semibold", className: "text-[10px]", rounded: "full", padding: "pill-xs", children: rejected ? "Balance proof needs correction" : "Balance due" }), _jsx(Text, { className: "mt-1", color: "muted", size: "xs", children: rejected
84
+ ? /*
85
+ * The note is REQUIRED on a rejection server-side, so the
86
+ * fallback here should effectively never render — it exists
87
+ * because a row written before that rule would otherwise say
88
+ * nothing at all, which is the one thing a rejection must not do.
89
+ */
90
+ balance.reviewNote
91
+ ? `Our team could not accept the last proof: ${balance.reviewNote}`
92
+ : "Our team could not accept the last proof. Please send a clearer screenshot."
93
+ : `Your item is ready. Pay the remaining ${amount} and upload the receipt.${dueText(balance.dueBy)}` })] }), _jsx(Form, { schema: balanceProofSchema, onSubmit: (e) => e.preventDefault(), children: () => (_jsxs(Stack, { gap: "md", children: [_jsx(FormErrorSummary, {}), _jsx(MediaUploadField, { label: "Payment screenshot (JPG/PNG/PDF)", value: proofUrl, onChange: setProofUrl, onUpload: onUpload, kind: "image", accept: "image/*,application/pdf", showYoutube: false, showExternal: false, helperText: "The confirmation screen from your bank or UPI app." }), _jsx(FieldInput, { name: "transactionId", label: "UTR / Transaction reference", required: true, value: transactionId, onChange: (value) => setTransactionId(value), placeholder: "e.g. 123456789012", hint: "Required \u2014 it is the only thing our team can check the payment against. A screenshot on its own is a picture." }), _jsx(Row, { gap: "3", children: _jsx(Button, { type: "button", variant: "primary", disabled: isPending || !proofUrl || transactionId.trim().length < 4, onClick: handleSubmit, paddingX: "md", paddingY: "sm", textSize: "sm", weight: "semibold", children: isPending ? "Sending…" : rejected ? "Re-send proof" : "Submit payment proof" }) })] })) })] }) }));
94
+ }
@@ -32,7 +32,16 @@ function legacyFallback(order) {
32
32
  method,
33
33
  transactionId: order.paymentTransactionId ?? order.paymentId,
34
34
  proofUrl: order.paymentProofUrl,
35
- amount: order.totalPrice,
35
+ /*
36
+ * 🛑 D46/D47 — `amountDue`, falling back to `totalPrice`. This figure is
37
+ * what a MANUAL payer is told to transfer and what an admin verifies the
38
+ * proof against, so on a points-funded order `totalPrice` would ask the
39
+ * buyer for money the order does not owe — and then the admin would reject
40
+ * a correct ₹750 UTR for not matching ₹1,000.
41
+ *
42
+ * `?? totalPrice`, never `?? 0`: absent means no points were used.
43
+ */
44
+ amount: order.amountDue ?? order.totalPrice,
36
45
  verificationMethod: method === "cod" ? "cod_collection" : method === "manual" ? "manual_review" : "order_status",
37
46
  };
38
47
  }
@@ -0,0 +1,8 @@
1
+ import type { OrderSourceContext } from "../schemas/firestore";
2
+ export interface OrderProvenanceCardProps {
3
+ sourceContext?: OrderSourceContext;
4
+ /** Falls back to the configured default currency when omitted. */
5
+ currency?: string;
6
+ className?: string;
7
+ }
8
+ export declare function OrderProvenanceCard({ sourceContext, currency, className, }: OrderProvenanceCardProps): import("react").JSX.Element | null;