@mohasinac/appkit 4.9.5 → 4.11.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 (395) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +4 -1
  3. package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +1 -1
  4. package/dist/_internal/client/features/lottery/LotteryPullForm.js +2 -2
  5. package/dist/_internal/server/features/admin/daily-digest-actions.d.ts +18 -0
  6. package/dist/_internal/server/features/admin/daily-digest-actions.js +37 -0
  7. package/dist/_internal/server/features/auctions/actions.js +3 -2
  8. package/dist/_internal/server/features/auctions/service.d.ts +4 -3
  9. package/dist/_internal/server/features/auctions/service.js +6 -6
  10. package/dist/_internal/server/features/audit-log/actions.d.ts +25 -0
  11. package/dist/_internal/server/features/audit-log/actions.js +38 -0
  12. package/dist/_internal/server/features/brands/actions.js +0 -2
  13. package/dist/_internal/server/features/brands/og.d.ts +4 -1
  14. package/dist/_internal/server/features/brands/og.js +1 -1
  15. package/dist/_internal/server/features/bundles/data.d.ts +9 -0
  16. package/dist/_internal/server/features/bundles/data.js +14 -0
  17. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  18. package/dist/_internal/server/features/bundles/index.js +1 -1
  19. package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
  20. package/dist/_internal/server/features/catalogue/og.js +27 -0
  21. package/dist/_internal/server/features/grouped/data.d.ts +16 -0
  22. package/dist/_internal/server/features/grouped/data.js +50 -1
  23. package/dist/_internal/server/features/grouped/index.d.ts +1 -1
  24. package/dist/_internal/server/features/grouped/index.js +1 -1
  25. package/dist/_internal/server/features/orders/actions.js +9 -0
  26. package/dist/_internal/server/features/orders/adapters.js +25 -0
  27. package/dist/_internal/server/features/products/data.d.ts +23 -0
  28. package/dist/_internal/server/features/products/data.js +159 -0
  29. package/dist/_internal/server/features/products/index.d.ts +1 -1
  30. package/dist/_internal/server/features/products/index.js +1 -1
  31. package/dist/_internal/server/functions/scheduled.d.ts +3 -1
  32. package/dist/_internal/server/functions/scheduled.js +17 -1
  33. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +40 -0
  34. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +164 -0
  35. package/dist/_internal/server/jobs/core/hardBanCascade.js +11 -0
  36. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -0
  37. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
  38. package/dist/_internal/server/jobs/core/testerSandboxRefresh.d.ts +12 -0
  39. package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +85 -0
  40. package/dist/_internal/server/jobs/core/whatsappNotify.js +16 -0
  41. package/dist/_internal/server/jobs/handlers/dailyStatusDigest.d.ts +2 -0
  42. package/dist/_internal/server/jobs/handlers/dailyStatusDigest.js +4 -0
  43. package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
  44. package/dist/_internal/server/jobs/handlers/index.js +3 -0
  45. package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.d.ts +2 -0
  46. package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.js +2 -0
  47. package/dist/_internal/server/notifications/channel-health.d.ts +27 -0
  48. package/dist/_internal/server/notifications/channel-health.js +101 -0
  49. package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
  50. package/dist/_internal/shared/features/auctions/config.js +31 -1
  51. package/dist/_internal/shared/features/brands/schema.d.ts +0 -6
  52. package/dist/_internal/shared/features/brands/schema.js +0 -1
  53. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +7 -0
  54. package/dist/_internal/shared/features/categories/bundle-schemas.js +3 -0
  55. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  56. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
  57. package/dist/_internal/shared/listing-types/art/config.js +1 -1
  58. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
  59. package/dist/_internal/shared/listing-types/classified/config.js +1 -1
  60. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
  61. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -1
  62. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
  63. package/dist/_internal/shared/listing-types/live/config.js +1 -1
  64. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
  65. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  66. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
  67. package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
  68. package/dist/client.d.ts +21 -12
  69. package/dist/client.js +14 -7
  70. package/dist/constants/api-endpoints.d.ts +9 -9
  71. package/dist/constants/api-endpoints.js +3 -3
  72. package/dist/contracts/client-auth.d.ts +3 -7
  73. package/dist/contracts/email.d.ts +1 -0
  74. package/dist/features/account/components/AddressForm.js +24 -2
  75. package/dist/features/account/components/BecomeSellerView.d.ts +1 -2
  76. package/dist/features/account/components/BecomeSellerView.js +1 -1
  77. package/dist/features/account/components/NotificationBell.js +1 -1
  78. package/dist/features/account/components/UserBidsView.d.ts +1 -0
  79. package/dist/features/account/components/UserBidsView.js +47 -0
  80. package/dist/features/account/components/UserOrdersView.d.ts +4 -11
  81. package/dist/features/account/components/UserOrdersView.js +54 -4
  82. package/dist/features/account/components/UserReturnsView.d.ts +4 -9
  83. package/dist/features/account/components/UserReturnsView.js +37 -3
  84. package/dist/features/account/components/index.d.ts +3 -2
  85. package/dist/features/account/components/index.js +1 -0
  86. package/dist/features/admin/actions/admin-actions.js +22 -0
  87. package/dist/features/admin/actions/admin-coupon-actions.js +10 -0
  88. package/dist/features/admin/actions/notification-actions.js +4 -3
  89. package/dist/features/admin/components/AdminAdsView.d.ts +2 -3
  90. package/dist/features/admin/components/AdminAdsView.js +86 -89
  91. package/dist/features/admin/components/AdminAllEventEntriesView.js +18 -3
  92. package/dist/features/admin/components/AdminAuditLogView.d.ts +11 -0
  93. package/dist/features/admin/components/AdminAuditLogView.js +95 -0
  94. package/dist/features/admin/components/AdminBlogEditorView.js +37 -3
  95. package/dist/features/admin/components/AdminBrandEditorView.js +10 -6
  96. package/dist/features/admin/components/AdminBundleEditorView.js +18 -2
  97. package/dist/features/admin/components/AdminCarouselEditorView.js +2 -2
  98. package/dist/features/admin/components/AdminCarouselGroupEditorView.js +2 -2
  99. package/dist/features/admin/components/AdminCartsView.js +34 -4
  100. package/dist/features/admin/components/AdminCategoryEditorView.js +5 -4
  101. package/dist/features/admin/components/AdminCouponEditorView.js +2 -2
  102. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  103. package/dist/features/admin/components/AdminHistoryView.js +11 -1
  104. package/dist/features/admin/components/AdminNotificationsView.js +27 -1
  105. package/dist/features/admin/components/AdminOrderEditorView.d.ts +10 -1
  106. package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
  107. package/dist/features/admin/components/AdminOrdersView.js +92 -24
  108. package/dist/features/admin/components/AdminPayoutMarkPaidModal.d.ts +7 -0
  109. package/dist/features/admin/components/AdminPayoutMarkPaidModal.js +47 -0
  110. package/dist/features/admin/components/AdminPayoutsView.js +15 -31
  111. package/dist/features/admin/components/AdminProductEditorView.js +26 -3
  112. package/dist/features/admin/components/AdminSiteSettingsView.js +31 -4
  113. package/dist/features/admin/components/AdminStoreAddressesView.js +22 -2
  114. package/dist/features/admin/components/AdminStoresView.js +7 -0
  115. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +2 -2
  116. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +2 -2
  117. package/dist/features/admin/components/AdminUserEditorView.d.ts +2 -2
  118. package/dist/features/admin/components/AdminUserEditorView.js +4 -2
  119. package/dist/features/admin/components/AdminUsersView.js +1 -1
  120. package/dist/features/admin/components/AdminWishlistsView.js +14 -1
  121. package/dist/features/admin/components/DataListingView.d.ts +2 -2
  122. package/dist/features/admin/components/ViewAuditLogEntryModal.d.ts +19 -0
  123. package/dist/features/admin/components/ViewAuditLogEntryModal.js +22 -0
  124. package/dist/features/admin/components/ViewNotificationModal.d.ts +21 -0
  125. package/dist/features/admin/components/ViewNotificationModal.js +15 -0
  126. package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +4 -7
  127. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +56 -36
  128. package/dist/features/admin/components/index.d.ts +8 -1
  129. package/dist/features/admin/components/index.js +4 -0
  130. package/dist/features/admin/constants/filter-tabs.d.ts +49 -0
  131. package/dist/features/admin/constants/filter-tabs.js +27 -0
  132. package/dist/features/admin/hooks/useAdminListing.d.ts +6 -0
  133. package/dist/features/admin/hooks/useAdminListing.js +3 -1
  134. package/dist/features/admin/hooks/useAdminListingData.d.ts +9 -1
  135. package/dist/features/admin/hooks/useAdminListingData.js +9 -2
  136. package/dist/features/admin/repository/site-settings.repository.d.ts +5 -0
  137. package/dist/features/admin/schemas/firestore.d.ts +21 -0
  138. package/dist/features/admin/schemas/firestore.js +6 -0
  139. package/dist/features/analytics/types.d.ts +1 -1
  140. package/dist/features/analytics/types.js +8 -0
  141. package/dist/features/auctions/actions/bid-actions.js +4 -1
  142. package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
  143. package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
  144. package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
  145. package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
  146. package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
  147. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
  148. package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
  149. package/dist/features/auctions/schemas/index.d.ts +5 -0
  150. package/dist/features/audit-log/repository/audit-log.repository.d.ts +45 -0
  151. package/dist/features/audit-log/repository/audit-log.repository.js +30 -0
  152. package/dist/features/audit-log/schemas/firestore.d.ts +59 -0
  153. package/dist/features/audit-log/schemas/firestore.js +35 -0
  154. package/dist/features/auth/actions/index.d.ts +0 -1
  155. package/dist/features/auth/actions/index.js +0 -1
  156. package/dist/features/auth/hooks/useAuth.d.ts +8 -35
  157. package/dist/features/auth/hooks/useAuth.js +21 -37
  158. package/dist/features/auth/permissions/constants.d.ts +1 -1
  159. package/dist/features/auth/permissions/constants.js +2 -0
  160. package/dist/features/blog/schemas/index.d.ts +32 -0
  161. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +31 -3
  162. package/dist/features/catalogue/components/CatalogueItemEditorView.js +2 -1
  163. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
  164. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
  165. package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
  166. package/dist/features/catalogue/index.d.ts +2 -0
  167. package/dist/features/catalogue/index.js +1 -0
  168. package/dist/features/categories/components/BrandDetailPageView.js +14 -12
  169. package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
  170. package/dist/features/categories/components/BundleDetailView.js +3 -2
  171. package/dist/features/categories/components/CategoryDetailPageView.js +7 -3
  172. package/dist/features/categories/components/CategoryHighlightsAndFaqSection.d.ts +14 -0
  173. package/dist/features/categories/components/CategoryHighlightsAndFaqSection.js +22 -0
  174. package/dist/features/categories/components/CategoryProductsView.d.ts +1 -5
  175. package/dist/features/categories/components/CategoryProductsView.js +1 -1
  176. package/dist/features/categories/components/CategorySelectorCreate.js +16 -2
  177. package/dist/features/categories/schemas/firestore.d.ts +19 -2
  178. package/dist/features/categories/schemas/index.d.ts +24 -3
  179. package/dist/features/categories/schemas/index.js +3 -1
  180. package/dist/features/categories/types/index.d.ts +7 -0
  181. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +17 -3
  182. package/dist/features/checkout/actions/checkout-value-otp-actions.js +101 -22
  183. package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
  184. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
  185. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
  186. package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
  187. package/dist/features/contact/components/ContactForm.js +17 -4
  188. package/dist/features/contact/components/ContactPageView.js +8 -2
  189. package/dist/features/contact/email.d.ts +1 -0
  190. package/dist/features/contact/email.js +3 -0
  191. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
  192. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
  193. package/dist/features/events/components/AdminEventEditorView.js +54 -2
  194. package/dist/features/events/components/AdminEventEntriesView.d.ts +2 -16
  195. package/dist/features/events/components/AdminEventEntriesView.js +56 -89
  196. package/dist/features/events/components/EventFormDrawer.js +5 -1
  197. package/dist/features/events/components/EventRaffleEntryForm.d.ts +1 -3
  198. package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
  199. package/dist/features/events/schemas/index.d.ts +22 -0
  200. package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
  201. package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
  202. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +12 -0
  203. package/dist/features/grouped/repository/grouped-listings.repository.js +34 -0
  204. package/dist/features/homepage/components/CharacterHotspotForm.js +202 -187
  205. package/dist/features/homepage/components/SectionCarousel.d.ts +1 -7
  206. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  207. package/dist/features/layout/BottomActions.js +4 -3
  208. package/dist/features/layout/BottomActionsContext.d.ts +10 -0
  209. package/dist/features/layout/BottomActionsContext.js +5 -1
  210. package/dist/features/layout/TitleBarLayout.d.ts +1 -1
  211. package/dist/features/layout/TitleBarLayout.js +3 -3
  212. package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
  213. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  214. package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
  215. package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
  216. package/dist/features/media/MediaImage.js +39 -3
  217. package/dist/features/media/MediaVideo.js +17 -1
  218. package/dist/features/media/types/index.d.ts +10 -0
  219. package/dist/features/media/types/index.js +1 -0
  220. package/dist/features/media/upload/MediaUploadField.d.ts +7 -1
  221. package/dist/features/media/upload/MediaUploadField.js +11 -7
  222. package/dist/features/media/upload/video-poster.d.ts +2 -0
  223. package/dist/features/media/upload/video-poster.js +16 -1
  224. package/dist/features/media/upload/video-poster.test.js +1 -1
  225. package/dist/features/orders/components/OrderStatusTimeline.d.ts +12 -0
  226. package/dist/features/orders/components/OrderStatusTimeline.js +55 -0
  227. package/dist/features/orders/components/index.d.ts +2 -0
  228. package/dist/features/orders/components/index.js +1 -0
  229. package/dist/features/orders/constants/payment-window.d.ts +25 -0
  230. package/dist/features/orders/constants/payment-window.js +25 -0
  231. package/dist/features/orders/repository/orders.repository.d.ts +32 -0
  232. package/dist/features/orders/repository/orders.repository.js +56 -0
  233. package/dist/features/orders/schemas/index.d.ts +24 -24
  234. package/dist/features/orders/types/index.d.ts +33 -0
  235. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
  236. package/dist/features/pre-orders/schemas/index.d.ts +5 -0
  237. package/dist/features/products/components/BidHistory.js +9 -1
  238. package/dist/features/products/components/GroupSettingsPanel.js +25 -3
  239. package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
  240. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +1 -4
  241. package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
  242. package/dist/features/products/components/ProductDetailActions.d.ts +1 -2
  243. package/dist/features/products/components/ProductDetailActions.js +1 -1
  244. package/dist/features/products/components/ProductDetailPageView.js +11 -116
  245. package/dist/features/products/components/ProductGrid.js +15 -1
  246. package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
  247. package/dist/features/products/components/RelatedItemsSection.js +17 -0
  248. package/dist/features/products/constants/action-defs.d.ts +1 -0
  249. package/dist/features/products/constants/action-defs.js +1 -0
  250. package/dist/features/products/schemas/index.d.ts +5 -0
  251. package/dist/features/promotions/components/CouponsIndexListing.d.ts +1 -3
  252. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  253. package/dist/features/search/components/SearchView.d.ts +1 -3
  254. package/dist/features/search/components/SearchView.js +1 -1
  255. package/dist/features/seller/components/QuickProductForm.js +2 -1
  256. package/dist/features/seller/components/SellerBidsView.js +66 -107
  257. package/dist/features/seller/components/SellerGoogleReviewsView.js +17 -1
  258. package/dist/features/seller/components/SellerOrdersView.d.ts +15 -3
  259. package/dist/features/seller/components/SellerOrdersView.js +134 -163
  260. package/dist/features/seller/components/SellerPayoutMethodsView.js +60 -48
  261. package/dist/features/seller/components/SellerPayoutSettingsView.js +69 -4
  262. package/dist/features/seller/components/SellerPayoutsView.d.ts +12 -0
  263. package/dist/features/seller/components/SellerPayoutsView.js +25 -5
  264. package/dist/features/seller/components/SellerProductShell.d.ts +10 -3
  265. package/dist/features/seller/components/SellerProductShell.js +90 -37
  266. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +2 -7
  267. package/dist/features/seller/components/SellerProductsFilterDrawer.js +4 -4
  268. package/dist/features/seller/components/SellerProductsView.d.ts +2 -4
  269. package/dist/features/seller/components/SellerProductsView.js +131 -189
  270. package/dist/features/seller/components/SellerReviewsView.js +95 -133
  271. package/dist/features/seller/components/SellerShippingConfigsView.js +47 -67
  272. package/dist/features/seller/components/SellerShippingView.js +41 -4
  273. package/dist/features/seller/components/SellerStoreCategoriesView.js +51 -59
  274. package/dist/features/seller/components/SellerStorefrontView.d.ts +6 -1
  275. package/dist/features/seller/components/SellerStorefrontView.js +42 -5
  276. package/dist/features/seller/components/index.d.ts +2 -2
  277. package/dist/features/seller/components/index.js +2 -2
  278. package/dist/features/shell/FormShell.d.ts +24 -4
  279. package/dist/features/shell/FormShell.js +12 -6
  280. package/dist/features/shell/QuickFormDrawer.js +67 -12
  281. package/dist/features/shell/StepForm.d.ts +30 -1
  282. package/dist/features/shell/StepForm.js +47 -4
  283. package/dist/features/shell/index.d.ts +1 -1
  284. package/dist/features/shell/index.js +1 -1
  285. package/dist/features/shipments/components/AdminShipmentEditorView.js +2 -2
  286. package/dist/features/shipments/schemas/validation.d.ts +14 -4
  287. package/dist/features/tester/components/AdminTesterFeedbackListView.js +23 -2
  288. package/dist/features/tester/components/TesterChecklistStepRow.js +1 -1
  289. package/dist/features/tester/components/TesterHubView.js +3 -2
  290. package/dist/features/tester/seed-data/orders-tester-seed-data.js +9 -1
  291. package/dist/features/tester/seed-data/products-tester-seed-data.js +43 -32
  292. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +487 -18
  293. package/dist/index.d.ts +17 -3
  294. package/dist/index.js +23 -5
  295. package/dist/next/routing/route-map.d.ts +13 -0
  296. package/dist/next/routing/route-map.js +12 -0
  297. package/dist/providers/email-resend/provider.js +1 -0
  298. package/dist/providers/firebase-client/auth.d.ts +1 -0
  299. package/dist/providers/firebase-client/auth.js +7 -1
  300. package/dist/repositories/index.d.ts +1 -0
  301. package/dist/repositories/index.js +1 -0
  302. package/dist/schemas/registry.d.ts +61 -25
  303. package/dist/security/pii-mask.js +1 -1
  304. package/dist/seed/bids-seed-data.js +48 -3
  305. package/dist/seed/categories-seed-data.js +69 -0
  306. package/dist/seed/grouped-listings-seed-data.js +167 -0
  307. package/dist/seed/payouts-seed-data.js +4 -4
  308. package/dist/seed/products-art-seed-data.js +188 -5
  309. package/dist/seed/products-auctions-seed-data.js +226 -6
  310. package/dist/seed/products-classifieds-seed-data.js +255 -8
  311. package/dist/seed/products-digital-codes-seed-data.js +258 -19
  312. package/dist/seed/products-live-items-seed-data.js +143 -10
  313. package/dist/seed/products-preorders-seed-data.js +213 -8
  314. package/dist/seed/products-prize-draws-seed-data.js +198 -0
  315. package/dist/seed/products-standard-seed-data.js +234 -4
  316. package/dist/seed/products-stickers-seed-data.js +178 -5
  317. package/dist/seed/site-settings-seed-data.js +23 -30
  318. package/dist/seed/store-extensions-seed-data.js +2 -2
  319. package/dist/server-entry.d.ts +6 -2
  320. package/dist/server-entry.js +24 -3
  321. package/dist/server.d.ts +10 -3
  322. package/dist/server.js +11 -4
  323. package/dist/styles.css +29 -1
  324. package/dist/tailwind-utilities.css +1 -1
  325. package/dist/ui/components/Form.d.ts +11 -2
  326. package/dist/ui/components/Form.js +4 -3
  327. package/dist/ui/components/FormField.d.ts +3 -1
  328. package/dist/ui/components/FormField.js +22 -4
  329. package/dist/ui/components/ImageLightbox.js +37 -3
  330. package/dist/ui/components/ImageLightbox.style.css +28 -0
  331. package/dist/ui/components/ListingLayout.d.ts +1 -2
  332. package/dist/ui/components/ListingLayout.js +1 -1
  333. package/dist/ui/components/RecordDetailModal.d.ts +68 -0
  334. package/dist/ui/components/RecordDetailModal.js +8 -0
  335. package/dist/ui/components/SlottedListingView.js +9 -1
  336. package/dist/ui/forms/FormErrorSummary.d.ts +25 -0
  337. package/dist/ui/forms/FormErrorSummary.js +37 -0
  338. package/dist/ui/forms/FormShell.d.ts +37 -2
  339. package/dist/ui/forms/FormShell.js +37 -7
  340. package/dist/ui/forms/FormShell.style.css +17 -0
  341. package/dist/ui/forms/index.d.ts +2 -0
  342. package/dist/ui/forms/index.js +1 -0
  343. package/dist/ui/index.d.ts +4 -0
  344. package/dist/ui/index.js +5 -0
  345. package/dist/utils/media-url.d.ts +12 -1
  346. package/dist/utils/media-url.js +59 -1
  347. package/dist/validation/schemas.d.ts +4 -4
  348. package/package.json +1 -1
  349. package/dist/_internal/client/features/classified/ClassifiedDetailView.d.ts +0 -9
  350. package/dist/_internal/client/features/classified/ClassifiedDetailView.js +0 -55
  351. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.d.ts +0 -18
  352. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +0 -21
  353. package/dist/_internal/client/features/live/LiveItemDetailView.d.ts +0 -9
  354. package/dist/_internal/client/features/live/LiveItemDetailView.js +0 -25
  355. package/dist/_internal/server/jobs/core/prizeRevealClose.d.ts +0 -2
  356. package/dist/_internal/server/jobs/core/prizeRevealClose.js +0 -28
  357. package/dist/_internal/server/jobs/core/prizeRevealExpiry.d.ts +0 -2
  358. package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +0 -61
  359. package/dist/_internal/server/jobs/core/prizeRevealOpen.d.ts +0 -2
  360. package/dist/_internal/server/jobs/core/prizeRevealOpen.js +0 -68
  361. package/dist/_internal/server/jobs/core/prizeRevealReminder.d.ts +0 -2
  362. package/dist/_internal/server/jobs/core/prizeRevealReminder.js +0 -49
  363. package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +0 -2
  364. package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +0 -2
  365. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +0 -2
  366. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +0 -2
  367. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +0 -2
  368. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +0 -2
  369. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +0 -2
  370. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +0 -2
  371. package/dist/features/auth/consent-otp.d.ts +0 -57
  372. package/dist/features/auth/consent-otp.js +0 -127
  373. package/dist/features/cart/components/CheckoutOtpModal.d.ts +0 -15
  374. package/dist/features/cart/components/CheckoutOtpModal.js +0 -12
  375. package/dist/features/checkout/actions/checkout-actions.d.ts +0 -31
  376. package/dist/features/checkout/actions/checkout-actions.js +0 -124
  377. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +0 -5
  378. package/dist/features/classified/components/ClassifiedIndexListing.js +0 -123
  379. package/dist/features/classified/components/ClassifiedListView.d.ts +0 -6
  380. package/dist/features/classified/components/ClassifiedListView.js +0 -44
  381. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +0 -5
  382. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +0 -114
  383. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +0 -6
  384. package/dist/features/digital-codes/components/DigitalCodesListView.js +0 -38
  385. package/dist/features/live/components/LiveItemsIndexListing.d.ts +0 -5
  386. package/dist/features/live/components/LiveItemsIndexListing.js +0 -115
  387. package/dist/features/live/components/LiveItemsListView.d.ts +0 -6
  388. package/dist/features/live/components/LiveItemsListView.js +0 -44
  389. package/dist/features/seller/components/SellerTemplatesView.d.ts +0 -12
  390. package/dist/features/seller/components/SellerTemplatesView.js +0 -276
  391. package/dist/react/hooks/useVisibleItems.d.ts +0 -37
  392. package/dist/react/hooks/useVisibleItems.js +0 -59
  393. package/dist/ui/components/TabStrip.d.ts +0 -34
  394. package/dist/ui/components/TabStrip.js +0 -56
  395. package/dist/ui/components/TabStrip.style.css +0 -97
