@mohasinac/appkit 4.10.0 → 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 (319) 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/audit-log/actions.d.ts +25 -0
  8. package/dist/_internal/server/features/audit-log/actions.js +38 -0
  9. package/dist/_internal/server/features/brands/actions.js +0 -2
  10. package/dist/_internal/server/features/brands/og.d.ts +4 -1
  11. package/dist/_internal/server/features/brands/og.js +1 -1
  12. package/dist/_internal/server/features/grouped/data.d.ts +4 -0
  13. package/dist/_internal/server/features/grouped/data.js +24 -0
  14. package/dist/_internal/server/features/grouped/index.d.ts +1 -1
  15. package/dist/_internal/server/features/grouped/index.js +1 -1
  16. package/dist/_internal/server/features/orders/actions.js +9 -0
  17. package/dist/_internal/server/features/orders/adapters.js +25 -0
  18. package/dist/_internal/server/functions/scheduled.d.ts +3 -1
  19. package/dist/_internal/server/functions/scheduled.js +17 -1
  20. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +40 -0
  21. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +164 -0
  22. package/dist/_internal/server/jobs/core/hardBanCascade.js +11 -0
  23. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -0
  24. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
  25. package/dist/_internal/server/jobs/core/testerSandboxRefresh.d.ts +12 -0
  26. package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +85 -0
  27. package/dist/_internal/server/jobs/core/whatsappNotify.js +16 -0
  28. package/dist/_internal/server/jobs/handlers/dailyStatusDigest.d.ts +2 -0
  29. package/dist/_internal/server/jobs/handlers/dailyStatusDigest.js +4 -0
  30. package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
  31. package/dist/_internal/server/jobs/handlers/index.js +3 -0
  32. package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.d.ts +2 -0
  33. package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.js +2 -0
  34. package/dist/_internal/server/notifications/channel-health.d.ts +27 -0
  35. package/dist/_internal/server/notifications/channel-health.js +101 -0
  36. package/dist/_internal/shared/features/brands/schema.d.ts +0 -6
  37. package/dist/_internal/shared/features/brands/schema.js +0 -1
  38. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +7 -0
  39. package/dist/_internal/shared/features/categories/bundle-schemas.js +3 -0
  40. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  41. package/dist/client.d.ts +21 -6
  42. package/dist/client.js +13 -3
  43. package/dist/constants/api-endpoints.d.ts +6 -9
  44. package/dist/constants/api-endpoints.js +2 -3
  45. package/dist/contracts/client-auth.d.ts +3 -7
  46. package/dist/contracts/email.d.ts +1 -0
  47. package/dist/features/account/components/AddressForm.js +24 -2
  48. package/dist/features/account/components/BecomeSellerView.d.ts +1 -2
  49. package/dist/features/account/components/BecomeSellerView.js +1 -1
  50. package/dist/features/account/components/NotificationBell.js +1 -1
  51. package/dist/features/account/components/UserBidsView.d.ts +1 -0
  52. package/dist/features/account/components/UserBidsView.js +47 -0
  53. package/dist/features/account/components/UserOrdersView.d.ts +4 -11
  54. package/dist/features/account/components/UserOrdersView.js +54 -4
  55. package/dist/features/account/components/UserReturnsView.d.ts +4 -9
  56. package/dist/features/account/components/UserReturnsView.js +37 -3
  57. package/dist/features/account/components/index.d.ts +3 -2
  58. package/dist/features/account/components/index.js +1 -0
  59. package/dist/features/admin/actions/admin-actions.js +22 -0
  60. package/dist/features/admin/actions/admin-coupon-actions.js +10 -0
  61. package/dist/features/admin/actions/notification-actions.js +4 -3
  62. package/dist/features/admin/components/AdminAdsView.d.ts +2 -3
  63. package/dist/features/admin/components/AdminAdsView.js +86 -89
  64. package/dist/features/admin/components/AdminAllEventEntriesView.js +18 -3
  65. package/dist/features/admin/components/AdminAuditLogView.d.ts +11 -0
  66. package/dist/features/admin/components/AdminAuditLogView.js +95 -0
  67. package/dist/features/admin/components/AdminBlogEditorView.js +37 -3
  68. package/dist/features/admin/components/AdminBrandEditorView.js +10 -6
  69. package/dist/features/admin/components/AdminBundleEditorView.js +18 -2
  70. package/dist/features/admin/components/AdminCarouselEditorView.js +2 -2
  71. package/dist/features/admin/components/AdminCarouselGroupEditorView.js +2 -2
  72. package/dist/features/admin/components/AdminCartsView.js +34 -4
  73. package/dist/features/admin/components/AdminCategoryEditorView.js +5 -4
  74. package/dist/features/admin/components/AdminCouponEditorView.js +2 -2
  75. package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
  76. package/dist/features/admin/components/AdminHistoryView.js +11 -1
  77. package/dist/features/admin/components/AdminNotificationsView.js +27 -1
  78. package/dist/features/admin/components/AdminOrderEditorView.d.ts +10 -1
  79. package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
  80. package/dist/features/admin/components/AdminOrdersView.js +92 -24
  81. package/dist/features/admin/components/AdminPayoutMarkPaidModal.d.ts +7 -0
  82. package/dist/features/admin/components/AdminPayoutMarkPaidModal.js +47 -0
  83. package/dist/features/admin/components/AdminPayoutsView.js +15 -31
  84. package/dist/features/admin/components/AdminProductEditorView.js +26 -3
  85. package/dist/features/admin/components/AdminSiteSettingsView.js +20 -1
  86. package/dist/features/admin/components/AdminStoreAddressesView.js +22 -2
  87. package/dist/features/admin/components/AdminStoresView.js +7 -0
  88. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +2 -2
  89. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +2 -2
  90. package/dist/features/admin/components/AdminUserEditorView.d.ts +2 -2
  91. package/dist/features/admin/components/AdminUserEditorView.js +4 -2
  92. package/dist/features/admin/components/AdminUsersView.js +1 -1
  93. package/dist/features/admin/components/AdminWishlistsView.js +14 -1
  94. package/dist/features/admin/components/DataListingView.d.ts +2 -2
  95. package/dist/features/admin/components/ViewAuditLogEntryModal.d.ts +19 -0
  96. package/dist/features/admin/components/ViewAuditLogEntryModal.js +22 -0
  97. package/dist/features/admin/components/ViewNotificationModal.d.ts +21 -0
  98. package/dist/features/admin/components/ViewNotificationModal.js +15 -0
  99. package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +4 -7
  100. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +56 -36
  101. package/dist/features/admin/components/index.d.ts +8 -1
  102. package/dist/features/admin/components/index.js +4 -0
  103. package/dist/features/admin/constants/filter-tabs.d.ts +49 -0
  104. package/dist/features/admin/constants/filter-tabs.js +27 -0
  105. package/dist/features/admin/hooks/useAdminListing.d.ts +6 -0
  106. package/dist/features/admin/hooks/useAdminListing.js +3 -1
  107. package/dist/features/admin/hooks/useAdminListingData.d.ts +9 -1
  108. package/dist/features/admin/hooks/useAdminListingData.js +9 -2
  109. package/dist/features/admin/repository/site-settings.repository.d.ts +5 -0
  110. package/dist/features/admin/schemas/firestore.d.ts +12 -0
  111. package/dist/features/analytics/types.d.ts +1 -1
  112. package/dist/features/analytics/types.js +8 -0
  113. package/dist/features/auctions/schemas/index.d.ts +5 -0
  114. package/dist/features/audit-log/repository/audit-log.repository.d.ts +45 -0
  115. package/dist/features/audit-log/repository/audit-log.repository.js +30 -0
  116. package/dist/features/audit-log/schemas/firestore.d.ts +59 -0
  117. package/dist/features/audit-log/schemas/firestore.js +35 -0
  118. package/dist/features/auth/actions/index.d.ts +0 -1
  119. package/dist/features/auth/actions/index.js +0 -1
  120. package/dist/features/auth/hooks/useAuth.d.ts +8 -35
  121. package/dist/features/auth/hooks/useAuth.js +21 -37
  122. package/dist/features/auth/permissions/constants.d.ts +1 -1
  123. package/dist/features/auth/permissions/constants.js +2 -0
  124. package/dist/features/blog/schemas/index.d.ts +32 -0
  125. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +31 -3
  126. package/dist/features/catalogue/components/CatalogueItemEditorView.js +2 -1
  127. package/dist/features/categories/components/BrandDetailPageView.js +14 -12
  128. package/dist/features/categories/components/CategoryDetailPageView.js +7 -3
  129. package/dist/features/categories/components/CategoryHighlightsAndFaqSection.d.ts +14 -0
  130. package/dist/features/categories/components/CategoryHighlightsAndFaqSection.js +22 -0
  131. package/dist/features/categories/components/CategoryProductsView.d.ts +1 -5
  132. package/dist/features/categories/components/CategoryProductsView.js +1 -1
  133. package/dist/features/categories/components/CategorySelectorCreate.js +16 -2
  134. package/dist/features/categories/schemas/firestore.d.ts +19 -2
  135. package/dist/features/categories/schemas/index.d.ts +24 -3
  136. package/dist/features/categories/schemas/index.js +3 -1
  137. package/dist/features/categories/types/index.d.ts +7 -0
  138. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +17 -3
  139. package/dist/features/checkout/actions/checkout-value-otp-actions.js +101 -22
  140. package/dist/features/contact/components/ContactForm.js +17 -4
  141. package/dist/features/contact/email.d.ts +1 -0
  142. package/dist/features/contact/email.js +3 -0
  143. package/dist/features/events/components/AdminEventEditorView.js +54 -2
  144. package/dist/features/events/components/AdminEventEntriesView.d.ts +2 -16
  145. package/dist/features/events/components/AdminEventEntriesView.js +56 -89
  146. package/dist/features/events/components/EventFormDrawer.js +5 -1
  147. package/dist/features/events/components/EventRaffleEntryForm.d.ts +1 -3
  148. package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
  149. package/dist/features/events/schemas/index.d.ts +22 -0
  150. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +4 -0
  151. package/dist/features/grouped/repository/grouped-listings.repository.js +18 -0
  152. package/dist/features/homepage/components/CharacterHotspotForm.js +202 -187
  153. package/dist/features/homepage/components/SectionCarousel.d.ts +1 -7
  154. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  155. package/dist/features/layout/TitleBarLayout.d.ts +1 -1
  156. package/dist/features/layout/TitleBarLayout.js +3 -3
  157. package/dist/features/media/MediaImage.js +39 -3
  158. package/dist/features/media/types/index.d.ts +10 -0
  159. package/dist/features/media/types/index.js +1 -0
  160. package/dist/features/media/upload/MediaUploadField.d.ts +7 -1
  161. package/dist/features/media/upload/MediaUploadField.js +11 -7
  162. package/dist/features/media/upload/video-poster.d.ts +2 -0
  163. package/dist/features/media/upload/video-poster.js +16 -1
  164. package/dist/features/media/upload/video-poster.test.js +1 -1
  165. package/dist/features/orders/components/OrderStatusTimeline.d.ts +12 -0
  166. package/dist/features/orders/components/OrderStatusTimeline.js +55 -0
  167. package/dist/features/orders/components/index.d.ts +2 -0
  168. package/dist/features/orders/components/index.js +1 -0
  169. package/dist/features/orders/constants/payment-window.d.ts +25 -0
  170. package/dist/features/orders/constants/payment-window.js +25 -0
  171. package/dist/features/orders/repository/orders.repository.d.ts +32 -0
  172. package/dist/features/orders/repository/orders.repository.js +56 -0
  173. package/dist/features/orders/schemas/index.d.ts +24 -24
  174. package/dist/features/orders/types/index.d.ts +33 -0
  175. package/dist/features/pre-orders/schemas/index.d.ts +5 -0
  176. package/dist/features/products/components/BidHistory.js +9 -1
  177. package/dist/features/products/components/GroupSettingsPanel.js +25 -3
  178. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  179. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +1 -4
  180. package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
  181. package/dist/features/products/components/ProductDetailActions.d.ts +1 -2
  182. package/dist/features/products/components/ProductDetailActions.js +1 -1
  183. package/dist/features/products/components/ProductGrid.js +15 -1
  184. package/dist/features/products/constants/action-defs.d.ts +1 -0
  185. package/dist/features/products/constants/action-defs.js +1 -0
  186. package/dist/features/products/schemas/index.d.ts +5 -0
  187. package/dist/features/promotions/components/CouponsIndexListing.d.ts +1 -3
  188. package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
  189. package/dist/features/search/components/SearchView.d.ts +1 -3
  190. package/dist/features/search/components/SearchView.js +1 -1
  191. package/dist/features/seller/components/QuickProductForm.js +2 -1
  192. package/dist/features/seller/components/SellerBidsView.js +66 -107
  193. package/dist/features/seller/components/SellerGoogleReviewsView.js +17 -1
  194. package/dist/features/seller/components/SellerOrdersView.d.ts +15 -3
  195. package/dist/features/seller/components/SellerOrdersView.js +134 -163
  196. package/dist/features/seller/components/SellerPayoutMethodsView.js +60 -48
  197. package/dist/features/seller/components/SellerPayoutSettingsView.js +69 -4
  198. package/dist/features/seller/components/SellerPayoutsView.d.ts +12 -0
  199. package/dist/features/seller/components/SellerPayoutsView.js +25 -5
  200. package/dist/features/seller/components/SellerProductShell.d.ts +10 -3
  201. package/dist/features/seller/components/SellerProductShell.js +89 -36
  202. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +2 -7
  203. package/dist/features/seller/components/SellerProductsFilterDrawer.js +4 -4
  204. package/dist/features/seller/components/SellerProductsView.d.ts +2 -4
  205. package/dist/features/seller/components/SellerProductsView.js +131 -189
  206. package/dist/features/seller/components/SellerReviewsView.js +95 -133
  207. package/dist/features/seller/components/SellerShippingConfigsView.js +47 -67
  208. package/dist/features/seller/components/SellerShippingView.js +41 -4
  209. package/dist/features/seller/components/SellerStoreCategoriesView.js +51 -59
  210. package/dist/features/seller/components/SellerStorefrontView.d.ts +6 -1
  211. package/dist/features/seller/components/SellerStorefrontView.js +42 -5
  212. package/dist/features/seller/components/index.d.ts +2 -2
  213. package/dist/features/seller/components/index.js +2 -2
  214. package/dist/features/shell/FormShell.d.ts +24 -4
  215. package/dist/features/shell/FormShell.js +12 -6
  216. package/dist/features/shell/QuickFormDrawer.js +67 -12
  217. package/dist/features/shell/StepForm.d.ts +30 -1
  218. package/dist/features/shell/StepForm.js +47 -4
  219. package/dist/features/shell/index.d.ts +1 -1
  220. package/dist/features/shell/index.js +1 -1
  221. package/dist/features/shipments/components/AdminShipmentEditorView.js +2 -2
  222. package/dist/features/shipments/schemas/validation.d.ts +14 -4
  223. package/dist/features/tester/components/AdminTesterFeedbackListView.js +23 -2
  224. package/dist/features/tester/components/TesterChecklistStepRow.js +1 -1
  225. package/dist/features/tester/components/TesterHubView.js +3 -2
  226. package/dist/features/tester/seed-data/orders-tester-seed-data.js +9 -1
  227. package/dist/features/tester/seed-data/products-tester-seed-data.js +43 -32
  228. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +404 -15
  229. package/dist/index.d.ts +15 -3
  230. package/dist/index.js +22 -5
  231. package/dist/next/routing/route-map.d.ts +11 -0
  232. package/dist/next/routing/route-map.js +5 -0
  233. package/dist/providers/email-resend/provider.js +1 -0
  234. package/dist/providers/firebase-client/auth.d.ts +1 -0
  235. package/dist/providers/firebase-client/auth.js +7 -1
  236. package/dist/repositories/index.d.ts +1 -0
  237. package/dist/repositories/index.js +1 -0
  238. package/dist/schemas/registry.d.ts +61 -25
  239. package/dist/security/pii-mask.js +1 -1
  240. package/dist/seed/categories-seed-data.js +69 -0
  241. package/dist/seed/products-auctions-seed-data.js +11 -0
  242. package/dist/seed/products-standard-seed-data.js +93 -4
  243. package/dist/seed/site-settings-seed-data.js +13 -1
  244. package/dist/seed/store-extensions-seed-data.js +1 -1
  245. package/dist/server-entry.d.ts +2 -1
  246. package/dist/server-entry.js +20 -2
  247. package/dist/server.d.ts +7 -2
  248. package/dist/server.js +8 -3
  249. package/dist/styles.css +1 -1
  250. package/dist/tailwind-utilities.css +1 -1
  251. package/dist/ui/components/Form.d.ts +11 -2
  252. package/dist/ui/components/Form.js +4 -3
  253. package/dist/ui/components/FormField.d.ts +3 -1
  254. package/dist/ui/components/FormField.js +22 -4
  255. package/dist/ui/components/ListingLayout.d.ts +1 -2
  256. package/dist/ui/components/ListingLayout.js +1 -1
  257. package/dist/ui/components/RecordDetailModal.d.ts +68 -0
  258. package/dist/ui/components/RecordDetailModal.js +8 -0
  259. package/dist/ui/components/SlottedListingView.js +9 -1
  260. package/dist/ui/forms/FormErrorSummary.d.ts +25 -0
  261. package/dist/ui/forms/FormErrorSummary.js +37 -0
  262. package/dist/ui/forms/FormShell.d.ts +37 -2
  263. package/dist/ui/forms/FormShell.js +37 -7
  264. package/dist/ui/forms/FormShell.style.css +17 -0
  265. package/dist/ui/forms/index.d.ts +2 -0
  266. package/dist/ui/forms/index.js +1 -0
  267. package/dist/ui/index.d.ts +4 -0
  268. package/dist/ui/index.js +5 -0
  269. package/dist/utils/media-url.d.ts +3 -1
  270. package/dist/utils/media-url.js +20 -1
  271. package/dist/validation/schemas.d.ts +4 -4
  272. package/package.json +1 -1
  273. package/dist/_internal/client/features/classified/ClassifiedDetailView.d.ts +0 -9
  274. package/dist/_internal/client/features/classified/ClassifiedDetailView.js +0 -55
  275. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.d.ts +0 -18
  276. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +0 -21
  277. package/dist/_internal/client/features/live/LiveItemDetailView.d.ts +0 -9
  278. package/dist/_internal/client/features/live/LiveItemDetailView.js +0 -25
  279. package/dist/_internal/server/jobs/core/prizeRevealClose.d.ts +0 -2
  280. package/dist/_internal/server/jobs/core/prizeRevealClose.js +0 -28
  281. package/dist/_internal/server/jobs/core/prizeRevealExpiry.d.ts +0 -2
  282. package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +0 -61
  283. package/dist/_internal/server/jobs/core/prizeRevealOpen.d.ts +0 -2
  284. package/dist/_internal/server/jobs/core/prizeRevealOpen.js +0 -68
  285. package/dist/_internal/server/jobs/core/prizeRevealReminder.d.ts +0 -2
  286. package/dist/_internal/server/jobs/core/prizeRevealReminder.js +0 -49
  287. package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +0 -2
  288. package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +0 -2
  289. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +0 -2
  290. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +0 -2
  291. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +0 -2
  292. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +0 -2
  293. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +0 -2
  294. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +0 -2
  295. package/dist/features/auth/consent-otp.d.ts +0 -57
  296. package/dist/features/auth/consent-otp.js +0 -127
  297. package/dist/features/cart/components/CheckoutOtpModal.d.ts +0 -15
  298. package/dist/features/cart/components/CheckoutOtpModal.js +0 -12
  299. package/dist/features/checkout/actions/checkout-actions.d.ts +0 -31
  300. package/dist/features/checkout/actions/checkout-actions.js +0 -124
  301. package/dist/features/classified/components/ClassifiedIndexListing.d.ts +0 -5
  302. package/dist/features/classified/components/ClassifiedIndexListing.js +0 -123
  303. package/dist/features/classified/components/ClassifiedListView.d.ts +0 -6
  304. package/dist/features/classified/components/ClassifiedListView.js +0 -44
  305. package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +0 -5
  306. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +0 -114
  307. package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +0 -6
  308. package/dist/features/digital-codes/components/DigitalCodesListView.js +0 -38
  309. package/dist/features/live/components/LiveItemsIndexListing.d.ts +0 -5
  310. package/dist/features/live/components/LiveItemsIndexListing.js +0 -115
  311. package/dist/features/live/components/LiveItemsListView.d.ts +0 -6
  312. package/dist/features/live/components/LiveItemsListView.js +0 -44
  313. package/dist/features/seller/components/SellerTemplatesView.d.ts +0 -12
  314. package/dist/features/seller/components/SellerTemplatesView.js +0 -276
  315. package/dist/react/hooks/useVisibleItems.d.ts +0 -37
  316. package/dist/react/hooks/useVisibleItems.js +0 -59
  317. package/dist/ui/components/TabStrip.d.ts +0 -34
  318. package/dist/ui/components/TabStrip.js +0 -56
  319. package/dist/ui/components/TabStrip.style.css +0 -97
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { useCallback, useContext, useEffect, useMemo, useState } from "react";
4
4
  import { Check } from "lucide-react";
