@mohasinac/appkit 4.30.19 → 4.31.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 (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 +1 -2
  313. package/dist/next/index.js +0 -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
@@ -1,126 +1,6 @@
1
1
  "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Badge, sortBy } from "@mohasinac/appkit/client";
4
- import { useState, useCallback } from "react";
5
- import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
6
- import { ConfirmDeleteModal, RowActionMenu, Text } from "../../../ui";
7
- import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
8
- import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
9
- import { ROUTES } from "../../../constants/index";
10
- import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../../admin/hooks/useAdminListingData";
11
- import { DataListingView } from "../../admin/components/DataListingView";
12
- import { SELLER_BULK_ACTIONS, ROW_ACTION_META } from "../../products/constants/action-defs";
13
- import { useAvailabilityScope } from "../../products/hooks/useAvailabilityScope";
14
- const LISTING_TYPES = ["classified"];
15
- const COLUMNS = [
16
- { key: "title", header: "Listing", render: (row) => _jsx(Text, { size: "sm", weight: "medium", children: row.title }) },
17
- { key: "price", header: "Price", render: (row) => _jsx(Text, { className: "tabular-nums", size: "sm", children: row.price }) },
18
- {
19
- key: "city",
20
- header: "Location",
21
- render: (row) => (_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: row.city || "—" })),
22
- },
23
- {
24
- key: "acceptsShipping",
25
- header: "Shipping",
26
- render: (row) => (_jsx(Badge, { variant: row.acceptsShipping ? "active" : "inactive", size: "xs", children: row.acceptsShipping ? "Ships" : "Meetup only" })),
27
- },
28
- {
29
- key: "status",
30
- header: "Status",
31
- render: (row) => (_jsx(Badge, { variant: row.status === "active" ? "active" : "inactive", size: "xs", className: "capitalize", children: row.status })),
32
- },
33
- {
34
- key: "createdAt",
35
- header: "Created",
36
- render: (row) => (_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: row.createdAt })),
37
- },
38
- ];
39
- export function SellerClassifiedView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }) {
40
- const [deleteTargetId, setDeleteTargetId] = useState(null);
41
- const { deletingId, handleDelete: performDelete } = useEntityDelete({
42
- endpoint: SELLER_ENDPOINTS.PRODUCT_BY_ID,
43
- deleteFn: onDelete,
44
- successMessage: "Listing deleted.",
45
- fetchOptions: { credentials: "include" },
46
- });
47
- const handleDelete = useCallback(async (id) => {
48
- await performDelete(id);
49
- setDeleteTargetId(null);
50
- }, [performDelete]);
51
- const handleEdit = useCallback((id) => {
52
- if (onEditClick)
53
- onEditClick(id);
54
- else
55
- window.location.href = String(ROUTES.STORE.CLASSIFIED_EDIT(id));
56
- }, [onEditClick]);
57
- const handleCreate = useCallback(() => {
58
- if (onCreateClick)
59
- onCreateClick();
60
- else
61
- window.location.href = String(ROUTES.STORE.CLASSIFIED_NEW);
62
- }, [onCreateClick]);
63
- const scope = useAvailabilityScope(LISTING_TYPES);
64
- const config = {
65
- portal: "seller",
66
- title: "Classified",
67
- searchPlaceholder: "Search classified listings...",
68
- emptyLabel: "No classified listings yet — post your first buy/sell/trade ad",
69
- filterKeys: [],
70
- defaultSort: sortBy("createdAt", "DESC"),
71
- queryKey: ["seller", "classified"],
72
- endpoint: SELLER_ENDPOINTS.PRODUCTS,
73
- sortOptions: [
74
- { value: sortBy("createdAt", "DESC"), label: "Newest" },
75
- { value: sortBy("createdAt", "ASC"), label: "Oldest" },
76
- { value: "title", label: "Name A–Z" },
77
- { value: sortBy("price", "ASC"), label: "Price: Low–High" },
78
- { value: sortBy("price", "DESC"), label: "Price: High–Low" },
79
- ],
80
- columns: COLUMNS,
81
- mapRows: (response) => toRecordArray(response.products).map((item, index) => {
82
- const classified = (item.classified ?? {});
83
- const meetupArea = (classified.meetupArea ?? {});
84
- return {
85
- id: toStringValue(item.id, `classified-${index}`),
86
- title: toStringValue(item.productTitle ?? item.title, "Untitled"),
87
- price: toCurrency(item.price),
88
- city: toStringValue(meetupArea.city ?? classified.city, ""),
89
- acceptsShipping: Boolean(classified.acceptsShipping),
90
- status: toStringValue(item.status, "draft"),
91
- createdAt: toRelativeDate(item.createdAt),
92
- };
93
- }),
94
- getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
95
- ? response.meta.total
96
- : mappedRows.length,
97
- buildFilters: () => "listingType==classified",
98
- buildExtraParams: () => scope.extraParams,
99
- renderAboveContent: scope.renderAboveContent,
100
- primaryAction: { label: "New Classified", onClick: () => handleCreate() },
101
- // Mirrors the "Edit" row action below so table rows and cards both navigate on click.
102
- onRowClick: (row) => handleEdit(row.id),
103
- // Rule #7: bulk-action array sourced from the SELLER_BULK_ACTIONS preset.
104
- buildBulkActions: onBulkDelete
105
- ? (selection) => SELLER_BULK_ACTIONS.classified.map((id) => ({
106
- id,
107
- label: ROW_ACTION_META[id].label,
108
- destructive: ROW_ACTION_META[id].destructive,
109
- onClick: async () => {
110
- await onBulkDelete(selection.selectedIds);
111
- selection.clearSelection();
112
- },
113
- }))
114
- : undefined,
115
- renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
116
- { label: ACTIONS.STORE["edit-listing"].label, onClick: () => handleEdit(row.id) },
117
- {
118
- label: ACTIONS.STORE["delete-listing"].label,
119
- destructive: true,
120
- onClick: () => setDeleteTargetId(row.id),
121
- disabled: deletingId === row.id,
122
- },
123
- ] })),
124
- };
125
- return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Classified Listing", message: "Are you sure you want to delete this classified listing? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { SellerListingTypeView, } from "./SellerListingTypeView";
4
+ export function SellerClassifiedView(props) {
5
+ return _jsx(SellerListingTypeView, { type: "classified", ...props });
126
6
  }