@@ -10,10 +10,58 @@ import { QuickEditMenu } from "./QuickEditMenu";
10
10
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
11
11
  import { ROUTES } from "../../../next/routing/route-map";
12
12
  import { ADMIN_BULK_ACTIONS, ROW_ACTION_META, ROW_ACTION_ID } from "../../products/constants/action-defs";
13
- import { ADMIN_ORDER_STATUS_TABS } from "../constants/filter-tabs";
13
+ import { ADMIN_ORDER_STATUS_TABS, ADMIN_ORDER_PAYMENT_REVIEW_TABS } from "../constants/filter-tabs";
14
+ import { isManualPaymentMethod, isPaymentReviewQueueMode } from "../../orders/constants/payment-window";
14
15
  import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../hooks/useAdminListingData";
15
16
  import { DataListingView } from "./DataListingView";
16
17
  import { AdminOrderEditorView } from "./AdminOrderEditorView";
18
+ /**
19
+ * `OrderDocument` has no `orderNumber` field — the real item info an order
20
+ * list row should show lives in the denormalized `items[]` snapshot
21
+ * (`productTitle`/`image`), written at order time specifically so list/detail
22
+ * UI never needs an extra product fetch. Falling back to `Order {id}` (a raw
23
+ * GUID) instead was Root Cause Pattern #(order-guid) — see CLAUDE.md.
24
+ */
25
+ function toOrderItemRows(item) {
26
+ const items = Array.isArray(item.items) ? item.items : [];
27
+ return items
28
+ .filter((entry) => Boolean(entry) && typeof entry === "object")
29
+ .map((entry) => ({
30
+ productId: typeof entry.productId === "string" ? entry.productId : "",
31
+ title: typeof entry.productTitle === "string" ? entry.productTitle : "Item",
32
+ image: typeof entry.image === "string" ? entry.image : undefined,
33
+ quantity: typeof entry.quantity === "number" ? entry.quantity : 1,
34
+ unitPrice: typeof entry.unitPrice === "number" ? entry.unitPrice : 0,
35
+ totalPrice: typeof entry.totalPrice === "number" ? entry.totalPrice : 0,
36
+ }));
37
+ }
38
+ function firstOrderItem(item) {
39
+ const items = toOrderItemRows(item);
40
+ return {
41
+ image: items[0]?.image,
42
+ title: items[0]?.title,
43
+ extraCount: Math.max(0, items.length - 1),
44
+ };
45
+ }
46
+ /**
47
+ * Short marker appended to a row's secondary line so a manual payment needing
48
+ * action is visible in the list itself, not only after opening the drawer.
49
+ * Mirrors the same `paymentProofUrl` / `paymentReviewOutcome` derivation the
50
+ * server-side queue uses (`listPaymentReviewQueue`) — kept in sync by reading
51
+ * the same two fields rather than a denormalised flag (Root Cause #42).
52
+ */
53
+ function paymentReviewLabel(item) {
54
+ if (!isManualPaymentMethod(toStringValue(item.paymentMethod, "")))
55
+ return undefined;
56
+ if (toStringValue(item.paymentStatus, "") === "paid")
57
+ return "Payment verified";
58
+ const outcome = toStringValue(item.paymentReviewOutcome, "");
59
+ if (outcome === "rejected_fraud")
60
+ return "Payment rejected";
61
+ if (outcome === "reupload_requested")
62
+ return "Re-upload requested";
63
+ return item.paymentProofUrl ? "Awaiting verification" : "Awaiting payment";
64
+ }
17
65
  export function AdminOrdersView({ children, ...props }) {
18
66
  const { showToast } = useToast();
19
67
  const router = useRouter();
@@ -37,7 +85,7 @@ export function AdminOrdersView({ children, ...props }) {
37
85
  title: "Orders",
38
86
  searchPlaceholder: "Search orders, buyers, or tracking IDs",
39
87
  emptyLabel: "No orders found",
40
- filterKeys: ["status"],
88
+ filterKeys: ["status", "paymentReview"],
41
89
  defaultSort: sortBy("createdAt", "DESC"),
42
90
  queryKey: ["admin", "orders", "listing"],
43
91
  endpoint: ADMIN_ENDPOINTS.ORDERS,
@@ -45,27 +93,47 @@ export function AdminOrdersView({ children, ...props }) {
45
93
  { value: sortBy("createdAt", "DESC"), label: "Newest" },
46
94
  { value: sortBy("createdAt", "ASC"), label: "Oldest" },
47
95
  ],
48
- mapRows: (response) => toRecordArray(response.orders).map((item, index) => ({
49
- id: toStringValue(item.id, `order-${index}`),
50
- primary: `Order ${toStringValue(item.orderNumber ?? item.id, "-")}`,
51
- secondary: [
52
- toStringValue(item.buyerName ?? item.customerName, "Unknown buyer"),
53
- toCurrency(item.totalAmount ?? item.total ?? item.amount),
54
- ].join(" · "),
55
- status: toStringValue(item.status, "Unknown"),
56
- updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
57
- paymentProofUrl: toStringValue(item.paymentProofUrl, "") || undefined,
58
- paymentTransactionId: toStringValue(item.paymentTransactionId, "") || undefined,
59
- paymentMethod: toStringValue(item.paymentMethod, "") || undefined,
60
- paymentStatus: toStringValue(item.paymentStatus, "") || undefined,
61
- displayedUpiId: toStringValue(item.displayedUpiId, "") || undefined,
62
- buyerReportedUpiId: toStringValue(item.buyerReportedUpiId, "") || undefined,
63
- paymentUpiMismatch: Boolean(item.paymentUpiMismatch),
64
- buyerMarkedPaid: Boolean(item.buyerMarkedPaid),
65
- buyerFraudAgreementAccepted: Boolean(item.buyerFraudAgreementAccepted),
66
- })),
96
+ mapRows: (response) => toRecordArray(response.orders).map((item, index) => {
97
+ const orderId = toStringValue(item.id, `order-${index}`);
98
+ const { image, title, extraCount } = firstOrderItem(item);
99
+ return {
100
+ id: orderId,
101
+ primary: title
102
+ ? `${title}${extraCount > 0 ? ` +${extraCount} more` : ""}`
103
+ : `Order ${orderId}`,
104
+ secondary: [
105
+ toStringValue(item.buyerName ?? item.customerName, "Unknown buyer"),
106
+ toCurrency(item.totalAmount ?? item.total ?? item.amount),
107
+ orderId.slice(0, 14),
108
+ paymentReviewLabel(item),
109
+ ]
110
+ .filter(Boolean)
111
+ .join(" · "),
112
+ status: toStringValue(item.status, "Unknown"),
113
+ updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
114
+ image,
115
+ items: toOrderItemRows(item),
116
+ paymentProofUrl: toStringValue(item.paymentProofUrl, "") || undefined,
117
+ paymentTransactionId: toStringValue(item.paymentTransactionId, "") || undefined,
118
+ paymentMethod: toStringValue(item.paymentMethod, "") || undefined,
119
+ paymentStatus: toStringValue(item.paymentStatus, "") || undefined,
120
+ displayedUpiId: toStringValue(item.displayedUpiId, "") || undefined,
121
+ buyerReportedUpiId: toStringValue(item.buyerReportedUpiId, "") || undefined,
122
+ paymentUpiMismatch: Boolean(item.paymentUpiMismatch),
123
+ buyerMarkedPaid: Boolean(item.buyerMarkedPaid),
124
+ buyerFraudAgreementAccepted: Boolean(item.buyerFraudAgreementAccepted),
125
+ };
126
+ }),
67
127
  getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
68
- buildFilters: (f) => (f.status && f.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, f.status) : undefined),
128
+ // The payment-review queue is always `status == pending` by definition, so
129
+ // a status chip on top of it could only ever narrow to zero rows. When the
130
+ // queue is active the status filter is dropped rather than combined.
131
+ buildFilters: (f) => {
132
+ if (isPaymentReviewQueueMode(f.paymentReview ?? ""))
133
+ return undefined;
134
+ return f.status && f.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, f.status) : undefined;
135
+ },
136
+ buildExtraParams: (f) => isPaymentReviewQueueMode(f.paymentReview ?? "") ? { paymentReview: f.paymentReview } : undefined,
69
137
  // Mirrors the row action's "View full details" entry so the row itself
