@mohasinac/appkit 4.53.2 → 4.54.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 (348) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/auth/capabilities.js +7 -5
  3. package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
  4. package/dist/_internal/server/features/checkout/actions.js +96 -51
  5. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  6. package/dist/_internal/server/features/checkout/index.js +1 -1
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
  8. package/dist/_internal/server/features/orders/adapters.js +1 -3
  9. package/dist/_internal/server/features/products/listing-tab-counts.js +81 -25
  10. package/dist/_internal/server/features/search/index-build/sources.js +43 -2
  11. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  12. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  13. package/dist/_internal/server/features/stores/adapters.js +0 -1
  14. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
  15. package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
  16. package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
  17. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
  18. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
  19. package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
  20. package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
  21. package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
  22. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
  23. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
  24. package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
  25. package/dist/_internal/server/notifications/channel-health.js +2 -2
  26. package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
  27. package/dist/_internal/server/notifications/send-guard.js +2 -4
  28. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  29. package/dist/_internal/shared/actions/action-registry.js +128 -28
  30. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  31. package/dist/_internal/shared/checkout/order-math.js +1 -1
  32. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  33. package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
  34. package/dist/_internal/shared/features/checkout/config.js +0 -2
  35. package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
  36. package/dist/_internal/shared/features/messaging/config.js +1 -4
  37. package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
  38. package/dist/_internal/shared/features/site-settings/fees.js +0 -2
  39. package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
  40. package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
  41. package/dist/_internal/shared/fees/calculator.d.ts +0 -8
  42. package/dist/_internal/shared/fees/calculator.js +0 -7
  43. package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
  44. package/dist/_internal/shared/listing-types/tiers.js +150 -0
  45. package/dist/cli/index.js +0 -2
  46. package/dist/client.d.ts +25 -4
  47. package/dist/client.js +36 -5
  48. package/dist/constants/api-endpoints.d.ts +21 -15
  49. package/dist/constants/api-endpoints.js +7 -8
  50. package/dist/constants/field-names.d.ts +1 -0
  51. package/dist/constants/field-names.js +1 -0
  52. package/dist/constants/notification-types.d.ts +1 -1
  53. package/dist/constants/notification-types.js +1 -1
  54. package/dist/core/integration-keys.d.ts +5 -5
  55. package/dist/core/integration-keys.js +21 -10
  56. package/dist/features/about/components/FeesView.js +0 -6
  57. package/dist/features/about/components/GuidesHubView.js +15 -2
  58. package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
  59. package/dist/features/account/components/UserOrdersView.js +26 -7
  60. package/dist/features/account/types/index.d.ts +0 -2
  61. package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
  62. package/dist/features/addresses/utils/postal-autofill.js +54 -0
  63. package/dist/features/admin/actions/notification-actions.d.ts +2 -8
  64. package/dist/features/admin/actions/notification-actions.js +9 -104
  65. package/dist/features/admin/components/AdminGuideHubView.js +1 -8
  66. package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
  67. package/dist/features/admin/components/AdminOrdersView.js +0 -2
  68. package/dist/features/admin/components/AdminSectionsView.js +3 -2
  69. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
  70. package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
  71. package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
  72. package/dist/features/admin/components/OwnerQuickActions.js +142 -0
  73. package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
  74. package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
  75. package/dist/features/admin/components/sections/icon-options.js +23 -0
  76. package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
  77. package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
  78. package/dist/features/admin/constants/site-settings-tabs.js +6 -12
  79. package/dist/features/admin/repository/site-settings.repository.js +1 -1
  80. package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
  81. package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
  82. package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
  83. package/dist/features/admin/schemas/admin-user-form.js +3 -44
  84. package/dist/features/admin/schemas/firestore.d.ts +28 -54
  85. package/dist/features/admin/schemas/firestore.js +40 -18
  86. package/dist/features/auctions/components/AuctionDetailPageView.js +4 -3
  87. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
  88. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
  89. package/dist/features/auth/checkout-value-otp.d.ts +1 -1
  90. package/dist/features/auth/checkout-value-otp.js +1 -1
  91. package/dist/features/auth/permissions/constants.d.ts +29 -2
  92. package/dist/features/auth/permissions/constants.js +67 -1
  93. package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
  94. package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
  95. package/dist/features/cart/components/CartDrawer.js +3 -2
  96. package/dist/features/cart/components/CartGroupLineRow.js +2 -1
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
  98. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  99. package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
  100. package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
  101. package/dist/features/cart/hooks/useAddToCart.js +10 -5
  102. package/dist/features/cart/repository/cart.repository.js +1 -2
  103. package/dist/features/cart/schemas/firestore.d.ts +1 -2
  104. package/dist/features/cart/utils/pending-ops.d.ts +11 -1
  105. package/dist/features/cart/utils/pending-ops.js +14 -2
  106. package/dist/features/categories/components/BrandDetailPageView.js +2 -1
  107. package/dist/features/categories/components/BundleDetailView.js +2 -1
  108. package/dist/features/categories/components/CategoryDetailPageView.js +2 -1
  109. package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
  110. package/dist/features/categories/components/CategoryGrid.js +9 -2
  111. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
  112. package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
  113. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  114. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -1
  115. package/dist/features/events/components/EventCard.d.ts +11 -1
  116. package/dist/features/events/components/EventCard.js +9 -2
  117. package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
  118. package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
  119. package/dist/features/homepage/components/CTABannerSection.js +6 -3
  120. package/dist/features/homepage/components/HeroCarousel.js +8 -6
  121. package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
  122. package/dist/features/homepage/components/SectionCarousel.js +13 -5
  123. package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
  124. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  125. package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
  126. package/dist/features/homepage/components/StatsCounterSection.js +2 -2
  127. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  128. package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
  129. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  130. package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
  131. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  132. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
  133. package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
  134. package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
  135. package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
  136. package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
  137. package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
  138. package/dist/features/homepage/constants/section-copy.d.ts +12 -10
  139. package/dist/features/homepage/constants/section-copy.js +28 -6
  140. package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
  141. package/dist/features/homepage/constants/stat-icons.js +17 -0
  142. package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
  143. package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
  144. package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
  145. package/dist/features/homepage/lib/section-defaults.js +24 -4
  146. package/dist/features/homepage/lib/section-renderer.js +48 -8
  147. package/dist/features/homepage/schemas/firestore.d.ts +18 -1
  148. package/dist/features/layout/AppLayoutShell.js +2 -1
  149. package/dist/features/layout/BottomActions.d.ts +1 -0
  150. package/dist/features/layout/BottomActions.js +330 -0
  151. package/dist/features/layout/BottomChrome.d.ts +45 -0
  152. package/dist/features/layout/BottomChrome.js +5 -17
  153. package/dist/features/layout/SideActionDock.js +36 -13
  154. package/dist/features/layout/index.d.ts +2 -7
  155. package/dist/features/layout/index.js +7 -7
  156. package/dist/features/layout/useIsDesktop.d.ts +36 -0
  157. package/dist/features/layout/useIsDesktop.js +48 -0
  158. package/dist/features/live/components/LiveItemDetailPageView.js +2 -1
  159. package/dist/features/orders/actions/refund-actions.js +0 -1
  160. package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
  161. package/dist/features/orders/components/OrderAddonBadges.js +3 -4
  162. package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
  163. package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
  164. package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
  165. package/dist/features/orders/components/index.d.ts +2 -1
  166. package/dist/features/orders/components/index.js +1 -1
  167. package/dist/features/orders/repository/orders.repository.d.ts +0 -8
  168. package/dist/features/orders/repository/orders.repository.js +0 -2
  169. package/dist/features/orders/schemas/firestore.d.ts +17 -9
  170. package/dist/features/orders/types/index.d.ts +2 -5
  171. package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
  172. package/dist/features/orders/utils/order-announcement-message.js +16 -0
  173. package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
  174. package/dist/features/orders/utils/payment-proof-message.js +17 -0
  175. package/dist/features/parts/components/PartDetailPageView.js +96 -1
  176. package/dist/features/parts/schemas/firestore.d.ts +247 -0
  177. package/dist/features/parts/schemas/firestore.js +6 -6
  178. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
  179. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
  180. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -3
  181. package/dist/features/products/api/[id]/route.js +8 -1
  182. package/dist/features/products/api/route.js +16 -4
  183. package/dist/features/products/components/AvailabilityScopeHint.js +1 -1
  184. package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
  185. package/dist/features/products/components/InteractiveProductCard.js +16 -4
  186. package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
  187. package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
  188. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
  189. package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
  190. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  191. package/dist/features/products/components/ProductDetailPageView.js +27 -2
  192. package/dist/features/products/components/ProductGrid.d.ts +14 -1
  193. package/dist/features/products/components/ProductGrid.js +22 -5
  194. package/dist/features/products/components/ProductsIndexListing.js +2 -2
  195. package/dist/features/reviews/api/[id]/route.js +83 -23
  196. package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
  197. package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
  198. package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
  199. package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
  200. package/dist/features/reviews/components/index.d.ts +4 -0
  201. package/dist/features/reviews/components/index.js +2 -0
  202. package/dist/features/scams/schemas/index.d.ts +10 -10
  203. package/dist/features/search/action-index/settings-entries.js +0 -9
  204. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  205. package/dist/features/seller/actions/seller-actions.js +49 -3
  206. package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
  207. package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
  208. package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
  209. package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
  210. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
  211. package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
  212. package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
  213. package/dist/features/store-extensions/schemas/firestore.js +0 -10
  214. package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
  215. package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
  216. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
  217. package/dist/features/stores/components/StoreGuideHubView.js +2 -8
  218. package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
  219. package/dist/features/stores/components/index.d.ts +0 -2
  220. package/dist/features/stores/components/index.js +0 -1
  221. package/dist/features/stores/repository/store.repository.d.ts +1 -26
  222. package/dist/features/stores/repository/store.repository.js +5 -60
  223. package/dist/features/stores/schemas/firestore.d.ts +6 -25
  224. package/dist/features/stores/schemas/firestore.js +6 -3
  225. package/dist/features/stores/schemas/index.d.ts +1 -87
  226. package/dist/features/stores/schemas/index.js +10 -15
  227. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
  228. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
  229. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
  230. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
  231. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
  232. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
  233. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +415 -69
  234. package/dist/index.d.ts +20 -32
  235. package/dist/index.js +34 -43
  236. package/dist/next/routing/route-map.d.ts +2 -8
  237. package/dist/next/routing/route-map.js +21 -4
  238. package/dist/providers/db-firebase/base.repository.d.ts +1 -1
  239. package/dist/providers/db-firebase/base.repository.js +1 -1
  240. package/dist/providers/payment-razorpay/index.d.ts +125 -0
  241. package/dist/providers/payment-razorpay/index.js +232 -0
  242. package/dist/providers/payment-razorpay/signature.d.ts +53 -0
  243. package/dist/providers/payment-razorpay/signature.js +71 -0
  244. package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
  245. package/dist/providers/shipping-shiprocket/index.js +356 -0
  246. package/dist/providers.d.ts +3 -0
  247. package/dist/providers.js +3 -0
  248. package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
  249. package/dist/react/hooks/useCanSeePrices.js +25 -0
  250. package/dist/repositories/index.d.ts +1 -1
  251. package/dist/repositories/index.js +1 -1
  252. package/dist/schemas/registry.d.ts +10 -115
  253. package/dist/schemas/registry.js +1 -2
  254. package/dist/security/pii-encrypt.js +1 -1
  255. package/dist/seed/_helpers/category-forest.js +27 -0
  256. package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -86
  257. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  258. package/dist/seed/_helpers/category-parts.js +13412 -3020
  259. package/dist/seed/carousel-slides-seed-data.js +47 -10
  260. package/dist/seed/categories-seed-data.js +48 -6
  261. package/dist/seed/faq-seed-data.js +2 -2
  262. package/dist/seed/homepage-sections-seed-data.js +286 -54
  263. package/dist/seed/index.d.ts +1 -1
  264. package/dist/seed/index.js +1 -1
  265. package/dist/seed/manifest.d.ts +1 -1
  266. package/dist/seed/manifest.js +1 -2
  267. package/dist/seed/model-composition-seed-data.js +6 -8
  268. package/dist/seed/part-glossary/chunk0.d.ts +9 -0
  269. package/dist/seed/part-glossary/chunk0.js +35448 -0
  270. package/dist/seed/part-glossary/chunk1.d.ts +9 -0
  271. package/dist/seed/part-glossary/chunk1.js +40494 -0
  272. package/dist/seed/part-glossary/chunk2.d.ts +9 -0
  273. package/dist/seed/part-glossary/chunk2.js +51242 -0
  274. package/dist/seed/part-glossary/chunk3.d.ts +9 -0
  275. package/dist/seed/part-glossary/chunk3.js +53337 -0
  276. package/dist/seed/part-glossary/chunk4.d.ts +9 -0
  277. package/dist/seed/part-glossary/chunk4.js +51454 -0
  278. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  279. package/dist/seed/part-glossary-seed-data.js +23 -47483
  280. package/dist/seed/site-settings-seed-data.js +34 -35
  281. package/dist/seed/store-extensions-seed-data.d.ts +1 -2
  282. package/dist/seed/store-extensions-seed-data.js +1 -23
  283. package/dist/seed/stores-seed-data.js +0 -1
  284. package/dist/server-entry.d.ts +1 -1
  285. package/dist/server-entry.js +1 -1
  286. package/dist/server.d.ts +8 -10
  287. package/dist/server.js +16 -22
  288. package/dist/styles.css +392 -43
  289. package/dist/tailwind-utilities.css +1 -1
  290. package/dist/tokens/themes/default-dark.js +1 -1
  291. package/dist/tokens/themes/default-light.js +2 -1
  292. package/dist/tokens/tokens.css +6 -2
  293. package/dist/ui/components/Button.d.ts +11 -0
  294. package/dist/ui/components/Button.js +11 -0
  295. package/dist/ui/components/Button.style.css +29 -0
  296. package/dist/ui/components/CarouselNav.d.ts +57 -0
  297. package/dist/ui/components/CarouselNav.js +25 -0
  298. package/dist/ui/components/CarouselNav.style.css +265 -0
  299. package/dist/ui/components/GatedPrice.js +30 -3
  300. package/dist/ui/components/GatedPrice.style.css +43 -40
  301. package/dist/ui/components/HorizontalScroller.d.ts +12 -1
  302. package/dist/ui/components/HorizontalScroller.js +43 -3
  303. package/dist/ui/components/ImageMosaic.d.ts +8 -1
  304. package/dist/ui/components/ImageMosaic.js +3 -2
  305. package/dist/ui/components/ImageMosaic.style.css +22 -0
  306. package/dist/ui/components/Layout.style.css +6 -0
  307. package/dist/ui/components/Semantic.d.ts +3 -2
  308. package/dist/ui/components/Semantic.js +1 -0
  309. package/dist/ui/components/Typography.d.ts +2 -0
  310. package/dist/ui/components/Typography.js +2 -0
  311. package/dist/ui/components/Typography.style.css +19 -0
  312. package/dist/ui/components/index.style.css +1 -0
  313. package/dist/ui/index.d.ts +3 -1
  314. package/dist/ui/index.js +4 -0
  315. package/package.json +3 -2
  316. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
  317. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
  318. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
  319. package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
  320. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
  321. package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
  322. package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
  323. package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
  324. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
  325. package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
  326. package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
  327. package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
  328. package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
  329. package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
  330. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
  331. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
  332. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
  333. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
  334. package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
  335. package/dist/features/whatsapp-bot/components/index.js +0 -2
  336. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
  337. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
  338. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
  339. package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
  340. package/dist/features/whatsapp-bot/index.d.ts +0 -3
  341. package/dist/features/whatsapp-bot/index.js +0 -3
  342. package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
  343. package/dist/features/whatsapp-bot/manifest.js +0 -13
  344. package/dist/features/whatsapp-bot/messages/en.json +0 -7
  345. package/dist/features/whatsapp-bot/server.d.ts +0 -7
  346. package/dist/features/whatsapp-bot/server.js +0 -7
  347. package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
  348. package/dist/features/whatsapp-bot/types/index.js +0 -1