5
5
  import { Button } from "../../ui/components/Button";
6
6
  import { classNames } from "../../ui/style.helper";
7
7
  import { Div, Nav, Row, Span, Stack, Text, useToast } from "../../ui";
8
8
  import { normalizeError } from "../../errors/normalize";
9
+ import { FormSchemaContext } from "./FormShell";
9
10
  /** Standalone step nav bar — use as `renderBottomBar` in FormShell. */
10
11
  export function StepFormActions({ currentStep, totalSteps, onNext, onPrev, completeLabel = "Publish Now", isLoading = false, disabled = false, }) {
11
12
  const isFirst = currentStep === 0;
@@ -34,10 +35,52 @@ export function StepIndicator({ steps, currentStep, onStepClick, stepErrors, })
34
35
  : "bg-[var(--appkit-color-border)]") }))] }, i));
35
36
  }) }));
36
37
  }
37
- export function StepForm({ steps, values, onChange, onComplete, completeLabel = "Publish Now", isLoading = false, formId, currentStep, onStepChange, hideActions = false, stepErrors, }) {
38
+ export function StepForm({ steps, values, onChange, onComplete, completeLabel = "Publish Now", isLoading = false, formId, currentStep, onStepChange, hideActions = false, stepErrors, schema, onValidationChange, }) {
38
39
  const { showToast } = useToast();
39
- const [fieldErrors, _setFieldErrors] = useState({});
40
+ const inheritedSchema = useContext(FormSchemaContext);
41
+ const [fieldErrors, setFieldErrors] = useState({});
40
42
  const [stepError, setStepError] = useState(null);
43
+ const fieldToStepIndex = useMemo(() => {
44
+ const map = {};
45
+ steps.forEach((step, i) => {
46
+ step.fields?.forEach((field) => { map[field] = i; });
47
+ });
48
+ return map;
49
+ }, [steps]);
50
+ const runValidation = useCallback((nextValues) => {
51
+ const activeSchema = steps[currentStep]?.schema ?? schema ?? inheritedSchema;
52
+ if (!activeSchema)
53
+ return;
54
+ // audit-unvalidated-safeparse-ok: bulk-replaces fieldErrors from the full
55
+ // parse result (clears fields that just became valid); applyZodIssues'
56
+ // incremental setFieldError-per-issue can't do that.
57
+ const parsed = activeSchema.safeParse(nextValues);
58
+ if (parsed.success) {
59
+ setFieldErrors({});
60
+ onValidationChange?.({}, fieldToStepIndex);
61
+ return;
62
+ }
63
+ const next = {};
64
+ for (const issue of parsed.error.issues) {
65
+ if (!issue.path || issue.path.length === 0)
66
+ continue;
67
+ next[issue.path.map(String).join(".")] = issue.message;
68
+ }
69
+ setFieldErrors(next);
70
+ onValidationChange?.(next, fieldToStepIndex);
71
+ }, [steps, currentStep, schema, inheritedSchema, fieldToStepIndex, onValidationChange]);
72
+ // Re-run validation whenever the active step or schema changes, so
73
+ // switching steps (or arriving with pre-filled values) shows accurate
74
+ // live errors immediately rather than only after the next keystroke.
75
+ useEffect(() => {
76
+ runValidation(values);
77
+ // eslint-disable-next-line react-hooks/exhaustive-deps
78
+ }, [currentStep, steps[currentStep]?.schema, schema, inheritedSchema]);
79
+ const handleFieldChange = useCallback((partial) => {
80
+ const merged = { ...values, ...partial };
81
+ onChange(partial);
82
+ runValidation(merged);
83
+ }, [values, onChange, runValidation]);
41
84
  // Persist step to localStorage if formId provided
42
85
  useEffect(() => {
43
86
  if (formId)
@@ -89,5 +132,5 @@ export function StepForm({ steps, values, onChange, onComplete, completeLabel =
89
132
  return (_jsxs(Stack, { children: [_jsx(StepIndicator, { steps: steps, currentStep: currentStep, stepErrors: stepErrors, onStepClick: (i) => { if (i !== currentStep) {
90
133
  setStepError(null);
91
134
  onStepChange(i);
92
- } } }), _jsx(Div, { className: "flex-1", children: currentStepDef?.render({ values, onChange, errors: fieldErrors }) }), !hideActions && stepError && (_jsx(Text, { className: "mt-3 text-[var(--appkit-color-error)]", size: "sm", children: stepError })), !hideActions && (_jsx(StepFormActions, { currentStep: currentStep, totalSteps: steps.length, onNext: () => void goNext(), onPrev: currentStep > 0 ? goPrev : undefined, completeLabel: completeLabel, isLoading: isLoading && isLast, disabled: isLoading }))] }));
135
+ } } }), _jsx(Div, { className: "flex-1", children: currentStepDef?.render({ values, onChange: handleFieldChange, errors: fieldErrors }) }), !hideActions && stepError && (_jsx(Text, { className: "mt-3 text-[var(--appkit-color-error)]", size: "sm", children: stepError })), !hideActions && (_jsx(StepFormActions, { currentStep: currentStep, totalSteps: steps.length, onNext: () => void goNext(), onPrev: currentStep > 0 ? goPrev : undefined, completeLabel: completeLabel, isLoading: isLoading && isLast, disabled: isLoading }))] }));
93
136
  }