@@ -1,4 +1,25 @@
1
+ /**
2
+ * SellerCouponEditorView — sectionised 2026-08-30.
3
+ *
4
+ * ## The schema ran and could not be seen
5
+ *
6
+ * Unusually for this sweep, `sellerCouponFormSchema` was genuinely parsed on
7
+ * submit. What it could not do was report: every control was a raw `<Input>`
8
+ * with **no `name`**, so `applyZodIssues` wrote errors keyed on schema paths
9
+ * that no control on the page displayed. A percentage over 100 produced a line
10
+ * in `FormErrorSummary` and nothing at all on the field that caused it.
11
+ *
12
+ * Generating the controls from the schema is what fixes that: the field name
13
+ * IS the schema key, by construction.
14
+ *
15
+ * The local error banner is gone too. It carried two different kinds of
16
+ * failure — schema issues (already listed by `FormErrorSummary`, so a second
17
+ * copy) and the caller's save error (which has no field to land on, and so is
18
+ * a toast). One surface each.
19
+ */
20
+ import React from "react";
1
21
  export interface CouponEditorDraft {
22
+ [key: string]: unknown;
2
23
  code: string;
3
24
  type: "percentage" | "fixed" | "free_shipping";
4
25
  value: string;
@@ -18,4 +39,4 @@ export interface SellerCouponEditorViewProps {
18
39
  onSave: (draft: CouponEditorDraft, couponId?: string) => Promise<void>;
19
40
  onCancel?: () => void;
20
41
  }
21
- export declare function SellerCouponEditorView({ couponId, initial, onSave, onCancel, }: SellerCouponEditorViewProps): import("react").JSX.Element;
42
+ export declare function SellerCouponEditorView({ couponId, initial, onSave, onCancel, }: SellerCouponEditorViewProps): React.JSX.Element;
@@ -1,24 +1,38 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
4
- import { Badge, Button, Checkbox, Div, Form, Heading, IconButton, Input, Label, Row, Select, Span, Stack, Text } from "../../../ui";
5
- import { ProductInlineSelect } from "./ProductInlineSelect";
6
- import { CategoryInlineSelect } from "./CategoryInlineSelect";
3
+ /**
4
+ * SellerCouponEditorView — sectionised 2026-08-30.
5
+ *
6
+ * ## The schema ran and could not be seen
7
+ *
8
+ * Unusually for this sweep, `sellerCouponFormSchema` was genuinely parsed on
9
+ * submit. What it could not do was report: every control was a raw `<Input>`
10
+ * with **no `name`**, so `applyZodIssues` wrote errors keyed on schema paths
11
+ * that no control on the page displayed. A percentage over 100 produced a line
12
+ * in `FormErrorSummary` and nothing at all on the field that caused it.
13
+ *
14
+ * Generating the controls from the schema is what fixes that: the field name
15
+ * IS the schema key, by construction.
16
+ *
17
+ * The local error banner is gone too. It carried two different kinds of
18
+ * failure — schema issues (already listed by `FormErrorSummary`, so a second
19
+ * copy) and the caller's save error (which has no field to land on, and so is
20
+ * a toast). One surface each.
21
+ */
22
+ import React from "react";
23
+ import { Badge, Div, Heading, Row, Stack, useToast } from "../../../ui";
7
24
  import { normalizeError } from "../../../errors/normalize";
8
- import { FormErrorSummary, applyZodIssues } from "../../../ui/forms";
25
+ import { toUserMessage } from "../../../errors/error-display-map";
26
+ import { FieldInput, FormErrorSummary, applyZodIssues } from "../../../ui/forms";
27
+ import { FormShellContext, useFormShellState } from "../../../ui/forms/FormShell";
28
+ import { buildSectionsFromSchema, visibleValues } from "../../shell/build-sections";
29
+ import { SectionForm, useSectionFormNav } from "../../shell/SectionForm";
9
30
  import { sellerCouponFormSchema } from "../schemas/coupon-form";
31
+ import { ProductInlineSelect } from "./ProductInlineSelect";
32
+ import { CategoryChipPicker } from "./CategoryChipPicker";
10
33
  const __O = {
11
34
  hidden: "overflow-hidden",
12
35
  };
13
- // ---------------------------------------------------------------------------
14
- // Types
15
- // ---------------------------------------------------------------------------
16
- const CLS_SECTION_LABEL = "font-medium text-[var(--appkit-color-text-secondary)] mb-3";
17
- const TYPE_OPTIONS = [
18
- { value: "percentage", label: "Percentage off (e.g. 10%)" },
19
- { value: "fixed", label: "Fixed amount off (e.g. ₹50)" },
20
- { value: "free_shipping", label: "Free shipping" },
21
- ];
22
36
  const EMPTY_DRAFT = {
23
37
  code: "",
24
38
  type: "percentage",
@@ -33,49 +47,81 @@ const EMPTY_DRAFT = {
33
47
  applicableProducts: [],
34
48
  applicableCategories: [],
35
49
  };
36
- // ---------------------------------------------------------------------------
37
- // Component
38
- // ---------------------------------------------------------------------------
50
+ const TYPE_OPTIONS = [
51
+ { value: "percentage", label: "Percentage off (e.g. 10%)" },
52
+ { value: "fixed", label: "Fixed amount off (e.g. ₹50)" },
53
+ { value: "free_shipping", label: "Free shipping" },
54
+ ];
39
55
  export function SellerCouponEditorView({ couponId, initial, onSave, onCancel, }) {
40
- const [draft, setDraft] = useState({ ...EMPTY_DRAFT, ...initial });
41
- const [saving, setSaving] = useState(false);
42
- const [error, setError] = useState(null);
43
- const set = (key, value) => setDraft((d) => ({ ...d, [key]: value }));
44
- const handleSubmit = async (e, setFieldError) => {
45
- e.preventDefault();
46
- // Replaces four hand-rolled `if` checks that covered presence and date
47
- // order and nothing else — a 500% percentage discount, a non-numeric
48
- // value, a negative minimum spend and a per-customer limit above the
49
- // total all passed. Errors now land on the field, not in one banner.
50
- const parsed = sellerCouponFormSchema.safeParse(draft);
56
+ const isEdit = Boolean(couponId);
57
+ const { showToast } = useToast();
58
+ const [draft, setDraft] = React.useState({
59
+ ...EMPTY_DRAFT,
60
+ ...initial,
61
+ });
62
+ const [saving, setSaving] = React.useState(false);
63
+ const patch = (partial) => setDraft((prev) => Object.assign({}, prev, partial));
64
+ const sections = React.useMemo(() => buildSectionsFromSchema(sellerCouponFormSchema, {
65
+ options: { type: TYPE_OPTIONS },
66
+ renderers: {
67
+ /*
68
+ * A code identifies the coupon to customers who already have it, so
69
+ * it is fixed after creation — a prop-driven hide, which is a
70
+ * `renderer` rather than a `when`: predicates see the draft only.
71
+ */
72
+ code: ({ values, onChange, errors }) => (_jsx(FieldCode, { value: values.code, error: errors.code, disabled: isEdit, onChange: (v) => onChange({ code: v }) })),
73
+ applicableProducts: ({ values, onChange }) => (_jsx(ProductInlineSelect, { scope: "store", multiple: true, value: values.applicableProducts, onChange: (ids) => onChange({ applicableProducts: ids }), placeholder: "Restrict to specific products\u2026" })),
74
+ applicableCategories: ({ values, onChange }) => (_jsx(CategoryChipPicker, { selected: values.applicableCategories, onSelectedChange: (next) => onChange({ applicableCategories: next }), emptyHint: "Leave both empty to apply the coupon to every product in your store." })),
75
+ },
76
+ }), [isEdit]);
77
+ const nav = useSectionFormNav(sections, draft, { scope: "store:coupon-editor" });
78
+ const { shellCtx, setFieldError, clearErrors } = useFormShellState(sellerCouponFormSchema, {
79
+ sections: nav.sectionMeta,
80
+ onGoToSection: nav.goToSection,
81
+ fieldToSectionIndex: nav.fieldToSectionIndex,
82
+ });
83
+ const handleSubmit = async () => {
84
+ clearErrors();
85
+ /*
86
+ * Replaces four hand-rolled `if` checks that covered presence and date
87
+ * order and nothing else — a 500% percentage discount, a non-numeric
88
+ * value, a negative minimum spend and a per-customer limit above the
89
+ * total all passed.
90
+ */
91
+ const parsed = sellerCouponFormSchema.safeParse(visibleValues(sellerCouponFormSchema, draft));
51
92
  if (!parsed.success) {
52
- if (setFieldError) {
53
- applyZodIssues(parsed.error.issues, setFieldError);
54
- }
55
- else {
56
- setError(parsed.error.issues[0]?.message ?? "Please check the form.");
57
- }
93
+ applyZodIssues(parsed.error.issues, setFieldError);
58
94
  return;
59
95
  }
60
- setError(null);
61
96
  setSaving(true);
62
97
  try {
63
98
  await onSave(draft, couponId);
64
99
  }
65
100
  catch (err) {
66
- void normalizeError(err);
67
- setError(err.message ?? "Failed to save coupon");
101
+ const normalized = normalizeError(err);
102
+ // The CODE, never the thrown message. `err.message` is written for a
103
+ // developer, and rendering it is how a Node require stack ended up inside
104
+ // the bid modal (Root Cause #86). `toUserMessage` terminates in a
105
+ // constant, so the authored sentence below is all a user can ever see.
106
+ showToast(toUserMessage(normalized.code, undefined, {
107
+ fallback: "Could not save the coupon. Try again.",
108
+ }), "error");
68
109
  }
69
110
  finally {
70
111
  setSaving(false);
71
112
  }
72
113
  };
73
- const isEdit = Boolean(couponId);
74
- return (_jsx(Form, { schema: sellerCouponFormSchema, onSubmit: (e) => e.preventDefault(), children: ({ setFieldError }) => (_jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden}`, rounded: "xl", shadow: "sm", children: [_jsx(Div, { className: "h-[3px] w-full [background:linear-gradient(to_right,var(--appkit-color-primary-700)_0%,var(--appkit-color-cobalt)_55%,var(--appkit-color-secondary-400)_100%)]", "aria-hidden": "true" }), _jsx(Div, { border: "bottom", paddingY: "y-md-lg", padding: "x-lg", children: _jsxs(Row, { justify: "between", gap: "3", children: [_jsx(Heading, { level: 2, className: "text-[var(--appkit-color-text)]", size: "lg", weight: "semibold", children: isEdit ? "Edit Coupon" : "Create Coupon" }), isEdit && (_jsx(Badge, { variant: draft.isActive ? "success" : "default", children: draft.isActive ? "Active" : "Inactive" }))] }) }), _jsxs(Stack, { gap: "5", padding: "lg", children: [_jsx(FormErrorSummary, {}), error && (_jsx(Div, { textSize: "sm", className: "border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "lg", children: error })), _jsx(Input, { label: "Coupon Code", value: draft.code, onChange: (e) => set("code", e.target.value.toUpperCase().replace(/\s+/g, "")), placeholder: "e.g. WELCOME10", required: true, disabled: isEdit, helperText: isEdit ? "Code cannot be changed after creation" : "Customers enter this at checkout" }), _jsx(Select, { label: "Discount Type", value: draft.type, options: TYPE_OPTIONS, onChange: (e) => set("type", e.target.value) }), draft.type !== "free_shipping" && (_jsx(Input, { label: draft.type === "percentage" ? "Discount Percentage (%)" : "Discount Amount (₹)", type: "number", min: 1, max: draft.type === "percentage" ? 100 : undefined, value: draft.value, onChange: (e) => set("value", e.target.value), placeholder: draft.type === "percentage" ? "e.g. 10" : "e.g. 50", required: true, helperText: draft.type === "percentage"
75
- ? "Enter a value between 1 and 100"
76
- : "Fixed rupee discount applied to the order" })), draft.type === "percentage" && (_jsx(Input, { label: "Max Discount Cap (\u20B9, optional)", type: "number", min: 0, value: draft.maxDiscount, onChange: (e) => set("maxDiscount", e.target.value), placeholder: "Leave blank for no cap", helperText: "Maximum rupee discount regardless of percentage" })), _jsx(Input, { label: "Minimum Order Amount (\u20B9, optional)", type: "number", min: 0, value: draft.minPurchase, onChange: (e) => set("minPurchase", e.target.value), placeholder: "Leave blank for no minimum" }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Usage Limits" }), _jsxs(Div, { layout: "grid", gap: "3", className: "grid-cols-2", children: [_jsx(Input, { label: "Total Uses", type: "number", min: 0, value: draft.totalLimit, onChange: (e) => set("totalLimit", e.target.value), placeholder: "0 = unlimited" }), _jsx(Input, { label: "Per Customer", type: "number", min: 0, value: draft.perUserLimit, onChange: (e) => set("perUserLimit", e.target.value), placeholder: "0 = unlimited" })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Validity Period" }), _jsxs(Div, { layout: "grid", gap: "3", className: "grid-cols-2", children: [_jsx(Input, { label: "Start Date", type: "date", value: draft.startDate, onChange: (e) => set("startDate", e.target.value), required: true }), _jsx(Input, { label: "End Date", type: "date", value: draft.endDate, onChange: (e) => set("endDate", e.target.value), required: true })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Applicability (optional)" }), _jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable products" }), _jsx(ProductInlineSelect, { scope: "store", multiple: true, value: draft.applicableProducts, onChange: (v) => set("applicableProducts", v), placeholder: "Restrict to specific products\u2026" })] }), _jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable categories" }), _jsx(CategoryInlineSelect, { value: "", onChange: (id) => {
77
- if (!id || draft.applicableCategories.includes(id))
78
- return;
79
- set("applicableCategories", [...draft.applicableCategories, id]);
80
- }, placeholder: "Add a category\u2026" }), draft.applicableCategories.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", padding: "t-xs", children: draft.applicableCategories.map((cid) => (_jsxs(Span, { layout: "inline-flex", gap: "xs", border: "strong", padding: "pill-sm", rounded: "full", surface: "muted", color: "primary", size: "xs", children: [cid, _jsx(IconButton, { type: "button", "aria-label": `Remove ${cid}`, variant: "ghost", className: "text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text)]", onClick: () => set("applicableCategories", draft.applicableCategories.filter((c) => c !== cid)), children: "\u00D7" })] }, cid))) }))] }), _jsx(Text, { size: "xs", className: "text-[var(--appkit-color-text-secondary)]", children: "Leave both empty to apply the coupon to every product in your store." })] })] }), _jsx(Row, { className: "border border-[var(--appkit-color-border)] dark:border-[var(--appkit-color-border-dark)]", padding: "inline", align: "center", gap: "3", rounded: "lg", children: _jsxs(Label, { layout: "flex", gap: "lg", className: "cursor-pointer w-full", children: [_jsx(Checkbox, { bare: true, checked: draft.isActive, onChange: (e) => set("isActive", e.target.checked), className: "h-4 w-4 rounded border-[var(--appkit-color-border)] text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text-primary)]", weight: "medium", children: "Active" }), _jsx(Text, { size: "xs", className: "text-[var(--appkit-color-text-secondary)]", children: "Customers can apply this coupon at checkout" })] })] }) })] }), _jsx(Div, { className: "border-t border-[var(--appkit-color-border)]", padding: "inlineLg", children: _jsxs(Row, { justify: "end", gap: "3", children: [onCancel && (_jsx(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: saving, children: "Cancel" })), _jsx(Button, { type: "submit", isLoading: saving, disabled: saving, onClick: (e) => void handleSubmit(e, setFieldError), children: isEdit ? "Save Changes" : "Create Coupon" })] }) })] })) }));
114
+ return (_jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden}`, rounded: "xl", shadow: "sm", children: [_jsx(Div, { className: "h-[3px] w-full [background:linear-gradient(to_right,var(--appkit-color-primary-700)_0%,var(--appkit-color-cobalt)_55%,var(--appkit-color-secondary-400)_100%)]", "aria-hidden": "true" }), _jsx(Div, { border: "bottom", paddingY: "y-md-lg", padding: "x-lg", children: _jsxs(Row, { justify: "between", gap: "3", children: [_jsx(Heading, { level: 2, className: "text-[var(--appkit-color-text)]", size: "lg", weight: "semibold", children: isEdit ? "Edit Coupon" : "Create Coupon" }), isEdit && (_jsx(Badge, { variant: draft.isActive ? "success" : "default", children: draft.isActive ? "Active" : "Inactive" }))] }) }), _jsx(Stack, { gap: "5", padding: "lg", children: _jsxs(FormShellContext.Provider, { value: shellCtx, children: [_jsx(FormErrorSummary, {}), _jsx(SectionForm, { sections: sections, values: draft, onChange: patch, onSubmit: () => void handleSubmit(), schema: sellerCouponFormSchema, openIds: nav.openIds, onOpenChange: nav.setOpenIds, isLoading: saving, submitLabel: isEdit ? "Save changes" : "Create coupon", onCancel: onCancel, cancelLabel: "Cancel" })] }) })] }));
115
+ }
116
+ /**
117
+ * The coupon code input.
118
+ *
119
+ * Its own component rather than an inline renderer for the DEEP_NESTING reason
120
+ * — and because the uppercase-and-strip-spaces normalisation is a rule about
121
+ * the field, not about this form.
122
+ */
123
+ function FieldCode({ value, error, disabled, onChange, }) {
124
+ return (_jsx(FieldInput, { name: "code", label: "Coupon code", required: true, disabled: disabled, value: value, error: error, placeholder: "e.g. WELCOME10", hint: disabled
125
+ ? "A code cannot change once customers have it."
126
+ : "Customers enter this at checkout.", onChange: (v) => onChange(v.toUpperCase().replace(/\s+/g, "")) }));
81
127
  }
@@ -1,8 +1,15 @@
1
+ /**
2
+ * SellerDigitalCodesView — seller browse/manage of digital code listings.
3
+ *
4
+ * A named wrapper, kept so the page, the barrel and every existing import path
5
+ * stay unchanged. All behaviour is `SellerListingTypeView`; everything this
6
+ * type does differently is one entry in `SELLER_LISTING_TYPE_SPECS`.
7
+ *
8
+ * This file was 213 lines of a component that four siblings also contained
9
+ * verbatim — see that file's header for why the duplication mattered rather
10
+ * than merely being untidy.
11
+ */
1
12
  import React from "react";
2
- export interface SellerDigitalCodesViewProps {
3
- onCreateClick?: () => void;
4
- onEditClick?: (id: string) => void;
5
- onDelete?: (id: string) => Promise<void>;
6
- onBulkDelete?: (ids: string[]) => Promise<void>;
7
- }
8
- export declare function SellerDigitalCodesView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }: SellerDigitalCodesViewProps): React.JSX.Element;
13
+ import { type SellerListingTypeViewProps } from "./SellerListingTypeView";
14
+ export type SellerDigitalCodesViewProps = SellerListingTypeViewProps;
15
+ export declare function SellerDigitalCodesView(props: SellerDigitalCodesViewProps): React.JSX.Element;
@@ -1,128 +1,6 @@
1
1
  "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { sortBy } from "@mohasinac/appkit/client";
4
- import { useState, useCallback } from "react";
5
- import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
6
- import { Badge, ConfirmDeleteModal, RowActionMenu, Span, Text } from "../../../ui";
7
- import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
8
- import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
9
- import { ROUTES } from "../../../constants/index";
10
- import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../../admin/hooks/useAdminListingData";
11
- import { DataListingView } from "../../admin/components/DataListingView";
12
- import { SELLER_BULK_ACTIONS, ROW_ACTION_META } from "../../products/constants/action-defs";
13
- import { useAvailabilityScope } from "../../products/hooks/useAvailabilityScope";
14
- const LISTING_TYPES = ["digital-code"];
15
- const COLUMNS = [
16
- { key: "title", header: "Product", render: (row) => _jsx(Text, { size: "sm", weight: "medium", children: row.title }) },
17
- { key: "price", header: "Price", render: (row) => _jsx(Text, { className: "tabular-nums", size: "sm", children: row.price }) },
18
- {
19
- key: "codePoolSize",
20
- header: "Total Codes",
21
- render: (row) => (_jsx(Text, { className: "tabular-nums", size: "sm", children: row.codePoolSize !== null ? row.codePoolSize : "—" })),
22
- },
23
- {
24
- key: "codesAvailable",
25
- header: "Available",
26
- render: (row) => (_jsx(Text, { className: "tabular-nums", size: "sm", children: row.codesAvailable !== null ? row.codesAvailable : "—" })),
27
- },
28
- {
29
- key: "deliveryMethod",
30
- header: "Delivery",
31
- render: (row) => (_jsx(Span, { layout: "inline-flex", size: "xs", weight: "medium", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", transform: "capitalize", children: row.deliveryMethod.replace(/-/g, " ") })),
32
- },
33
- {
34
- key: "status",
35
- header: "Status",
36
- render: (row) => (_jsx(Badge, { variant: row.status === "active" ? "active" : "inactive", size: "xs", className: "capitalize", children: row.status })),
37
- },
38
- {
39
- key: "createdAt",
40
- header: "Created",
41
- render: (row) => (_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: row.createdAt })),
42
- },
43
- ];
44
- export function SellerDigitalCodesView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }) {
45
- const [deleteTargetId, setDeleteTargetId] = useState(null);
46
- const { deletingId, handleDelete: performDelete } = useEntityDelete({
47
- endpoint: SELLER_ENDPOINTS.PRODUCT_BY_ID,
48
- deleteFn: onDelete,
49
- successMessage: "Code deleted.",
50
- fetchOptions: { credentials: "include" },
51
- });
52
- const handleDelete = useCallback(async (id) => {
53
- await performDelete(id);
54
- setDeleteTargetId(null);
55
- }, [performDelete]);
56
- const handleEdit = useCallback((id) => {
57
- if (onEditClick)
58
- onEditClick(id);
59
- else
60
- window.location.href = String(ROUTES.STORE.DIGITAL_CODES_EDIT(id));
61
- }, [onEditClick]);
62
- const handleCreate = useCallback(() => {
63
- if (onCreateClick)
64
- onCreateClick();
65
- else
66
- window.location.href = String(ROUTES.STORE.DIGITAL_CODES_NEW);
67
- }, [onCreateClick]);
68
- const scope = useAvailabilityScope(LISTING_TYPES);
69
- const config = {
70
- portal: "seller",
71
- title: "Digital Codes",
72
- searchPlaceholder: "Search digital code listings...",
73
- emptyLabel: "No digital code listings yet",
74
- filterKeys: [],
75
- defaultSort: sortBy("createdAt", "DESC"),
76
- queryKey: ["seller", "digital-codes"],
77
- endpoint: SELLER_ENDPOINTS.PRODUCTS,
78
- sortOptions: [
79
- { value: sortBy("createdAt", "DESC"), label: "Newest" },
80
- { value: sortBy("createdAt", "ASC"), label: "Oldest" },
81
- { value: "title", label: "Name A–Z" },
82
- { value: sortBy("price", "ASC"), label: "Price: Low–High" },
83
- ],
84
- columns: COLUMNS,
85
- mapRows: (response) => toRecordArray(response.products).map((item, index) => {
86
- const dc = (item.digitalCode ?? {});
87
- return {
88
- id: toStringValue(item.id, `dc-${index}`),
89
- title: toStringValue(item.productTitle ?? item.title, "Untitled"),
90
- price: toCurrency(item.price),
91
- codePoolSize: typeof dc.codePoolSize === "number" ? dc.codePoolSize : null,
92
- codesAvailable: typeof dc.codesAvailable === "number" ? dc.codesAvailable : null,
93
- deliveryMethod: toStringValue(dc.codeDeliveryMethod, "auto-claim"),
94
- status: toStringValue(item.status, "draft"),
95
- createdAt: toRelativeDate(item.createdAt),
96
- };
97
- }),
98
- getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
99
- buildFilters: () => "listingType==digital-code",
100
- buildExtraParams: () => scope.extraParams,
101
- renderAboveContent: scope.renderAboveContent,
102
- primaryAction: { label: "New Digital Code", onClick: () => handleCreate() },
103
- // Mirrors the "Edit" row action below so table rows and cards both navigate on click.
104
- onRowClick: (row) => handleEdit(row.id),
105
- // Rule #7: bulk-action array sourced from the SELLER_BULK_ACTIONS preset.
106
- buildBulkActions: onBulkDelete
107
- ? (selection) => SELLER_BULK_ACTIONS.digitalCodes.map((id) => ({
108
- id,
109
- label: ROW_ACTION_META[id].label,
110
- destructive: ROW_ACTION_META[id].destructive,
111
- onClick: async () => {
112
- await onBulkDelete(selection.selectedIds);
113
- selection.clearSelection();
114
- },
115
- }))
116
- : undefined,
117
- renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
118
- { label: ACTIONS.STORE["edit-listing"].label, onClick: () => handleEdit(row.id) },
119
- {
120
- label: ACTIONS.STORE["delete-listing"].label,
121
- destructive: true,
122
- onClick: () => setDeleteTargetId(row.id),
123
- disabled: deletingId === row.id,
124
- },
125
- ] })),
126
- };
127
- return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Digital Code Listing", message: "Are you sure you want to delete this digital code listing? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { SellerListingTypeView, } from "./SellerListingTypeView";
4
+ export function SellerDigitalCodesView(props) {
5
+ return _jsx(SellerListingTypeView, { type: "digital-code", ...props });
128
6
  }