70
138
  // is clickable, not just the overflow menu.
71
139
  onRowClick: (row) => {
@@ -128,7 +196,7 @@ export function AdminOrdersView({ children, ...props }) {
128
196
  submitLabel: "Update",
129
197
  },
130
198
  ] })),
131
- renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsx(FilterChipGroup, { label: "Status", tabs: ADMIN_ORDER_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) })),
199
+ renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(_Fragment, { children: [_jsx(FilterChipGroup, { label: "Status", tabs: ADMIN_ORDER_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id, paymentReview: "" })) }), _jsx(FilterChipGroup, { label: "Manual payment", tabs: ADMIN_ORDER_PAYMENT_REVIEW_TABS, value: pendingFilters.paymentReview ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, paymentReview: id, status: "" })) })] })),
132
200
  };
133
- return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(AdminOrderEditorView, { open: drawerOpen, onClose: () => setDrawerOpen(false), orderId: selectedRow?.id, orderLabel: selectedRow?.primary, currentStatus: selectedRow?.status, paymentProofUrl: selectedRow?.paymentProofUrl, paymentTransactionId: selectedRow?.paymentTransactionId, paymentMethod: selectedRow?.paymentMethod, paymentStatus: selectedRow?.paymentStatus, displayedUpiId: selectedRow?.displayedUpiId, buyerReportedUpiId: selectedRow?.buyerReportedUpiId, paymentUpiMismatch: selectedRow?.paymentUpiMismatch, buyerMarkedPaid: selectedRow?.buyerMarkedPaid, buyerFraudAgreementAccepted: selectedRow?.buyerFraudAgreementAccepted })] }));
201
+ return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(AdminOrderEditorView, { open: drawerOpen, onClose: () => setDrawerOpen(false), orderId: selectedRow?.id, orderLabel: selectedRow?.primary, currentStatus: selectedRow?.status, items: selectedRow?.items, paymentProofUrl: selectedRow?.paymentProofUrl, paymentTransactionId: selectedRow?.paymentTransactionId, paymentMethod: selectedRow?.paymentMethod, paymentStatus: selectedRow?.paymentStatus, displayedUpiId: selectedRow?.displayedUpiId, buyerReportedUpiId: selectedRow?.buyerReportedUpiId, paymentUpiMismatch: selectedRow?.paymentUpiMismatch, buyerMarkedPaid: selectedRow?.buyerMarkedPaid, buyerFraudAgreementAccepted: selectedRow?.buyerFraudAgreementAccepted })] }));
134
202
  }