@@ -1,5 +1,5 @@
1
1
  export type { FormShellSection, FormShellProps, UseFormShellResult } from "./FormShell";
2
- export { FormShell, useFormShell } from "./FormShell";
2
+ export { FormShell, useFormShell, FormSchemaContext } from "./FormShell";
3
3
  export type { CommandPaletteGroup, CommandPaletteProps } from "./CommandPalette";
4
4
  export { CommandPalette, useCommandPaletteHotkey } from "./CommandPalette";
5
5
  export type { QuickFieldType, QuickFieldDef, QuickFormDrawerProps } from "./QuickFormDrawer";
@@ -1,4 +1,4 @@
1
- export { FormShell, useFormShell } from "./FormShell";
1
+ export { FormShell, useFormShell, FormSchemaContext } from "./FormShell";
2
2
  export { CommandPalette, useCommandPaletteHotkey } from "./CommandPalette";
3
3
  export { QuickFormDrawer } from "./QuickFormDrawer";
4
4
  export { StepForm, StepFormActions, StepIndicator } from "./StepForm";
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import React from "react";
4
4
  import { useQueryClient } from "@tanstack/react-query";
5
5
  import { useApiMutation } from "@mohasinac/appkit/client";
6
- import { Alert, Button, Div, Form, FieldInput, FieldSelect, FieldTextarea, Grid, Heading, Stack, Table, Thead, Tbody, Tr, Th, Td, Text, TextLink, } from "../../../ui";
6
+ import { Alert, Button, Div, Form, FieldInput, FieldSelect, FieldTextarea, Grid, Heading, Stack, Table, Thead, Tbody, Tr, Th, Td, Text, TextLink, FormErrorSummary, } from "../../../ui";
7
7
  import { apiClient } from "../../../http";
