@mohasinac/appkit 4.30.18 β†’ 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 (557) hide show
  1. package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +5 -2
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -3
  3. package/dist/_internal/client/features/layout/useSidebarSearch.d.ts +21 -5
  4. package/dist/_internal/client/features/layout/useSidebarSearch.js +27 -6
  5. package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +23 -3
  6. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +106 -86
  7. package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +16 -5
  8. package/dist/_internal/client/features/lottery/LotteryPullForm.js +65 -40
  9. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +5 -2
  10. package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +11 -3
  11. package/dist/_internal/client/hand-mode/HandModeProvider.js +2 -0
  12. package/dist/_internal/server/features/auctions/actions.js +14 -3
  13. package/dist/_internal/server/features/auctions/service.js +1 -1
  14. package/dist/_internal/server/features/auth/permissions.d.ts +2 -0
  15. package/dist/_internal/server/features/auth/permissions.js +3 -2
  16. package/dist/_internal/server/features/blog/data.js +2 -2
  17. package/dist/_internal/server/features/blog/service.js +3 -3
  18. package/dist/_internal/server/features/brands/data.js +1 -1
  19. package/dist/_internal/server/features/brands/service.js +3 -3
  20. package/dist/_internal/server/features/bundles/actions.js +6 -1
  21. package/dist/_internal/server/features/bundles/data.js +21 -4
  22. package/dist/_internal/server/features/cart/data.js +3 -1
  23. package/dist/_internal/server/features/cart/service.js +13 -2
  24. package/dist/_internal/server/features/categories/data.js +26 -6
  25. package/dist/_internal/server/features/classified/index.d.ts +0 -1
  26. package/dist/_internal/server/features/classified/index.js +0 -1
  27. package/dist/_internal/server/features/digital-code/index.d.ts +0 -1
  28. package/dist/_internal/server/features/digital-code/index.js +0 -1
  29. package/dist/_internal/server/features/events/actions.js +17 -4
  30. package/dist/_internal/server/features/events/data.js +1 -1
  31. package/dist/_internal/server/features/events/service.js +1 -1
  32. package/dist/_internal/server/features/grouped/data.js +7 -2
  33. package/dist/_internal/server/features/item-requests/data.js +1 -1
  34. package/dist/_internal/server/features/live/index.d.ts +0 -1
  35. package/dist/_internal/server/features/live/index.js +0 -1
  36. package/dist/_internal/server/features/lottery/actions.js +2 -2
  37. package/dist/_internal/server/features/lottery/data.js +1 -1
  38. package/dist/_internal/server/features/orders/actions.js +7 -7
  39. package/dist/_internal/server/features/orders/data.d.ts +1 -1
  40. package/dist/_internal/server/features/orders/data.js +14 -2
  41. package/dist/_internal/server/features/orders/service.js +1 -1
  42. package/dist/_internal/server/features/pre-orders/service.js +1 -1
  43. package/dist/_internal/server/features/prize-draws/actions.js +1 -1
  44. package/dist/_internal/server/features/products/data.js +21 -6
  45. package/dist/_internal/server/features/products/list-public.d.ts +9 -0
  46. package/dist/_internal/server/features/products/list-public.js +95 -7
  47. package/dist/_internal/server/features/products/service.js +1 -1
  48. package/dist/_internal/server/features/promotions/actions.js +1 -1
  49. package/dist/_internal/server/features/promotions/data.js +1 -1
  50. package/dist/_internal/server/features/promotions/service.js +1 -1
  51. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  52. package/dist/_internal/server/features/reviews/data.js +6 -1
  53. package/dist/_internal/server/features/reviews/og-data.js +1 -1
  54. package/dist/_internal/server/features/shared/listing-data-factory.js +7 -2
  55. package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
  56. package/dist/_internal/server/features/site-settings/adapters.js +8 -5
  57. package/dist/_internal/server/features/stores/data.js +1 -1
  58. package/dist/_internal/server/features/sublisting-categories/data.js +1 -1
  59. package/dist/_internal/server/features/tester/visibility.d.ts +2 -1
  60. package/dist/_internal/server/features/tester/visibility.js +2 -2
  61. package/dist/_internal/server/functions/scheduled.d.ts +3 -1
  62. package/dist/_internal/server/functions/scheduled.js +27 -1
  63. package/dist/_internal/server/jobs/core/auctionSettlement.js +6 -1
  64. package/dist/_internal/server/jobs/core/hardBanCascade.js +4 -0
  65. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  66. package/dist/_internal/server/jobs/core/index.js +2 -0
  67. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +7 -15
  68. package/dist/_internal/server/jobs/core/pageViewPrune.d.ts +10 -0
  69. package/dist/_internal/server/jobs/core/pageViewPrune.js +44 -0
  70. package/dist/_internal/server/jobs/core/pageViewRollup.d.ts +2 -0
  71. package/dist/_internal/server/jobs/core/pageViewRollup.js +87 -0
  72. package/dist/_internal/server/jobs/core/revenueRollup.js +7 -1
  73. package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
  74. package/dist/_internal/server/jobs/handlers/index.js +2 -0
  75. package/dist/_internal/server/jobs/handlers/pageViewPrune.d.ts +2 -0
  76. package/dist/_internal/server/jobs/handlers/pageViewPrune.js +2 -0
  77. package/dist/_internal/server/jobs/handlers/pageViewRollup.d.ts +2 -0
  78. package/dist/_internal/server/jobs/handlers/pageViewRollup.js +2 -0
  79. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  80. package/dist/_internal/shared/actions/action-registry.js +69 -22
  81. package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -4
  82. package/dist/_internal/shared/checkout/rules/classified.rule.js +7 -2
  83. package/dist/_internal/shared/features/layout/matchesNavQuery.d.ts +14 -0
  84. package/dist/_internal/shared/features/layout/matchesNavQuery.js +72 -0
  85. package/dist/_internal/shared/features/layout/types.d.ts +37 -1
  86. package/dist/_internal/shared/features/layout/types.js +19 -1
  87. package/dist/_internal/shared/features/notifications/action-url.d.ts +9 -1
  88. package/dist/_internal/shared/features/notifications/action-url.js +47 -0
  89. package/dist/_internal/shared/features/offers/config.d.ts +65 -0
  90. package/dist/_internal/shared/features/offers/config.js +73 -2
  91. package/dist/_internal/shared/features/orders/schema.d.ts +19 -1
  92. package/dist/_internal/shared/features/orders/schema.js +22 -2
  93. package/dist/_internal/shared/features/site-settings/types.d.ts +12 -3
  94. package/dist/_internal/shared/listing-types/capabilities.d.ts +8 -2
  95. package/dist/_internal/shared/listing-types/capabilities.js +6 -1
  96. package/dist/_internal/shared/listing-types/classified/ctas.js +6 -1
  97. package/dist/_internal/shared/listing-types/feature-flags.d.ts +10 -5
  98. package/dist/_internal/shared/listing-types/feature-flags.js +11 -6
  99. package/dist/client/api/useApiQuery.js +17 -6
  100. package/dist/client.d.ts +38 -20
  101. package/dist/client.js +39 -14
  102. package/dist/configs/next.js +10 -2
  103. package/dist/constants/api-endpoints.d.ts +18 -54
  104. package/dist/constants/api-endpoints.js +6 -26
  105. package/dist/constants/field-names.d.ts +6 -24
  106. package/dist/constants/field-names.js +10 -27
  107. package/dist/constants/geo/countries.d.ts +50 -0
  108. package/dist/constants/geo/countries.js +129 -0
  109. package/dist/constants/geo/subdivisions.d.ts +13 -0
  110. package/dist/constants/geo/subdivisions.js +104 -0
  111. package/dist/constants/index.d.ts +2 -2
  112. package/dist/constants/index.js +2 -2
  113. package/dist/constants/table-keys.d.ts +24 -0
  114. package/dist/constants/table-keys.js +28 -0
  115. package/dist/contracts/client-realtime.d.ts +6 -0
  116. package/dist/contracts/extend.d.ts +0 -9
  117. package/dist/contracts/index.d.ts +1 -1
  118. package/dist/contracts/realtime-session.d.ts +12 -12
  119. package/dist/contracts/realtime-session.js +79 -77
  120. package/dist/core/browser.d.ts +1 -1
  121. package/dist/core/browser.js +1 -1
  122. package/dist/core/index.d.ts +1 -1
  123. package/dist/core/index.js +1 -1
  124. package/dist/core/site-config.d.ts +0 -3
  125. package/dist/core/site-config.js +0 -3
  126. package/dist/errors/index.d.ts +1 -1
  127. package/dist/errors/index.js +1 -1
  128. package/dist/errors/messages.d.ts +0 -8
  129. package/dist/errors/messages.js +0 -9
  130. package/dist/features/about/components/DeveloperView.js +7 -2
  131. package/dist/features/about/components/PolicyPageView.js +9 -1
  132. package/dist/features/about/components/PublicProfileView.js +23 -5
  133. package/dist/features/about/schemas/index.d.ts +8 -8
  134. package/dist/features/account/components/AddressFilters.js +32 -11
  135. package/dist/features/account/components/AddressForm.d.ts +26 -25
  136. package/dist/features/account/components/AddressForm.js +81 -103
  137. package/dist/features/account/components/AddressesIndexListing.js +8 -4
  138. package/dist/features/account/components/NotificationBell.js +4 -3
  139. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  140. package/dist/features/account/components/UserOffersPanel.js +1 -1
  141. package/dist/features/account/components/UserSidebar.d.ts +3 -4
  142. package/dist/features/account/components/UserSupportView.js +89 -58
  143. package/dist/features/account/components/index.d.ts +1 -7
  144. package/dist/features/account/components/index.js +0 -3
  145. package/dist/features/account/hooks/useAddresses.d.ts +4 -3
  146. package/dist/features/account/hooks/useAddresses.js +4 -6
  147. package/dist/features/account/hooks/useCollapsedSections.d.ts +51 -10
  148. package/dist/features/account/hooks/useCollapsedSections.js +211 -38
  149. package/dist/features/account/hooks/useProfile.d.ts +8 -0
  150. package/dist/features/account/index.d.ts +0 -3
  151. package/dist/features/account/index.js +0 -3
  152. package/dist/features/account/schemas/index.d.ts +0 -92
  153. package/dist/features/account/schemas/index.js +42 -20
  154. package/dist/features/addresses/components/AddressLocationFields.d.ts +13 -0
  155. package/dist/features/addresses/components/AddressLocationFields.js +41 -0
  156. package/dist/features/addresses/hooks/usePostalLookup.d.ts +17 -0
  157. package/dist/features/addresses/hooks/usePostalLookup.js +133 -0
  158. package/dist/features/addresses/schemas/address-form.d.ts +423 -0
  159. package/dist/features/addresses/schemas/address-form.js +212 -0
  160. package/dist/features/addresses/schemas/index.d.ts +1 -0
  161. package/dist/features/addresses/schemas/index.js +8 -0
  162. package/dist/features/admin/actions/admin-read-actions.d.ts +1 -1
  163. package/dist/features/admin/actions/index.d.ts +0 -1
  164. package/dist/features/admin/actions/index.js +0 -1
  165. package/dist/features/admin/actions/notification-actions.js +1 -41
  166. package/dist/features/admin/components/AdminActionIndexView.d.ts +32 -0
  167. package/dist/features/admin/components/AdminActionIndexView.js +128 -0
  168. package/dist/features/admin/components/AdminAdEditorView.js +159 -163
  169. package/dist/features/admin/components/AdminAddressEditorView.js +97 -55
  170. package/dist/features/admin/components/AdminBrandEditorView.d.ts +15 -0
  171. package/dist/features/admin/components/AdminBrandEditorView.js +113 -77
  172. package/dist/features/admin/components/AdminBundleEditorView.d.ts +19 -9
  173. package/dist/features/admin/components/AdminBundleEditorView.js +136 -168
  174. package/dist/features/admin/components/AdminCategoryEditorView.js +120 -43
  175. package/dist/features/admin/components/AdminCouponEditorView.js +145 -109
  176. package/dist/features/admin/components/AdminEmployeeEditorView.js +125 -56
  177. package/dist/features/admin/components/AdminFaqEditorView.js +112 -58
  178. package/dist/features/admin/components/AdminFeatureEditorView.js +108 -68
  179. package/dist/features/admin/components/AdminFulfillmentView.js +5 -2
  180. package/dist/features/admin/components/AdminMediaView.js +3 -3
  181. package/dist/features/admin/components/AdminNavEditorView.js +69 -44
  182. package/dist/features/admin/components/AdminOrderEditorView.js +47 -10
  183. package/dist/features/admin/components/AdminPrizeDrawsView.js +16 -2
  184. package/dist/features/admin/components/AdminSidebar.d.ts +11 -7
  185. package/dist/features/admin/components/AdminSiteSettingsView.js +37 -37
  186. package/dist/features/admin/components/AdminStoreEditorView.js +75 -52
  187. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +71 -30
  188. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +95 -65
  189. package/dist/features/admin/components/BrandQuickCreateForm.d.ts +10 -0
  190. package/dist/features/admin/components/BrandQuickCreateForm.js +49 -26
  191. package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +11 -0
  192. package/dist/features/admin/components/CategoryQuickCreateForm.js +48 -26
  193. package/dist/features/admin/components/index.d.ts +2 -2
  194. package/dist/features/admin/components/index.js +1 -1
  195. package/dist/features/admin/constants/site-settings-tabs.d.ts +120 -0
  196. package/dist/features/admin/constants/site-settings-tabs.js +152 -0
  197. package/dist/features/admin/index.d.ts +0 -3
  198. package/dist/features/admin/index.js +0 -2
  199. package/dist/features/admin/repository/analytics-rollup.repository.d.ts +35 -0
  200. package/dist/features/admin/repository/analytics-rollup.repository.js +30 -0
  201. package/dist/features/admin/schemas/admin-editor-forms.d.ts +56 -57
  202. package/dist/features/admin/schemas/admin-editor-forms.js +97 -54
  203. package/dist/features/admin/schemas/admin-ops-forms.d.ts +57 -5
  204. package/dist/features/admin/schemas/admin-ops-forms.js +104 -20
  205. package/dist/features/admin/schemas/admin-user-form.js +7 -0
  206. package/dist/features/admin/schemas/firestore.d.ts +48 -95
  207. package/dist/features/admin/schemas/firestore.js +15 -151
  208. package/dist/features/admin/schemas/nav-item-form.js +9 -2
  209. package/dist/features/admin/server.d.ts +0 -4
  210. package/dist/features/admin/server.js +0 -2
  211. package/dist/features/admin/types/index.d.ts +0 -7
  212. package/dist/features/analytics/repository/page-views.repository.d.ts +14 -0
  213. package/dist/features/analytics/repository/page-views.repository.js +24 -0
  214. package/dist/features/analytics/types.d.ts +1 -1
  215. package/dist/features/analytics/types.js +13 -0
  216. package/dist/features/auctions/components/AuctionDetailPageView.js +6 -2
  217. package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -1
  218. package/dist/features/auth/actions/index.d.ts +0 -1
  219. package/dist/features/auth/actions/index.js +0 -1
  220. package/dist/features/auth/actions/profile-actions.js +4 -3
  221. package/dist/features/auth/actions/realtime-token-actions.js +1 -12
  222. package/dist/features/auth/auth-helpers.js +5 -7
  223. package/dist/features/auth/components/ForgotPasswordView.js +1 -1
  224. package/dist/features/auth/components/Guards.js +2 -1
  225. package/dist/features/auth/components/LoginForm.d.ts +0 -2
  226. package/dist/features/auth/components/LoginForm.js +2 -4
  227. package/dist/features/auth/components/RegisterForm.js +62 -19
  228. package/dist/features/auth/components/ResetPasswordView.js +1 -1
  229. package/dist/features/auth/hooks/useAuth.js +3 -0
  230. package/dist/features/auth/permissions/constants.d.ts +27 -1
  231. package/dist/features/auth/role-predicates.d.ts +75 -7
  232. package/dist/features/auth/role-predicates.js +28 -2
  233. package/dist/features/auth/schemas/firestore.d.ts +22 -0
  234. package/dist/features/auth/schemas/index.d.ts +1 -1
  235. package/dist/features/auth/schemas/index.js +44 -8
  236. package/dist/features/auth/types/index.d.ts +14 -1
  237. package/dist/features/blog/api/route.js +10 -2
  238. package/dist/features/blog/components/BlogIndexListing.js +1 -1
  239. package/dist/features/blog/hooks/useBlog.js +2 -2
  240. package/dist/features/blog/repository/blog.repository.js +3 -1
  241. package/dist/features/blog/schemas/index.d.ts +4 -0
  242. package/dist/features/blog/schemas/index.js +2 -0
  243. package/dist/features/blog/types/index.d.ts +1 -1
  244. package/dist/features/cart/actions/cart-actions.js +13 -4
  245. package/dist/features/cart/utils/pending-ops.js +1 -1
  246. package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +22 -0
  247. package/dist/features/catalogue/components/CatalogueItemEditorView.js +112 -52
  248. package/dist/features/catalogue/schemas/validation.d.ts +4 -4
  249. package/dist/features/catalogue/schemas/validation.js +47 -10
  250. package/dist/features/categories/components/BrandDetailPageView.js +28 -12
  251. package/dist/features/categories/components/CategoryDetailPageView.js +37 -20
  252. package/dist/features/categories/repository/categories.repository.js +3 -1
  253. package/dist/features/categories/schemas/bundle-form.d.ts +142 -0
  254. package/dist/features/categories/schemas/bundle-form.js +149 -0
  255. package/dist/features/checkout/actions/checkout-value-otp-actions.js +10 -1
  256. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +1 -1
  257. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +5 -4
  258. package/dist/features/classified/components/ClassifiedDetailPageView.js +47 -18
  259. package/dist/features/consultation/components/ConsultationForm.js +1 -1
  260. package/dist/features/consultation/schemas/index.js +34 -10
  261. package/dist/features/corporate/schemas/index.js +36 -15
  262. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +4 -1
  263. package/dist/features/events/components/EventBanner.js +5 -2
  264. package/dist/features/events/components/EventOfferCard.js +3 -1
  265. package/dist/features/events/components/EventPollWidget.js +1 -1
  266. package/dist/features/events/components/SpinWheelView.js +3 -2
  267. package/dist/features/filters/FilterPanel.js +3 -3
  268. package/dist/features/filters/RangeFilter.d.ts +10 -0
  269. package/dist/features/filters/RangeFilter.js +41 -4
  270. package/dist/features/grouped/components/GroupedListingEditorView.js +2 -1
  271. package/dist/features/history/hooks/useHistory.js +29 -27
  272. package/dist/features/homepage/components/AdSlot.js +3 -1
  273. package/dist/features/homepage/components/GoogleReviewsSection.js +8 -2
  274. package/dist/features/homepage/components/MarketplaceHomepageView.js +58 -15
  275. package/dist/features/homepage/components/SocialFeedSection.js +4 -1
  276. package/dist/features/homepage/hooks/useBlogArticles.js +1 -1
  277. package/dist/features/homepage/lib/live-stats.js +8 -1
  278. package/dist/features/homepage/repository/carousel.repository.js +2 -1
  279. package/dist/features/layout/BottomActions.js +84 -11
  280. package/dist/features/layout/BottomActionsContext.d.ts +1 -6
  281. package/dist/features/layout/BottomActionsContext.js +1 -1
  282. package/dist/features/layout/hooks/useBottomActions.js +2 -2
  283. package/dist/features/layout/hooks/useFormBottomActions.d.ts +12 -1
  284. package/dist/features/layout/hooks/useFormBottomActions.js +12 -6
  285. package/dist/features/live/components/LiveItemDetailPageView.js +4 -1
  286. package/dist/features/lottery/schemas/config-write.d.ts +9 -5
  287. package/dist/features/lottery/schemas/config-write.js +69 -9
  288. package/dist/features/media/finalize.js +3 -1
  289. package/dist/features/media/modals/ImageEditor.js +1 -1
  290. package/dist/features/media/modals/VideoThumbnailSelector.js +5 -2
  291. package/dist/features/media/modals/VideoTrimModal.js +5 -2
  292. package/dist/features/media/upload/MediaUploadField.js +2 -2
  293. package/dist/features/messages/hooks/useConversation.js +18 -4
  294. package/dist/features/messages/hooks/useConversations.js +25 -8
  295. package/dist/features/orders/components/RefundRequestView.js +5 -2
  296. package/dist/features/orders/schemas/buyer-forms.d.ts +6 -3
  297. package/dist/features/orders/schemas/buyer-forms.js +31 -3
  298. package/dist/features/orders/schemas/index.d.ts +2 -2
  299. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -1
  300. package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
  301. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -1
  302. package/dist/features/products/components/GroupSettingsPanel.js +3 -1
  303. package/dist/features/products/components/MakeOfferButton.d.ts +13 -2
  304. package/dist/features/products/components/MakeOfferButton.js +33 -11
  305. package/dist/features/products/components/PrizeDrawDetailPageView.js +4 -1
  306. package/dist/features/products/components/ProductDetailActions.js +0 -1
  307. package/dist/features/products/components/ProductDetailPageView.d.ts +7 -3
  308. package/dist/features/products/components/ProductDetailPageView.js +16 -7
  309. package/dist/features/products/components/ShareButton.js +3 -1
  310. package/dist/features/products/constants/action-defs.d.ts +1 -2
  311. package/dist/features/products/constants/action-defs.js +40 -43
  312. package/dist/features/products/repository/loadProductFeatures.js +10 -2
  313. package/dist/features/products/repository/products.repository.d.ts +5 -1
  314. package/dist/features/products/repository/products.repository.js +25 -2
  315. package/dist/features/products/schemas/firestore.d.ts +7 -3
  316. package/dist/features/products/schemas/product-features.validators.js +3 -0
  317. package/dist/features/promotions/components/CouponCard.js +11 -8
  318. package/dist/features/reviews/actions/review-actions.js +8 -1
  319. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -3
  320. package/dist/features/reviews/components/ReviewDetailShell.js +3 -1
  321. package/dist/features/scams/actions/scam-actions.d.ts +9 -1
  322. package/dist/features/scams/actions/scam-actions.js +52 -12
  323. package/dist/features/scams/components/SellerTrustBadge.d.ts +1 -1
  324. package/dist/features/scams/components/SellerTrustBadge.js +13 -0
  325. package/dist/features/scams/repository/scammer.repository.js +2 -1
  326. package/dist/features/scams/schemas/firestore.d.ts +15 -1
  327. package/dist/features/scams/schemas/report-form.d.ts +5 -5
  328. package/dist/features/scams/schemas/report-form.js +18 -3
  329. package/dist/features/search/action-index/derive.d.ts +49 -0
  330. package/dist/features/search/action-index/derive.js +121 -0
  331. package/dist/features/search/action-index/repository.d.ts +42 -0
  332. package/dist/features/search/action-index/repository.js +100 -0
  333. package/dist/features/search/action-index/settings-entries.d.ts +41 -0
  334. package/dist/features/search/action-index/settings-entries.js +268 -0
  335. package/dist/features/search/action-index/types.d.ts +81 -0
  336. package/dist/features/search/action-index/types.js +102 -0
  337. package/dist/features/search/action-index/validate-entry.d.ts +34 -0
  338. package/dist/features/search/action-index/validate-entry.js +114 -0
  339. package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
  340. package/dist/features/search/hooks/useNavSuggestions.js +23 -3
  341. package/dist/features/search/repository/search.repository.js +3 -1
  342. package/dist/features/seller/actions/offer-actions.js +43 -19
  343. package/dist/features/seller/actions/seller-actions.js +29 -5
  344. package/dist/features/seller/components/CategoryChipPicker.d.ts +9 -0
  345. package/dist/features/seller/components/CategoryChipPicker.js +12 -0
  346. package/dist/features/seller/components/FulfillmentView.js +5 -2
  347. package/dist/features/seller/components/PhysicalLocationModal.js +1 -1
  348. package/dist/features/seller/components/PrintCenterView.js +3 -1
  349. package/dist/features/seller/components/SellerAddressesView.js +5 -1
  350. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +83 -43
  351. package/dist/features/seller/components/SellerArtView.d.ts +14 -7
  352. package/dist/features/seller/components/SellerArtView.js +4 -119
  353. package/dist/features/seller/components/SellerBidsView.js +1 -1
  354. package/dist/features/seller/components/SellerClassifiedView.d.ts +14 -7
  355. package/dist/features/seller/components/SellerClassifiedView.js +4 -124
  356. package/dist/features/seller/components/SellerCouponEditorView.d.ts +22 -1
  357. package/dist/features/seller/components/SellerCouponEditorView.js +91 -45
  358. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  359. package/dist/features/seller/components/SellerDigitalCodesView.d.ts +14 -7
  360. package/dist/features/seller/components/SellerDigitalCodesView.js +4 -126
  361. package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
  362. package/dist/features/seller/components/SellerListingTypeView.d.ts +66 -0
  363. package/dist/features/seller/components/SellerListingTypeView.js +277 -0
  364. package/dist/features/seller/components/SellerLiveView.d.ts +14 -7
  365. package/dist/features/seller/components/SellerLiveView.js +4 -126
  366. package/dist/features/seller/components/SellerOrdersView.js +3 -3
  367. package/dist/features/seller/components/SellerPayoutMethodsView.js +2 -2
  368. package/dist/features/seller/components/SellerProductShell.d.ts +5 -0
  369. package/dist/features/seller/components/SellerProductShell.js +15 -5
  370. package/dist/features/seller/components/SellerProductsView.js +24 -10
  371. package/dist/features/seller/components/SellerReviewsView.js +47 -16
  372. package/dist/features/seller/components/SellerShippingConfigsView.js +5 -4
  373. package/dist/features/seller/components/SellerSidebar.d.ts +3 -6
  374. package/dist/features/seller/components/SellerStickersView.d.ts +14 -7
  375. package/dist/features/seller/components/SellerStickersView.js +4 -119
  376. package/dist/features/seller/components/SellerStoreCategoriesView.js +3 -2
  377. package/dist/features/seller/components/SellerSupportView.d.ts +31 -0
  378. package/dist/features/seller/components/SellerSupportView.js +100 -0
  379. package/dist/features/seller/components/index.d.ts +4 -8
  380. package/dist/features/seller/components/index.js +2 -4
  381. package/dist/features/seller/index.d.ts +0 -1
  382. package/dist/features/seller/index.js +0 -1
  383. package/dist/features/seller/schemas/coupon-form.d.ts +214 -0
  384. package/dist/features/seller/schemas/coupon-form.js +155 -23
  385. package/dist/features/seller/schemas/offer-forms.d.ts +16 -7
  386. package/dist/features/seller/schemas/offer-forms.js +28 -12
  387. package/dist/features/shell/FormShell.js +2 -2
  388. package/dist/features/shell/QuickFormDrawer.js +2 -2
  389. package/dist/features/shell/SectionForm.d.ts +19 -1
  390. package/dist/features/shell/SectionForm.js +104 -17
  391. package/dist/features/shell/build-sections.d.ts +23 -0
  392. package/dist/features/shell/build-sections.js +106 -8
  393. package/dist/features/shell/field-ui-meta.d.ts +44 -0
  394. package/dist/features/shell/field-ui-meta.js +14 -7
  395. package/dist/features/shell/form-sections.d.ts +46 -0
  396. package/dist/features/shell/form-sections.js +114 -0
  397. package/dist/features/shipments/components/AdminShipmentEditorView.js +87 -64
  398. package/dist/features/shipments/schemas/validation.d.ts +2 -2
  399. package/dist/features/shipments/schemas/validation.js +44 -13
  400. package/dist/features/store-extensions/schemas/custom-role-form.js +6 -2
  401. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +7 -7
  402. package/dist/features/store-extensions/schemas/payout-method-form.js +14 -0
  403. package/dist/features/stores/actions/store-query-actions.js +3 -2
  404. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -1
  405. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -1
  406. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  407. package/dist/features/stores/components/StoreDetailLayoutView.js +12 -3
  408. package/dist/features/support/repository/support.repository.d.ts +21 -0
  409. package/dist/features/support/repository/support.repository.js +63 -0
  410. package/dist/features/support/schemas/firestore.d.ts +27 -2
  411. package/dist/features/support/schemas/firestore.js +2 -0
  412. package/dist/features/support/schemas/ticket-create-form.js +7 -0
  413. package/dist/features/tester/schemas/checklist-item-form.d.ts +43 -0
  414. package/dist/features/tester/schemas/checklist-item-form.js +109 -0
  415. package/dist/features/tester/seed-data/blog-tester-seed-data.js +2 -2
  416. package/dist/features/tester/seed-data/categories-tester-seed-data.js +2 -2
  417. package/dist/features/tester/seed-data/events-tester-seed-data.js +5 -5
  418. package/dist/features/tester/seed-data/orders-tester-seed-data.js +2 -2
  419. package/dist/features/tester/seed-data/products-tester-seed-data.js +48 -49
  420. package/dist/features/tester/seed-data/stores-tester-seed-data.js +3 -3
  421. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +291 -30
  422. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +51 -14
  423. package/dist/features/wishlist/hooks/useWishlistToggle.js +8 -1
  424. package/dist/http/api-handler.js +2 -1
  425. package/dist/index.d.ts +25 -104
  426. package/dist/index.js +38 -143
  427. package/dist/jobs.d.ts +1 -1
  428. package/dist/jobs.js +1 -1
  429. package/dist/monitoring/browser.d.ts +0 -2
  430. package/dist/monitoring/browser.js +12 -1
  431. package/dist/monitoring/index.d.ts +0 -2
  432. package/dist/monitoring/index.js +0 -1
  433. package/dist/next/api/routeHandler.js +9 -4
  434. package/dist/next/index.d.ts +1 -2
  435. package/dist/next/index.js +0 -1
  436. package/dist/next/middleware/index.d.ts +0 -2
  437. package/dist/next/middleware/index.js +0 -1
  438. package/dist/next/routing/route-map.d.ts +8 -7
  439. package/dist/next/routing/route-map.js +10 -3
  440. package/dist/providers/auth-firebase/session.js +3 -1
  441. package/dist/providers/db-firebase/admin-app-lite.js +8 -8
  442. package/dist/providers/db-firebase/admin.js +27 -13
  443. package/dist/providers/db-firebase/browser-stub.d.ts +1 -11
  444. package/dist/providers/db-firebase/browser-stub.js +6 -11
  445. package/dist/providers/db-firebase/index.d.ts +0 -1
  446. package/dist/providers/db-firebase/index.js +0 -1
  447. package/dist/providers/db-firebase/rtdb-paths.d.ts +15 -6
  448. package/dist/providers/db-firebase/rtdb-paths.js +15 -6
  449. package/dist/providers/db-firebase/rtdb-url.d.ts +27 -0
  450. package/dist/providers/db-firebase/rtdb-url.js +50 -0
  451. package/dist/providers/db-firebase/sieve.d.ts +22 -0
  452. package/dist/providers/firebase-client/realtime.d.ts +20 -0
  453. package/dist/providers/firebase-client/realtime.js +34 -1
  454. package/dist/providers.d.ts +1 -1
  455. package/dist/providers.js +1 -1
  456. package/dist/react/hooks/use-action-dispatch.js +8 -2
  457. package/dist/react/hooks/useFormStatePreservation.js +3 -1
  458. package/dist/react/hooks/useListingTypeFlags.d.ts +1 -1
  459. package/dist/react/hooks/useListingTypeFlags.js +1 -1
  460. package/dist/react/hooks/usePendingFilters.js +5 -3
  461. package/dist/react/hooks/usePendingTable.js +15 -3
  462. package/dist/react/hooks/useRealtimeEvent.js +20 -9
  463. package/dist/repositories/index.d.ts +0 -1
  464. package/dist/repositories/index.js +0 -1
  465. package/dist/schemas/registry.d.ts +197 -232
  466. package/dist/schemas/registry.js +5 -6
  467. package/dist/schemas/webhooks/razorpay.d.ts +50 -50
  468. package/dist/security/authorization.d.ts +9 -0
  469. package/dist/security/authorization.js +16 -2
  470. package/dist/security/browser.d.ts +1 -3
  471. package/dist/security/browser.js +5 -2
  472. package/dist/security/index.d.ts +1 -3
  473. package/dist/security/index.js +19 -2
  474. package/dist/security/pii-encrypt.js +16 -0
  475. package/dist/security/pii-schemas.d.ts +0 -14
  476. package/dist/security/pii-schemas.js +7 -15
  477. package/dist/seed/_helpers/category-forest.js +2 -2
  478. package/dist/seed/_helpers/media.d.ts +19 -0
  479. package/dist/seed/_helpers/media.js +75 -0
  480. package/dist/seed/blog-posts-seed-data.js +17 -17
  481. package/dist/seed/carousel-slides-seed-data.js +7 -7
  482. package/dist/seed/cart-seed-data.js +13 -13
  483. package/dist/seed/categories-seed-data.js +10 -10
  484. package/dist/seed/events-seed-data.js +24 -24
  485. package/dist/seed/factories/product.factory.js +4 -4
  486. package/dist/seed/factories/store.factory.js +3 -3
  487. package/dist/seed/factories/user.factory.js +2 -2
  488. package/dist/seed/grouped-listings-seed-data.js +11 -11
  489. package/dist/seed/homepage-sections-seed-data.js +2 -2
  490. package/dist/seed/index.d.ts +0 -1
  491. package/dist/seed/index.js +0 -1
  492. package/dist/seed/manifest.d.ts +1 -1
  493. package/dist/seed/manifest.js +0 -5
  494. package/dist/seed/notifications-seed-data.js +20 -1
  495. package/dist/seed/orders-seed-data.js +2 -2
  496. package/dist/seed/products-art-seed-data.js +16 -16
  497. package/dist/seed/products-auctions-seed-data.js +34 -34
  498. package/dist/seed/products-classifieds-seed-data.js +35 -37
  499. package/dist/seed/products-digital-codes-seed-data.js +20 -20
  500. package/dist/seed/products-live-items-seed-data.js +11 -11
  501. package/dist/seed/products-preorders-seed-data.js +13 -13
  502. package/dist/seed/products-prize-draws-seed-data.js +43 -43
  503. package/dist/seed/products-standard-seed-data.js +54 -54
  504. package/dist/seed/products-stickers-seed-data.js +15 -15
  505. package/dist/seed/reviews-seed-data.js +4 -4
  506. package/dist/seed/scammers-seed-data.js +3 -3
  507. package/dist/seed/site-settings-seed-data.js +11 -24
  508. package/dist/seed/store-extensions-seed-data.js +10 -10
  509. package/dist/seed/stores-seed-data.js +11 -11
  510. package/dist/seed/support-tickets-seed-data.d.ts +14 -0
  511. package/dist/seed/support-tickets-seed-data.js +20 -1
  512. package/dist/seed/users-seed-data.js +20 -20
  513. package/dist/server-entry.d.ts +0 -1
  514. package/dist/server-entry.js +0 -1
  515. package/dist/server.d.ts +9 -6
  516. package/dist/server.js +7 -13
  517. package/dist/styles.css +248 -68
  518. package/dist/tailwind-utilities.css +1 -1
  519. package/dist/tokens/themes/default-dark.js +2 -2
  520. package/dist/tokens/themes/default-light.js +2 -2
  521. package/dist/tokens/tokens.css +24 -4
  522. package/dist/ui/components/ActionRow.d.ts +50 -0
  523. package/dist/ui/components/ActionRow.js +53 -0
  524. package/dist/ui/components/ActionRow.style.css +145 -0
  525. package/dist/ui/components/Drawer.d.ts +10 -0
  526. package/dist/ui/components/Drawer.js +2 -1
  527. package/dist/ui/components/FilterDrawer.js +4 -1
  528. package/dist/ui/components/FilterDrawer.style.css +6 -12
  529. package/dist/ui/components/FormActionBar.js +14 -1
  530. package/dist/ui/components/FormActionBar.style.css +12 -11
  531. package/dist/ui/components/ListingLayout.js +8 -1
  532. package/dist/ui/components/ListingLayout.style.css +6 -13
  533. package/dist/ui/components/Modal.d.ts +15 -1
  534. package/dist/ui/components/Modal.js +17 -3
  535. package/dist/ui/components/QuickCreateModal.js +2 -2
  536. package/dist/ui/components/QuickCreateModal.style.css +78 -84
  537. package/dist/ui/components/RecordDetailModal.js +2 -2
  538. package/dist/ui/components/SideDrawer.d.ts +8 -0
  539. package/dist/ui/components/SideDrawer.js +2 -1
  540. package/dist/ui/components/SideDrawer.style.css +6 -3
  541. package/dist/ui/components/SideModal.d.ts +11 -1
  542. package/dist/ui/components/SideModal.js +3 -2
  543. package/dist/ui/components/SideModal.style.css +14 -0
  544. package/dist/ui/components/Typography.style.css +33 -24
  545. package/dist/ui/components/index.style.css +1 -0
  546. package/dist/ui/components/toolbar-collapse.js +1 -2
  547. package/dist/ui/forms/FormShell.style.css +260 -311
  548. package/dist/ui/index.d.ts +2 -0
  549. package/dist/ui/index.js +1 -0
  550. package/dist/utils/index.d.ts +0 -1
  551. package/dist/utils/index.js +0 -1
  552. package/dist/validation/index.d.ts +1 -1
  553. package/dist/validation/index.js +1 -1
  554. package/dist/validation/schemas.d.ts +0 -19
  555. package/dist/validation/schemas.js +8 -19
  556. package/package.json +1 -1
  557. package/scripts/seed-cli.mjs +3 -6