@@ -0,0 +1,7 @@
1
+ export interface AdminPayoutMarkPaidModalProps {
2
+ isOpen: boolean;
3
+ payoutId: string | null;
4
+ onClose: () => void;
5
+ onSuccess?: () => void;
6
+ }
7
+ export declare function AdminPayoutMarkPaidModal({ isOpen, payoutId, onClose, onSuccess }: AdminPayoutMarkPaidModalProps): import("react").JSX.Element;
@@ -0,0 +1,47 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * AdminPayoutMarkPaidModal — the single "mark payout as paid" form + mutation,
5
+ * shared by the payouts list row action and the standalone payout detail
6
+ * page so the two surfaces can't drift (same class of fix as
7
+ * SellerOrderDetailPanel for orders — see CLAUDE.md Root Cause list).
8
+ */
9
+ import { useState } from "react";
10
+ import { useApiMutation } from "@mohasinac/appkit/client";
11
+ import { useQueryClient } from "@tanstack/react-query";
12
+ import { Button, Form, FormActions, Input, Modal, useToast } from "../../../ui";
13
+ import { apiClient } from "../../../http";
14
+ import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
15
+ export function AdminPayoutMarkPaidModal({ isOpen, payoutId, onClose, onSuccess }) {
16
+ const [transactionId, setTransactionId] = useState("");
17
+ const { showToast } = useToast();
18
+ const queryClient = useQueryClient();
19
+ const markPaid = useApiMutation({
20
+ mutationFn: () => {
21
+ if (!payoutId)
22
+ throw new Error("No payout selected");
23
+ return apiClient.patch(ADMIN_ENDPOINTS.PAYOUT_BY_ID(payoutId), {
24
+ status: "paid",
25
+ transactionId: transactionId.trim() || undefined,
26
+ });
27
+ },
28
+ onSuccess: () => {
29
+ showToast("Payout marked as paid.", "success");
30
+ setTransactionId("");
31
+ void queryClient.invalidateQueries({ queryKey: ["admin", "payouts", "listing"] });
32
+ onSuccess?.();
33
+ onClose();
34
+ },
35
+ onError: () => {
36
+ showToast("Failed to update payout.", "error");
37
+ },
38
+ });
39
+ const handleClose = () => {
40
+ setTransactionId("");
41
+ onClose();
42
+ };
43
+ return (_jsx(Modal, { isOpen: isOpen, onClose: handleClose, title: "Mark payout as paid", children: _jsxs(Form, { onSubmit: (e) => {
44
+ e.preventDefault();
45
+ markPaid.mutate();
46
+ }, spacing: "md", children: [_jsx(Input, { label: "Transaction / reference ID", value: transactionId, onChange: (e) => setTransactionId(e.target.value), placeholder: "UTR, UPI ref, or bank transfer ID (optional)" }), _jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "outline", onClick: handleClose, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "primary", disabled: markPaid.isPending, children: markPaid.isPending ? "Saving..." : "Confirm paid" })] })] }) }));
47
+ }
@@ -1,13 +1,16 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { normalizeError } from "../../../errors/normalize";
4
- import { useApiMutation, useBulkEvent, RTDB_PATHS } from "@mohasinac/appkit/client";
4
+ import { useBulkEvent, RTDB_PATHS } from "@mohasinac/appkit/client";
5
5
  import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit/client";