@@ -30,7 +30,7 @@ export function NotificationPreferencesPanel({ fetchUrl = ACCOUNT_ENDPOINTS.NOTI
30
30
  const { showToast } = useToast();
31
31
  const { data: settings } = useSiteSettings();
32
32
  const adminChannels = settings?.notificationChannels;
33
- const [channels, setChannels] = useState({ email: true, whatsapp: true, sms: true });
33
+ const [channels, setChannels] = useState({ email: true, sms: true });
34
34
  const [types, setTypes] = useState({
35
35
  orderUpdates: true, bids: true, promotions: true,
36
36
  system: true, reviews: true, messages: true, offers: true,
@@ -92,8 +92,7 @@ export function NotificationPreferencesPanel({ fetchUrl = ACCOUNT_ENDPOINTS.NOTI
92
92
  }
93
93
  // Which channels are admin-enabled (only show those toggles to the user)
94
94
  const emailAdminEnabled = adminChannels?.email?.enabled ?? false;
95
- const whatsappAdminEnabled = adminChannels?.whatsapp?.enabled ?? false;
96
95
  const smsAdminEnabled = adminChannels?.sms?.enabled ?? false;
97
- const anyChannelEnabled = emailAdminEnabled || whatsappAdminEnabled || smsAdminEnabled;
98
- return (_jsxs(Stack, { gap: "lg", children: [_jsx(SectionCard, { title: "In-app notifications", children: _jsxs(Row, { align: "center", justify: "between", gap: "md", padding: "y-sm", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[var(--appkit-color-text)]", size: "sm", weight: "medium", children: "In-app notifications" }), _jsx(Text, { variant: "secondary", className: "mt-0.5", size: "xs", children: "Always on \u2014 displayed in the notification bell and inbox" })] }), _jsx(Row, { className: "h-5 w-9 bg-[var(--appkit-color-primary)] px-[0.125rem]", align: "center", justify: "end", rounded: "full", "aria-label": "Always on", children: _jsx(Span, { className: "h-4 w-4", rounded: "full", surface: "default", shadow: "default" }) })] }) }), anyChannelEnabled && (_jsxs(SectionCard, { title: "Notification channels", children: [emailAdminEnabled && (_jsx(ToggleRow, { label: "Email", description: "Receive notifications by email", checked: channels.email !== false, onChange: (v) => setChannel("email", v) })), whatsappAdminEnabled && (_jsx(ToggleRow, { label: "WhatsApp", description: "Receive notifications on WhatsApp", checked: channels.whatsapp !== false, onChange: (v) => setChannel("whatsapp", v) })), smsAdminEnabled && (_jsx(ToggleRow, { label: "SMS", description: "Receive SMS text notifications", checked: channels.sms !== false, onChange: (v) => setChannel("sms", v) }))] })), _jsx(SectionCard, { title: "Notification types", children: TYPE_ROWS.map((row) => (_jsx(ToggleRow, { label: row.label, description: row.description, checked: types[row.key] !== false, onChange: (v) => setType(row.key, v) }, row.key))) }), _jsxs(Row, { justify: "end", gap: "sm", children: [saved && (_jsx(Text, { className: "text-[var(--appkit-color-success)] self-center", size: "sm", children: "Preferences saved \u2713" })), _jsx(Button, { onClick: handleSave, isLoading: saving, size: "sm", children: "Save preferences" })] })] }));
96
+ const anyChannelEnabled = emailAdminEnabled || smsAdminEnabled;
97
+ return (_jsxs(Stack, { gap: "lg", children: [_jsx(SectionCard, { title: "In-app notifications", children: _jsxs(Row, { align: "center", justify: "between", gap: "md", padding: "y-sm", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[var(--appkit-color-text)]", size: "sm", weight: "medium", children: "In-app notifications" }), _jsx(Text, { variant: "secondary", className: "mt-0.5", size: "xs", children: "Always on \u2014 displayed in the notification bell and inbox" })] }), _jsx(Row, { className: "h-5 w-9 bg-[var(--appkit-color-primary)] px-[0.125rem]", align: "center", justify: "end", rounded: "full", "aria-label": "Always on", children: _jsx(Span, { className: "h-4 w-4", rounded: "full", surface: "default", shadow: "default" }) })] }) }), anyChannelEnabled && (_jsxs(SectionCard, { title: "Notification channels", children: [emailAdminEnabled && (_jsx(ToggleRow, { label: "Email", description: "Receive notifications by email", checked: channels.email !== false, onChange: (v) => setChannel("email", v) })), smsAdminEnabled && (_jsx(ToggleRow, { label: "SMS", description: "Receive SMS text notifications", checked: channels.sms !== false, onChange: (v) => setChannel("sms", v) }))] })), _jsx(SectionCard, { title: "Notification types", children: TYPE_ROWS.map((row) => (_jsx(ToggleRow, { label: row.label, description: row.description, checked: types[row.key] !== false, onChange: (v) => setType(row.key, v) }, row.key))) }), _jsxs(Row, { justify: "end", gap: "sm", children: [saved && (_jsx(Text, { className: "text-[var(--appkit-color-success)] self-center", size: "sm", children: "Preferences saved \u2713" })), _jsx(Button, { onClick: handleSave, isLoading: saving, size: "sm", children: "Save preferences" })] })] }));
99
98
  }
@@ -11,7 +11,23 @@ import { OrderCard } from "../../orders/components/OrdersList.js";
11
11
  import { useOrderScope } from "../../orders/components/OrderScopeTabs.js";
12
12
  import { useSearchParams } from "next/navigation.js";
13
13
  const CANCELLABLE_STATUSES = new Set(["pending", "confirmed", "processing"]);
14
- const TRACKABLE_STATUSES = new Set(["shipped"]);
14
+ /*
15
+ * 🛑 Every PRE-DELIVERY status, not just "shipped".
16
+ *
17
+ * It was `["shipped"]` alone, so a buyer whose order was pending, confirmed
18
+ * or processing had no "where is it" link at all — which is precisely when
19
+ * they most want one. The timeline on the track page reads correctly for all
20
+ * of these: it shows the stages reached and the stages still ahead.
21
+ *
22
+ * Delivered, cancelled, refunded and returned are excluded because tracking a
23
+ * finished order is the order detail page's job, not a courier's.
24
+ */
25
+ const TRACKABLE_STATUSES = new Set([
26
+ "pending",
27
+ "confirmed",
28
+ "processing",
29
+ "shipped",
30
+ ]);
15
31
  const SORT_OPTIONS = [
16
32
  { value: sortBy("createdAt", "DESC"), label: "Newest first" },
17
33
  { value: sortBy("createdAt", "ASC"), label: "Oldest first" },
@@ -77,12 +93,15 @@ export function UserOrdersView({ onOrderClick }) {
77
93
  portal: "user",
78
94
  title: "My Orders",
79
95
  search: {
80
- placeholder: "Search by order id…",
81
- // `/api/user/orders` filters in memory on `o.id` and nothing else — not
82
- // the product titles the rows display, which is what a buyer would try
83
- // first. Saying "order id" is the honest promise until the route can
84
- // match more.
85
- fields: ["id"],
96
+ placeholder: "Search by item or order id…",
97
+ /*
98
+ * The route now matches product titles as well as the order id, so the
99
+ * placeholder can promise it. It said "order id" because that was all
100
+ * the route could do, with a comment calling that "the honest promise
101
+ * until the route can match more" — this is the promise catching up,
102
+ * not a widened claim.
103
+ */
104
+ fields: ["id", "productTitle"],
86
105
  },
87
106
  emptyLabel: emptyMessage,
88
107
  filterKeys: ["status", "orderType"],
@@ -75,8 +75,6 @@ export interface UserAddress {
75
75
  export interface NotificationChannelPrefs {
76
76
  /** Disable all email notifications for this user (default: true = enabled). */
77
77
  email?: boolean;
78
- /** Disable all WhatsApp notifications for this user. */
79
- whatsapp?: boolean;
80
78
  /** Disable all SMS notifications for this user. */
81
79
  sms?: boolean;
82
80
  }
@@ -0,0 +1,39 @@
1
+ interface CityState {
2
+ city: string;
3
+ state: string;
4
+ }
5
+ /**
6
+ * What the last autofill wrote, so a later one can tell its own output apart
7
+ * from a human's typing. A field is absent when the helper declined to write
8
+ * it — which makes it the human's, and untouchable.
9
+ */
10
+ export type PostalAutofillMemo = Partial<CityState>;
11
+ /**
12
+ * Merge `resolved` into `prev`, returning the new values and an updated memo.
13
+ *
14
+ * ── 🛑 THE BUG THIS EXISTS TO FIX ─────────────────────────────────────────
15
+ *
16
+ * Both address forms used `prev.city.trim() ? prev.city : city` — fill only
17
+ * an EMPTY field. That intent is right and is preserved here: correcting an
18
+ * address someone deliberately typed is a bug they cannot report, because
19
+ * they watch their own input vanish with no idea what did it.
20
+ *
21
+ * But "empty" cannot tell WHO filled the field. After the first lookup the
22
+ * city is non-empty — written by the autofill itself — so every subsequent
23
+ * lookup is refused. Enter 413001, get Solapur/Maharashtra; correct the PIN
24
+ * to 500005 (Hyderabad) and the form still shows Solapur. The PIN and the
25
+ * city now disagree, the form validates, and the parcel ships to the wrong
26
+ * city — worse than never autofilling at all.
27
+ *
28
+ * ── The rule ──────────────────────────────────────────────────────────────
29
+ *
30
+ * A field is ours to overwrite when it is EMPTY, or when it still holds
31
+ * exactly what we last wrote into it. The moment a human edits it, it stops
32
+ * matching the memo and becomes untouchable again — the original guarantee,
33
+ * now actually enforceable rather than approximated by "is it blank".
34
+ */
35
+ export declare function applyPostalAutofill<T extends CityState>(prev: T, resolved: Partial<CityState>, memo: PostalAutofillMemo): {
36
+ next: T;
37
+ memo: PostalAutofillMemo;
38
+ };
39
+ export {};
@@ -0,0 +1,54 @@
1
+ /*
2
+ * WHY: A postal lookup must fill the city/state it knows WITHOUT overwriting
3
+ * what the person typed — and the obvious test for that ("is the field
4
+ * empty?") silently breaks every lookup after the first.
5
+ * WHAT: `applyPostalAutofill` — merge a resolved city/state into form values,
6
+ * overwriting only values this helper itself wrote earlier.
7
+ *
8
+ * EXPORTS: applyPostalAutofill, type PostalAutofillMemo
9
+ *
10
+ * @tag domain:addresses
11
+ * @tag layer:utils
12
+ * @tag pattern:pure
13
+ * @tag sideEffects:none
14
+ */
15
+ /**
16
+ * Merge `resolved` into `prev`, returning the new values and an updated memo.
17
+ *
18
+ * ── 🛑 THE BUG THIS EXISTS TO FIX ─────────────────────────────────────────
19
+ *
20
+ * Both address forms used `prev.city.trim() ? prev.city : city` — fill only
21
+ * an EMPTY field. That intent is right and is preserved here: correcting an
22
+ * address someone deliberately typed is a bug they cannot report, because
23
+ * they watch their own input vanish with no idea what did it.
24
+ *
25
+ * But "empty" cannot tell WHO filled the field. After the first lookup the
26
+ * city is non-empty — written by the autofill itself — so every subsequent
27
+ * lookup is refused. Enter 413001, get Solapur/Maharashtra; correct the PIN
28
+ * to 500005 (Hyderabad) and the form still shows Solapur. The PIN and the
29
+ * city now disagree, the form validates, and the parcel ships to the wrong
30
+ * city — worse than never autofilling at all.
31
+ *
32
+ * ── The rule ──────────────────────────────────────────────────────────────
33
+ *
34
+ * A field is ours to overwrite when it is EMPTY, or when it still holds
35
+ * exactly what we last wrote into it. The moment a human edits it, it stops
36
+ * matching the memo and becomes untouchable again — the original guarantee,
37
+ * now actually enforceable rather than approximated by "is it blank".
38
+ */
39
+ export function applyPostalAutofill(prev, resolved, memo) {
40
+ const nextMemo = {};
41
+ const merge = (field) => {
42
+ const current = prev[field];
43
+ const incoming = resolved[field];
44
+ const ours = current.trim() === "" || current === memo[field];
45
+ if (!ours || !incoming)
46
+ return current; // human's value, or nothing to say
47
+ nextMemo[field] = incoming;
48
+ return incoming;
49
+ };
50
+ return {
51
+ next: { ...prev, city: merge("city"), state: merge("state") },
52
+ memo: nextMemo,
53
+ };
54
+ }
@@ -11,12 +11,8 @@ export declare function getUnreadNotificationCount(userId: string): Promise<numb
11
11
  export interface SendNotificationInput extends NotificationCreateInput {
12
12
  /** User's email — used by the email channel when enabled. */
13
13
  userEmail?: string;
14
- /** User's phone with country code, digits only — used by WhatsApp channel. */
15
- userPhone?: string;
16
14
  /** Pre-rendered email HTML — falls back to a plain-text <p> when absent. */
17
15
  emailHtml?: string;
18
- /** Buyer paid the ₹10 WhatsApp order-updates addon — enables WhatsApp channel for this notification even when the user has no standing WhatsApp subscription. */
19
- orderWhatsappAddonPaid?: boolean;
20
16
  /**
21
17
  * Which portal the recipient reads this in — decides where `actionUrl`
22
18
  * points when the caller does not supply one.
@@ -52,17 +48,15 @@ export interface SendNotificationInput extends NotificationCreateInput {
52
48
  export interface SendNotificationResult {
53
49
  notification: NotificationDocument;
54
50
  email: "sent" | "skipped" | "failed";
55
- /** WhatsApp dispatch is now async (enqueued as a `whatsappNotify` job) — "queued" replaces "sent" as the immediate outcome; the real delivery result lands on `notification.whatsappStatus`. */
56
- whatsapp: "queued" | "skipped" | "failed";
57
51
  }
58
52
  /**
59
53
  * Create an in-app notification and fan out to enabled external channels.
60
54
  *
61
- * In-app is always written. Email / WhatsApp are sent only when:
55
+ * In-app is always written. Email is sent only when:
62
56
  * 1. The channel is enabled in siteSettings.notificationChannels
63
57
  * 2. Notification priority meets the channel's minPriority threshold
64
58
  * 3. The optional `types` filter includes this notification type (or is absent)
65
- * 4. The contact field (userEmail / userPhone) is supplied by the caller
59
+ * 4. The contact field (userEmail) is supplied by the caller
66
60
  * 5. The required credentials are set in siteSettings.credentials
67
61
  */
68
62
  export declare function sendNotification(input: SendNotificationInput): Promise<SendNotificationResult>;
@@ -4,11 +4,11 @@ import { siteSettingsRepository } from "../repository/site-settings.repository.j
4
4
  import { userRepository } from "../../auth/repository/user.repository.js";
5
5
  import { createResendProvider } from "../../../providers/email-resend/provider.js";
6
6
  import { isChannelHealthy, withChannelRetry } from "../../../_internal/server/notifications/channel-health.js";
7
- import { enqueueJob } from "../../jobs/actions/enqueue-job.js";
8
7
  import { serverLogger } from "../../../monitoring/index.js";
9
8
  import { resolveNotificationActionUrl, TYPE_AUDIENCE, } from "../../../_internal/shared/features/notifications/action-url.js";
10
9
  import { isEmailEligible } from "../../../_internal/shared/features/notifications/email-eligibility.js";
11
10
  import { renderNotificationEmail } from "../../email/notification-templates.js";
11
+ import { DEFAULT_NOTIFICATION_CHANNELS, meetsMinPriority, } from "../schemas/firestore.js";
12
12
  /**
13
13
  * A notification's `actionUrl` is a site-relative path — correct for the
14
14
  * in-app bell, useless in an email, where a bare `/user/orders/x` is not a
@@ -31,56 +31,6 @@ function absoluteActionUrl(path) {
31
31
  const base = process.env.NEXT_PUBLIC_APP_URL?.replace(/\/+$/, "");
32
32
  return base ? `${base}${path}` : path;
33
33
  }
34
- import { DEFAULT_NOTIFICATION_CHANNELS, meetsMinPriority, } from "../schemas/firestore.js";
35
- /**
36
- * Notification types whose WhatsApp send is gated behind the buyer's
37
- * per-order ₹10 WhatsApp-updates addon (`OrderDocument.whatsappNotifyAddon`)
38
- * — see `orderWhatsappAddonPaid` on `SendNotificationInput`. Every other
39
- * type (bid_won, offers, scam reports, support tickets, admin alerts, …)
40
- * keeps the original two-gate behavior (admin channel enabled + user hasn't
41
- * opted out) unchanged.
42
- */
43
- const ORDER_GATED_TYPES = new Set([
44
- "order_placed",
45
- "order_confirmed",
46
- "order_shipped",
47
- "order_delivered",
48
- "order_cancelled",
49
- "refund_initiated",
50
- ]);
51
- /**
52
- * Notification type → the flat `SiteSettingsCredentials` field holding its
53
- * approved Meta template name.
54
- *
55
- * 🛑 **`Partial` here is CORRECT and is not the `typeToPrefsKey` mistake.**
56
- *
57
- * The distinction is what a missing key MEANS. A missing `typeToPrefsKey`
58
- * entry silently ignored a user's opt-out — a real setting that read as
59
- * honoured and was not. A missing entry here means "no Meta-approved template
60
- * exists for this type", which is a fact about the Meta account, not a bug:
61
- * six of the 28 types have one, and the rest legitimately fall back to
62
- * free-form (which Meta accepts inside the 24-hour customer-service window
63
- * and rejects outside it — the runner already logs that rejection).
64
- *
65
- * Getting six approved templates is a Meta Business review process, not a
66
- * code change, so listing all 28 here with empty values would be a
67
- * `Record<…>` that lies about coverage.
68
- *
69
- * The six that ARE approved are the order lifecycle, which is also the set
70
- * gated behind the buyer's ₹10 addon above — the two lists agree on purpose.
71
- */
72
- const WHATSAPP_TEMPLATE_FIELD = {
73
- order_placed: "whatsappTemplateOrderPlaced",
74
- order_confirmed: "whatsappTemplateOrderConfirmed",
75
- order_shipped: "whatsappTemplateOrderShipped",
76
- order_delivered: "whatsappTemplateOrderDelivered",
77
- order_cancelled: "whatsappTemplateOrderCancelled",
78
- refund_initiated: "whatsappTemplateRefundInitiated",
79
- };
80
- function resolveWhatsAppTemplateName(type, creds) {
81
- const field = WHATSAPP_TEMPLATE_FIELD[type];
82
- return (field ? creds[field] : undefined)?.trim() ?? "";
83
- }
84
34
  export async function markNotificationRead(id) {
85
35
  await notificationRepository.markAsRead(id);
86
36
  }
@@ -103,15 +53,15 @@ export async function getUnreadNotificationCount(userId) {
103
53
  /**
104
54
  * Create an in-app notification and fan out to enabled external channels.
105
55
  *
106
- * In-app is always written. Email / WhatsApp are sent only when:
56
+ * In-app is always written. Email is sent only when:
107
57
  * 1. The channel is enabled in siteSettings.notificationChannels
108
58
  * 2. Notification priority meets the channel's minPriority threshold
109
59
  * 3. The optional `types` filter includes this notification type (or is absent)
110
- * 4. The contact field (userEmail / userPhone) is supplied by the caller
60
+ * 4. The contact field (userEmail) is supplied by the caller
111
61
  * 5. The required credentials are set in siteSettings.credentials
112
62
  */
113
63
  export async function sendNotification(input) {
114
- const { userEmail, userPhone, emailHtml, audience, eligibilityOverride, ...notifInput } = input;
64
+ const { userEmail, emailHtml, audience, eligibilityOverride, ...notifInput } = input;
115
65
  /*
116
66
  * Fill `actionUrl` when the caller did not.
117
67
  *
@@ -153,12 +103,12 @@ export async function sendNotification(input) {
153
103
  * suppresses the emailed/messaged COPY, not the notification.
154
104
  *
155
105
  * One map gates both channels deliberately. If a type is ever genuinely
156
- * WhatsApp-worthy but not email-worthy, split the map then rather than
106
+ * worth a channel of its own, split the map then rather than
157
107
  * loosening this early return.
158
108
  */
159
109
  if (!isEmailEligible(notifInput.type) &&
160
110
  eligibilityOverride !== "staff_requested") {
161
- return { notification, email: "skipped", whatsapp: "skipped" };
111
+ return { notification, email: "skipped" };
162
112
  }
163
113
  // Load channel config + credentials (one Firestore read).
164
114
  let settings;
@@ -168,7 +118,7 @@ export async function sendNotification(input) {
168
118
  catch (err) {
169
119
  void normalizeError(err);
170
120
  serverLogger.warn("sendNotification: could not load siteSettings — skipping external channels", { err });
171
- return { notification, email: "skipped", whatsapp: "skipped" };
121
+ return { notification, email: "skipped" };
172
122
  }
173
123
  const channels = settings.notificationChannels ?? DEFAULT_NOTIFICATION_CHANNELS;
174
124
  const creds = settings.credentials ?? {};
@@ -200,7 +150,6 @@ export async function sendNotification(input) {
200
150
  ? userRepository.revealUser(fetchedUserDoc)
201
151
  : null;
202
152
  const resolvedEmail = userEmail ?? fetchedUserPlain?.email ?? undefined;
203
- const resolvedPhone = userPhone ?? fetchedUserPlain?.phoneNumber ?? undefined;
204
153
  // Map NotificationType to a NotificationTypePrefs key.
205
154
  /*
206
155
  * 🛑 COMPLETE and compile-checked: `Record<NotificationType, …>`, not
@@ -263,7 +212,7 @@ export async function sendNotification(input) {
263
212
  const typeKey = typeToPrefsKey[type];
264
213
  // If the user has explicitly disabled this notification type, skip all external channels.
265
214
  if (typeKey && userTypePrefs[typeKey] === false) {
266
- return { notification, email: "skipped", whatsapp: "skipped" };
215
+ return { notification, email: "skipped" };
267
216
  }
268
217
  // Email channel — admin enabled AND user hasn't opted out
269
218
  let emailStatus = "skipped";
@@ -310,54 +259,10 @@ export async function sendNotification(input) {
310
259
  }
311
260
  }
312
261
  }
313
- // WhatsApp channel — admin enabled AND user hasn't opted out AND (for
314
- // order-lifecycle types) the buyer paid the per-order WhatsApp addon.
315
- let whatsappStatus = "skipped";
316
- if (channels.whatsapp.enabled &&
317
- userChannelPrefs.whatsapp !== false &&
318
- resolvedPhone &&
319
- meetsMinPriority(priority, channels.whatsapp.minPriority) &&
320
- (!channels.whatsapp.types?.length || channels.whatsapp.types.includes(type)) &&
321
- (!ORDER_GATED_TYPES.has(type) || input.orderWhatsappAddonPaid === true)) {
322
- const phoneNumberId = creds.whatsappPhoneNumberId?.trim() ?? "";
323
- const accessToken = creds.whatsappCloudApiToken?.trim() ?? "";
324
- if (phoneNumberId && accessToken) {
325
- try {
326
- const { jobId } = await enqueueJob({
327
- jobType: "whatsappNotify",
328
- payload: {
329
- toPhone: resolvedPhone,
330
- title,
331
- message,
332
- type,
333
- templateName: resolveWhatsAppTemplateName(type, creds),
334
- templateLanguage: creds.whatsappTemplateLanguage ?? "en",
335
- notificationId: notification.id,
336
- phoneNumberId,
337
- accessToken,
338
- },
339
- requestedBy: input.userId,
340
- });
341
- whatsappStatus = "queued";
342
- await notificationRepository
343
- .update(notification.id, { whatsappStatus: "queued", whatsappJobId: jobId })
344
- .catch((err) => {
345
- void normalizeError(err);
346
- serverLogger.warn("sendNotification: failed to write whatsappJobId onto notification doc", { notificationId: notification.id });
347
- });
348
- }
349
- catch (err) {
350
- void normalizeError(err);
351
- serverLogger.error("sendNotification: WhatsApp job enqueue failed", { userId: input.userId, err });
352
- whatsappStatus = "failed";
353
- }
354
- }
355
- }
356
262
  serverLogger.info("sendNotification: dispatched", {
357
263
  userId: input.userId,
358
264
  type,
359
265
  email: emailStatus,
360
- whatsapp: whatsappStatus,
361
266
  });
362
- return { notification, email: emailStatus, whatsapp: whatsappStatus };
267
+ return { notification, email: emailStatus };
363
268
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Users, Package, Store, ShoppingBag, FileText, Settings, Shield, BarChart2, AlertTriangle, BookOpen, MessageSquare, CreditCard, } from "lucide-react";
2
+ import { Users, Package, Store, ShoppingBag, FileText, Settings, Shield, BarChart2, AlertTriangle, BookOpen, CreditCard, } from "lucide-react";
3
3
  import { Alert, Div, Grid, Heading, Row, Section, Stack, Text, TextLink } from "../../../ui/index.js";
4
4
  import { ROUTES } from "../../../next/routing/route-map.js";
5
5
  const CLS_WARN_PANEL = "rounded-2xl border border-amber-200 bg-warning-surface dark:border-amber-800 p-[var(--appkit-space-6)]";
@@ -69,13 +69,6 @@ const GUIDE_CARDS = [
69
69
  href: String(ROUTES.ADMIN.GUIDE_TRUST),
70
70
  permission: "admin:moderation:read",
71
71
  },
72
- {
73
- Icon: MessageSquare,
74
- title: "WhatsApp Integration",
75
- description: "Connect Meta's WhatsApp Business Cloud API — Business Manager setup, phone registration, access tokens, and message templates.",
76
- href: String(ROUTES.ADMIN.GUIDE_WHATSAPP),
77
- permission: "admin:site:read",
78
- },
79
72
  {
80
73
  Icon: CreditCard,
81
74
  title: "Payments (Razorpay)",
@@ -32,7 +32,7 @@ export interface AdminOrderEditorViewProps {
32
32
  paymentReviewOutcome?: string;
33
33
  /**
34
34
  * Paid add-ons + applied coupon for this order. Operational, not decorative:
35
- * `whatsappNotifyAddon` is who a status change should message, and the
35
+ * `giftWrapAddon` tells the packer to wrap the parcel, and the
36
36
  * coupon is what an admin needs when reconciling a discounted order.
37
37
  */
38
38
  addons?: OrderAddonBadgesOrder;
@@ -198,8 +198,6 @@ export function AdminOrdersView({ children, ...props }) {
198
198
  // Straight off the order document — the admin list route returns
199
199
  // raw docs, so these need no serializer entry (cf. Root Cause #38).
200
200
  addons: {
201
- whatsappNotifyAddon: Boolean(item.whatsappNotifyAddon),
202
- whatsappNotifyFee: Number(item.whatsappNotifyFee ?? 0) || undefined,
203
201
  giftWrapAddon: Boolean(item.giftWrapAddon),
204
202
  giftWrapFee: Number(item.giftWrapFee ?? 0) || undefined,
205
203
  giftWrapMessage: toStringValue(item.giftWrapMessage) || undefined,
@@ -6,7 +6,8 @@ import React from "react";
6
6
  import { useQuery, useQueryClient } from "@tanstack/react-query";
7
7
  import { ProductInlineSelect } from "../../seller/components/ProductInlineSelect.js";
8
8
  import { CategoryInlineSelect } from "../../seller/components/CategoryInlineSelect.js";
9
- import { Button, Checkbox, Div, Input, Modal, Row, Select, Stack, Text, Textarea, useToast } from "../../../ui/index.js";
9
+ import { Button, Checkbox, Div, Input, Modal, PaginatedSelect, Row, Select, Stack, Text, Textarea, useToast } from "../../../ui/index.js";
10
+ import { ICON_KEY_OPTIONS } from "./sections/icon-options.js";
10
11
  import { FormErrorSummary, applyZodIssues } from "../../../ui/forms/index.js";
11
12
  import { homepageSectionFormSchema, } from "../schemas/homepage-section-form.js";
12
13
  import { SectionForm, useSectionFormNav } from "../../shell/index.js";
@@ -753,7 +754,7 @@ export function AdminSectionsView({ children }) {
753
754
  return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: "Welcome Section Builder" }), _jsx(Input, { label: "Headline (h1)", value: welcomeBuilder.h1, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, h1: e.target.value })) }), _jsx(Input, { label: "Subtitle", value: welcomeBuilder.subtitle, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, subtitle: e.target.value })) }), _jsx(Textarea, { label: "Description", value: welcomeBuilder.description, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, description: e.target.value })), rows: 3 }), _jsx(Checkbox, { checked: welcomeBuilder.showCTA, label: "Show CTA button", onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, showCTA: e.target.checked })) }), welcomeBuilder.showCTA ? (_jsxs(_Fragment, { children: [_jsx(Input, { label: "CTA text", value: welcomeBuilder.ctaText, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, ctaText: e.target.value })) }), _jsx(Input, { label: "CTA link", value: welcomeBuilder.ctaLink, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, ctaLink: e.target.value })), placeholder: String(ROUTES.PUBLIC.PRODUCTS) })] })) : null] }));
754
755
  }
755
756
  function renderTrustIndicatorsBuilder() {
756
- return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: "Trust Indicators Builder" }), _jsx(Input, { label: "Section title", value: trustIndicatorsBuilder.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => ({ ...prev, title: e.target.value })) }), trustIndicatorsBuilder.indicators.map((ind, index) => (_jsxs(Stack, { className: `${__P.p3}`, gap: "sm", rounded: "md", border: "default", children: [_jsxs(Row, { align: "center", justify: "between", children: [_jsxs(Text, { className: "tracking-wide", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: ["Indicator ", index + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: prev.indicators.filter((_, i) => i !== index) })), children: "Remove" })] }), _jsx(Input, { label: "Icon (emoji or text)", value: ind.icon, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], icon: e.target.value }; return { ...prev, indicators: next }; }) }), _jsx(Input, { label: "Title", value: ind.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], title: e.target.value }; return { ...prev, indicators: next }; }) }), _jsx(Input, { label: "Description", value: ind.description, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], description: e.target.value }; return { ...prev, indicators: next }; }) })] }, ind.id))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: [...prev.indicators, { id: `ti-${Date.now()}`, icon: "✨", title: "", description: "" }] })), children: "+ Add indicator" })] }));
757
+ return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: "Trust Indicators Builder" }), _jsx(Input, { label: "Section title", value: trustIndicatorsBuilder.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => ({ ...prev, title: e.target.value })) }), trustIndicatorsBuilder.indicators.map((ind, index) => (_jsxs(Stack, { className: `${__P.p3}`, gap: "sm", rounded: "md", border: "default", children: [_jsxs(Row, { align: "center", justify: "between", children: [_jsxs(Text, { className: "tracking-wide", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: ["Indicator ", index + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: prev.indicators.filter((_, i) => i !== index) })), children: "Remove" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { color: "muted", size: "xs", weight: "semibold", children: "Icon" }), _jsx(PaginatedSelect, { options: ICON_KEY_OPTIONS, value: ind.icon || null, ariaLabel: `Icon for indicator ${index + 1}`, placeholder: "Choose an icon", onChange: (value) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], icon: value ?? "" }; return { ...prev, indicators: next }; }) })] }), _jsx(Input, { label: "Title", value: ind.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], title: e.target.value }; return { ...prev, indicators: next }; }) }), _jsx(Input, { label: "Description", value: ind.description, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], description: e.target.value }; return { ...prev, indicators: next }; }) })] }, ind.id))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: [...prev.indicators, { id: `ti-${Date.now()}`, icon: "verify", title: "", description: "" }] })), children: "+ Add indicator" })] }));
757
758
  }
758
759
  function renderCategoriesBuilder() {
759
760
  return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: "Categories Section Builder" }), _jsx(Input, { label: "Section title", value: categoriesBuilder.title, onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Input, { label: LBL_VIEW_MORE, value: categoriesBuilder.viewMoreLabel, onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, viewMoreLabel: e.target.value })), placeholder: PH_VIEW_MORE, helperText: HELP_VIEW_MORE }), _jsx(Input, { label: "Max categories (4\u201312)", type: "number", min: 4, max: 12, value: String(categoriesBuilder.maxCategories), onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, maxCategories: Math.min(12, Math.max(4, Number(e.target.value) || 4)) })) }), _jsx(Checkbox, { checked: categoriesBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(categoriesBuilder.scrollInterval), onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, scrollInterval: Math.max(1000, Number(e.target.value) || 1000) })) }), _jsx(Checkbox, { checked: categoriesBuilder.loop, label: "Loop carousel", onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, loop: e.target.checked })) })] }));