@mohasinac/appkit 4.30.19 → 4.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/dist/_internal/client/features/layout/useSidebarSearch.d.ts +21 -5
  2. package/dist/_internal/client/features/layout/useSidebarSearch.js +27 -6
  3. package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +23 -3
  4. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +106 -87
  5. package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +16 -5
  6. package/dist/_internal/client/features/lottery/LotteryPullForm.js +65 -40
  7. package/dist/_internal/server/features/auth/permissions.d.ts +2 -0
  8. package/dist/_internal/server/features/auth/permissions.js +3 -2
  9. package/dist/_internal/server/features/categories/data.js +15 -4
  10. package/dist/_internal/server/features/classified/index.d.ts +0 -1
  11. package/dist/_internal/server/features/classified/index.js +0 -1
  12. package/dist/_internal/server/features/digital-code/index.d.ts +0 -1
  13. package/dist/_internal/server/features/digital-code/index.js +0 -1
  14. package/dist/_internal/server/features/live/index.d.ts +0 -1
  15. package/dist/_internal/server/features/live/index.js +0 -1
  16. package/dist/_internal/server/features/products/data.js +15 -5
  17. package/dist/_internal/server/features/products/list-public.d.ts +9 -0
  18. package/dist/_internal/server/features/products/list-public.js +95 -7
  19. package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
  20. package/dist/_internal/server/features/site-settings/adapters.js +8 -5
  21. package/dist/_internal/server/features/tester/visibility.d.ts +2 -1
  22. package/dist/_internal/server/features/tester/visibility.js +2 -2
  23. package/dist/_internal/server/functions/scheduled.d.ts +3 -1
  24. package/dist/_internal/server/functions/scheduled.js +27 -1
  25. package/dist/_internal/server/jobs/core/hardBanCascade.js +4 -0
  26. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  27. package/dist/_internal/server/jobs/core/index.js +2 -0
  28. package/dist/_internal/server/jobs/core/pageViewPrune.d.ts +10 -0
  29. package/dist/_internal/server/jobs/core/pageViewPrune.js +44 -0
  30. package/dist/_internal/server/jobs/core/pageViewRollup.d.ts +2 -0
  31. package/dist/_internal/server/jobs/core/pageViewRollup.js +87 -0
  32. package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
  33. package/dist/_internal/server/jobs/handlers/index.js +2 -0
  34. package/dist/_internal/server/jobs/handlers/pageViewPrune.d.ts +2 -0
  35. package/dist/_internal/server/jobs/handlers/pageViewPrune.js +2 -0
  36. package/dist/_internal/server/jobs/handlers/pageViewRollup.d.ts +2 -0
  37. package/dist/_internal/server/jobs/handlers/pageViewRollup.js +2 -0
  38. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  39. package/dist/_internal/shared/actions/action-registry.js +69 -22
  40. package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -4
  41. package/dist/_internal/shared/checkout/rules/classified.rule.js +7 -2
  42. package/dist/_internal/shared/features/layout/matchesNavQuery.d.ts +14 -0
  43. package/dist/_internal/shared/features/layout/matchesNavQuery.js +72 -0
  44. package/dist/_internal/shared/features/layout/types.d.ts +37 -1
  45. package/dist/_internal/shared/features/layout/types.js +19 -1
  46. package/dist/_internal/shared/features/notifications/action-url.d.ts +9 -1
  47. package/dist/_internal/shared/features/notifications/action-url.js +47 -0
  48. package/dist/_internal/shared/features/offers/config.d.ts +65 -0
  49. package/dist/_internal/shared/features/offers/config.js +73 -2
  50. package/dist/_internal/shared/features/orders/schema.d.ts +19 -1
  51. package/dist/_internal/shared/features/orders/schema.js +22 -2
  52. package/dist/_internal/shared/features/site-settings/types.d.ts +12 -3
  53. package/dist/_internal/shared/listing-types/capabilities.d.ts +8 -2
  54. package/dist/_internal/shared/listing-types/capabilities.js +6 -1
  55. package/dist/_internal/shared/listing-types/classified/ctas.js +6 -1
  56. package/dist/_internal/shared/listing-types/feature-flags.d.ts +10 -5
  57. package/dist/_internal/shared/listing-types/feature-flags.js +11 -6
  58. package/dist/client.d.ts +37 -20
  59. package/dist/client.js +36 -14
  60. package/dist/configs/next.js +10 -2
  61. package/dist/constants/api-endpoints.d.ts +18 -54
  62. package/dist/constants/api-endpoints.js +6 -26
  63. package/dist/constants/field-names.d.ts +6 -24
  64. package/dist/constants/field-names.js +10 -27
  65. package/dist/constants/geo/countries.d.ts +50 -0
  66. package/dist/constants/geo/countries.js +129 -0
  67. package/dist/constants/geo/subdivisions.d.ts +13 -0
  68. package/dist/constants/geo/subdivisions.js +104 -0
  69. package/dist/constants/index.d.ts +2 -2
  70. package/dist/constants/index.js +2 -2
  71. package/dist/constants/table-keys.d.ts +24 -0
  72. package/dist/constants/table-keys.js +28 -0
  73. package/dist/contracts/extend.d.ts +0 -9
  74. package/dist/contracts/index.d.ts +1 -1
  75. package/dist/contracts/realtime-session.js +7 -0
  76. package/dist/core/browser.d.ts +1 -1
  77. package/dist/core/browser.js +1 -1
  78. package/dist/core/index.d.ts +1 -1
  79. package/dist/core/index.js +1 -1
  80. package/dist/core/site-config.d.ts +0 -3
  81. package/dist/core/site-config.js +0 -3
  82. package/dist/errors/messages.d.ts +0 -8
  83. package/dist/errors/messages.js +0 -9
  84. package/dist/features/about/schemas/index.d.ts +8 -8
  85. package/dist/features/account/components/AddressFilters.js +32 -11
  86. package/dist/features/account/components/AddressForm.d.ts +26 -25
  87. package/dist/features/account/components/AddressForm.js +81 -103
  88. package/dist/features/account/components/AddressesIndexListing.js +8 -4
  89. package/dist/features/account/components/UserSidebar.d.ts +3 -4
  90. package/dist/features/account/components/UserSupportView.js +89 -58
  91. package/dist/features/account/components/index.d.ts +1 -7
  92. package/dist/features/account/components/index.js +0 -3
  93. package/dist/features/account/hooks/useAddresses.d.ts +4 -3
  94. package/dist/features/account/hooks/useAddresses.js +4 -6
  95. package/dist/features/account/hooks/useCollapsedSections.d.ts +51 -10
  96. package/dist/features/account/hooks/useCollapsedSections.js +211 -38
  97. package/dist/features/account/hooks/useProfile.d.ts +8 -0
  98. package/dist/features/account/index.d.ts +0 -3
  99. package/dist/features/account/index.js +0 -3
  100. package/dist/features/account/schemas/index.d.ts +0 -92
  101. package/dist/features/account/schemas/index.js +42 -20
  102. package/dist/features/addresses/components/AddressLocationFields.d.ts +13 -0
  103. package/dist/features/addresses/components/AddressLocationFields.js +41 -0
  104. package/dist/features/addresses/hooks/usePostalLookup.d.ts +17 -0
  105. package/dist/features/addresses/hooks/usePostalLookup.js +133 -0
  106. package/dist/features/addresses/schemas/address-form.d.ts +423 -0
  107. package/dist/features/addresses/schemas/address-form.js +212 -0
  108. package/dist/features/addresses/schemas/index.d.ts +1 -0
  109. package/dist/features/addresses/schemas/index.js +8 -0
  110. package/dist/features/admin/actions/admin-read-actions.d.ts +1 -1
  111. package/dist/features/admin/actions/index.d.ts +0 -1
  112. package/dist/features/admin/actions/index.js +0 -1
  113. package/dist/features/admin/actions/notification-actions.js +1 -41
  114. package/dist/features/admin/components/AdminActionIndexView.d.ts +32 -0
  115. package/dist/features/admin/components/AdminActionIndexView.js +128 -0
  116. package/dist/features/admin/components/AdminAdEditorView.js +159 -163
  117. package/dist/features/admin/components/AdminAddressEditorView.js +97 -55
  118. package/dist/features/admin/components/AdminBrandEditorView.d.ts +15 -0
  119. package/dist/features/admin/components/AdminBrandEditorView.js +113 -77
  120. package/dist/features/admin/components/AdminBundleEditorView.d.ts +19 -9
  121. package/dist/features/admin/components/AdminBundleEditorView.js +136 -168
  122. package/dist/features/admin/components/AdminCategoryEditorView.js +120 -43
  123. package/dist/features/admin/components/AdminCouponEditorView.js +145 -109
  124. package/dist/features/admin/components/AdminEmployeeEditorView.js +125 -56
  125. package/dist/features/admin/components/AdminFaqEditorView.js +112 -58
  126. package/dist/features/admin/components/AdminFeatureEditorView.js +108 -68
  127. package/dist/features/admin/components/AdminNavEditorView.js +69 -44
  128. package/dist/features/admin/components/AdminOrderEditorView.js +47 -10
  129. package/dist/features/admin/components/AdminPrizeDrawsView.js +16 -2
  130. package/dist/features/admin/components/AdminSidebar.d.ts +11 -7
  131. package/dist/features/admin/components/AdminSiteSettingsView.js +37 -37
  132. package/dist/features/admin/components/AdminStoreEditorView.js +75 -52
  133. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +71 -30
  134. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +95 -65
  135. package/dist/features/admin/components/BrandQuickCreateForm.d.ts +10 -0
  136. package/dist/features/admin/components/BrandQuickCreateForm.js +49 -26
  137. package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +11 -0
  138. package/dist/features/admin/components/CategoryQuickCreateForm.js +48 -26
  139. package/dist/features/admin/components/index.d.ts +2 -2
  140. package/dist/features/admin/components/index.js +1 -1
  141. package/dist/features/admin/constants/site-settings-tabs.d.ts +120 -0
  142. package/dist/features/admin/constants/site-settings-tabs.js +152 -0
  143. package/dist/features/admin/index.d.ts +0 -3
  144. package/dist/features/admin/index.js +0 -2
  145. package/dist/features/admin/repository/analytics-rollup.repository.d.ts +35 -0
  146. package/dist/features/admin/repository/analytics-rollup.repository.js +30 -0
  147. package/dist/features/admin/schemas/admin-editor-forms.d.ts +56 -57
  148. package/dist/features/admin/schemas/admin-editor-forms.js +97 -54
  149. package/dist/features/admin/schemas/admin-ops-forms.d.ts +57 -5
  150. package/dist/features/admin/schemas/admin-ops-forms.js +104 -20
  151. package/dist/features/admin/schemas/admin-user-form.js +7 -0
  152. package/dist/features/admin/schemas/firestore.d.ts +48 -95
  153. package/dist/features/admin/schemas/firestore.js +15 -151
  154. package/dist/features/admin/schemas/nav-item-form.js +9 -2
  155. package/dist/features/admin/server.d.ts +0 -4
  156. package/dist/features/admin/server.js +0 -2
  157. package/dist/features/admin/types/index.d.ts +0 -7
  158. package/dist/features/analytics/repository/page-views.repository.d.ts +14 -0
  159. package/dist/features/analytics/repository/page-views.repository.js +24 -0
  160. package/dist/features/auth/actions/index.d.ts +0 -1
  161. package/dist/features/auth/actions/index.js +0 -1
  162. package/dist/features/auth/actions/realtime-token-actions.js +1 -12
  163. package/dist/features/auth/auth-helpers.js +5 -7
  164. package/dist/features/auth/components/Guards.js +2 -1
  165. package/dist/features/auth/components/LoginForm.d.ts +0 -2
  166. package/dist/features/auth/components/LoginForm.js +1 -3
  167. package/dist/features/auth/components/RegisterForm.js +62 -19
  168. package/dist/features/auth/permissions/constants.d.ts +27 -1
  169. package/dist/features/auth/role-predicates.d.ts +75 -7
  170. package/dist/features/auth/role-predicates.js +28 -2
  171. package/dist/features/auth/schemas/firestore.d.ts +22 -0
  172. package/dist/features/auth/schemas/index.d.ts +1 -1
  173. package/dist/features/auth/schemas/index.js +44 -8
  174. package/dist/features/auth/types/index.d.ts +14 -1
  175. package/dist/features/blog/api/route.js +10 -2
  176. package/dist/features/blog/components/BlogIndexListing.js +1 -1
  177. package/dist/features/blog/hooks/useBlog.js +2 -2
  178. package/dist/features/blog/schemas/index.d.ts +4 -0
  179. package/dist/features/blog/schemas/index.js +2 -0
  180. package/dist/features/blog/types/index.d.ts +1 -1
  181. package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +22 -0
  182. package/dist/features/catalogue/components/CatalogueItemEditorView.js +112 -52
  183. package/dist/features/catalogue/schemas/validation.d.ts +4 -4
  184. package/dist/features/catalogue/schemas/validation.js +47 -10
  185. package/dist/features/categories/schemas/bundle-form.d.ts +142 -0
  186. package/dist/features/categories/schemas/bundle-form.js +149 -0
  187. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +5 -4
  188. package/dist/features/classified/components/ClassifiedDetailPageView.js +37 -16
  189. package/dist/features/consultation/components/ConsultationForm.js +1 -1
  190. package/dist/features/consultation/schemas/index.js +34 -10
  191. package/dist/features/corporate/schemas/index.js +36 -15
  192. package/dist/features/filters/FilterPanel.js +3 -3
  193. package/dist/features/filters/RangeFilter.d.ts +10 -0
  194. package/dist/features/filters/RangeFilter.js +41 -4
  195. package/dist/features/homepage/components/MarketplaceHomepageView.js +24 -5
  196. package/dist/features/homepage/hooks/useBlogArticles.js +1 -1
  197. package/dist/features/layout/BottomActions.js +84 -11
  198. package/dist/features/layout/BottomActionsContext.d.ts +1 -6
  199. package/dist/features/layout/BottomActionsContext.js +1 -1
  200. package/dist/features/layout/hooks/useBottomActions.js +2 -2
  201. package/dist/features/layout/hooks/useFormBottomActions.d.ts +12 -1
  202. package/dist/features/layout/hooks/useFormBottomActions.js +12 -6
  203. package/dist/features/lottery/schemas/config-write.d.ts +9 -5
  204. package/dist/features/lottery/schemas/config-write.js +69 -9
  205. package/dist/features/orders/schemas/buyer-forms.d.ts +6 -3
  206. package/dist/features/orders/schemas/buyer-forms.js +31 -3
  207. package/dist/features/orders/schemas/index.d.ts +2 -2
  208. package/dist/features/products/components/GroupSettingsPanel.js +3 -1
  209. package/dist/features/products/components/MakeOfferButton.d.ts +13 -2
  210. package/dist/features/products/components/MakeOfferButton.js +33 -11
  211. package/dist/features/products/components/ProductDetailActions.js +0 -1
  212. package/dist/features/products/components/ProductDetailPageView.d.ts +7 -3
  213. package/dist/features/products/components/ProductDetailPageView.js +8 -5
  214. package/dist/features/products/constants/action-defs.d.ts +1 -2
  215. package/dist/features/products/constants/action-defs.js +40 -43
  216. package/dist/features/products/repository/products.repository.d.ts +5 -1
  217. package/dist/features/products/repository/products.repository.js +23 -1
  218. package/dist/features/products/schemas/firestore.d.ts +7 -3
  219. package/dist/features/products/schemas/product-features.validators.js +3 -0
  220. package/dist/features/promotions/components/CouponCard.js +8 -7
  221. package/dist/features/scams/schemas/firestore.d.ts +15 -1
  222. package/dist/features/scams/schemas/report-form.d.ts +5 -5
  223. package/dist/features/scams/schemas/report-form.js +18 -3
  224. package/dist/features/search/action-index/derive.d.ts +49 -0
  225. package/dist/features/search/action-index/derive.js +121 -0
  226. package/dist/features/search/action-index/repository.d.ts +42 -0
  227. package/dist/features/search/action-index/repository.js +100 -0
  228. package/dist/features/search/action-index/settings-entries.d.ts +41 -0
  229. package/dist/features/search/action-index/settings-entries.js +268 -0
  230. package/dist/features/search/action-index/types.d.ts +81 -0
  231. package/dist/features/search/action-index/types.js +102 -0
  232. package/dist/features/search/action-index/validate-entry.d.ts +34 -0
  233. package/dist/features/search/action-index/validate-entry.js +114 -0
  234. package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
  235. package/dist/features/search/hooks/useNavSuggestions.js +23 -3
  236. package/dist/features/search/repository/search.repository.js +3 -1
  237. package/dist/features/seller/actions/offer-actions.js +43 -24
  238. package/dist/features/seller/actions/seller-actions.js +29 -5
  239. package/dist/features/seller/components/CategoryChipPicker.d.ts +9 -0
  240. package/dist/features/seller/components/CategoryChipPicker.js +12 -0
  241. package/dist/features/seller/components/SellerAddressesView.js +5 -1
  242. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +83 -43
  243. package/dist/features/seller/components/SellerArtView.d.ts +14 -7
  244. package/dist/features/seller/components/SellerArtView.js +4 -119
  245. package/dist/features/seller/components/SellerClassifiedView.d.ts +14 -7
  246. package/dist/features/seller/components/SellerClassifiedView.js +4 -124
  247. package/dist/features/seller/components/SellerCouponEditorView.d.ts +22 -1
  248. package/dist/features/seller/components/SellerCouponEditorView.js +91 -45
  249. package/dist/features/seller/components/SellerDigitalCodesView.d.ts +14 -7
  250. package/dist/features/seller/components/SellerDigitalCodesView.js +4 -126
  251. package/dist/features/seller/components/SellerListingTypeView.d.ts +66 -0
  252. package/dist/features/seller/components/SellerListingTypeView.js +277 -0
  253. package/dist/features/seller/components/SellerLiveView.d.ts +14 -7
  254. package/dist/features/seller/components/SellerLiveView.js +4 -126
  255. package/dist/features/seller/components/SellerSidebar.d.ts +3 -6
  256. package/dist/features/seller/components/SellerStickersView.d.ts +14 -7
  257. package/dist/features/seller/components/SellerStickersView.js +4 -119
  258. package/dist/features/seller/components/SellerSupportView.d.ts +31 -0
  259. package/dist/features/seller/components/SellerSupportView.js +100 -0
  260. package/dist/features/seller/components/index.d.ts +4 -8
  261. package/dist/features/seller/components/index.js +2 -4
  262. package/dist/features/seller/index.d.ts +0 -1
  263. package/dist/features/seller/index.js +0 -1
  264. package/dist/features/seller/schemas/coupon-form.d.ts +214 -0
  265. package/dist/features/seller/schemas/coupon-form.js +155 -23
  266. package/dist/features/seller/schemas/offer-forms.d.ts +16 -7
  267. package/dist/features/seller/schemas/offer-forms.js +28 -12
  268. package/dist/features/shell/FormShell.js +2 -2
  269. package/dist/features/shell/QuickFormDrawer.js +2 -2
  270. package/dist/features/shell/SectionForm.d.ts +19 -1
  271. package/dist/features/shell/SectionForm.js +104 -17
  272. package/dist/features/shell/build-sections.d.ts +23 -0
  273. package/dist/features/shell/build-sections.js +106 -8
  274. package/dist/features/shell/field-ui-meta.d.ts +44 -0
  275. package/dist/features/shell/field-ui-meta.js +14 -7
  276. package/dist/features/shell/form-sections.d.ts +46 -0
  277. package/dist/features/shell/form-sections.js +114 -0
  278. package/dist/features/shipments/components/AdminShipmentEditorView.js +87 -64
  279. package/dist/features/shipments/schemas/validation.d.ts +2 -2
  280. package/dist/features/shipments/schemas/validation.js +44 -13
  281. package/dist/features/store-extensions/schemas/custom-role-form.js +6 -2
  282. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +7 -7
  283. package/dist/features/store-extensions/schemas/payout-method-form.js +14 -0
  284. package/dist/features/stores/actions/store-query-actions.js +3 -2
  285. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -1
  286. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -1
  287. package/dist/features/support/repository/support.repository.d.ts +21 -0
  288. package/dist/features/support/repository/support.repository.js +63 -0
  289. package/dist/features/support/schemas/firestore.d.ts +27 -2
  290. package/dist/features/support/schemas/firestore.js +2 -0
  291. package/dist/features/support/schemas/ticket-create-form.js +7 -0
  292. package/dist/features/tester/schemas/checklist-item-form.d.ts +43 -0
  293. package/dist/features/tester/schemas/checklist-item-form.js +109 -0
  294. package/dist/features/tester/seed-data/blog-tester-seed-data.js +2 -2
  295. package/dist/features/tester/seed-data/categories-tester-seed-data.js +2 -2
  296. package/dist/features/tester/seed-data/events-tester-seed-data.js +5 -5
  297. package/dist/features/tester/seed-data/orders-tester-seed-data.js +2 -2
  298. package/dist/features/tester/seed-data/products-tester-seed-data.js +48 -49
  299. package/dist/features/tester/seed-data/stores-tester-seed-data.js +3 -3
  300. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +275 -29
  301. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +48 -12
  302. package/dist/http/api-handler.js +2 -1
  303. package/dist/index.d.ts +24 -103
  304. package/dist/index.js +33 -141
  305. package/dist/jobs.d.ts +1 -1
  306. package/dist/jobs.js +1 -1
  307. package/dist/monitoring/browser.d.ts +0 -2
  308. package/dist/monitoring/browser.js +12 -1
  309. package/dist/monitoring/index.d.ts +0 -2
  310. package/dist/monitoring/index.js +0 -1
  311. package/dist/next/api/routeHandler.js +6 -3
  312. package/dist/next/index.d.ts +7 -2
  313. package/dist/next/index.js +36 -1
  314. package/dist/next/middleware/index.d.ts +0 -2
  315. package/dist/next/middleware/index.js +0 -1
  316. package/dist/next/routing/route-map.d.ts +8 -7
  317. package/dist/next/routing/route-map.js +10 -3
  318. package/dist/providers/db-firebase/admin.js +15 -1
  319. package/dist/providers/db-firebase/sieve.d.ts +22 -0
  320. package/dist/react/hooks/useListingTypeFlags.d.ts +1 -1
  321. package/dist/react/hooks/useListingTypeFlags.js +1 -1
  322. package/dist/react/hooks/usePendingFilters.js +5 -3
  323. package/dist/react/hooks/usePendingTable.js +15 -3
  324. package/dist/repositories/index.d.ts +0 -1
  325. package/dist/repositories/index.js +0 -1
  326. package/dist/schemas/registry.d.ts +197 -232
  327. package/dist/schemas/registry.js +5 -6
  328. package/dist/schemas/webhooks/razorpay.d.ts +50 -50
  329. package/dist/security/authorization.d.ts +9 -0
  330. package/dist/security/authorization.js +16 -2
  331. package/dist/security/browser.d.ts +1 -3
  332. package/dist/security/browser.js +5 -2
  333. package/dist/security/index.d.ts +1 -3
  334. package/dist/security/index.js +19 -2
  335. package/dist/security/pii-encrypt.js +16 -0
  336. package/dist/security/pii-schemas.d.ts +0 -14
  337. package/dist/security/pii-schemas.js +7 -15
  338. package/dist/seed/_helpers/category-forest.js +2 -2
  339. package/dist/seed/_helpers/media.d.ts +19 -0
  340. package/dist/seed/_helpers/media.js +75 -0
  341. package/dist/seed/blog-posts-seed-data.js +17 -17
  342. package/dist/seed/carousel-slides-seed-data.js +7 -7
  343. package/dist/seed/cart-seed-data.js +13 -13
  344. package/dist/seed/categories-seed-data.js +10 -10
  345. package/dist/seed/events-seed-data.js +24 -24
  346. package/dist/seed/factories/product.factory.js +4 -4
  347. package/dist/seed/factories/store.factory.js +3 -3
  348. package/dist/seed/factories/user.factory.js +2 -2
  349. package/dist/seed/grouped-listings-seed-data.js +11 -11
  350. package/dist/seed/homepage-sections-seed-data.js +2 -2
  351. package/dist/seed/index.d.ts +0 -1
  352. package/dist/seed/index.js +0 -1
  353. package/dist/seed/manifest.d.ts +1 -1
  354. package/dist/seed/manifest.js +0 -5
  355. package/dist/seed/notifications-seed-data.js +20 -1
  356. package/dist/seed/orders-seed-data.js +2 -2
  357. package/dist/seed/products-art-seed-data.js +16 -16
  358. package/dist/seed/products-auctions-seed-data.js +34 -34
  359. package/dist/seed/products-classifieds-seed-data.js +35 -37
  360. package/dist/seed/products-digital-codes-seed-data.js +20 -20
  361. package/dist/seed/products-live-items-seed-data.js +11 -11
  362. package/dist/seed/products-preorders-seed-data.js +13 -13
  363. package/dist/seed/products-prize-draws-seed-data.js +43 -43
  364. package/dist/seed/products-standard-seed-data.js +54 -54
  365. package/dist/seed/products-stickers-seed-data.js +15 -15
  366. package/dist/seed/reviews-seed-data.js +4 -4
  367. package/dist/seed/scammers-seed-data.js +3 -3
  368. package/dist/seed/site-settings-seed-data.js +11 -24
  369. package/dist/seed/store-extensions-seed-data.js +10 -10
  370. package/dist/seed/stores-seed-data.js +11 -11
  371. package/dist/seed/support-tickets-seed-data.d.ts +14 -0
  372. package/dist/seed/support-tickets-seed-data.js +20 -1
  373. package/dist/seed/users-seed-data.js +20 -20
  374. package/dist/server-entry.d.ts +0 -1
  375. package/dist/server-entry.js +0 -1
  376. package/dist/server.d.ts +9 -6
  377. package/dist/server.js +7 -13
  378. package/dist/styles.css +248 -68
  379. package/dist/tailwind-utilities.css +1 -1
  380. package/dist/tokens/themes/default-dark.js +2 -2
  381. package/dist/tokens/themes/default-light.js +2 -2
  382. package/dist/tokens/tokens.css +24 -4
  383. package/dist/ui/components/ActionRow.d.ts +50 -0
  384. package/dist/ui/components/ActionRow.js +53 -0
  385. package/dist/ui/components/ActionRow.style.css +145 -0
  386. package/dist/ui/components/Drawer.d.ts +10 -0
  387. package/dist/ui/components/Drawer.js +2 -1
  388. package/dist/ui/components/FilterDrawer.js +4 -1
  389. package/dist/ui/components/FilterDrawer.style.css +6 -12
  390. package/dist/ui/components/FormActionBar.js +14 -1
  391. package/dist/ui/components/FormActionBar.style.css +12 -11
  392. package/dist/ui/components/ListingLayout.js +8 -1
  393. package/dist/ui/components/ListingLayout.style.css +6 -13
  394. package/dist/ui/components/Modal.d.ts +15 -1
  395. package/dist/ui/components/Modal.js +17 -3
  396. package/dist/ui/components/QuickCreateModal.js +2 -2
  397. package/dist/ui/components/QuickCreateModal.style.css +78 -84
  398. package/dist/ui/components/RecordDetailModal.js +2 -2
  399. package/dist/ui/components/SideDrawer.d.ts +8 -0
  400. package/dist/ui/components/SideDrawer.js +2 -1
  401. package/dist/ui/components/SideDrawer.style.css +6 -3
  402. package/dist/ui/components/SideModal.d.ts +11 -1
  403. package/dist/ui/components/SideModal.js +3 -2
  404. package/dist/ui/components/SideModal.style.css +14 -0
  405. package/dist/ui/components/Typography.style.css +33 -24
  406. package/dist/ui/components/index.style.css +1 -0
  407. package/dist/ui/forms/FormShell.style.css +260 -311
  408. package/dist/ui/index.d.ts +2 -0
  409. package/dist/ui/index.js +1 -0
  410. package/dist/utils/index.d.ts +0 -1
  411. package/dist/utils/index.js +0 -1
  412. package/dist/validation/index.d.ts +1 -1
  413. package/dist/validation/index.js +1 -1
  414. package/dist/validation/schemas.d.ts +0 -19
  415. package/dist/validation/schemas.js +8 -19
  416. package/package.json +1 -1
  417. package/scripts/seed-cli.mjs +3 -6
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * SellerSupportView — the tickets raised about this seller's store.
5
+ *
6
+ * ## Why there was nothing here before
7
+ *
8
+ * Support has always had a buyer surface and an admin surface and no seller
9
+ * one — no page, no API route, not even a `ROUTES.STORE.SUPPORT` constant.
10
+ * The reason was structural rather than an oversight: `SupportTicketDocument`
11
+ * had no queryable `storeId`, so "the tickets about my store" was not a
12
+ * question the data could answer.
13
+ *
14
+ * There is a category called `store_change_request` — sellers asking an admin
15
+ * to change a store field they cannot edit themselves — which a seller could
16
+ * only ever file through the BUYER surface, and then never see again from the
17
+ * store dashboard.
18
+ *
19
+ * ## Read-only, deliberately
20
+ *
21
+ * A seller can see and follow a ticket about their store; replying goes
22
+ * through the ticket thread the buyer and admin already share, and status is
23
+ * an admin decision. Giving a seller a status control here would let them
24
+ * close a complaint made against them.
25
+ */
26
+ import React from "react";
27
+ import { Badge, Span, Stack, Text } from "../../../ui";
28
+ import { DataListingView } from "../../admin/components/DataListingView";
29
+ import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
30
+ import { SUPPORT_TICKET_FIELDS } from "../../../constants/field-names";
31
+ import { sieveFilter, SIEVE_OP } from "../../../utils/sieve-builder";
32
+ import { toRelativeDate, toStringValue } from "../../admin/hooks/useAdminListingData";
33
+ /** Status → badge tone. Mirrors `TicketStatusValues`. */
34
+ const STATUS_VARIANT = {
35
+ open: "info",
36
+ in_progress: "warning",
37
+ waiting_on_user: "warning",
38
+ resolved: "success",
39
+ closed: "default",
40
+ };
41
+ export function SellerSupportView({ labels = {} }) {
42
+ const mapRows = React.useCallback((response) => {
43
+ const items = Array.isArray(response?.items) ? response.items : [];
44
+ return items.map((raw) => {
45
+ const t = (raw ?? {});
46
+ return {
47
+ id: toStringValue(t.id),
48
+ primary: toStringValue(t.subject),
49
+ secondary: toStringValue(t.description).slice(0, 140),
50
+ status: toStringValue(t.status),
51
+ category: toStringValue(t.category).replace(/_/g, " "),
52
+ updated: toRelativeDate(t.updatedAt ?? t.createdAt),
53
+ };
54
+ });
55
+ }, []);
56
+ return (_jsxs(Stack, { gap: "md", children: [_jsx(DataListingView, { config: {
57
+ portal: "seller",
58
+ title: labels.title ?? "Support",
59
+ subtitle: "Tickets buyers and staff have raised about your store.",
60
+ /*
61
+ * The box is declared only because the endpoint now serves it —
62
+ * `supportTickets` gained a `searchTxt` corpus in this same commit.
63
+ * `fields` names what is actually matched, and it is SUBJECT ONLY:
64
+ * the description and every message body are PII-encrypted at rest,
65
+ * so they are not in the index and a placeholder promising them
66
+ * would be a promise the backend cannot keep.
67
+ */
68
+ search: {
69
+ placeholder: "Search by subject…",
70
+ mode: "partial",
71
+ fields: ["subject"],
72
+ commit: "debounce",
73
+ },
74
+ emptyLabel: "No tickets have been raised about your store.",
75
+ queryKey: ["store", "support-tickets"],
76
+ endpoint: SELLER_ENDPOINTS.SUPPORT,
77
+ filterKeys: ["status"],
78
+ defaultSort: "",
79
+ sortOptions: [],
80
+ mapRows,
81
+ getTotal: (response, rows) => response?.total ?? rows.length,
82
+ buildFilters: (filterState) => filterState.status
83
+ ? sieveFilter(SUPPORT_TICKET_FIELDS.STATUS, SIEVE_OP.EQ, filterState.status)
84
+ : undefined,
85
+ columns: [
86
+ { key: "primary", header: "Subject" },
87
+ {
88
+ key: "status",
89
+ header: "Status",
90
+ render: (row) => (_jsx(Badge, { variant: STATUS_VARIANT[row.status] ?? "default", children: row.status.replace(/_/g, " ") })),
91
+ },
92
+ {
93
+ key: "category",
94
+ header: "About",
95
+ render: (row) => (_jsx(Span, { size: "xs", color: "muted", children: row.category })),
96
+ },
97
+ { key: "updated", header: "Updated" },
98
+ ],
99
+ } }), _jsx(Text, { size: "xs", color: "muted", children: "Replies and status changes happen in the ticket thread with our support team \u2014 a ticket raised about your store is not one you can close." })] }));
100
+ }
@@ -1,13 +1,9 @@
1
1
  export { SellerDashboardView } from "./SellerDashboardView";