6
6
  import { sortBy } from "@mohasinac/appkit/client";
7
7
  import React, { useState, useEffect } from "react";
8
8
  import { useQueryClient } from "@tanstack/react-query";
9
- import { Button, FilterChipGroup, Form, FormActions, Input, ListingLayout, Modal, RowActionMenu, useToast, } from "../../../ui";
9
+ import { Button, FilterChipGroup, ListingLayout, RowActionMenu, useToast, } from "../../../ui";
10
+ import { AdminPayoutMarkPaidModal } from "./AdminPayoutMarkPaidModal";
11
+ import { useRouter } from "next/navigation";
10
12
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
13
+ import { ROUTES } from "../../../next/routing/route-map";
11
14
  import { ADMIN_PAYOUT_STATUS_TABS } from "../constants/filter-tabs";
12
15
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
13
16
  import { ADMIN_BULK_ACTIONS, ROW_ACTION_META } from "../../products/constants/action-defs";
@@ -15,9 +18,9 @@ import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../ho
15
18
  import { DataListingView } from "./DataListingView";
16
19
  import { apiClient } from "../../../http";
17
20
  export function AdminPayoutsView({ children, ...props }) {
21
+ const router = useRouter();
18
22
  const [markPaidOpen, setMarkPaidOpen] = useState(false);
19
23
  const [selectedPayoutId, setSelectedPayoutId] = useState(null);
20
- const [transactionId, setTransactionId] = useState("");
21
24
  const [calculating, setCalculating] = useState(false);
22
25
  const toast = useToast();
23
26
  const queryClient = useQueryClient();
@@ -57,26 +60,6 @@ export function AdminPayoutsView({ children, ...props }) {
57
60
  }
58
61
  // eslint-disable-next-line react-hooks/exhaustive-deps
59
62
  }, [bulkEvent.status]);