8
8
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
9
9
  import { ROUTES } from "../../../next/routing/route-map";
@@ -77,7 +77,7 @@ export function AdminShipmentEditorView({ shipmentId, onSaved }) {
77
77
  onSaved?.(saved.id);
78
78
  },
79
79
  });
80
- return (_jsx(Form, { schema: createShipmentSchema, spacing: "md", children: ({ setFieldError }) => (_jsxs(_Fragment, { children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(FieldInput, { name: "shipmentNumber", label: "Shipment Number", required: true, value: shipmentNumber, onChange: setShipmentNumber, placeholder: "SH-2026-0001" }), _jsx(FieldInput, { name: "supplierName", label: "Supplier Name", required: true, value: supplierName, onChange: setSupplierName }), _jsx(FieldInput, { name: "originCountry", label: "Origin Country", value: originCountry, onChange: setOriginCountry }), _jsx(FieldSelect, { name: "status", label: "Status", required: true, value: status, onChange: setStatus, options: STATUS_OPTIONS }), _jsx(FieldInput, { name: "trackingNumber", label: "Tracking Number", value: trackingNumber, onChange: setTrackingNumber }), _jsx(FieldInput, { name: "carrier", label: "Carrier", value: carrier, onChange: setCarrier }), _jsx(FieldInput, { name: "etaDate", label: "ETA Date", type: "date", value: etaDate, onChange: setEtaDate }), _jsx(FieldInput, { name: "laborHoursSpent", label: "Labor Hours Spent", type: "number", min: "0", value: laborHoursSpent, onChange: setLaborHoursSpent }), _jsx(FieldInput, { name: "customsTotal", label: "Customs Total (\u20B9)", type: "number", min: "0", value: customsTotalRupees, onChange: setCustomsTotalRupees, hint: "Split across lots by declared value" }), _jsx(FieldInput, { name: "shippingTotal", label: "Shipping Total (\u20B9)", type: "number", min: "0", value: shippingTotalRupees, onChange: setShippingTotalRupees, hint: "Split across lots by weight" })] }), _jsx(FieldTextarea, { name: "notes", label: "Notes", value: notes, onChange: setNotes, rows: 3 }), _jsx(Button, { type: "button", isLoading: saveMutation.isPending, onClick: () => {
80
+ return (_jsx(Form, { schema: createShipmentSchema, spacing: "md", children: ({ setFieldError }) => (_jsxs(_Fragment, { children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(FieldInput, { name: "shipmentNumber", label: "Shipment Number", required: true, value: shipmentNumber, onChange: setShipmentNumber, placeholder: "SH-2026-0001" }), _jsx(FieldInput, { name: "supplierName", label: "Supplier Name", required: true, value: supplierName, onChange: setSupplierName }), _jsx(FieldInput, { name: "originCountry", label: "Origin Country", value: originCountry, onChange: setOriginCountry }), _jsx(FieldSelect, { name: "status", label: "Status", required: true, value: status, onChange: setStatus, options: STATUS_OPTIONS }), _jsx(FieldInput, { name: "trackingNumber", label: "Tracking Number", value: trackingNumber, onChange: setTrackingNumber }), _jsx(FieldInput, { name: "carrier", label: "Carrier", value: carrier, onChange: setCarrier }), _jsx(FieldInput, { name: "etaDate", label: "ETA Date", type: "date", value: etaDate, onChange: setEtaDate }), _jsx(FieldInput, { name: "laborHoursSpent", label: "Labor Hours Spent", type: "number", min: "0", value: laborHoursSpent, onChange: setLaborHoursSpent }), _jsx(FieldInput, { name: "customsTotal", label: "Customs Total (\u20B9)", type: "number", min: "0", value: customsTotalRupees, onChange: setCustomsTotalRupees, hint: "Split across lots by declared value" }), _jsx(FieldInput, { name: "shippingTotal", label: "Shipping Total (\u20B9)", type: "number", min: "0", value: shippingTotalRupees, onChange: setShippingTotalRupees, hint: "Split across lots by weight" })] }), _jsx(FieldTextarea, { name: "notes", label: "Notes", value: notes, onChange: setNotes, rows: 3 }), _jsx(FormErrorSummary, {}), _jsx(Button, { type: "button", isLoading: saveMutation.isPending, onClick: () => {
81
81
  const parsed = createShipmentSchema.safeParse({
82
82
  shipmentNumber,
83
83
  supplierName,
@@ -22,9 +22,9 @@ export declare const createShipmentSchema: z.ZodObject<{
22
22
  shippingTotal: number;
23
23
  notes?: string | undefined;
24
24
  trackingNumber?: string | undefined;
25
+ carrier?: string | undefined;
25
26
  etaDate?: string | Date | undefined;
26
27
  originCountry?: string | undefined;
27
- carrier?: string | undefined;
28
28
  receivedDate?: string | Date | undefined;
29
29
  laborHoursSpent?: number | undefined;
30
30
  laborRatePerHour?: number | undefined;
@@ -36,9 +36,9 @@ export declare const createShipmentSchema: z.ZodObject<{
36
36
  shippingTotal: number;
37
37
  notes?: string | undefined;
38
38
  trackingNumber?: string | undefined;
39
+ carrier?: string | undefined;
39
40
  etaDate?: string | Date | undefined;
40
41
  originCountry?: string | undefined;
41
- carrier?: string | undefined;
42
42
  receivedDate?: string | Date | undefined;
43
43
  laborHoursSpent?: number | undefined;
44
44
  laborRatePerHour?: number | undefined;
@@ -61,11 +61,11 @@ export declare const updateShipmentSchema: z.ZodObject<{
61
61
  status?: "received" | "cancelled" | "processing" | "completed" | "ordered" | "planning" | "in_transit" | "customs" | undefined;
62
62
  notes?: string | undefined;
63
63
  trackingNumber?: string | undefined;
64
+ carrier?: string | undefined;
64
65
  shipmentNumber?: string | undefined;
65
66
  etaDate?: string | Date | undefined;
66
67
  supplierName?: string | undefined;
67
68
  originCountry?: string | undefined;
68
- carrier?: string | undefined;
69
69
  receivedDate?: string | Date | undefined;
70
70
  customsTotal?: number | undefined;
71
71
  shippingTotal?: number | undefined;
@@ -75,11 +75,11 @@ export declare const updateShipmentSchema: z.ZodObject<{
75
75
  status?: "received" | "cancelled" | "processing" | "completed" | "ordered" | "planning" | "in_transit" | "customs" | undefined;
76
76
  notes?: string | undefined;
77
77
  trackingNumber?: string | undefined;
78
+ carrier?: string | undefined;
78
79
  shipmentNumber?: string | undefined;
79
80
  etaDate?: string | Date | undefined;
80
81
  supplierName?: string | undefined;
81
82
  originCountry?: string | undefined;
82
- carrier?: string | undefined;
83
83
  receivedDate?: string | Date | undefined;
84
84
  customsTotal?: number | undefined;
85
85
  shippingTotal?: number | undefined;
@@ -98,6 +98,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
98
98
  thumbnailUrl: z.ZodOptional<z.ZodString>;
99
99
  source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
100
100
  youtubeId: z.ZodOptional<z.ZodString>;
101
+ duration: z.ZodOptional<z.ZodNumber>;
101
102
  }, "strip", z.ZodTypeAny, {
102
103
  type: "video" | "image" | "file";
103
104
  url: string;
@@ -105,6 +106,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
105
106
  alt?: string | undefined;
106
107
  thumbnailUrl?: string | undefined;
107
108
  youtubeId?: string | undefined;
109
+ duration?: number | undefined;
108
110
  }, {
109
111
  type: "video" | "image" | "file";
110
112
  url: string;
@@ -112,6 +114,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
112
114
  alt?: string | undefined;
113
115
  thumbnailUrl?: string | undefined;
114
116
  youtubeId?: string | undefined;
117
+ duration?: number | undefined;
115
118
  }>, "many">>>;
116
119
  remainderItemCount: z.ZodOptional<z.ZodNumber>;
117
120
  remainderEstimatedValue: z.ZodOptional<z.ZodNumber>;
@@ -123,6 +126,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
123
126
  alt?: string | undefined;
124
127
  thumbnailUrl?: string | undefined;
125
128
  youtubeId?: string | undefined;
129
+ duration?: number | undefined;
126
130
  }[];
127
131
  lotName: string;
128
132
  weightGrams: number;
@@ -141,6 +145,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
141
145
  alt?: string | undefined;
142
146
  thumbnailUrl?: string | undefined;
143
147
  youtubeId?: string | undefined;
148
+ duration?: number | undefined;
144
149
  }[] | undefined;
145
150
  supplierOrderRef?: string | undefined;
146
151
  remainderItemCount?: number | undefined;
@@ -158,6 +163,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
158
163
  thumbnailUrl: z.ZodOptional<z.ZodString>;
159
164
  source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
160
165
  youtubeId: z.ZodOptional<z.ZodString>;
166
+ duration: z.ZodOptional<z.ZodNumber>;
161
167
  }, "strip", z.ZodTypeAny, {
162
168
  type: "video" | "image" | "file";
163
169
  url: string;
@@ -165,6 +171,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
165
171
  alt?: string | undefined;
166
172
  thumbnailUrl?: string | undefined;
167
173
  youtubeId?: string | undefined;
174
+ duration?: number | undefined;
168
175
  }, {
169
176
  type: "video" | "image" | "file";
170
177
  url: string;
@@ -172,6 +179,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
172
179
  alt?: string | undefined;
173
180
  thumbnailUrl?: string | undefined;
174
181
  youtubeId?: string | undefined;
182
+ duration?: number | undefined;
175
183
  }>, "many">>>>;
176
184
  remainderItemCount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
177
185
  remainderEstimatedValue: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
@@ -183,6 +191,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
183
191
  alt?: string | undefined;
184
192
  thumbnailUrl?: string | undefined;
185
193
  youtubeId?: string | undefined;
194
+ duration?: number | undefined;
186
195
  }[] | undefined;
187
196
  lotName?: string | undefined;
188
197
  supplierOrderRef?: string | undefined;
@@ -198,6 +207,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
198
207
  alt?: string | undefined;
199
208
  thumbnailUrl?: string | undefined;
200
209
  youtubeId?: string | undefined;
210
+ duration?: number | undefined;
201
211
  }[] | undefined;
202
212
  lotName?: string | undefined;
203
213
  supplierOrderRef?: string | undefined;
@@ -4,8 +4,9 @@ import { useApiMutation } from "../../../client";
4
4
  import { SIEVE_OP, sieveFilter } from "../../../utils/sieve-builder";
5
5
  import { sortBy } from "../../../constants/sort";
6
6
  import { TESTER_CHECKLIST_RESPONSE_FIELDS } from "../schemas/firestore";
7
+ import React from "react";
7
8
  import { useQueryClient } from "@tanstack/react-query";
8
- import { FilterChipGroup, RowActionMenu, Stack, Text } from "../../../ui";
9
+ import { FilterChipGroup, RecordDetailModal, RowActionMenu, Stack, Text } from "../../../ui";
9
10
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
10
11
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
11
12
  import { toRecordArray, toRelativeDate, toStringValue, } from "../../admin/hooks/useAdminListingData";
@@ -39,6 +40,7 @@ const COLUMNS = [
39
40
  ];
40
41
  export function AdminTesterFeedbackListView(_props) {
41
42
  const queryClient = useQueryClient();
43
+ const [selected, setSelected] = React.useState(null);
42
44
  const patchMutation = useApiMutation({
43
45
  mutationFn: async (id) => {
44
46
  await apiClient.patch(ADMIN_ENDPOINTS.TESTER_FEEDBACK_BY_ID(id), {});
@@ -78,6 +80,7 @@ export function AdminTesterFeedbackListView(_props) {
78
80
  status: toStringValue(item.status, "new"),
79
81
  updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
80
82
  screenshotUrl: item.screenshotUrl ? toStringValue(item.screenshotUrl, "") : undefined,
83
+ _raw: item,
81
84
  })),
82
85
  getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
83
86
  buildFilters: (state) => {
@@ -97,7 +100,14 @@ export function AdminTesterFeedbackListView(_props) {
97
100
  { id: "new", label: "New" },
98
101
  { id: "reviewed", label: "Reviewed" },
99
102
  ], value: pendingFilters.status || "", onChange: (v) => setPendingFilters((p) => ({ ...p, status: v })) })] })),
103
+ // "Confirm bug" used to be reachable without ever reading the tester's
104
+ // own comment or opening their screenshot — the row truncates both.
105
+ onRowClick: (row) => setSelected(row),
100
106
  renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
107
+ {
108
+ label: "View details",
109
+ onClick: () => setSelected(row),
110
+ },
101
111
  {
102
112
  label: ACTIONS.ADMIN["mark-feedback-reviewed"].label,
103
113
  disabled: row.status === "reviewed",
@@ -110,5 +120,16 @@ export function AdminTesterFeedbackListView(_props) {
110
120
  },
111
121
  ] })),
112
122
  };
113
- return _jsx(DataListingView, { config: config });
123
+ const raw = selected?._raw ?? {};
124
+ return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(RecordDetailModal, { isOpen: Boolean(selected), onClose: () => setSelected(null), title: selected?.primary ?? "Tester Feedback", badges: [
125
+ { label: selected?.answer === "no" ? "Reported a problem" : "Passed", variant: selected?.answer === "no" ? "danger" : "success" },
126
+ { label: selected?.status ?? "new", variant: "default" },
127
+ ], description: toStringValue(raw.comment, "") || undefined, fields: [
128
+ { label: "Checklist item", value: toStringValue(raw.checklistItemId, "—") },
129
+ { label: "Phase", value: toStringValue(raw.phase, "—") },
130
+ { label: "Group / page", value: `${toStringValue(raw.groupKey, "—")} / ${toStringValue(raw.pageKey, "—")}` },
131
+ { label: "Answered", value: selected?.updatedAt ?? "—" },
132
+ ], items: selected?.screenshotUrl
133
+ ? { heading: "Screenshot", entries: [{ image: selected.screenshotUrl, title: "Tester screenshot" }] }
134
+ : undefined })] }));
114
135
  }