2
2
  export type { SellerDashboardViewProps } from "./SellerDashboardView";
3
3
  export { SellerProductsView } from "./SellerProductsView";
4
+ export { SellerListingTypeView, SELLER_LISTING_TYPE_SPECS } from "./SellerListingTypeView";
5
+ export type { SellerListingTypeViewProps, SellerListingTypeSpec, SellerListingTypeKey, SellerListingRow } from "./SellerListingTypeView";
4
6
  export type { SellerProductsViewProps } from "./SellerProductsView";
5
- export { SellerAuctionsView } from "./SellerAuctionsView";
6
- export type { SellerAuctionsViewProps } from "./SellerAuctionsView";
7
- export { SellerPreOrdersView } from "./SellerPreOrdersView";
8
- export type { SellerPreOrdersViewProps } from "./SellerPreOrdersView";
9
- export { SellerPrizeDrawsView } from "./SellerPrizeDrawsView";
10
- export type { SellerPrizeDrawsViewProps } from "./SellerPrizeDrawsView";
11
7
  export { PrintCenterView } from "./PrintCenterView";
12
8
  export { SellerOrdersView, SellerOrderDetailPanel } from "./SellerOrdersView";
13
9
  export type { SellerOrdersViewProps } from "./SellerOrdersView";
@@ -62,8 +58,6 @@ export { SellerDashboardView as StoreDashboardView } from "./SellerDashboardView
62
58
  export type { SellerDashboardViewProps as StoreDashboardViewProps } from "./SellerDashboardView";