60
- const markPaid = useApiMutation({
61
- mutationFn: () => {
62
- if (!selectedPayoutId)
63
- throw new Error("No payout selected");
64
- return apiClient.patch(ADMIN_ENDPOINTS.PAYOUT_BY_ID(selectedPayoutId), {
65
- status: "paid",
66
- transactionId: transactionId.trim() || undefined,
67
- });
68
- },
69
- onSuccess: () => {
70
- toast.showToast("Payout marked as paid.", "success");
71
- setMarkPaidOpen(false);
72
- setSelectedPayoutId(null);
73
- setTransactionId("");
74
- void queryClient.invalidateQueries({ queryKey: ["admin", "payouts", "listing"] });
75
- },
76
- onError: () => {
77
- toast.showToast("Failed to update payout.", "error");
78
- },
79
- });
80
63
  const handleExportCsv = async () => {
81
64
  try {
82
65
  const blob = await apiClient.blob(ADMIN_ENDPOINTS.PAYOUTS_EXPORT);
@@ -92,10 +75,6 @@ export function AdminPayoutsView({ children, ...props }) {
92
75
  toast.showToast("CSV export failed.", "error");
93
76
  }
94
77
  };
95
- const closePaidModal = () => {
96
- setMarkPaidOpen(false);
97
- setTransactionId("");
98
- };
99
78
  if (React.Children.count(children) > 0) {
100
79
  return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
101
80
  }
@@ -121,6 +100,7 @@ export function AdminPayoutsView({ children, ...props }) {
121
100
  updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
122
101
  })),