@@ -25,5 +25,5 @@ export function TesterChecklistStepRow({ item, testerDisplayName, onAnswer, onSa
25
25
  setSaving(false);
26
26
  }
27
27
  };
28
- return (_jsxs(Stack, { gap: "xs", padding: "sm", border: "default", rounded: "md", children: [_jsxs(Row, { gap: "sm", justify: "between", align: "center", wrap: true, children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { weight: "medium", children: item.label }), item.description && (_jsx(Text, { size: "xs", color: "muted", children: item.description })), item.href && (_jsx(Anchor, { href: item.href, tone: "brand", underline: "hover", children: "Go test this \u2192" }))] }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { type: "button", size: "sm", variant: item.answer === "yes" ? "primary" : "outline", onClick: () => onAnswer(item.checklistItemId, "yes"), children: "Yes" }), _jsx(Button, { type: "button", size: "sm", variant: item.answer === "no" ? "danger" : "outline", onClick: () => onAnswer(item.checklistItemId, "no"), children: "No" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setExpanded((v) => !v), children: expanded ? "Hide note" : "Add note" })] })] }), expanded && (_jsx(Div, { padding: "t-sm", border: "default", className: "border-t", children: _jsxs(Stack, { gap: "sm", children: [_jsx(FieldTextarea, { name: `comment-${item.checklistItemId}`, label: "Comment", value: comment, onChange: setComment, placeholder: "What did you notice? Colors, styles, readability, bugs..." }), _jsx(MediaUploadField, { label: "Screenshot (optional)", value: screenshotUrl, onChange: setScreenshotUrl, onUpload: handleUpload, kind: "image" }), _jsx(Row, { children: _jsx(Button, { type: "button", action: ACTIONS.TESTER["save-note"], isLoading: saving, onClick: handleSave }) })] }) }))] }));
28
+ return (_jsxs(Stack, { gap: "xs", padding: "sm", border: "default", rounded: "md", children: [_jsxs(Row, { gap: "sm", justify: "between", align: "center", wrap: true, children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { weight: "medium", children: item.label }), item.description && (_jsx(Text, { size: "xs", color: "muted", children: item.description })), item.href && (_jsx(Anchor, { href: item.href, tone: "brand", underline: "hover", target: "_blank", rel: "noopener noreferrer", children: "Go test this \u2192" }))] }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { type: "button", size: "sm", variant: item.answer === "yes" ? "primary" : "outline", onClick: () => onAnswer(item.checklistItemId, "yes"), children: "Yes" }), _jsx(Button, { type: "button", size: "sm", variant: item.answer === "no" ? "danger" : "outline", onClick: () => onAnswer(item.checklistItemId, "no"), children: "No" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setExpanded((v) => !v), children: expanded ? "Hide note" : "Add note" })] })] }), expanded && (_jsx(Div, { padding: "t-sm", border: "default", className: "border-t", children: _jsxs(Stack, { gap: "sm", children: [_jsx(FieldTextarea, { name: `comment-${item.checklistItemId}`, label: "Comment", value: comment, onChange: setComment, placeholder: "What did you notice? Colors, styles, readability, bugs..." }), _jsx(MediaUploadField, { label: "Screenshot (optional)", value: screenshotUrl, onChange: setScreenshotUrl, onUpload: handleUpload, kind: "image" }), _jsx(Row, { children: _jsx(Button, { type: "button", action: ACTIONS.TESTER["save-note"], isLoading: saving, onClick: handleSave }) })] }) }))] }));
29
29
  }