63
59
  export { SellerProductsView as StoreProductListingsView } from "./SellerProductsView";
64
60
  export type { SellerProductsViewProps as StoreProductListingsViewProps } from "./SellerProductsView";
65
- export { SellerAuctionsView as StoreAuctionsView } from "./SellerAuctionsView";
66
- export type { SellerAuctionsViewProps as StoreAuctionsViewProps } from "./SellerAuctionsView";
67
61
  export { SellerOrdersView as StoreOrdersView } from "./SellerOrdersView";
68
62
  export type { SellerOrdersViewProps as StoreOrdersViewProps } from "./SellerOrdersView";
69
63
  export { SellerOffersView as StoreOffersView } from "./SellerOffersView";
@@ -132,3 +126,5 @@ export { BarcodeField } from "./BarcodeField";
132
126
  export type { BarcodeFieldProps } from "./BarcodeField";
133
127
  export { FulfillmentView } from "./FulfillmentView";
134
128
  export type { FulfillmentViewProps } from "./FulfillmentView";
129
+ export { SellerSupportView } from "./SellerSupportView";
130
+ export type { SellerSupportViewProps } from "./SellerSupportView";
@@ -1,8 +1,6 @@
1
1
  export { SellerDashboardView } from "./SellerDashboardView";
2
2
  export { SellerProductsView } from "./SellerProductsView";