123
102
  getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
103
+ onRowClick: (row) => router.push(String(ROUTES.ADMIN.PAYOUT_DETAIL(row.id))),
124
104
  buildFilters: (state) => {
125
105
  // An explicit status chip always wins. Otherwise, hide the noise
126
106
  // (already-paid payouts) by default — mirrors the isSold-hide-by-
@@ -143,6 +123,10 @@ export function AdminPayoutsView({ children, ...props }) {
143
123
  onClick: () => selection.clearSelection(),
144
124
  })),
145
125
  renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
126
+ {
127
+ label: "View full page",
128
+ onClick: () => router.push(String(ROUTES.ADMIN.PAYOUT_DETAIL(row.id))),
129
+ },
146
130
  {
147
131
  label: ACTIONS.ADMIN["grant-payout"].label,
148
132
  onClick: () => {
@@ -157,8 +141,8 @@ export function AdminPayoutsView({ children, ...props }) {
157
141
  { id: "true", label: "Show all" },
158
142
  ], value: pendingFilters.showAllPayouts ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, showAllPayouts: id })), allId: "" })] })),
159
143
  };
160
- return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(Modal, { isOpen: markPaidOpen, onClose: closePaidModal, title: "Mark payout as paid", children: _jsxs(Form, { onSubmit: (e) => {
161
- e.preventDefault();
162
- markPaid.mutate();
163
- }, spacing: "md", children: [_jsx(Input, { label: "Transaction / reference ID", value: transactionId, onChange: (e) => setTransactionId(e.target.value), placeholder: "UTR, UPI ref, or bank transfer ID (optional)" }), _jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "outline", onClick: closePaidModal, children: "Cancel" }), _jsx(Button, { type: "submit", variant: "primary", disabled: markPaid.isPending, children: markPaid.isPending ? "Saving..." : "Confirm paid" })] })] }) })] }));
144
+ return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(AdminPayoutMarkPaidModal, { isOpen: markPaidOpen, payoutId: selectedPayoutId, onClose: () => {
145
+ setMarkPaidOpen(false);
146
+ setSelectedPayoutId(null);
147
+ } })] }));
164
148
  }
@@ -6,8 +6,21 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  import { Row } from "@mohasinac/appkit/ui";
7
7
  import { useApiMutation } from "@mohasinac/appkit/client";
8
8
  import React from "react";
9
+ import { z } from "zod";
9
10
  import { useQuery } from "@tanstack/react-query";
10
11
  import { Button, Card, CardBody, ConfirmDeleteModal, Div, PaginatedSelect, Form, Stack, StackedViewShell, Tabs, TabsContent, TabsList, TabsTrigger, Text, useToast, Show, StickyToolbar, } from "../../../ui";
12
+ import { useFormShellState, applyZodIssues, FormErrorSummary, FormShellContext } from "../../../ui/forms";
13
+ // Admin form-input validation — deliberately a small local schema, not the
14
+ // broader `productItemSchema` (that one requires `id`/`price`/`status` as
15
+ // non-optional, since it's the full read/display shape used across many
16
+ // features — applying it directly here would show false "required" errors
17
+ // on every keystroke while creating a new product, before an id exists).
18
+ const adminProductFormSchema = z.object({
19
+ title: z.string().min(1, "Product title is required"),
20
+ price: z.number().min(0).optional(),
21
+ images: z.array(z.string()).max(5, "Up to 5 gallery images allowed").optional(),
22
+ video: z.object({ url: z.string(), thumbnailUrl: z.string().optional() }).optional(),
23
+ }).passthrough();
11
24
  import { apiClient } from "../../../http";
12
25
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
13
26
  import { ProductForm } from "../../products/components/ProductForm";