@@ -1,63 +1,236 @@
1
1
  "use client";
2
- import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { normalizeError } from "../../../errors/normalize";
3
4
  import { useCurrentProfile, useUpdateCurrentProfile } from "./useProfile";
4
5
  const PERSIST_DEBOUNCE_MS = 600;
5
- /** Persisted, per-user, accordion-scoped collapse state for a page's
6
- * dashboard sections. Debounces writes to PATCH /api/user/profile so rapid
7
- * toggling doesn't fire a request per click. */
8
- export function useCollapsedSections({ sectionIds, }) {
6
+ const LOCAL_KEY = "letitrip:section-state";
7
+ /**
8
+ * ─────────────────────────────────────────────────────────────────────────────
9
+ * Persisted, per-user, per-surface open/closed state for collapsible sections.
10
+ *
11
+ * `useSectionState` is the implementation; `useCollapsedSections` below is a
12
+ * thin adapter preserving the older hook's exact semantics for its existing
13
+ * call sites.
14
+ *
15
+ * πŸ›‘ THE STORED VALUE IS WHAT IS **OPEN**, NOT WHAT IS COLLAPSED.
16
+ *
17
+ * The predecessor stored `uiPreferences.collapsedSections`: one flat, global,
18
+ * un-namespaced array of collapsed ids, shared by every page and kept apart
19
+ * only by a naming convention. Two consequences, both of which the polarity
20
+ * flip removes rather than patches:
21
+ *
22
+ * - a never-seen surface had to DEFAULT to collapsed, because "absent" and
23
+ * "deliberately collapsed" were the same value. Storing what is open makes
24
+ * a never-seen scope resolve to `defaultOpen` by absence, so "section 1
25
+ * open, the rest collapsed" needs no sentinel;
26
+ * - one page's ids could collide with another's.
27
+ *
28
+ * The scope key is `"{portal}:{surface}"` and is supplied by the caller. It is
29
+ * deliberately NOT derived from the section ids β€” a hash would change the
30
+ * moment a section is added, silently resetting every user's layout.
31
+ *
32
+ * ── localStorage mirror ─────────────────────────────────────────────────────
33
+ * The profile arrives over the network, so a server-only read paints every
34
+ * section in its default state and then snaps to the user's real layout a
35
+ * moment later. Writes go to localStorage synchronously (instant, and it
36
+ * survives for signed-out users) and to the user document debounced (durable,
37
+ * and it follows the user to another device). localStorage seeds first paint;
38
+ * the profile is authoritative once it lands.
39
+ *
40
+ * ── Migration ───────────────────────────────────────────────────────────────
41
+ * One-way and lossless: the first time a scope is read with no `sectionState`
42
+ * entry, its open set is derived from the legacy `collapsedSections`
43
+ * (`sectionIds βˆ’ collapsed`) and persisted under the new key. `collapsedSections`
44
+ * keeps being written for one release so a rollback loses nothing.
45
+ */
46
+ // ─────────────────────────────────────────────────────────────────────────────
47
+ // localStorage mirror
48
+ // ─────────────────────────────────────────────────────────────────────────────
49
+ function readLocalScopes() {
50
+ if (typeof window === "undefined")
51
+ return {};
52
+ try {
53
+ const raw = window.localStorage.getItem(LOCAL_KEY);
54
+ if (!raw)
55
+ return {};
56
+ const parsed = JSON.parse(raw);
57
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
58
+ return {};
59
+ // Validate rather than trust: this value survives across releases and a
60
+ // shape written by an older version must degrade to "no preference", not
61
+ // to a render crash. Every entry is checked, so the cast above is a claim
62
+ // this loop then makes true.
63
+ const out = {};
64
+ for (const [scope, ids] of Object.entries(parsed)) {
65
+ if (Array.isArray(ids))
66
+ out[scope] = ids.filter((id) => typeof id === "string");
67
+ }
68
+ return out;
69
+ // localStorage throws on access in private mode, and JSON.parse throws on a
70
+ // value some other version wrote. Neither is reportable β€” the user document
71
+ // is the durable copy and this is only a first-paint cache β€” but the throw
72
+ // is still normalized rather than swallowed raw.
73
+ }
74
+ catch (err) {
75
+ void normalizeError(err);
76
+ return {};
77
+ }
78
+ }
79
+ function writeLocalScope(scope, openIds) {
80
+ if (typeof window === "undefined")
81
+ return;
82
+ try {
83
+ const all = readLocalScopes();
84
+ all[scope] = openIds;
85
+ window.localStorage.setItem(LOCAL_KEY, JSON.stringify(all));
86
+ // setItem throws on quota exhaustion and in private mode. Same reasoning as
87
+ // readLocalScopes β€” the debounced profile PATCH is the durable write, so
88
+ // losing the mirror costs one frame of default layout and nothing else.
89
+ }
90
+ catch (err) {
91
+ void normalizeError(err);
92
+ }
93
+ }
94
+ export function useSectionState({ scope, sectionIds, defaultOpen, mode = "multi", }) {
9
95
  const { data: profile } = useCurrentProfile();
10
96
  const updateProfile = useUpdateCurrentProfile();
11
- // Full server-side list, including other pages' entries this hook must
12
- // never clobber when it persists its own page's next state.
13
- const savedFullListRef = useRef([]);
14
- const [localCollapsed, setLocalCollapsed] = useState(null);
15
- const debounceRef = useRef(null);
16
97
  const sectionIdsRef = useRef(sectionIds);
17
98
  sectionIdsRef.current = sectionIds;
99
+ const fallbackOpen = useMemo(() => defaultOpen ?? (sectionIds.length > 0 ? [sectionIds[0]] : []),
100
+ // Only the first id matters for the default, so this does not need to
101
+ // re-run every time the array identity changes.
102
+ // eslint-disable-next-line react-hooks/exhaustive-deps
103
+ [defaultOpen, sectionIds[0], sectionIds.length]);
104
+ const fallbackOpenRef = useRef(fallbackOpen);
105
+ fallbackOpenRef.current = fallbackOpen;
106
+ // Server copy of EVERY scope, so persisting this surface never clobbers
107
+ // another's entry.
108
+ const savedScopesRef = useRef({});
109
+ const legacyCollapsedRef = useRef(undefined);
110
+ const debounceRef = useRef(null);
111
+ /** `scope: ""` opts out of every durable store β€” see the option's docstring. */
112
+ const persistent = scope !== "";
113
+ // Seeded synchronously from localStorage so first paint is already correct.
114
+ const [localOpen, setLocalOpen] = useState(() => {
115
+ if (!persistent)
116
+ return null;
117
+ const cached = readLocalScopes()[scope];
118
+ return cached ? new Set(cached) : null;
119
+ });
18
120
  useEffect(() => {
19
- if (!profile)
121
+ if (!persistent || !profile)
20
122
  return;
21
- const serverList = profile.uiPreferences?.collapsedSections;
22
- savedFullListRef.current = serverList ?? [];
23
- setLocalCollapsed((prev) => {
24
- if (prev !== null)
25
- return prev; // local interaction already in progress β€” don't clobber it
26
- const known = new Set(serverList ?? []);
27
- const initial = new Set();
28
- for (const id of sectionIdsRef.current) {
29
- // Never-set user (serverList undefined) β†’ default every section collapsed.
30
- if (serverList === undefined || known.has(id))
31
- initial.add(id);
32
- }
33
- return initial;
34
- });
35
- }, [profile]);
123
+ const prefs = profile.uiPreferences;
124
+ savedScopesRef.current = prefs?.sectionState ?? {};
125
+ legacyCollapsedRef.current = prefs?.collapsedSections;
126
+ const stored = savedScopesRef.current[scope];
127
+ if (stored) {
128
+ setLocalOpen(new Set(stored));
129
+ return;
130
+ }
131
+ // No entry for this scope yet β€” derive one from the legacy flat list if the
132
+ // user has one, otherwise fall back to the default. Persisting is left to
133
+ // the first real toggle: writing on mere page view would fire a profile
134
+ // PATCH for every visitor on every dashboard.
135
+ const legacy = legacyCollapsedRef.current;
136
+ if (legacy !== undefined) {
137
+ const collapsed = new Set(legacy);
138
+ setLocalOpen(new Set(sectionIdsRef.current.filter((id) => !collapsed.has(id))));
139
+ }
140
+ else {
141
+ setLocalOpen(new Set(fallbackOpenRef.current));
142
+ }
143
+ }, [profile, scope, persistent]);
36
144
  useEffect(() => () => {
37
145
  if (debounceRef.current)
38
146
  clearTimeout(debounceRef.current);
39
147
  }, []);