@@ -0,0 +1,66 @@
1
+ import React from "react";
2
+ import type { JsonValue } from "../../../schemas/types";
3
+ import type { AdminTableColumn } from "../../admin/types";
4
+ import { SELLER_BULK_ACTIONS } from "../../products/constants/action-defs";
5
+ /**
6
+ * The shared row, plus whatever a spec's `extraFields` adds.
7
+ *
8
+ * Extra values are display STRINGS, deliberately — every per-type column in the
9
+ * five originals rendered text, a pill or a badge derived from one value, and a
10
+ * string keeps the row type non-generic so the columns array needs no type
11
+ * parameter threaded through five call sites.
12
+ */
13
+ export interface SellerListingRow {
14
+ [key: string]: string;
15
+ id: string;
16
+ title: string;
17
+ price: string;
18
+ status: string;
19
+ createdAt: string;
20
+ }
21
+ export interface SellerListingTypeSpec {
22
+ /** Seller-side edit route. The plugin registry carries only PUBLIC routes. */
23
+ editRoute: (id: string) => string;
24
+ /** Seller-side "create new" route. */
25
+ newRoute: string;
26
+ /** Primary CTA label — not derivable ("New Art Print" vs "New Live Item"). */
27
+ createLabel: string;
28
+ /** Which `SELLER_BULK_ACTIONS` preset backs the bulk bar. */
29
+ bulkKey: keyof typeof SELLER_BULK_ACTIONS;
30
+ /** What this type calls one of its listings in the delete dialog. */
31
+ deleteLabel: string;
32
+ searchPlaceholder: string;
33
+ emptyLabel: string;
34
+ /** Heading override; defaults to the plugin's `pluralLabel`. */
35
+ title?: string;
36
+ /** Header for the first column. Defaults to "Listing". */
37
+ titleHeader?: string;
38
+ /** Header for the last column. Defaults to "Created". */
39
+ createdHeader?: string;
40
+ /** Toast on a successful delete. Defaults to "Listing deleted." */
41
+ deleteSuccess?: string;
42
+ /** Per-type row values, read off the raw document. */
43
+ extraFields?: (item: Record<string, JsonValue>) => Record<string, string>;
44
+ /** Columns inserted between Price and Status. */
45
+ extraColumns?: AdminTableColumn<SellerListingRow>[];
46
+ }
47
+ /**
48
+ * Everything that genuinely differs between the five, in one place.
49
+ *
50
+ * A `Record<…, SellerListingTypeSpec>` rather than a `Partial`: a key here is a
51
+ * deliberate claim that this type has a dedicated seller browse page, and the
52
+ * type union is deliberately the narrow set of five rather than `ListingType`,
53
+ * because standard / auction / pre-order / prize-draw do NOT have one — their
54
+ * store routes redirect into the multi-type `SellerProductsView`.
55
+ */
56
+ export type SellerListingTypeKey = "art" | "stickers" | "classified" | "digital-code" | "live";
57
+ export declare const SELLER_LISTING_TYPE_SPECS: Record<SellerListingTypeKey, SellerListingTypeSpec>;
58
+ export interface SellerListingTypeViewProps {
59
+ onCreateClick?: () => void;
60
+ onEditClick?: (id: string) => void;
61
+ onDelete?: (id: string) => Promise<void>;
62
+ onBulkDelete?: (ids: string[]) => Promise<void>;
63
+ }
64
+ export declare function SellerListingTypeView({ type, onCreateClick, onEditClick, onDelete, onBulkDelete, }: SellerListingTypeViewProps & {
65
+ type: SellerListingTypeKey;
66
+ }): React.JSX.Element;