@@ -106,6 +119,12 @@ export function AdminProductEditorView({ productId, onSaved, onDeleted, embedded
106
119
  const [mode, setMode] = React.useState("standard");
107
120
  const [deleteOpen, setDeleteOpen] = React.useState(false);
108
121
  const { showToast } = useToast();
122
+ const { shellCtx, setFieldError, validate } = useFormShellState(adminProductFormSchema);
123
+ // Live validation — re-run on every product change, not just on submit.
124
+ React.useEffect(() => {
125
+ validate(product);
126
+ // eslint-disable-next-line react-hooks/exhaustive-deps
127
+ }, [product, validate]);
109
128
  const productQuery = useQuery({
110
129
  queryKey: ["admin", "product", productId],
111
130
  queryFn: async () => {
@@ -153,6 +172,10 @@ export function AdminProductEditorView({ productId, onSaved, onDeleted, embedded
153
172
  onSaved(id);
154
173
  },
155
174
  onError: (err) => {
175
+ const issues = err?.issues;
176
+ if (issues && issues.length > 0) {
177
+ applyZodIssues(issues, setFieldError);
178
+ }
156
179
  showToast(err?.message ?? "Failed to save product.", "error");
157
180
  },
158
181
  });
@@ -168,13 +191,13 @@ export function AdminProductEditorView({ productId, onSaved, onDeleted, embedded
168
191
  },
169
192
  });
170
193
  const isSubmitting = saveMutation.isPending || productQuery.isLoading;
171
- const actionSidebar = (_jsxs(Card, { variant: "outlined", padding: "md", spacing: "sm", children: [_jsx(Text, { className: "tracking-widest", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Status" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: isEdit ? product.status ?? "—" : "New" }), _jsx(Button, { type: "submit", form: "product-editor-form", className: "w-full", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", className: "w-full", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] }));
172
- const formContent = (_jsxs(Form, { id: "product-editor-form", onSubmit: (e) => {
194
+ const actionSidebar = (_jsx(FormShellContext.Provider, { value: shellCtx, children: _jsxs(Card, { variant: "outlined", padding: "md", spacing: "sm", children: [_jsx(Text, { className: "tracking-widest", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Status" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: isEdit ? product.status ?? "—" : "New" }), _jsx(FormErrorSummary, {}), _jsx(Button, { type: "submit", form: "product-editor-form", className: "w-full", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", className: "w-full", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] }) }));
195
+ const formContent = (_jsxs(Form, { id: "product-editor-form", shellCtx: shellCtx, onSubmit: (e) => {
173
196
  e.preventDefault();
174
197
  saveMutation.mutate();
175
198
  }, spacing: "lg", children: [_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Listing Type" }), _jsxs(Tabs, { value: mode, onChange: handleModeChange, children: [_jsxs(TabsList, { children: [(!enabledListingTypes || enabledListingTypes.includes("standard")) && (_jsx(TabsTrigger, { value: "standard", children: "Standard" })), (!enabledListingTypes || enabledListingTypes.includes("auction")) && (_jsx(TabsTrigger, { value: "auction", children: "Auction" })), (!enabledListingTypes || enabledListingTypes.includes("pre-order")) && (_jsx(TabsTrigger, { value: "preorder", children: "Pre-order" })), (!enabledListingTypes || enabledListingTypes.includes("prize-draw")) && (_jsx(TabsTrigger, { value: "prize-draw", children: "Prize Draw" })), (!enabledListingTypes || enabledListingTypes.includes("classified")) && (_jsx(TabsTrigger, { value: "classified", children: "Classified" })), (!enabledListingTypes || enabledListingTypes.includes("digital-code")) && (_jsx(TabsTrigger, { value: "digital-code", children: "Digital Code" })), (!enabledListingTypes || enabledListingTypes.includes("live")) && (_jsx(TabsTrigger, { value: "live", children: "Live Item" }))] }), _jsx(TabsContent, { value: "standard" }), _jsx(TabsContent, { value: "auction" }), _jsx(TabsContent, { value: "preorder" }), _jsx(TabsContent, { value: "prize-draw" }), _jsx(TabsContent, { value: "classified" }), _jsx(TabsContent, { value: "digital-code" }), _jsx(TabsContent, { value: "live" })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Classification" }), _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: "Store" }), _jsx(PaginatedSelect, { value: product.storeId ?? null, onChange: handleStoreSelect, loadOptions: loadStoreOptions, placeholder: "Search stores\u2026", searchPlaceholder: "Type store name\u2026", noResultsText: "No stores found", ariaLabel: "Store" })] }), _jsx(ProductForm, { product: product, onChange: setProduct, renderGroupSettings: isEdit && productId
176
199
  ? (p) => (_jsx(GroupSettingsPanel, { productId: productId, productSlug: p.slug ?? productId, groupId: p.groupId, isGroupParent: p.isGroupParent, groupParentSlug: p.groupParentSlug, groupChildSlugs: p.groupChildSlugs, groupTitle: p.groupTitle, isAuction: modeFromProduct(p) === "auction", storeProductsEndpoint: ADMIN_ENDPOINTS.PRODUCTS, onGroupChanged: () => productQuery.refetch() }))
177
- : undefined, renderGroupJoinField: ({ label, value, onChange, disabled }) => (_jsx(GroupInlineSelect, { scope: "admin", value: value ?? "", onChange: (id) => onChange(id || undefined), disabled: disabled, label: label, placeholder: "None (standalone product)", allowCreate: false })), renderCategorySelector: ({ label, value, onChange, disabled }) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: label }), _jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadCategoryOptions, placeholder: "Search categories\u2026", searchPlaceholder: "Type category name\u2026", noResultsText: "No categories found", ariaLabel: label, disabled: disabled, createLabel: "Category", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })), renderBrandSelector: (args) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: args.label }), _jsx(PaginatedSelect, { value: args.multi ? null : (args.value || null), onChange: (v) => args.onValueChange(v ?? ""), loadOptions: loadBrandOptions, placeholder: "Search brands\u2026", searchPlaceholder: "Type brand name\u2026", noResultsText: "No brands found", ariaLabel: args.label, disabled: args.disabled, createLabel: "Brand", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })) })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Inventory" }), _jsx(BarcodeField, { value: product.barcodeId ?? "", onChange: (v) => setProduct((prev) => ({ ...prev, barcodeId: v || undefined })), onScan: (v) => setProduct((prev) => ({ ...prev, barcodeId: v })), helperText: "Leave blank to auto-generate. Scan a pre-printed sticker to link it." })] }), _jsxs(Row, { gap: "3", className: "lg:hidden", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] })] }, "product-form"));
200
+ : undefined, renderGroupJoinField: ({ label, value, onChange, disabled }) => (_jsx(GroupInlineSelect, { scope: "admin", value: value ?? "", onChange: (id) => onChange(id || undefined), disabled: disabled, label: label, placeholder: "None (standalone product)", allowCreate: false })), renderCategorySelector: ({ label, value, onChange, disabled }) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: label }), _jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadCategoryOptions, placeholder: "Search categories\u2026", searchPlaceholder: "Type category name\u2026", noResultsText: "No categories found", ariaLabel: label, disabled: disabled, createLabel: "Category", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })), renderBrandSelector: (args) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: args.label }), _jsx(PaginatedSelect, { value: args.multi ? null : (args.value || null), onChange: (v) => args.onValueChange(v ?? ""), loadOptions: loadBrandOptions, placeholder: "Search brands\u2026", searchPlaceholder: "Type brand name\u2026", noResultsText: "No brands found", ariaLabel: args.label, disabled: args.disabled, createLabel: "Brand", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })) })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Inventory" }), _jsx(BarcodeField, { value: product.barcodeId ?? "", onChange: (v) => setProduct((prev) => ({ ...prev, barcodeId: v || undefined })), onScan: (v) => setProduct((prev) => ({ ...prev, barcodeId: v })), helperText: "Leave blank to auto-generate. Scan a pre-printed sticker to link it." })] }), _jsx(FormErrorSummary, {}), _jsxs(Row, { gap: "3", className: "lg:hidden", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] })] }, "product-form"));
178
201
  if (embedded) {
179
202
  return _jsx(Div, { className: `${__O.yAuto} ${__P.p4}`, children: formContent });
180
203
  }