3
- export { SellerAuctionsView } from "./SellerAuctionsView";
4
- export { SellerPreOrdersView } from "./SellerPreOrdersView";
5
- export { SellerPrizeDrawsView } from "./SellerPrizeDrawsView";
3
+ export { SellerListingTypeView, SELLER_LISTING_TYPE_SPECS } from "./SellerListingTypeView";
6
4
  export { PrintCenterView } from "./PrintCenterView";
7
5
  export { SellerOrdersView, SellerOrderDetailPanel } from "./SellerOrdersView";
8
6
  export { SellerOffersView } from "./SellerOffersView";
@@ -34,7 +32,6 @@ export { StoreSidebar } from "./SellerSidebar";
34
32
  export { SellerDashboardView as StoreDashboardView } from "./SellerDashboardView";
35
33
  // SellerProductsView aliased as StoreProductListingsView (StoreProductsView is the public customer-facing store listing)
36
34
  export { SellerProductsView as StoreProductListingsView } from "./SellerProductsView";
37
- export { SellerAuctionsView as StoreAuctionsView } from "./SellerAuctionsView";
38
35
  export { SellerOrdersView as StoreOrdersView } from "./SellerOrdersView";
39
36
  export { SellerOffersView as StoreOffersView } from "./SellerOffersView";