@@ -2,11 +2,12 @@
2
2
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
4
  import { useQuery, useQueryClient } from "@tanstack/react-query";
5
- import { Alert, Details, Div, FieldInput, Heading, Stack, Summary, Text } from "../../../ui";
5
+ import { Alert, Details, Div, FieldInput, Heading, Stack, Summary, Text, TextLink } from "../../../ui";
6
6
  import { apiClient } from "../../../http";
7
7
  import { useApiMutation } from "../../../client";
8
8
  import { useSession } from "../../../react";
9
9
  import { ACCOUNT_ENDPOINTS } from "../../../constants/api-endpoints";
10
+ import { ROUTES } from "../../../next/routing/route-map";
10
11
  import { TesterChecklistStepRow } from "./TesterChecklistStepRow";
11
12
  function matchesQuery(item, query) {
12
13
  if (!query)
@@ -88,7 +89,7 @@ export function TesterHubView({ sandboxExpiresAt }) {
88
89
  const handleSaveNote = async (checklistItemId, comment, screenshotUrl) => {
89
90
  await upsertMutation.mutateAsync({ checklistItemId, patch: { comment, screenshotUrl } });
90
91
  };
91
- return (_jsxs(Stack, { gap: "lg", children: [_jsx(Heading, { level: 1, children: "Tester Hub" }), _jsx(Text, { color: "muted", children: "Work through the checklist below and answer Yes/No for each test case. Add a comment and screenshot wherever something looks off \u2014 colors, styles, readability, bugs. Your answers save automatically." }), sandboxExpiresAt && (_jsxs(Alert, { variant: "info", title: "Shared test sandbox", children: ["The shared test store/products/categories expire on ", new Date(sandboxExpiresAt).toLocaleDateString(), "."] })), _jsx(FieldInput, { name: "checklist-search", label: "Search test cases", value: search, onChange: setSearch, placeholder: "Search by title or route, e.g. checkout, /store/payouts..." }), sortedPhaseNumbers.map((phaseNumber) => {
92
+ return (_jsxs(Stack, { gap: "lg", children: [_jsx(Heading, { level: 1, children: "Tester Hub" }), _jsx(Text, { color: "muted", children: "Work through the checklist below and answer Yes/No for each test case. Add a comment and screenshot wherever something looks off \u2014 colors, styles, readability, bugs. Your answers save automatically." }), _jsx(TextLink, { href: String(ROUTES.PUBLIC.BUG_HUNTERS), variant: "underline", weight: "medium", children: "View Bug Hunters Leaderboard \u2192" }), sandboxExpiresAt && (_jsxs(Alert, { variant: "info", title: "Shared test sandbox", children: ["The shared test store/products/categories expire on ", new Date(sandboxExpiresAt).toLocaleDateString(), "."] })), _jsx(FieldInput, { name: "checklist-search", label: "Search test cases", value: search, onChange: setSearch, placeholder: "Search by title or route, e.g. checkout, /store/payouts..." }), sortedPhaseNumbers.map((phaseNumber) => {
92
93
  const groups = phases.get(phaseNumber);
93
94
  const phaseItemCount = Array.from(groups.values())
94
95
  .flatMap((g) => Array.from(g.pages.values()))
@@ -82,7 +82,15 @@ const _rawOrdersTesterSeedData = [
82
82
  key: "shipped",
83
83
  status: "shipped",
84
84
  paymentStatus: "paid",
85
- extra: { trackingNumber: "TEST-TRACK-001", shippingCarrier: "Test Carrier", shippingDate: daysAgo(1) },
85
+ extra: {
86
+ trackingNumber: "TEST-TRACK-001",
87
+ shippingCarrier: "Test Carrier",
88
+ shippingDate: daysAgo(1),
89
+ // Real-looking passthrough URL — exercises the "opens in new tab"
90
+ // tracking-link case on /user/orders/[id]/track (no live courier
91
+ // API integration; this is exactly what a seller/admin would type in).
92
+ trackingUrl: "https://www.example.com/track/TEST-TRACK-001",
93
+ },
86
94
  }),
87
95
  standardOrder({
88
96
  key: "delivered",
@@ -5,9 +5,12 @@
5
5
  * pre-ordering against real code paths — including navigating every entry of the store
6
6
  * detail page's listing-type dropdown (see StoreNavTabs). Auto-expires after 7 days
7
7
  * (testerSandboxCleanup cascades into any bids on the auction).
8
- * WHAT: Exports productsTesterSeedData — 2 standard + 2 auction + 1 pre-order + 1 prize-draw +
8
+ * WHAT: Exports productsTesterSeedData — 2 standard + 4 auction (3 staggered 1h/2h/3h "still
9
+ * open" cycling fixtures + 1 already-ended "won" fixture) + 1 pre-order + 1 prize-draw +
9
10
  * 1 classified + 1 digital-code + 1 live + 1 art + 1 stickers product + 1 product-group
10
11
  * ("Set") parent (product-tester-standard-1/2 are its children, linked via groupId).
12
+ * The 3 staggered auction ids/end-dates are recomputed on every seed run (including the
13
+ * testerSandboxRefresh job, every 4h) so testers can watch one actually end mid-session.
11
14
  *
12
15
  * EXPORTS:
13
16
  * productsTesterSeedData — Array of Partial<ProductDocument> for the seed runner
@@ -42,7 +45,46 @@ function withTokens(p) {
42
45
  searchTokens: buildSearchTokens(p.title, p.description, p.brand, p.brandSlug, p.categoryNames, p.tags),
43
46
  };
44
47
  }
48
+ // Staggered, incrementing-id auction fixtures so testers can watch a live
49
+ // auction actually cross its end time within a single sandbox refresh cycle
50
+ // (testerSandboxRefresh re-imports this module every 4 hours, recomputing
51
+ // these Date.now()-relative offsets fresh each time) instead of the old
52
+ // single fixture that always sat 5 days out. A loop (not hand-typed ids)
53
+ // avoids id collisions if the stagger list is ever extended.
54
+ const AUCTION_CYCLE_STAGGER_HOURS = [1, 2, 3];
55
+ const stagedAuctions = AUCTION_CYCLE_STAGGER_HOURS.map((hours, i) => withTokens({
56
+ id: `auction-tester-sandbox-cycle-${i + 1}`,
57
+ slug: `auction-tester-sandbox-cycle-${i + 1}`,
58
+ title: `Test Auction — Ends in ~${hours}h`,
59
+ description: `Disposable test auction for the tester QA program, staggered to end roughly ${hours} hour(s) after the last sandbox refresh so testers can watch the end-of-auction flow live. Place a bid — it auto-expires in 7 days, cascading to any bids.`,
60
+ categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
61
+ categoryNames: COLLECTIBLES_CATEGORY_NAMES,
62
+ brandSlug: "brand-tester-sandbox",
63
+ brand: "TestBrand",
64
+ startingBid: 15000,
65
+ currentBid: 15000,
66
+ currency: "INR",
67
+ price: 150,
68
+ stockQuantity: 1,
69
+ availableQuantity: 1,
70
+ auctionEndDate: new Date(Date.now() + hours * 60 * 60 * 1000),
71
+ bidCount: 0,
72
+ bidsHaveStarted: false,
73
+ isSold: false,
74
+ mainImage: seedExtMedia(`https://picsum.photos/seed/auction-image-tester-sandbox-cycle-${i + 1}-20260101/900/900`),
75
+ images: [seedExtMedia(`https://picsum.photos/seed/auction-image-tester-sandbox-cycle-${i + 1}-20260101/900/900`)],
76
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
77
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
78
+ listingType: "auction",
79
+ customFields: [],
80
+ customSections: [],
81
+ isPromoted: false,
82
+ isOnSale: false,
83
+ createdAt: new Date(),
84
+ updatedAt: new Date(),
85
+ }));
45
86
  export const productsTesterSeedData = [
87
+ ...stagedAuctions,
46
88
  withTokens({
47
89
  id: "product-tester-standard-1",
48
90
  slug: "product-tester-standard-1",
@@ -131,37 +173,6 @@ export const productsTesterSeedData = [
131
173
  createdAt: new Date(),
132
174
  updatedAt: new Date(),
133
175
  }),
134
- withTokens({
135
- id: "auction-tester-sandbox-1",
136
- slug: "auction-tester-sandbox-1",
137
- title: "Test Auction — Bid Me!",
138
- description: "Disposable test auction for the tester QA program. Place a bid — it auto-expires in 7 days, cascading to any bids.",
139
- categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
140
- categoryNames: COLLECTIBLES_CATEGORY_NAMES,
141
- brandSlug: "brand-tester-sandbox",
142
- brand: "TestBrand",
143
- startingBid: 15000,
144
- currentBid: 15000,
145
- currency: "INR",
146
- price: 150,
147
- stockQuantity: 1,
148
- availableQuantity: 1,
149
- auctionEndDate: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000),
150
- bidCount: 0,
151
- bidsHaveStarted: false,
152
- isSold: false,
153
- mainImage: seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-1-20260101/900/900"),
154
- images: [seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-1-20260101/900/900")],
155
- status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
156
- condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
157
- listingType: "auction",
158
- customFields: [],
159
- customSections: [],
160
- isPromoted: false,
161
- isOnSale: false,
162
- createdAt: new Date(),
163
- updatedAt: new Date(),
164
- }),
165
176
  withTokens({
166
177
  id: "auction-tester-sandbox-won",
167
178
  slug: "auction-tester-sandbox-won",