40
- const persist = useCallback((nextForThisPage) => {
148
+ const persist = useCallback((next) => {
149
+ if (!persistent)
150
+ return;
151
+ const openIds = sectionIdsRef.current.filter((id) => next.has(id));
152
+ writeLocalScope(scope, openIds);
153
+ savedScopesRef.current = { ...savedScopesRef.current, [scope]: openIds };
41
154
  if (debounceRef.current)
42
155
  clearTimeout(debounceRef.current);
43
156
  debounceRef.current = setTimeout(() => {
157
+ // Keep writing the legacy list for one release: derived from this
158
+ // surface's ids only, merged over whatever other pages recorded, so a
159
+ // rollback finds the same state it would have written itself.
44
160
  const ids = sectionIdsRef.current;
45
- const others = savedFullListRef.current.filter((id) => !ids.includes(id));
46
- const merged = [...others, ...nextForThisPage];
47
- savedFullListRef.current = merged;
48
- updateProfile.mutate({ uiPreferences: { collapsedSections: merged } });
161
+ const others = (legacyCollapsedRef.current ?? []).filter((id) => !ids.includes(id));
162
+ const collapsedHere = ids.filter((id) => !next.has(id));
163
+ const mergedLegacy = [...others, ...collapsedHere];
164
+ legacyCollapsedRef.current = mergedLegacy;
165
+ updateProfile.mutate({
166
+ uiPreferences: {
167
+ sectionState: { [scope]: openIds },
168
+ collapsedSections: mergedLegacy,
169
+ },
170
+ });
49
171
  }, PERSIST_DEBOUNCE_MS);
50
- }, [updateProfile]);
51
- const isCollapsed = useCallback((id) => localCollapsed?.has(id) ?? true, [localCollapsed]);
172
+ }, [scope, persistent, updateProfile]);
173
+ const effectiveOpen = localOpen ?? new Set(fallbackOpen);
174
+ const isOpen = useCallback((id) => (localOpen ?? new Set(fallbackOpenRef.current)).has(id), [localOpen]);
52
175
  const toggle = useCallback((id) => {
53
- setLocalCollapsed((prev) => {
54
- const wasCollapsed = prev?.has(id) ?? true;
55
- const next = wasCollapsed
56
- ? new Set(sectionIdsRef.current.filter((s) => s !== id)) // opening id collapses every sibling
57
- : new Set(sectionIdsRef.current); // closing the open one β€” back to all-collapsed
176
+ setLocalOpen((prev) => {
177
+ const current = prev ?? new Set(fallbackOpenRef.current);
178
+ const next = new Set(current);
179
+ if (next.has(id))
180
+ next.delete(id);
181
+ else if (mode === "single") {
182
+ next.clear();
183
+ next.add(id);
184
+ }
185
+ else
186
+ next.add(id);
187
+ persist(next);
188
+ return next;
189
+ });
190
+ }, [mode, persist]);
191
+ const open = useCallback((id) => {
192
+ setLocalOpen((prev) => {
193
+ const current = prev ?? new Set(fallbackOpenRef.current);
194
+ if (current.has(id))
195
+ return current;
196
+ // Deliberately additive even under `mode: "single"`: this exists for
197
+ // error recovery, and collapsing the section the user was just editing
198
+ // in order to reveal the one that failed loses their place.
199
+ const next = new Set(current);
200
+ next.add(id);
201
+ persist(next);
202
+ return next;
203
+ });
204
+ }, [persist]);
205
+ const setOpenIds = useCallback((ids) => {
206
+ setLocalOpen(() => {
207
+ const next = new Set(ids);
58
208
  persist(next);
59
209
  return next;
60
210
  });
61
211
  }, [persist]);
212
+ const openIds = useMemo(() => sectionIds.filter((id) => effectiveOpen.has(id)),
213
+ // effectiveOpen is derived from localOpen; depending on the Set identity
214
+ // directly would recompute on every render.
215
+ // eslint-disable-next-line react-hooks/exhaustive-deps
216
+ [sectionIds, localOpen, fallbackOpen]);
217
+ return { isOpen, toggle, open, setOpenIds, openIds };
218
+ }
219
+ /**
220
+ * @deprecated Prefer `useSectionState`, which is namespaced per surface,
221
+ * supports several sections open at once, and defaults to section 1 open.
222
+ *
223
+ * Kept so the existing dashboard call sites need no edit. Semantics are
224
+ * byte-identical to the original: default all-collapsed (`defaultOpen: []`)
225
+ * and accordion (`mode: "single"`).
226
+ */
227
+ export function useCollapsedSections({ sectionIds, scope = "legacy:collapsed-sections", }) {
228
+ const { isOpen, toggle } = useSectionState({
229
+ scope,
230
+ sectionIds,
231
+ defaultOpen: [],
232
+ mode: "single",
233
+ });
234
+ const isCollapsed = useCallback((id) => !isOpen(id), [isOpen]);
62
235
  return { isCollapsed, toggle };
63
236
  }
@@ -12,7 +12,11 @@ export interface UserProfile {
12
12
  googleLinked?: boolean;
13
13
  googleLinkedEmail?: string | null;
14
14
  uiPreferences?: {
15
+ /** @deprecated Superseded by `sectionState`. Still written during the
16
+ * migration window so an existing user's layout carries over. */
15
17
  collapsedSections?: string[];
18
+ /** scope -> ids that are OPEN. See useSectionState. */
19
+ sectionState?: Record<string, string[]>;
16
20
  dataViewMode?: "table" | "grid" | "list";
17
21
  handMode?: "left" | "right";
18
22
  };
@@ -32,7 +36,11 @@ export interface UpdateCurrentProfileInput {
32
36
  bio?: string;
33
37
  profileIsPublic?: boolean;
34
38
  uiPreferences?: {
39
+ /** @deprecated Superseded by `sectionState`. Still written during the
40
+ * migration window so an existing user's layout carries over. */
35
41
  collapsedSections?: string[];
42
+ /** scope -> ids that are OPEN. See useSectionState. */
43
+ sectionState?: Record<string, string[]>;
36
44
  dataViewMode?: "table" | "grid" | "list";
37
45
  handMode?: "left" | "right";
38
46
  };
@@ -3,14 +3,11 @@ export * from "./schemas";
3
3
  export * from "./columns";
4
4
  export * from "./hooks/useAccount";
5
5
  export * from "./hooks/useAddresses";
6
- export * from "./hooks/useAddressForm";
7
6
  export * from "./hooks/useAddressSelector";
8
7
  export * from "./hooks/useNotifications";
9
8
  export * from "./hooks/useProfileStats";
10
9
  export * from "./hooks/useCollapsedSections";
11
10
  export { useCurrentProfile as useProfile, useUpdateCurrentProfile as useUpdateProfile, } from "./hooks/useProfile";
12
11
  export * from "./hooks/usePublicProfile";
13
- export * from "./constants/addresses";
14
- export * from "./address-validation";
15
12
  export * from "./components";
16
13
  export { manifest } from "./manifest";
@@ -3,14 +3,11 @@ export * from "./schemas";
3
3
  export * from "./columns";
4
4
  export * from "./hooks/useAccount";
5
5
  export * from "./hooks/useAddresses";
6
- export * from "./hooks/useAddressForm";
7
6
  export * from "./hooks/useAddressSelector";
8
7
  export * from "./hooks/useNotifications";
9
8
  export * from "./hooks/useProfileStats";
10
9
  export * from "./hooks/useCollapsedSections";
11
10
  export { useCurrentProfile as useProfile, useUpdateCurrentProfile as useUpdateProfile, } from "./hooks/useProfile";
12
11
  export * from "./hooks/usePublicProfile";
13
- export * from "./constants/addresses";
14
- export * from "./address-validation";
15
12
  export * from "./components";
16
13
  export { manifest } from "./manifest";
@@ -1,39 +1,5 @@
1
1
  export * from "./firestore";
2
2
  import { z } from "zod";
3
- export declare const userAddressSchema: z.ZodObject<{
4
- id: z.ZodString;
5
- label: z.ZodOptional<z.ZodString>;
6
- line1: z.ZodString;
7
- line2: z.ZodOptional<z.ZodString>;
8
- city: z.ZodString;
9
- state: z.ZodString;
10
- postalCode: z.ZodString;
11
- country: z.ZodString;
12
- isDefault: z.ZodOptional<z.ZodBoolean>;
13
- phone: z.ZodOptional<z.ZodString>;
14
- }, "strip", z.ZodTypeAny, {
15
- country: string;
16
- id: string;
17
- city: string;
18
- state: string;
19
- postalCode: string;
20
- line1: string;
21
- label?: string | undefined;
22
- isDefault?: boolean | undefined;
23
- phone?: string | undefined;
24
- line2?: string | undefined;
25
- }, {
26
- country: string;
27
- id: string;
28
- city: string;
29
- state: string;
30
- postalCode: string;
31
- line1: string;
32
- label?: string | undefined;
33
- isDefault?: boolean | undefined;
34
- phone?: string | undefined;
35
- line2?: string | undefined;
36
- }>;
37
3
  export declare const notificationPreferencesSchema: z.ZodObject<{
38
4
  orderUpdates: z.ZodOptional<z.ZodBoolean>;
39
5
  promotions: z.ZodOptional<z.ZodBoolean>;
@@ -71,40 +37,6 @@ export declare const userProfileSchema: z.ZodObject<{
71
37
  phone: z.ZodOptional<z.ZodString>;
72
38
  photoURL: z.ZodOptional<z.ZodString>;
73
39
  bio: z.ZodOptional<z.ZodString>;
74
- addresses: z.ZodOptional<z.ZodArray<z.ZodObject<{
75
- id: z.ZodString;
76
- label: z.ZodOptional<z.ZodString>;
77
- line1: z.ZodString;
78
- line2: z.ZodOptional<z.ZodString>;
79
- city: z.ZodString;
80
- state: z.ZodString;
81
- postalCode: z.ZodString;
82
- country: z.ZodString;
83
- isDefault: z.ZodOptional<z.ZodBoolean>;
84
- phone: z.ZodOptional<z.ZodString>;
85
- }, "strip", z.ZodTypeAny, {
86
- country: string;
87
- id: string;
88
- city: string;
89
- state: string;
90
- postalCode: string;
91
- line1: string;
92
- label?: string | undefined;
93
- isDefault?: boolean | undefined;
94
- phone?: string | undefined;
95
- line2?: string | undefined;
96
- }, {
97
- country: string;
98
- id: string;
99
- city: string;
100
- state: string;
101
- postalCode: string;
102
- line1: string;
103
- label?: string | undefined;
104
- isDefault?: boolean | undefined;
105
- phone?: string | undefined;
106
- line2?: string | undefined;
107
- }>, "many">>;
108
40
  notificationPreferences: z.ZodOptional<z.ZodObject<{
109
41
  orderUpdates: z.ZodOptional<z.ZodBoolean>;
110
42
  promotions: z.ZodOptional<z.ZodBoolean>;
@@ -132,18 +64,6 @@ export declare const userProfileSchema: z.ZodObject<{
132
64
  displayName?: string | undefined;
133
65
  createdAt?: string | undefined;
134
66
  updatedAt?: string | undefined;
135
- addresses?: {
136
- country: string;
137
- id: string;
138
- city: string;
139
- state: string;
140
- postalCode: string;
141
- line1: string;
142
- label?: string | undefined;
143
- isDefault?: boolean | undefined;
144
- phone?: string | undefined;
145
- line2?: string | undefined;
146
- }[] | undefined;
147
67
  photoURL?: string | undefined;
148
68
  bio?: string | undefined;
149
69
  phone?: string | undefined;
@@ -160,18 +80,6 @@ export declare const userProfileSchema: z.ZodObject<{
160
80
  displayName?: string | undefined;
161
81
  createdAt?: string | undefined;
162
82
  updatedAt?: string | undefined;
163
- addresses?: {
164
- country: string;
165
- id: string;
166
- city: string;
167
- state: string;
168
- postalCode: string;
169
- line1: string;
170
- label?: string | undefined;
171
- isDefault?: boolean | undefined;
172
- phone?: string | undefined;
173
- line2?: string | undefined;
174
- }[] | undefined;
175
83
  photoURL?: string | undefined;
176
84
  bio?: string | undefined;
177
85
  phone?: string | undefined;
@@ -1,18 +1,16 @@
1
1
  export * from "./firestore";
2
2
  import { z } from "zod";
3
+ import { annotate } from "../../shell/field-ui-meta";
3
4
  // --- Sub-schemas --------------------------------------------------------------
4
- export const userAddressSchema = z.object({
5
- id: z.string(),
6
- label: z.string().optional(),
7
- line1: z.string(),
8
- line2: z.string().optional(),
9
- city: z.string(),
10
- state: z.string(),
11
- postalCode: z.string(),
12
- country: z.string(),
13
- isDefault: z.boolean().optional(),
14
- phone: z.string().optional(),
15
- });
5
+ /*
6
+ * `userAddressSchema` is DELETED (W5 / D19).
7
+ *
8
+ * It carried the `line1`/`line2` naming β€” one of the eleven address shapes,
9
+ * and the only one that disagreed with `AddressDocument` on field NAMES rather
10
+ * than just on rules. Zero consumers outside the barrel that re-exported it.
11
+ * The one shape is `addressFormSchema` in
12
+ * `features/addresses/schemas/address-form.ts`.
13
+ */
16
14
  export const notificationPreferencesSchema = z.object({
17
15
  orderUpdates: z.boolean().optional(),
18
16
  promotions: z.boolean().optional(),
@@ -39,7 +37,6 @@ export const userProfileSchema = z.object({
39
37
  phone: z.string().optional(),
40
38
  photoURL: z.string().optional(),
41
39
  bio: z.string().optional(),
42
- addresses: z.array(userAddressSchema).optional(),
43
40
  notificationPreferences: notificationPreferencesSchema.optional(),
44
41
  createdAt: z.string().optional(),
45
42
  updatedAt: z.string().optional(),
@@ -51,10 +48,23 @@ export const userProfileSchema = z.object({
51
48
  * validation too.
52
49
  */
53
50
  export const updateProfileSchema = z.object({
54
- displayName: z.string().min(1, "Enter your name").optional(),
55
- phoneNumber: z.string().optional(),
56
- bio: z.string().max(500, "Bio must be 500 characters or fewer").optional(),
57
- profileIsPublic: z.boolean().optional(),
51
+ displayName: annotate(z.string().min(1, "Enter your name").optional(), {
52
+ section: "profile", sectionLabel: "Your details", sectionRequired: true,
53
+ quick: true, order: 1, row: "pair", label: "Display name",
54
+ }),
55
+ phoneNumber: annotate(z.string().optional(), {
56
+ section: "profile", quick: true, order: 2, row: "pair",
57
+ label: "Phone number", inputType: "tel",
58
+ }),
59
+ bio: annotate(z.string().max(500, "Bio must be 500 characters or fewer").optional(), {
60
+ section: "profile", order: 3, row: "full", kind: "textarea",
61
+ label: "Bio", help: "Up to 500 characters. Buyers see this on your public profile.",
62
+ }),
63
+ profileIsPublic: annotate(z.boolean().optional(), {
64
+ section: "visibility", sectionLabel: "Visibility", order: 1, row: "full",
65
+ label: "Public profile",
66
+ help: "When on, your profile is visible to other LetItRip users.",
67
+ }),
58
68
  });
59
69
  /**
60
70
  * Changing the account email.
@@ -69,11 +79,23 @@ export const updateProfileSchema = z.object({
69
79
  * credential, not chosen here.
70
80
  */
71
81
  export const changeEmailSchema = z.object({
72
- newEmail: z
82
+ newEmail: annotate(z
73
83
  .string()
74
84
  .trim()
75
85
  .toLowerCase()
76
86
  .min(1, "Enter the new email address.")
77
- .email("That doesn't look like an email address."),
78
- emailPassword: z.string().min(1, "Enter your current password to confirm."),
87
+ .email("That doesn't look like an email address."), {
88
+ section: "basics", sectionLabel: "Change email", sectionRequired: true,
89
+ order: 1, row: "full", label: "New email address", inputType: "email",
90
+ }),
91
+ /*
92
+ * πŸ›‘ `inputType: "password"` is not cosmetic. Without it the generated
93
+ * control is a bare `<FieldInput>` with no `type`, which renders a password
94
+ * IN PLAINTEXT β€” the defect found the first time this generator met a
95
+ * credential field.
96
+ */
97
+ emailPassword: annotate(z.string().min(1, "Enter your current password to confirm."), {
98
+ section: "basics", order: 2, row: "full", label: "Current password",
99
+ inputType: "password",
100
+ }),
79
101
  });
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ import type { JsonValue } from "@mohasinac/appkit/client";
3
+ export interface AddressLocationFieldsProps {
4
+ country: string;
5
+ state: string;
6
+ postalCode: string;
7
+ errors: Record<string, string>;
8
+ isLooking?: boolean;
9
+ onChange: (partial: Record<string, JsonValue>) => void;
10
+ /** Called with (postalCode, country) whenever either settles. */
11
+ onPostalSettled: (postalCode: string, country: string) => void;
12
+ }
13
+ export declare function AddressLocationFields({ country, state, postalCode, errors, isLooking, onChange, onPostalSettled, }: AddressLocationFieldsProps): React.JSX.Element;
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { PaginatedSelect, Stack, Text } from "../../../ui";
4
+ import { FieldInput } from "../../../ui/forms/FieldInput";
5
+ import { FormGroup } from "../../../ui/components/Form";
6
+ import { countryFor, postalLabelFor, COUNTRIES } from "../../../constants/geo/countries";
7
+ import { subdivisionsFor } from "../../../constants/geo/subdivisions";
8
+ const COUNTRY_OPTIONS = Object.values(COUNTRIES).map((c) => ({
9
+ value: c.code,
10
+ label: c.name,
11
+ }));
12
+ export function AddressLocationFields({ country, state, postalCode, errors, isLooking = false, onChange, onPostalSettled, }) {
13
+ const def = countryFor(country);
14
+ const states = subdivisionsFor(def?.code);
15
+ const postalLabel = postalLabelFor(country);
16
+ return (_jsxs(Stack, { gap: "sm", children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(PaginatedSelectField, { label: "Country", value: def?.code ?? "", error: errors.country, onChange: (next) => {
17
+ /*
18
+ * Changing country invalidates the state: "Karnataka" is not a
19
+ * Canadian province. Cleared rather than carried, because a state
20
+ * that no longer belongs to its country is a row nothing can
21
+ * group or ship.
22
+ */
23
+ onChange({ country: next, state: "" });
24
+ onPostalSettled(postalCode, next);
25
+ } }), states.length > 0 ? (_jsx(PaginatedSelectField, { label: "State / region", value: state, error: errors.state, options: states.map((s) => ({ value: s, label: s })), onChange: (next) => onChange({ state: next }) })) : (_jsx(FieldInput, { name: "state", label: "State / region", required: true, value: state, error: errors.state, onChange: (v) => onChange({ state: v }) }))] }), _jsx(FieldInput, { name: "postalCode", label: postalLabel, required: true, value: postalCode, error: errors.postalCode, hint: isLooking
26
+ ? "Looking up your city…"
27
+ : "We fill in the city and state when we recognise it.", onChange: (v) => {
28
+ onChange({ postalCode: v });
29
+ onPostalSettled(v, country);
30
+ }, onBlur: () => onPostalSettled(postalCode, country) }), !def && country.trim() && (_jsx(Text, { size: "xs", color: "muted", children: "We do not know the postal format for that country, so anything plausible is accepted." }))] }));
31
+ }
32
+ /**
33
+ * A labelled `PaginatedSelect`.
34
+ *
35
+ * The primitive takes no `label` or `error` of its own β€” the generator wraps
36
+ * it the same way at `build-sections.tsx:392`. This is that wrapper, named,
37
+ * so the two country pickers in this file do not each rebuild it.
38
+ */
39
+ function PaginatedSelectField({ label, value, error, options = COUNTRY_OPTIONS, onChange, }) {
40
+ return (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", weight: "medium", color: "muted", children: [label, " *"] }), _jsx(PaginatedSelect, { value: value, options: options, onChange: (next) => onChange(next ?? ""), ariaLabel: label, placeholder: `Select ${label.toLowerCase()}…` }), error && (_jsx(Text, { size: "xs", color: "error", role: "alert", children: error }))] }));
41
+ }
@@ -0,0 +1,17 @@
1
+ export interface PostalLookupResult {
2
+ city: string;
3
+ state: string;
4
+ }
5
+ export interface UsePostalLookupOptions {
6
+ /** Called with the resolved place. Only ever fires on a hit. */
7
+ onResolved: (result: PostalLookupResult) => void;
8
+ /** Skip the lookup entirely β€” e.g. while the form is submitting. */
9
+ enabled?: boolean;
10
+ }
11
+ export interface UsePostalLookupResult {
12
+ /** Feed it the current postal code and country on every change or blur. */
13
+ lookup: (postalCode: string, country: string) => void;
14
+ /** True while a request is in flight. Purely for a spinner; never gates. */
15
+ isLooking: boolean;
16
+ }
17
+ export declare function usePostalLookup({ onResolved, enabled, }: UsePostalLookupOptions): UsePostalLookupResult;