40
37
  export { SellerCouponsView as StoreCouponsView } from "./SellerCouponsView";
@@ -69,3 +66,4 @@ export { SellerDigitalCodesView } from "./SellerDigitalCodesView";
69
66
  export { SellerLiveView } from "./SellerLiveView";
70
67
  export { BarcodeField } from "./BarcodeField";
71
68
  export { FulfillmentView } from "./FulfillmentView";
69
+ export { SellerSupportView } from "./SellerSupportView";
@@ -8,4 +8,3 @@ export * from "./components";
8
8
  export * from "./schemas";
9
9
  export * from "./columns";
10
10
  export { manifest } from "./manifest";
11
- export { SELLER_PAGE_PERMISSIONS } from "./permission-map";
@@ -8,4 +8,3 @@ export * from "./components";
8
8
  export * from "./schemas";
9
9
  export * from "./columns";
10
10
  export { manifest } from "./manifest";
11
- export { SELLER_PAGE_PERMISSIONS } from "./permission-map";
@@ -3,6 +3,68 @@ import { z } from "zod";
3
3
  * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
4
4
  * by schema instance and every zod wrapper returns a new one.
5
5
  */
6
+ /**
7
+ * The fields both coupon editors share, before either adds its own rules.
8
+ *
9
+ * Split out of `sellerCouponFormSchema` so the ADMIN editor can extend it.
10
+ * It could not before: that schema ends in `.superRefine`, which returns a
11
+ * ZodEffects with no `.extend()` — which is a large part of why the admin
12
+ * editor ended up declaring its own five-field `.passthrough()` stub locally
13
+ * and validating nothing at all.
14
+ */
15
+ export declare const couponFormBase: z.ZodObject<{
16
+ code: z.ZodString;
17
+ type: z.ZodEnum<["percentage", "fixed", "free_shipping"]>;
18
+ value: z.ZodEffects<z.ZodString, string, string>;
19
+ minPurchase: z.ZodEffects<z.ZodString, string, string>;
20
+ maxDiscount: z.ZodEffects<z.ZodString, string, string>;
21
+ totalLimit: z.ZodEffects<z.ZodString, string, string>;
22
+ perUserLimit: z.ZodEffects<z.ZodString, string, string>;
23
+ startDate: z.ZodString;
24
+ endDate: z.ZodString;
25
+ isActive: z.ZodBoolean;
26
+ applicableProducts: z.ZodArray<z.ZodString, "many">;
27
+ applicableCategories: z.ZodArray<z.ZodString, "many">;
28
+ }, "strip", z.ZodTypeAny, {
29
+ value: string;
30
+ code: string;
31
+ type: "fixed" | "percentage" | "free_shipping";
32
+ isActive: boolean;
33
+ endDate: string;
34
+ maxDiscount: string;
35
+ minPurchase: string;
36
+ applicableProducts: string[];
37
+ applicableCategories: string[];
38
+ totalLimit: string;
39
+ perUserLimit: string;
40
+ startDate: string;
41
+ }, {
42
+ value: string;
43
+ code: string;
44
+ type: "fixed" | "percentage" | "free_shipping";
45
+ isActive: boolean;
46
+ endDate: string;
47
+ maxDiscount: string;
48
+ minPurchase: string;
49
+ applicableProducts: string[];
50
+ applicableCategories: string[];
51
+ totalLimit: string;
52
+ perUserLimit: string;
53
+ startDate: string;
54
+ }>;
55
+ /**
56
+ * The cross-field rules both editors need. Shared for the same reason the
57
+ * fields are: a percentage over 100 is the store paying the customer whichever
58
+ * portal typed it.
59
+ */
60
+ export declare function refineCouponCommon(v: {
61
+ type: string;
62
+ value: string;
63
+ startDate: string;
64
+ endDate: string;
65
+ totalLimit: string;
66
+ perUserLimit: string;
67
+ }, ctx: z.RefinementCtx): void;
6
68
  export declare const sellerCouponFormSchema: z.ZodEffects<z.ZodObject<{
7
69
  code: z.ZodString;
8
70
  type: z.ZodEnum<["percentage", "fixed", "free_shipping"]>;
@@ -70,3 +132,155 @@ export declare const sellerCouponFormSchema: z.ZodEffects<z.ZodObject<{
70
132
  startDate: string;
71
133
  }>;
72
134
  export type SellerCouponFormValues = z.infer<typeof sellerCouponFormSchema>;
135
+ /**
136
+ * What `POST /api/store/coupons` accepts.
137
+ *
138
+ * The index signature is what lets it pass as a JSON body without a cast at the
139
+ * callsite — the named fields still constrain what may be set.
140
+ */
141
+ export interface SellerCouponPayload {
142
+ [key: string]: string | number | boolean | string[] | undefined;
143
+ code: string;
144
+ type: SellerCouponFormValues["type"];
145
+ value: number;
146
+ minPurchase?: number;
147
+ maxDiscount?: number;
148
+ totalLimit: number;
149
+ perUserLimit: number;
150
+ startDate: string;
151
+ endDate: string;
152
+ isActive: boolean;
153
+ applicableProducts?: string[];
154
+ applicableCategories?: string[];
155
+ }
156
+ /**
157
+ * The draft, as the route wants it.
158
+ *
159
+ * 🛑 One implementation because the conditions have to match the form's, and a
160
+ * per-callsite conversion is how they stopped matching: the create client
161
+ * correctly zeroed `value` for a free-shipping coupon and then sent
162
+ * `maxDiscount` for EVERY type — so a cap typed while the type was
163
+ * "percentage" survived a switch to fixed or free-shipping, invisibly, because
164
+ * the input that would have shown it was no longer rendered.
165
+ *
166
+ * The rule is now stated once, here, next to the `when` predicates it mirrors:
167
+ * a field the form hides is a field the payload omits.
168
+ */
169
+ export declare function couponDraftToPayload(draft: SellerCouponFormValues): SellerCouponPayload;
170
+ /**
171
+ * A coupon as an ADMIN edits it — the seller's fields plus the ones only the
172
+ * platform can set.
173
+ *
174
+ * `AdminCouponEditorView` declared its own schema locally: five fields, two of
175
+ * them `.passthrough()`, against nineteen rendered controls. It was passed to
176
+ * `<Form schema>` and never parsed, so none of the seventeen unlisted controls
177
+ * was checked by anything — `value` could be 500%, `endDate` could precede
178
+ * `startDate`, and `buyQuantity` could be zero.
179
+ *
180
+ * Extending the shared base rather than restating it is what keeps the two
181
+ * portals' rules from drifting; that they had already drifted is Root Cause
182
+ * #59's shape on the validation axis.
183
+ */
184
+ export declare const adminCouponFormSchema: z.ZodEffects<z.ZodObject<{
185
+ code: z.ZodString;
186
+ value: z.ZodEffects<z.ZodString, string, string>;
187
+ minPurchase: z.ZodEffects<z.ZodString, string, string>;
188
+ maxDiscount: z.ZodEffects<z.ZodString, string, string>;
189
+ totalLimit: z.ZodEffects<z.ZodString, string, string>;
190
+ perUserLimit: z.ZodEffects<z.ZodString, string, string>;
191
+ startDate: z.ZodString;
192
+ endDate: z.ZodString;
193
+ isActive: z.ZodBoolean;
194
+ applicableProducts: z.ZodArray<z.ZodString, "many">;
195
+ applicableCategories: z.ZodArray<z.ZodString, "many">;
196
+ } & {
197
+ type: z.ZodEnum<["percentage", "fixed", "free_shipping", "buy_x_get_y"]>;
198
+ name: z.ZodString;
199
+ description: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
200
+ buyQuantity: z.ZodEffects<z.ZodString, string, string>;
201
+ getQuantity: z.ZodEffects<z.ZodString, string, string>;
202
+ currentUsage: z.ZodOptional<z.ZodNumber>;
203
+ firstTimeUserOnly: z.ZodBoolean;
204
+ appliesToAuctions: z.ZodBoolean;
205
+ }, "strip", z.ZodTypeAny, {
206
+ value: string;
207
+ code: string;
208
+ type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
209
+ name: string;
210
+ isActive: boolean;
211
+ endDate: string;
212
+ firstTimeUserOnly: boolean;
213
+ maxDiscount: string;
214
+ minPurchase: string;
215
+ buyQuantity: string;
216
+ getQuantity: string;
217
+ applicableProducts: string[];
218
+ applicableCategories: string[];
219
+ totalLimit: string;
220
+ perUserLimit: string;
221
+ startDate: string;
222
+ appliesToAuctions: boolean;
223
+ description?: string | undefined;
224
+ currentUsage?: number | undefined;
225
+ }, {
226
+ value: string;
227
+ code: string;
228
+ type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
229
+ name: string;
230
+ isActive: boolean;
231
+ endDate: string;
232
+ firstTimeUserOnly: boolean;
233
+ maxDiscount: string;
234
+ minPurchase: string;
235
+ buyQuantity: string;
236
+ getQuantity: string;
237
+ applicableProducts: string[];
238
+ applicableCategories: string[];
239
+ totalLimit: string;
240
+ perUserLimit: string;
241
+ startDate: string;
242
+ appliesToAuctions: boolean;
243
+ description?: string | undefined;
244
+ currentUsage?: number | undefined;
245
+ }>, {
246
+ value: string;
247
+ code: string;
248
+ type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
249
+ name: string;
250
+ isActive: boolean;
251
+ endDate: string;
252
+ firstTimeUserOnly: boolean;
253
+ maxDiscount: string;
254
+ minPurchase: string;
255
+ buyQuantity: string;
256
+ getQuantity: string;
257
+ applicableProducts: string[];
258
+ applicableCategories: string[];
259
+ totalLimit: string;
260
+ perUserLimit: string;
261
+ startDate: string;
262
+ appliesToAuctions: boolean;
263
+ description?: string | undefined;
264
+ currentUsage?: number | undefined;
265
+ }, {
266
+ value: string;
267
+ code: string;
268
+ type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
269
+ name: string;
270
+ isActive: boolean;
271
+ endDate: string;
272
+ firstTimeUserOnly: boolean;
273
+ maxDiscount: string;
274
+ minPurchase: string;
275
+ buyQuantity: string;
276
+ getQuantity: string;
277
+ applicableProducts: string[];
278
+ applicableCategories: string[];
279
+ totalLimit: string;
280
+ perUserLimit: string;
281
+ startDate: string;
282
+ appliesToAuctions: boolean;
283
+ description?: string | undefined;
284
+ currentUsage?: number | undefined;
285
+ }>;
286
+ export type AdminCouponFormValues = z.infer<typeof adminCouponFormSchema>;
@@ -44,7 +44,16 @@ const numericString = (label) => z
44
44
  * 🛑 `annotate()` must be the OUTERMOST call on each field — it keys a WeakMap
45
45
  * by schema instance and every zod wrapper returns a new one.
46
46
  */
47
- export const sellerCouponFormSchema = z
47
+ /**
48
+ * The fields both coupon editors share, before either adds its own rules.
49
+ *
50
+ * Split out of `sellerCouponFormSchema` so the ADMIN editor can extend it.
51
+ * It could not before: that schema ends in `.superRefine`, which returns a
52
+ * ZodEffects with no `.extend()` — which is a large part of why the admin
53
+ * editor ended up declaring its own five-field `.passthrough()` stub locally
54
+ * and validating nothing at all.
55
+ */
56
+ export const couponFormBase = z
48
57
  .object({
49
58
  code: annotate(z
50
59
  .string()
@@ -57,14 +66,26 @@ export const sellerCouponFormSchema = z
57
66
  type: annotate(z.enum(["percentage", "fixed", "free_shipping"]), {
58
67
  section: "basics", quick: true, order: 2, row: "pair",
59
68
  }),
69
+ /*
70
+ * `when` carries what the editor held as JSX conditionals, so a field the
71
+ * form hides is one the payload cannot carry — see `couponDraftToPayload`.
72
+ */
60
73
  value: annotate(numericString("The discount value"), {
61
74
  section: "basics", quick: true, order: 3, row: "pair",
75
+ when: (v) => v.type !== "free_shipping",
62
76
  }),
63
77
  minPurchase: annotate(numericString("Minimum purchase"), {
64
78
  section: "limits", sectionLabel: "Limits", order: 1, row: "pair",
65
79
  }),
80
+ /*
81
+ * A percentage cap is meaningless on a fixed or free-shipping coupon. The
82
+ * input was already hidden for those, and the value was SENT anyway — so a
83
+ * cap typed while the type was "percentage" persisted after switching to
84
+ * free shipping, invisibly.
85
+ */
66
86
  maxDiscount: annotate(numericString("Maximum discount"), {
67
87
  section: "limits", order: 2, row: "pair",
88
+ when: (v) => v.type === "percentage",
68
89
  }),
69
90
  totalLimit: annotate(numericString("Total uses"), {
70
91
  section: "limits", order: 3, row: "pair",
@@ -87,30 +108,141 @@ export const sellerCouponFormSchema = z
87
108
  applicableCategories: annotate(z.array(z.string()), {
88
109
  section: "scope", order: 2, row: "full", kind: "list",
89
110
  }),
111
+ });
112
+ /**
113
+ * The cross-field rules both editors need. Shared for the same reason the
114
+ * fields are: a percentage over 100 is the store paying the customer whichever
115
+ * portal typed it.
116
+ */
117
+ export function refineCouponCommon(v, ctx) {
118
+ {
119
+ const issue = (path, message) => ctx.addIssue({ code: z.ZodIssueCode.custom, path: [path], message });
120
+ // A discount value is required for everything except free shipping, and
121
+ // a percentage above 100 is not a discount — it is the store paying the
122
+ // customer. Nothing bounded this before.
123
+ if (v.type !== "free_shipping") {
124
+ const amount = Number(v.value);
125
+ if (v.value.trim() === "")
126
+ issue("value", "A discount value is required.");
127
+ else if (amount <= 0)
128
+ issue("value", "The discount must be greater than zero.");
129
+ else if (v.type === "percentage" && amount > 100) {
130
+ issue("value", "A percentage discount cannot exceed 100%.");
131
+ }
132
+ }
133
+ if (v.startDate && v.endDate && v.startDate > v.endDate) {
134
+ issue("endDate", "The end date must be after the start date.");
135
+ }
136
+ // A per-customer limit above the total makes the total unreachable — the
137
+ // coupon reads as more generous than it can ever be.
138
+ const total = Number(v.totalLimit);
139
+ const perUser = Number(v.perUserLimit);
140
+ if (v.totalLimit.trim() && v.perUserLimit.trim() && perUser > total) {
141
+ issue("perUserLimit", "Uses per customer cannot exceed the total uses.");
142
+ }
143
+ }
144
+ }
145
+ export const sellerCouponFormSchema = couponFormBase.superRefine(refineCouponCommon);
146
+ /**
147
+ * The draft, as the route wants it.
148
+ *
149
+ * 🛑 One implementation because the conditions have to match the form's, and a
150
+ * per-callsite conversion is how they stopped matching: the create client
151
+ * correctly zeroed `value` for a free-shipping coupon and then sent
152
+ * `maxDiscount` for EVERY type — so a cap typed while the type was
153
+ * "percentage" survived a switch to fixed or free-shipping, invisibly, because
154
+ * the input that would have shown it was no longer rendered.
155
+ *
156
+ * The rule is now stated once, here, next to the `when` predicates it mirrors:
157
+ * a field the form hides is a field the payload omits.
158
+ */
159
+ export function couponDraftToPayload(draft) {
160
+ const isPercentage = draft.type === "percentage";
161
+ const hasValue = draft.type !== "free_shipping";
162
+ return {
163
+ code: draft.code,
164
+ type: draft.type,
165
+ value: hasValue ? Number(draft.value) || 0 : 0,
166
+ minPurchase: draft.minPurchase ? Number(draft.minPurchase) : undefined,
167
+ maxDiscount: isPercentage && draft.maxDiscount ? Number(draft.maxDiscount) : undefined,
168
+ totalLimit: Number(draft.totalLimit) || 0,
169
+ perUserLimit: Number(draft.perUserLimit) || 0,
170
+ startDate: draft.startDate,
171
+ endDate: draft.endDate,
172
+ isActive: draft.isActive,
173
+ ...(draft.applicableProducts?.length ? { applicableProducts: draft.applicableProducts } : {}),
174
+ ...(draft.applicableCategories?.length
175
+ ? { applicableCategories: draft.applicableCategories }
176
+ : {}),
177
+ };
178
+ }
179
+ /**
180
+ * A coupon as an ADMIN edits it — the seller's fields plus the ones only the
181
+ * platform can set.
182
+ *
183
+ * `AdminCouponEditorView` declared its own schema locally: five fields, two of
184
+ * them `.passthrough()`, against nineteen rendered controls. It was passed to
185
+ * `<Form schema>` and never parsed, so none of the seventeen unlisted controls
186
+ * was checked by anything — `value` could be 500%, `endDate` could precede
187
+ * `startDate`, and `buyQuantity` could be zero.
188
+ *
189
+ * Extending the shared base rather than restating it is what keeps the two
190
+ * portals' rules from drifting; that they had already drifted is Root Cause
191
+ * #59's shape on the validation axis.
192
+ */
193
+ export const adminCouponFormSchema = couponFormBase
194
+ .extend({
195
+ /*
196
+ * Widened past the seller's three. Only the platform runs buy-x-get-y —
197
+ * a seller offering one would be spending another seller's stock.
198
+ */
199
+ type: annotate(z.enum(["percentage", "fixed", "free_shipping", "buy_x_get_y"]), {
200
+ section: "basics", quick: true, order: 2, row: "pair", label: "Coupon type",
201
+ }),
202
+ name: annotate(z.string().min(1, "Give the campaign a name.").max(120), {
203
+ section: "basics", quick: true, order: 4, row: "pair", label: "Campaign name",
204
+ }),
205
+ description: annotate(z.string().max(500).optional().or(z.literal("")), {
206
+ section: "basics", order: 5, row: "full", kind: "textarea",
207
+ }),
208
+ buyQuantity: annotate(numericString("Buy quantity"), {
209
+ section: "basics", order: 6, row: "pair", kind: "number",
210
+ when: (v) => v.type === "buy_x_get_y",
211
+ }),
212
+ getQuantity: annotate(numericString("Get quantity"), {
213
+ section: "basics", order: 7, row: "pair", kind: "number",
214
+ when: (v) => v.type === "buy_x_get_y",
215
+ }),
216
+ /*
217
+ * Written by orders, never by this form. `t3-mirror` renders it read-only
218
+ * instead of as a box an admin could set to whatever they liked — which is
219
+ * what "Current usage" was, `disabled` by an attribute a programmatic
220
+ * submit ignores.
221
+ */
222
+ currentUsage: annotate(z.number().int().min(0).optional(), {
223
+ section: "limits", order: 5, row: "pair", derived: true, tier: "t3-mirror",
224
+ label: "Current usage", help: "Updated by orders.",
225
+ }),
226
+ firstTimeUserOnly: annotate(z.boolean(), {
227
+ section: "scope", order: 3, row: "quarter", label: "First-time users only",
228
+ }),
229
+ appliesToAuctions: annotate(z.boolean(), {
230
+ section: "scope", order: 4, row: "quarter", label: "Applies to auctions",
231
+ }),
90
232
  })
91
233
  .superRefine((v, ctx) => {
92
- const issue = (path, message) => ctx.addIssue({ code: z.ZodIssueCode.custom, path: [path], message });
93
- // A discount value is required for everything except free shipping, and
94
- // a percentage above 100 is not a discount — it is the store paying the
95
- // customer. Nothing bounded this before.
96
- if (v.type !== "free_shipping") {
97
- const amount = Number(v.value);
98
- if (v.value.trim() === "")
99
- issue("value", "A discount value is required.");
100
- else if (amount <= 0)
101
- issue("value", "The discount must be greater than zero.");
102
- else if (v.type === "percentage" && amount > 100) {
103
- issue("value", "A percentage discount cannot exceed 100%.");
234
+ refineCouponCommon(v, ctx);
235
+ // A buy-x-get-y with a zero on either side is not an offer.
236
+ if (v.type === "buy_x_get_y") {
237
+ for (const key of ["buyQuantity", "getQuantity"]) {
238
+ const n = Number(v[key]);
239
+ if (v[key].trim() === "" || !Number.isFinite(n) || n < 1) {
240
+ ctx.addIssue({
241
+ code: z.ZodIssueCode.custom,
242
+ path: [key],
243
+ message: "Enter a whole number of one or more.",
244
+ });
245
+ }
104
246
  }
105
247
  }
106
- if (v.startDate && v.endDate && v.startDate > v.endDate) {
107
- issue("endDate", "The end date must be after the start date.");
108
- }
109
- // A per-customer limit above the total makes the total unreachable — the
110
- // coupon reads as more generous than it can ever be.
111
- const total = Number(v.totalLimit);
112
- const perUser = Number(v.perUserLimit);
113
- if (v.totalLimit.trim() && v.perUserLimit.trim() && perUser > total) {
114
- issue("perUserLimit", "Uses per customer cannot exceed the total uses.");
115
- }
116
248
  });
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import type { OfferBounds } from "../../../_internal/shared/features/offers/config";
2
3
  export declare const counterOfferFormSchema: z.ZodObject<{
3
4
  counterAmount: z.ZodNumber;
4
5
  sellerNote: z.ZodOptional<z.ZodString>;
@@ -13,16 +14,24 @@ export type CounterOfferFormValues = z.infer<typeof counterOfferFormSchema>;
13
14
  /**
14
15
  * Buyer-side Make-an-Offer form.
15
16
  *
16
- * A factory rather than a constant because both bounds depend on the listing:
17
- * the floor is `minOfferAmount(listedPrice, minOfferPercent)` and the ceiling is
18
- * the listed price itself. Both are re-checked server-side in `makeOffer` — this
19
- * exists so the buyer is told before submitting, using the SAME
20
- * `minOfferAmount()` the server uses, rather than a second rounding rule that
21
- * could disagree by a rupee.
17
+ * A factory rather than a constant because both bounds depend on the listing.
18
+ * It takes the already-resolved `OfferBounds` rather than recomputing them:
19
+ * `resolveOfferBounds()` is what `makeOffer` enforces, so anything this schema
20
+ * accepts, the server accepts. Deriving a second floor here is exactly how the
21
+ * forms came to advertise a 50% minimum the server rejected at 70 (see the
22
+ * offers config header).
23
+ *
24
+ * Three shapes, all from the same bounds object:
25
+ *
26
+ * - **Buy request** (`isBuyRequest`) — no cart on this type and no haggling
27
+ * opted in, so `min === max` and the only legal amount is the asking price.
28
+ * - **Offer, no cart** — floor to asking price *inclusive*: with no Add to Cart
29
+ * button, refusing a full-price offer would leave the buyer nowhere to go.
30
+ * - **Offer, cartable** — the original rule, ceiling exclusive of the price.
22
31
  */
23
32
  export declare function makeOfferFormSchema(opts: {
24
33
  listedPrice: number;
25
- minOffer: number;
34
+ bounds: OfferBounds;
26
35
  formatAmount: (n: number) => string;
27
36
  }): z.ZodObject<{
28
37
  offerAmount: z.ZodNumber;