@mohasinac/appkit 4.53.1 → 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 (384) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/theme/ThemeProvider.js +15 -1
  3. package/dist/_internal/server/features/auth/capabilities.js +7 -5
  4. package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
  5. package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
  6. package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
  7. package/dist/_internal/server/features/checkout/actions.js +96 -51
  8. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  9. package/dist/_internal/server/features/checkout/index.js +1 -1
  10. package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
  11. package/dist/_internal/server/features/orders/adapters.js +1 -3
  12. package/dist/_internal/server/features/price-index/market.d.ts +57 -0
  13. package/dist/_internal/server/features/price-index/market.js +120 -0
  14. package/dist/_internal/server/features/products/list-public.d.ts +12 -0
  15. package/dist/_internal/server/features/products/list-public.js +10 -1
  16. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
  17. package/dist/_internal/server/features/products/listing-tab-counts.js +184 -10
  18. package/dist/_internal/server/features/search/index-build/sources.js +43 -2
  19. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  20. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  21. package/dist/_internal/server/features/stores/adapters.js +0 -1
  22. package/dist/_internal/server/features/stores/tabs.d.ts +7 -2
  23. package/dist/_internal/server/features/stores/tabs.js +5 -3
  24. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
  25. package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
  26. package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
  27. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
  28. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
  29. package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
  30. package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
  31. package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
  32. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
  33. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
  34. package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
  35. package/dist/_internal/server/notifications/channel-health.js +2 -2
  36. package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
  37. package/dist/_internal/server/notifications/send-guard.js +2 -4
  38. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  39. package/dist/_internal/shared/actions/action-registry.js +128 -28
  40. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  41. package/dist/_internal/shared/checkout/order-math.js +1 -1
  42. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  43. package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
  44. package/dist/_internal/shared/features/checkout/config.js +0 -2
  45. package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
  46. package/dist/_internal/shared/features/messaging/config.js +1 -4
  47. package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
  48. package/dist/_internal/shared/features/site-settings/fees.js +0 -2
  49. package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
  50. package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
  51. package/dist/_internal/shared/fees/calculator.d.ts +0 -8
  52. package/dist/_internal/shared/fees/calculator.js +0 -7
  53. package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
  54. package/dist/_internal/shared/listing-types/tiers.js +150 -0
  55. package/dist/_internal/shared/search/match.js +28 -2
  56. package/dist/cli/index.js +0 -2
  57. package/dist/client.d.ts +25 -4
  58. package/dist/client.js +36 -5
  59. package/dist/constants/api-endpoints.d.ts +28 -15
  60. package/dist/constants/api-endpoints.js +14 -8
  61. package/dist/constants/field-names.d.ts +1 -0
  62. package/dist/constants/field-names.js +1 -0
  63. package/dist/constants/notification-types.d.ts +1 -1
  64. package/dist/constants/notification-types.js +1 -1
  65. package/dist/core/integration-keys.d.ts +5 -5
  66. package/dist/core/integration-keys.js +21 -10
  67. package/dist/features/about/components/FeesView.js +0 -6
  68. package/dist/features/about/components/GuidesHubView.js +15 -2
  69. package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
  70. package/dist/features/account/components/UserOrdersView.js +26 -7
  71. package/dist/features/account/types/index.d.ts +0 -2
  72. package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
  73. package/dist/features/addresses/utils/postal-autofill.js +54 -0
  74. package/dist/features/admin/actions/notification-actions.d.ts +2 -8
  75. package/dist/features/admin/actions/notification-actions.js +9 -104
  76. package/dist/features/admin/components/AdminGuideHubView.js +1 -8
  77. package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
  78. package/dist/features/admin/components/AdminOrdersView.js +0 -2
  79. package/dist/features/admin/components/AdminSectionsView.js +3 -2
  80. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
  81. package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
  82. package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
  83. package/dist/features/admin/components/OwnerQuickActions.js +142 -0
  84. package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
  85. package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
  86. package/dist/features/admin/components/sections/icon-options.js +23 -0
  87. package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
  88. package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
  89. package/dist/features/admin/constants/site-settings-tabs.js +6 -12
  90. package/dist/features/admin/repository/site-settings.repository.js +1 -1
  91. package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
  92. package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
  93. package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
  94. package/dist/features/admin/schemas/admin-user-form.js +3 -44
  95. package/dist/features/admin/schemas/firestore.d.ts +28 -54
  96. package/dist/features/admin/schemas/firestore.js +40 -18
  97. package/dist/features/auctions/components/AuctionDetailPageView.js +12 -10
  98. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
  99. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
  100. package/dist/features/auth/checkout-value-otp.d.ts +1 -1
  101. package/dist/features/auth/checkout-value-otp.js +1 -1
  102. package/dist/features/auth/permissions/constants.d.ts +29 -2
  103. package/dist/features/auth/permissions/constants.js +67 -1
  104. package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
  105. package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
  106. package/dist/features/cart/components/CartDrawer.js +3 -2
  107. package/dist/features/cart/components/CartGroupLineRow.js +2 -1
  108. package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
  109. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  110. package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
  111. package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
  112. package/dist/features/cart/hooks/useAddToCart.js +10 -5
  113. package/dist/features/cart/repository/cart.repository.js +1 -2
  114. package/dist/features/cart/schemas/firestore.d.ts +1 -2
  115. package/dist/features/cart/utils/pending-ops.d.ts +11 -1
  116. package/dist/features/cart/utils/pending-ops.js +14 -2
  117. package/dist/features/categories/api/[id]/price-guidance/route.js +1 -24
  118. package/dist/features/categories/components/BrandDetailPageView.js +15 -6
  119. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
  120. package/dist/features/categories/components/BrandDetailTabs.js +18 -3
  121. package/dist/features/categories/components/BundleCollage.js +3 -2
  122. package/dist/features/categories/components/BundleDetailView.js +2 -1
  123. package/dist/features/categories/components/BundleItemsPicker.js +3 -4
  124. package/dist/features/categories/components/CategoryDetailPageView.js +19 -8
  125. package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
  126. package/dist/features/categories/components/CategoryDetailTabs.js +29 -7
  127. package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
  128. package/dist/features/categories/components/CategoryGrid.js +9 -2
  129. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
  130. package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
  131. package/dist/features/classified/components/ClassifiedDetailPageView.js +12 -2
  132. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +12 -2
  133. package/dist/features/events/components/EventCard.d.ts +11 -1
  134. package/dist/features/events/components/EventCard.js +9 -2
  135. package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
  136. package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
  137. package/dist/features/homepage/components/CTABannerSection.js +6 -3
  138. package/dist/features/homepage/components/HeroCarousel.js +8 -6
  139. package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
  140. package/dist/features/homepage/components/SectionCarousel.js +13 -5
  141. package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
  142. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  143. package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
  144. package/dist/features/homepage/components/StatsCounterSection.js +2 -2
  145. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  146. package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
  147. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  148. package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
  149. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  150. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
  151. package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
  152. package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
  153. package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
  154. package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
  155. package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
  156. package/dist/features/homepage/constants/section-copy.d.ts +12 -10
  157. package/dist/features/homepage/constants/section-copy.js +28 -6
  158. package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
  159. package/dist/features/homepage/constants/stat-icons.js +17 -0
  160. package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
  161. package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
  162. package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
  163. package/dist/features/homepage/lib/section-defaults.js +24 -4
  164. package/dist/features/homepage/lib/section-renderer.js +48 -8
  165. package/dist/features/homepage/schemas/firestore.d.ts +18 -1
  166. package/dist/features/layout/AppLayoutShell.js +2 -1
  167. package/dist/features/layout/BottomActions.d.ts +1 -0
  168. package/dist/features/layout/BottomActions.js +330 -0
  169. package/dist/features/layout/BottomChrome.d.ts +45 -0
  170. package/dist/features/layout/BottomChrome.js +5 -17
  171. package/dist/features/layout/SideActionDock.js +36 -13
  172. package/dist/features/layout/index.d.ts +2 -7
  173. package/dist/features/layout/index.js +7 -7
  174. package/dist/features/layout/useIsDesktop.d.ts +36 -0
  175. package/dist/features/layout/useIsDesktop.js +48 -0
  176. package/dist/features/live/components/LiveItemDetailPageView.js +12 -2
  177. package/dist/features/orders/actions/refund-actions.js +0 -1
  178. package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
  179. package/dist/features/orders/components/OrderAddonBadges.js +3 -4
  180. package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
  181. package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
  182. package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
  183. package/dist/features/orders/components/index.d.ts +2 -1
  184. package/dist/features/orders/components/index.js +1 -1
  185. package/dist/features/orders/repository/orders.repository.d.ts +0 -8
  186. package/dist/features/orders/repository/orders.repository.js +0 -2
  187. package/dist/features/orders/schemas/firestore.d.ts +17 -9
  188. package/dist/features/orders/types/index.d.ts +2 -5
  189. package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
  190. package/dist/features/orders/utils/order-announcement-message.js +16 -0
  191. package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
  192. package/dist/features/orders/utils/payment-proof-message.js +17 -0
  193. package/dist/features/parts/components/PartDetailPageView.js +96 -1
  194. package/dist/features/parts/schemas/firestore.d.ts +247 -0
  195. package/dist/features/parts/schemas/firestore.js +6 -6
  196. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
  197. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
  198. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -10
  199. package/dist/features/price-index/components/PriceIndexToolView.d.ts +21 -0
  200. package/dist/features/price-index/components/PriceIndexToolView.js +230 -27
  201. package/dist/features/price-index/lookup-target.d.ts +48 -0
  202. package/dist/features/price-index/lookup-target.js +107 -0
  203. package/dist/features/products/api/[id]/route.js +8 -1
  204. package/dist/features/products/api/route.js +16 -4
  205. package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
  206. package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
  207. package/dist/features/products/components/CompareOverlay.d.ts +2 -1
  208. package/dist/features/products/components/CompareOverlay.js +2 -1
  209. package/dist/features/products/components/GroupSettingsPanel.js +2 -1
  210. package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
  211. package/dist/features/products/components/InteractiveProductCard.js +16 -4
  212. package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
  213. package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
  214. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
  215. package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
  216. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  217. package/dist/features/products/components/ProductDetailPageView.js +34 -4
  218. package/dist/features/products/components/ProductGrid.d.ts +14 -1
  219. package/dist/features/products/components/ProductGrid.js +22 -5
  220. package/dist/features/products/components/ProductsIndexListing.js +2 -2
  221. package/dist/features/products/components/SublistingCarouselSection.js +2 -1
  222. package/dist/features/products/repository/products.repository.d.ts +1 -0
  223. package/dist/features/products/repository/products.repository.js +5 -1
  224. package/dist/features/products/utils/group-member-image.d.ts +9 -2
  225. package/dist/features/products/utils/group-member-image.js +2 -1
  226. package/dist/features/reviews/api/[id]/route.js +83 -23
  227. package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
  228. package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
  229. package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
  230. package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
  231. package/dist/features/reviews/components/index.d.ts +4 -0
  232. package/dist/features/reviews/components/index.js +2 -0
  233. package/dist/features/scams/schemas/index.d.ts +10 -10
  234. package/dist/features/search/action-index/settings-entries.js +0 -9
  235. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  236. package/dist/features/seller/actions/seller-actions.js +49 -3
  237. package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
  238. package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
  239. package/dist/features/seller/components/SellerProductsView.js +3 -2
  240. package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
  241. package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
  242. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
  243. package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
  244. package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
  245. package/dist/features/store-extensions/schemas/firestore.js +0 -10
  246. package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
  247. package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
  248. package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
  249. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
  250. package/dist/features/stores/components/StoreGuideHubView.js +2 -8
  251. package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
  252. package/dist/features/stores/components/index.d.ts +0 -2
  253. package/dist/features/stores/components/index.js +0 -1
  254. package/dist/features/stores/repository/store.repository.d.ts +1 -26
  255. package/dist/features/stores/repository/store.repository.js +5 -60
  256. package/dist/features/stores/schemas/firestore.d.ts +6 -25
  257. package/dist/features/stores/schemas/firestore.js +6 -3
  258. package/dist/features/stores/schemas/index.d.ts +1 -87
  259. package/dist/features/stores/schemas/index.js +10 -15
  260. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
  261. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
  262. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +114 -2
  263. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
  264. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
  265. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
  266. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
  267. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +427 -69
  268. package/dist/index.d.ts +20 -32
  269. package/dist/index.js +34 -43
  270. package/dist/next/routing/route-map.d.ts +2 -8
  271. package/dist/next/routing/route-map.js +21 -4
  272. package/dist/providers/db-firebase/base.repository.d.ts +1 -1
  273. package/dist/providers/db-firebase/base.repository.js +1 -1
  274. package/dist/providers/payment-razorpay/index.d.ts +125 -0
  275. package/dist/providers/payment-razorpay/index.js +232 -0
  276. package/dist/providers/payment-razorpay/signature.d.ts +53 -0
  277. package/dist/providers/payment-razorpay/signature.js +71 -0
  278. package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
  279. package/dist/providers/shipping-shiprocket/index.js +356 -0
  280. package/dist/providers.d.ts +3 -0
  281. package/dist/providers.js +3 -0
  282. package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
  283. package/dist/react/hooks/useCanSeePrices.js +25 -0
  284. package/dist/repositories/index.d.ts +1 -1
  285. package/dist/repositories/index.js +1 -1
  286. package/dist/schemas/registry.d.ts +10 -115
  287. package/dist/schemas/registry.js +1 -2
  288. package/dist/security/pii-encrypt.js +1 -1
  289. package/dist/seed/_helpers/category-forest.js +27 -0
  290. package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -86
  291. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  292. package/dist/seed/_helpers/category-parts.js +13412 -3020
  293. package/dist/seed/carousel-slides-seed-data.js +47 -10
  294. package/dist/seed/categories-seed-data.js +48 -6
  295. package/dist/seed/faq-seed-data.js +2 -2
  296. package/dist/seed/homepage-sections-seed-data.js +286 -54
  297. package/dist/seed/index.d.ts +1 -1
  298. package/dist/seed/index.js +1 -1
  299. package/dist/seed/manifest.d.ts +1 -1
  300. package/dist/seed/manifest.js +1 -2
  301. package/dist/seed/model-composition-seed-data.js +6 -8
  302. package/dist/seed/part-glossary/chunk0.d.ts +9 -0
  303. package/dist/seed/part-glossary/chunk0.js +35448 -0
  304. package/dist/seed/part-glossary/chunk1.d.ts +9 -0
  305. package/dist/seed/part-glossary/chunk1.js +40494 -0
  306. package/dist/seed/part-glossary/chunk2.d.ts +9 -0
  307. package/dist/seed/part-glossary/chunk2.js +51242 -0
  308. package/dist/seed/part-glossary/chunk3.d.ts +9 -0
  309. package/dist/seed/part-glossary/chunk3.js +53337 -0
  310. package/dist/seed/part-glossary/chunk4.d.ts +9 -0
  311. package/dist/seed/part-glossary/chunk4.js +51454 -0
  312. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  313. package/dist/seed/part-glossary-seed-data.js +23 -47483
  314. package/dist/seed/products-beyblade-x-seed-data.js +36 -1
  315. package/dist/seed/site-settings-seed-data.js +34 -35
  316. package/dist/seed/store-extensions-seed-data.d.ts +1 -2
  317. package/dist/seed/store-extensions-seed-data.js +1 -23
  318. package/dist/seed/stores-seed-data.js +0 -1
  319. package/dist/server-entry.d.ts +1 -1
  320. package/dist/server-entry.js +1 -1
  321. package/dist/server.d.ts +10 -10
  322. package/dist/server.js +24 -22
  323. package/dist/styles.css +392 -43
  324. package/dist/tailwind-utilities.css +1 -1
  325. package/dist/tokens/themes/default-dark.js +1 -1
  326. package/dist/tokens/themes/default-light.js +2 -1
  327. package/dist/tokens/tokens.css +6 -2
  328. package/dist/ui/components/Button.d.ts +11 -0
  329. package/dist/ui/components/Button.js +11 -0
  330. package/dist/ui/components/Button.style.css +29 -0
  331. package/dist/ui/components/CarouselNav.d.ts +57 -0
  332. package/dist/ui/components/CarouselNav.js +25 -0
  333. package/dist/ui/components/CarouselNav.style.css +265 -0
  334. package/dist/ui/components/GatedPrice.js +30 -3
  335. package/dist/ui/components/GatedPrice.style.css +43 -40
  336. package/dist/ui/components/HorizontalScroller.d.ts +12 -1
  337. package/dist/ui/components/HorizontalScroller.js +43 -3
  338. package/dist/ui/components/ImageMosaic.d.ts +8 -1
  339. package/dist/ui/components/ImageMosaic.js +3 -2
  340. package/dist/ui/components/ImageMosaic.style.css +22 -0
  341. package/dist/ui/components/Layout.style.css +6 -0
  342. package/dist/ui/components/Semantic.d.ts +3 -2
  343. package/dist/ui/components/Semantic.js +1 -0
  344. package/dist/ui/components/Typography.d.ts +2 -0
  345. package/dist/ui/components/Typography.js +2 -0
  346. package/dist/ui/components/Typography.style.css +19 -0
  347. package/dist/ui/components/index.style.css +1 -0
  348. package/dist/ui/index.d.ts +3 -1
  349. package/dist/ui/index.js +4 -0
  350. package/package.json +3 -2
  351. package/scripts/seed-cli.mjs +133 -27
  352. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
  353. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
  354. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
  355. package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
  356. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
  357. package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
  358. package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
  359. package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
  360. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
  361. package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
  362. package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
  363. package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
  364. package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
  365. package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
  366. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
  367. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
  368. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
  369. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
  370. package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
  371. package/dist/features/whatsapp-bot/components/index.js +0 -2
  372. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
  373. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
  374. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
  375. package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
  376. package/dist/features/whatsapp-bot/index.d.ts +0 -3
  377. package/dist/features/whatsapp-bot/index.js +0 -3
  378. package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
  379. package/dist/features/whatsapp-bot/manifest.js +0 -13
  380. package/dist/features/whatsapp-bot/messages/en.json +0 -7
  381. package/dist/features/whatsapp-bot/server.d.ts +0 -7
  382. package/dist/features/whatsapp-bot/server.js +0 -7
  383. package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
  384. package/dist/features/whatsapp-bot/types/index.js +0 -1
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useRef, useState, useEffect, useCallback, } from "react";
4
4
  import { ChevronLeft, ChevronRight } from "lucide-react";
5
+ import { CarouselNav } from "./CarouselNav.js";
5
6
  const BREAKPOINTS = [
6
7
  ["2xl", 1536],
7
8
  ["xl", 1280],
@@ -21,12 +22,23 @@ function resolvePerView(perView, containerWidth) {
21
22
  }
22
23
  return 1;
23
24
  }
24
- export function HorizontalScroller({ children, className = "", gap = 16, snapToItems, showArrows, arrowSize = "md", arrowStyle = "circle", showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows = 1, autoScroll, autoScrollInterval = 3500, minItemWidth, pauseOnHover = false, itemClassName = "", loop = false, }) {
25
+ export function HorizontalScroller({ children, className = "", gap = 16, snapToItems, showArrows, arrowSize = "md", arrowStyle = "circle", showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows = 1, autoScroll, autoScrollInterval = 3500, minItemWidth, pauseOnHover = false, itemClassName = "", loop = false, showNav = false, navAriaLabel, }) {
25
26
  const [itemWidth, setItemWidth] = useState(undefined);
26
27
  const [colCount, setColCount] = useState(typeof perView === "number" ? perView : 3);
27
28
  const [isPaused, setIsPaused] = useState(false);
28
29
  const [atStart, setAtStart] = useState(true);
29
30
  const [atEnd, setAtEnd] = useState(true);
31
+ /*
32
+ * Page position, for the optional `showNav` indicator.
33
+ *
34
+ * 🛑 Derived from scroll geometry, never stored as the source of truth: the
35
+ * rail is a native scroller and a user can drag it to any offset, so an index
36
+ * this component *decided* would disagree with where the content actually is
37
+ * the first time someone swipes. One page = one viewport width, matching what
38
+ * `scrollBy` already moves.
39
+ */
40
+ const [pageIndex, setPageIndex] = useState(0);
41
+ const [pageCount, setPageCount] = useState(1);
30
42
  const internalRef = useRef(null);
31
43
  const containerRef = (externalRef ??
32
44
  internalRef);
@@ -91,6 +103,11 @@ export function HorizontalScroller({ children, className = "", gap = 16, snapToI
91
103
  return;
92
104
  // 1px tolerance for sub-pixel rounding
93
105
  const maxScroll = el.scrollWidth - el.clientWidth;
106
+ const width = el.clientWidth;
107
+ if (width > 0) {
108
+ setPageCount(Math.max(1, Math.ceil(el.scrollWidth / width)));
109
+ setPageIndex(Math.round(el.scrollLeft / width));
110
+ }
94
111
  if (maxScroll <= 1) {
95
112
  setAtStart(true);
96
113
  setAtEnd(true);
@@ -99,6 +116,12 @@ export function HorizontalScroller({ children, className = "", gap = 16, snapToI
99
116
  setAtStart(el.scrollLeft <= 1);
100
117
  setAtEnd(el.scrollLeft >= maxScroll - 1);
101
118
  }, [containerRef]);
119
+ const goToPage = useCallback((page) => {
120
+ const el = containerRef.current;
121
+ if (!el)
122
+ return;
123
+ el.scrollTo({ left: page * el.clientWidth, behavior: "smooth" });
124
+ }, [containerRef]);
102
125
  const handleKeyDown = useCallback((e) => {
103
126
  if (e.key === "ArrowRight") {
104
127
  e.preventDefault();
@@ -196,6 +219,23 @@ export function HorizontalScroller({ children, className = "", gap = 16, snapToI
196
219
  updateExtents();
197
220
  onScroll?.();
198
221
  };
222
+ /*
223
+ * The in-flow position indicator.
224
+ *
225
+ * 🛑 This is the fix for "no affordance on a phone", and it deliberately does
226
+ * NOT un-hide the absolute arrows below 640px. Those are `display:none` there
227
+ * for a documented reason — a 44px circle has nowhere to go over a
228
+ * single-column card, and `--with-arrows` reserves 2 × 44px of wrapper gutter
229
+ * to seat them, which on a narrow screen is width taken from the card itself.
230
+ * An in-flow control needs no gutter and no breakpoint, so the affordance
231
+ * exists at every width instead of appearing at one.
232
+ *
233
+ * No `progressMs`: a rail's autoScroll advances by 0.8 of a viewport rather
234
+ * than one page, so a fill timed to the interval would not line up with the
235
+ * segment it sits in. A position cue that is right beats a progress cue that
236
+ * is approximately right.
237
+ */
238
+ const navNode = showNav && pageCount > 1 ? (_jsx(CarouselNav, { count: pageCount, index: pageIndex, onSelect: goToPage, onPrev: () => scrollBy(-1), onNext: () => scrollBy(1), tone: "on-surface", atStart: atStart, atEnd: atEnd, loop: loop, paused: isPaused, ariaLabel: navAriaLabel ?? "Scroll position", className: "appkit-hscroller__nav" })) : null;
199
239
  if (showArrows) {
200
240
  const prevDisabled = !loop && atStart;
201
241
  const nextDisabled = !loop && atEnd;
@@ -206,9 +246,9 @@ export function HorizontalScroller({ children, className = "", gap = 16, snapToI
206
246
  className,
207
247
  ]
208
248
  .filter(Boolean)
209
- .join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-511", children: [!arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(-1), "aria-label": "Previous", "aria-disabled": prevDisabled || undefined, disabled: prevDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--prev appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronLeft, { className: "w-4 h-4" }) })), _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-512", children: content }), !arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(1), "aria-label": "Next", "aria-disabled": nextDisabled || undefined, disabled: nextDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--next appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronRight, { className: "w-4 h-4" }) }))] }));
249
+ .join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-511", children: [!arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(-1), "aria-label": "Previous", "aria-disabled": prevDisabled || undefined, disabled: prevDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--prev appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronLeft, { className: "w-4 h-4" }) })), _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-512", children: content }), !arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(1), "aria-label": "Next", "aria-disabled": nextDisabled || undefined, disabled: nextDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--next appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronRight, { className: "w-4 h-4" }) })), navNode] }));
210
250
  }
211
- return (_jsx("div", { className: ["appkit-hscroller", className].filter(Boolean).join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-513", children: _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-514", children: content }) }));
251
+ return (_jsxs("div", { className: ["appkit-hscroller", className].filter(Boolean).join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-513", children: [_jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-514", children: content }), navNode] }));
212
252
  }
213
253
  function scrollerCls(snapToItems, showScrollbar) {
214
254
  return [
@@ -1,11 +1,18 @@
1
1
  import React from "react";
2
2
  /** Below this there is nothing to arrange, so the caller should render nothing. */
3
3
  export declare const MOSAIC_MIN = 3;
4
+ /**
5
+ * `band` — the category-hero strip this was built for (180/260px).
6
+ * `hero` — the homepage hero's right column, roughly double height.
7
+ */
8
+ export type ImageMosaicSize = "band" | "hero";
4
9
  export interface ImageMosaicProps {
5
10
  /** Image URLs, most important first. Fewer than `MOSAIC_MIN` renders null. */
6
11
  images: readonly string[];
7
12
  /** Describes the SUBJECT, not the images — one alt for a decorative group. */
8
13
  alt: string;
14
+ /** Height preset. Defaults to `"band"`, the original behaviour. */
15
+ size?: ImageMosaicSize;
9
16
  className?: string;
10
17
  }
11
18
  /**
@@ -40,4 +47,4 @@ export interface ImageMosaicProps {
40
47
  * breaks SSR/hydration agreement and makes the page feel unstable — and it is
41
48
  * the shape Root Cause #25 is about on the seed side.
42
49
  */
43
- export declare function ImageMosaic({ images, alt, className }: ImageMosaicProps): React.JSX.Element | null;
50
+ export declare function ImageMosaic({ images, alt, size, className }: ImageMosaicProps): React.JSX.Element | null;
@@ -37,10 +37,11 @@ export const MOSAIC_MIN = 3;
37
37
  * breaks SSR/hydration agreement and makes the page feel unstable — and it is
38
38
  * the shape Root Cause #25 is about on the seed side.
39
39
  */
40
- export function ImageMosaic({ images, alt, className }) {
40
+ export function ImageMosaic({ images, alt, size = "band", className }) {
41
41
  const tiles = images.filter(Boolean).slice(0, MOSAIC_MAX);
42
42
  if (tiles.length < MOSAIC_MIN)
43
43
  return null;
44
44
  const [lead, ...rest] = tiles;
45
- return (_jsxs(Div, { className: `appkit-image-mosaic ${className ?? ""}`, role: "img", "aria-label": alt, children: [_jsx(Div, { className: "appkit-image-mosaic__lead", children: _jsx(MediaImage, { src: lead, alt: "", size: "card" }) }), _jsx(Div, { className: "appkit-image-mosaic__rest", children: rest.map((src, i) => (_jsx(Div, { className: "appkit-image-mosaic__tile", children: _jsx(MediaImage, { src: src, alt: "", size: "thumbnail" }) }, `${src}-${i}`))) })] }));
45
+ const sizeClass = size === "hero" ? "appkit-image-mosaic--hero" : "";
46
+ return (_jsxs(Div, { className: `appkit-image-mosaic ${sizeClass} ${className ?? ""}`, role: "img", "aria-label": alt, children: [_jsx(Div, { className: "appkit-image-mosaic__lead", children: _jsx(MediaImage, { src: lead, alt: "", size: "card" }) }), _jsx(Div, { className: "appkit-image-mosaic__rest", children: rest.map((src, i) => (_jsx(Div, { className: "appkit-image-mosaic__tile", children: _jsx(MediaImage, { src: src, alt: "", size: "thumbnail" }) }, `${src}-${i}`))) })] }));
46
47
  }
@@ -27,6 +27,28 @@
27
27
  }
28
28
  }
29
29
 
30
+ /*
31
+ * `size="hero"` — the homepage hero's right column.
32
+ *
33
+ * 🛑 A separate modifier rather than a caller `className` height, because the
34
+ * fixed-height rule above is this primitive's OWN decision (see the header) and
35
+ * a consumer utility would simply fight it — with `important: true` in both
36
+ * Tailwind configs, which of the two wins is decided by emission order, not by
37
+ * the author. The band height is tuned for a category title; a hero column
38
+ * standing beside a `size="7xl"` headline needs roughly double or the mosaic
39
+ * reads as a letterboxed strip next to the copy.
40
+ */
41
+ .appkit-image-mosaic--hero {
42
+ height: clamp(320px, 34vw, 460px);
43
+ border-radius: var(--appkit-radius-2xl);
44
+ }
45
+
46
+ @media (min-width: 768px) {
47
+ .appkit-image-mosaic--hero {
48
+ height: clamp(360px, 34vw, 480px);
49
+ }
50
+ }
51
+
30
52
  .appkit-image-mosaic__lead,
31
53
  .appkit-image-mosaic__tile {
32
54
  position: relative;
@@ -324,6 +324,12 @@
324
324
  .appkit-section--tone-page-header { background-image: var(--appkit-gradient-page-header); }
325
325
  .appkit-section--tone-hero { background-image: var(--appkit-gradient-section-mesh); }
326
326
  .appkit-section--tone-accent-banner { background-image: var(--appkit-gradient-accent-banner); }
327
+ /* The variant layer finally exposing --appkit-gradient-whatsapp-card, which
328
+ had existed in the token layer with that exact name and NO consumer. The
329
+ community card used `accent-banner` instead — the same primary→secondary
330
+ gradient as CTABannerSection two sections below it, which is a real part of
331
+ why the homepage read monotonous. */
332
+ .appkit-section--tone-whatsapp { background-image: var(--appkit-gradient-whatsapp-card); }
327
333
 
328
334
  /* Semantic — Ul/Ol marker presets */
329
335
  .appkit-list--marker-disc { list-style: disc; padding-left: 1.25rem; }
@@ -41,7 +41,7 @@ import type { SurfaceProps, RoundedKey, PaddingKey, BorderKey, SurfaceKey } from
41
41
  * `--appkit-gradient-*` CSS variable so admin custom themes restyle the
42
42
  * section without consumer changes.
43
43
  */
44
- export type SectionTone = "plain" | "page-header" | "hero" | "accent-banner";
44
+ export type SectionTone = "plain" | "page-header" | "hero" | "accent-banner" | "whatsapp";
45
45
  type SemanticColor = "default" | "primary" | "muted" | "faint" | "inverse" | "success" | "warning" | "error" | "info";
46
46
  type SectionLayout = "default" | "flex" | "flex-col" | "flex-sm-row" | "flex-sm-row-between";
47
47
  type SectionGap = "none" | "xs" | "sm" | "md" | "lg";
@@ -62,7 +62,8 @@ export interface SectionProps extends React.HTMLAttributes<HTMLElement>, Surface
62
62
  /**
63
63
  * Themed background tone. Defaults to `"plain"`. Use `"page-header"` for
64
64
  * subtle gradient page-headers, `"hero"` for radial mesh hero backgrounds,
65
- * `"accent-banner"` for primary→secondary brand banners.
65
+ * `"accent-banner"` for primary→secondary brand banners, `"whatsapp"` for
66
+ * the WhatsApp-brand green→teal community card.
66
67
  */
67
68
  tone?: SectionTone;
68
69
  /** Scoped color/gradient/image background — an alternative to `tone` for admin/CMS-configured section backgrounds. Renders behind `children`, absolutely positioned within the section. */
@@ -6,6 +6,7 @@ const SECTION_TONE_MAP = {
6
6
  "page-header": "appkit-section--tone-page-header",
7
7
  hero: "appkit-section--tone-hero",
8
8
  "accent-banner": "appkit-section--tone-accent-banner",
9
+ whatsapp: "appkit-section--tone-whatsapp",
9
10
  };
10
11
  const SEMANTIC_COLOR_MAP = {
11
12
  default: "",
@@ -44,6 +44,8 @@ declare const TYPOGRAPHY: {
44
44
  readonly inherit: "";
45
45
  readonly accent: "appkit-color--accent";
46
46
  readonly inverse: "appkit-color--inverse";
47
+ /** Second tier on a dark/branded surface. See Typography.style.css. */
48
+ readonly "inverse-muted": "appkit-color--inverse-muted";
47
49
  };
48
50
  };
49
51
  export type ColorVariant = keyof typeof TYPOGRAPHY.colorVariant;
@@ -46,6 +46,8 @@ const TYPOGRAPHY = {
46
46
  inherit: "",
47
47
  accent: "appkit-color--accent",
48
48
  inverse: "appkit-color--inverse",
49
+ /** Second tier on a dark/branded surface. See Typography.style.css. */
50
+ "inverse-muted": "appkit-color--inverse-muted",
49
51
  },
50
52
  };
51
53
  const DROP_SHADOW_MAP = {
@@ -165,6 +165,25 @@
165
165
  color: var(--appkit-color-text-on-primary, #ffffff);
166
166
  }
167
167
 
168
+ /* Secondary text on a surface that stays dark/branded in EVERY theme.
169
+ *
170
+ * WHY: eight live sites hand-rolled a second tier on a branded surface and
171
+ * none of them worked the same way. Three in WhatsAppCommunitySection were
172
+ * `className="/80"` / `"/90"` / `"/75"` — codemod residue from a sweep that
173
+ * stripped `text-white` off `text-white/80` and left the modifier. Tailwind
174
+ * cannot generate a class named `/80`, so all three were silent no-ops and
175
+ * the intended hierarchy rendered flat. Five more in HeroCarousel used raw
176
+ * `opacity-70`/`-80`/`-90`, which fades the whole element, not just its ink.
177
+ *
178
+ * Reads --appkit-color-text-on-primary rather than literal white, so a theme
179
+ * whose on-primary ink is not #fff still gets a correct second tier. Three
180
+ * different alphas for one idea is the drift that produced this; there is one
181
+ * tier here on purpose.
182
+ */
183
+ .appkit-color--inverse-muted {
184
+ color: color-mix(in srgb, var(--appkit-color-text-on-primary, #ffffff) 78%, transparent);
185
+ }
186
+
168
187
  .dark .appkit-color--primary {
169
188
  color: var(--appkit-color-text);
170
189
  }
@@ -40,6 +40,7 @@
40
40
  @import "./DescriptionField.style.css";
41
41
  @import "./FormGrid.style.css";
42
42
  @import "./HorizontalScroller.style.css";
43
+ @import "./CarouselNav.style.css";
43
44
  @import "./NavigationLoader.style.css";
44
45
  @import "./ImageLightbox.style.css";
45
46
  @import "./SideModal.style.css";
@@ -106,7 +106,7 @@ export { StarRating } from "./components/StarRating";
106
106
  export type { BreadcrumbProps, BreadcrumbItem } from "./components/Breadcrumb";
107
107
  export { Breadcrumb } from "./components/Breadcrumb";
108
108
  export { ImageMosaic, MOSAIC_MIN } from "./components/ImageMosaic";
109
- export type { ImageMosaicProps } from "./components/ImageMosaic";
109
+ export type { ImageMosaicProps, ImageMosaicSize } from "./components/ImageMosaic";
110
110
  export { SplitTile } from "./components/SplitTile";
111
111
  export type { SplitTileProps, SplitTilePane } from "./components/SplitTile";
112
112
  export type { ImageLightboxProps, LightboxImage, } from "./components/ImageLightbox";
@@ -133,6 +133,8 @@ export type { ItemRowProps } from "./components/ItemRow";
133
133
  export { ItemRow } from "./components/ItemRow";
134
134
  export type { HorizontalScrollerProps, PerViewConfig, } from "./components/HorizontalScroller";
135
135
  export { HorizontalScroller } from "./components/HorizontalScroller";
136
+ export { CarouselNav, CAROUSEL_RAIL_MAX } from "./components/CarouselNav";
137
+ export type { CarouselNavProps, CarouselNavTone } from "./components/CarouselNav";
136
138
  export type { FormGridProps, FormFieldProps } from "./components/FormGrid";
137
139
  export { FormGrid, FormField as FormGridField } from "./components/FormGrid";
138
140
  export type { SettingsSectionProps, ToggleRowProps } from "./components/SettingsSection";
package/dist/ui/index.js CHANGED
@@ -98,6 +98,10 @@ export { SummaryCard } from "./components/SummaryCard.js";
98
98
  export { CountdownDisplay } from "./components/CountdownDisplay.js";
99
99
  export { ItemRow } from "./components/ItemRow.js";
100
100
  export { HorizontalScroller } from "./components/HorizontalScroller.js";
101
+ /* The ONE carousel position/navigation control — replaces the hero's bespoke
102
+ pill dots, the rail arrows that vanished below 640px, and the testimonial
103
+ rail's complete absence of an indicator. */
104
+ export { CarouselNav, CAROUSEL_RAIL_MAX } from "./components/CarouselNav.js";
101
105
  export { FormGrid, FormField as FormGridField } from "./components/FormGrid.js";
102
106
  export { SettingsSection, ToggleRow } from "./components/SettingsSection.js";
103
107
  export { DetailPageHero } from "./components/DetailPageHero.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.53.1",
3
+ "version": "4.54.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -254,7 +254,8 @@
254
254
  "driver.js": "^1.8.0",
255
255
  "jsbarcode": "^3.12.3",
256
256
  "motion": "^13.1.1",
257
- "phonepe-pg-sdk-node": "^2.0.2",
257
+ "phonepe-pg-sdk-node": ">=2.0.2",
258
+ "razorpay": "^2.9.8",
258
259
  "react-advanced-cropper": "^0.20.1",
259
260
  "tailwind-merge": "^3.3.0",
260
261
  "zod": "^3.24.0",
@@ -387,6 +387,104 @@ const COLLECTION_MAP = {
387
387
  * A root with no mapping yields NO franchise (living collectibles are not an
388
388
  * IP) — see `FRANCHISE_BY_CATEGORY_ROOT`.
389
389
  */
390
+ /**
391
+ * The real, sellable catalogue — everything else in the product seed is demo
392
+ * furniture and is DROPPED HERE, before anything is written.
393
+ *
394
+ * ── 🛑 WHY A FILTER AND NOT A DELETION ────────────────────────────────────
395
+ *
396
+ * The fixtures stay in their files on purpose: they are the only coverage
397
+ * several features have (every `preOrderProductionStatus` value, a sold-out
398
+ * reservation, a depleted digital-code pool, an ended-unsold auction), and
399
+ * the tester checklist deep-links to them by id. Deleting them would silently
400
+ * remove that coverage. Not LOADING them is the part that was wanted.
401
+ *
402
+ * ── 🛑 WHY THIS HAD TO EXIST ──────────────────────────────────────────────
403
+ *
404
+ * `appkit-seed load` writes every registered row and `purge` deletes
405
+ * `seedPurpose: "test"` afterwards — so the demo listings came BACK on every
406
+ * reseed, and anyone who ran `load` to fix imagery silently republished 76
407
+ * fake products to the live storefront. That happened twice in one session.
408
+ * The owner's instruction was "delete them from the seed itself and make sure
409
+ * they do not return"; this is the point where that can be guaranteed, since
410
+ * every write path funnels through here.
411
+ *
412
+ * ── The discriminator is the STORE, not the listing type ──────────────────
413
+ *
414
+ * `store-beyblade-arena` is the fictional demo seller; `store-letitrip-
415
+ * official` is the real one. Keying on the store rather than on a per-file
416
+ * allow-list means a fixture added to ANY product seed file later is excluded
417
+ * automatically, which is the failure mode this is replacing — a list that
418
+ * has to be remembered is a list that drifts.
419
+ *
420
+ * Set `SEED_INCLUDE_DEMO=1` to load them anyway, for local demo work.
421
+ */
422
+ const REAL_STORE_IDS = new Set(["store-letitrip-official"]);
423
+
424
+ function realListingsOnly(products) {
425
+ if (process.env.SEED_INCLUDE_DEMO === "1") {
426
+ console.log("▌ SEED_INCLUDE_DEMO=1 — demo listings INCLUDED");
427
+ return products;
428
+ }
429
+ /*
430
+ * 🛑 TWO rules, because the store alone is not enough. Six prize-draw
431
+ * fixtures live under the REAL store and are still demo furniture — their
432
+ * imagery is a 460-byte generated colour tile from /images/seed-tiles/,
433
+ * which is the giveaway: a listing nobody photographed is a listing nobody
434
+ * intends to sell. Measured before writing this: every one of the six, and
435
+ * nothing real, matches.
436
+ */
437
+ const isPlaceholder = (p) => {
438
+ const urls = [p?.mainImage, ...(Array.isArray(p?.images) ? p.images : [])]
439
+ .map((v) => (typeof v === "string" ? v : v?.url))
440
+ .filter(Boolean);
441
+ return urls.length > 0 && urls.every((u) => String(u).includes("/images/seed-tiles/"));
442
+ };
443
+ const kept = products.filter((p) => REAL_STORE_IDS.has(p?.storeId) && !isPlaceholder(p));
444
+ const dropped = products.length - kept.length;
445
+ if (dropped > 0) {
446
+ console.log(` • ${dropped} demo listing(s) not loaded (set SEED_INCLUDE_DEMO=1 to include)`);
447
+ }
448
+ return kept;
449
+ }
450
+
451
+ /**
452
+ * Drop bundle categories whose members are not in the loaded catalogue.
453
+ *
454
+ * 🛑 A bundle is ALL-OR-NOTHING — `canAddToCart` buys every member together —
455
+ * so a bundle missing even one member is unsellable, and one missing ALL of
456
+ * them is a card that opens an empty page. Measured right after the demo
457
+ * listings stopped loading: of the five seeded bundles, three had zero
458
+ * surviving members and the other two had 1-of-4 and 2-of-3. All five were
459
+ * still `isActive: true`, and all five rendered on the HOMEPAGE as collage
460
+ * cards built from `display.mosaicImages` — which are baked at seed time from
461
+ * the members' own imagery, so they kept showing pictures of products that no
462
+ * longer exist. That is 92 placeholder-tile references on the homepage.
463
+ *
464
+ * Derived rather than hand-maintained for the same reason as the product
465
+ * filter: a bundle that becomes valid later starts loading again on its own,
466
+ * and one that breaks stops, with nobody having to remember either.
467
+ *
468
+ * Only `categoryType: "bundle"` rows are considered. Every other category is
469
+ * taxonomy and is never touched — rebuilding the tree is expensive and is
470
+ * explicitly not what this is for.
471
+ */
472
+ function loadableBundlesOnly(categories, loadedProducts) {
473
+ const live = new Set(loadedProducts.map((p) => p?.id).filter(Boolean));
474
+ let dropped = 0;
475
+ const kept = categories.filter((c) => {
476
+ if (c?.categoryType !== "bundle") return true;
477
+ const ids = Array.isArray(c.bundleProductIds) ? c.bundleProductIds : [];
478
+ const ok = ids.length > 0 && ids.every((id) => live.has(id));
479
+ if (!ok) dropped++;
480
+ return ok;
481
+ });
482
+ if (dropped > 0) {
483
+ console.log(` • ${dropped} bundle(s) not loaded — members missing from the catalogue`);
484
+ }
485
+ return kept;
486
+ }
487
+
390
488
  function withFranchise(products) {
391
489
  let stamped = 0;
392
490
  const out = products.map((p) => {
@@ -469,32 +567,13 @@ function withDerivedCategoryFields(products) {
469
567
  return out;
470
568
  }
471
569
 
472
- const SEED_DATA_MAP = {
473
- users: usersSeedData,
474
- /*
475
- * store-extensions. COLLECTION_MAP was only HALF the wiring: load() reads
476
- * SEED_DATA_MAP and short-circuits on an empty array, so adding the ten
477
- * collection names alone produced "no seed data, skipping" for all ten.
478
- * Same shape as the art/stickers note further down -- added everywhere
479
- * except the map that actually runs.
480
- */
481
- payoutMethods: payoutMethodsSeedData,
482
- shippingConfigs: shippingConfigsSeedData,
483
- analyticsCards: analyticsCardsSeedData,
484
- analyticsAlerts: analyticsAlertsSeedData,
485
- storeCategories: storeCategoriesSeedData,
486
- listingTemplates: listingTemplatesSeedData,
487
- moderationQueue: moderationQueueSeedData,
488
- reports: reportsSeedData,
489
- itemRequests: itemRequestsSeedData,
490
- storeGoogleConfig: storeGoogleConfigSeedData,
491
- addresses: addressesSeedData,
492
- storeAddresses: storeAddressesSeedData,
493
- // SB-UNI-C: brands were merged into categories (categoryType:"brand") — no
494
- // standalone brands collection/seed exists anymore.
495
- categories: categoriesSeedData,
496
- stores: storesSeedData,
497
- products: withFranchise(withDerivedCategoryFields([
570
+ /**
571
+ * The real catalogue, computed ONCE so the bundle filter and the product
572
+ * loader cannot disagree about what "loaded" means. Deriving it twice is
573
+ * Root Cause #75's shape — two copies of one rule, one of which learns about
574
+ * a change and the other does not.
575
+ */
576
+ const REAL_PRODUCTS = realListingsOnly([
498
577
  ...(productsStandardSeedData || []),
499
578
  // Real, wiki-verified Beyblade X listings under store-letitrip-official —
500
579
  // added 2026-10-19 for PhonePe merchant registration, which requires at
@@ -536,7 +615,34 @@ const SEED_DATA_MAP = {
536
615
  * what should happen to a leaf that now has BOTH a real listing and a
537
616
  * generated one.
538
617
  */
539
- ])),
618
+ ]);
619
+
620
+ const SEED_DATA_MAP = {
621
+ users: usersSeedData,
622
+ /*
623
+ * store-extensions. COLLECTION_MAP was only HALF the wiring: load() reads
624
+ * SEED_DATA_MAP and short-circuits on an empty array, so adding the ten
625
+ * collection names alone produced "no seed data, skipping" for all ten.
626
+ * Same shape as the art/stickers note further down -- added everywhere
627
+ * except the map that actually runs.
628
+ */
629
+ payoutMethods: payoutMethodsSeedData,
630
+ shippingConfigs: shippingConfigsSeedData,
631
+ analyticsCards: analyticsCardsSeedData,
632
+ analyticsAlerts: analyticsAlertsSeedData,
633
+ storeCategories: storeCategoriesSeedData,
634
+ listingTemplates: listingTemplatesSeedData,
635
+ moderationQueue: moderationQueueSeedData,
636
+ reports: reportsSeedData,
637
+ itemRequests: itemRequestsSeedData,
638
+ storeGoogleConfig: storeGoogleConfigSeedData,
639
+ addresses: addressesSeedData,
640
+ storeAddresses: storeAddressesSeedData,
641
+ // SB-UNI-C: brands were merged into categories (categoryType:"brand") — no
642
+ // standalone brands collection/seed exists anymore.
643
+ categories: loadableBundlesOnly(categoriesSeedData, REAL_PRODUCTS),
644
+ stores: storesSeedData,
645
+ products: withFranchise(withDerivedCategoryFields(REAL_PRODUCTS)),
540
646
  orders: ordersSeedData,
541
647
  reviews: reviewsSeedData,
542
648
  bids: bidsSeedData,
@@ -1,27 +0,0 @@
1
- /**
2
- * Core: async WhatsApp Business Catalog import (`whatsappCatalogImport` job).
3
- *
4
- * `POST /api/store/whatsapp-settings/catalog-import` used to do this inline:
5
- * one Meta fetch capped at `limit=250`, then a sequential per-item loop doing
6
- * up to 2 `findBySlug` reads plus 1 `create` write EACH — a real 10s-timeout
7
- * risk on Vercel Hobby (CLAUDE.md Rule #6) well before the cap was reached.
8
- * It also declared `paging.next` in its response type and never followed it,
9
- * so a catalog larger than 250 items silently imported only the first page.
10
- *
11
- * Running here instead buys the Function's 300s budget, which is what makes
12
- * following `paging.next` safe rather than making the timeout worse.
13
- *
14
- * Two efficiency changes vs. the old route:
15
- * - Existing-slug detection is ONE `findByStore` read into a Set, not 2 reads
16
- * per item. A seller's WA catalog is populated by pushing their own store's
17
- * products, so store-scoped lookup is equivalent to the old global
18
- * `findBySlug` here while costing a single query.
19
- * - That Set is updated as we create, so duplicate rows within one Meta
20
- * response can't produce two products.
21
- */
22
- import type { JobContext } from "../runtime/types";
23
- import type { JobRunResult } from "./jobRunners";
24
- export interface WhatsAppCatalogImportPayload {
25
- storeSlug: string;
26
- }
27
- export declare function runWhatsAppCatalogImport(payload: WhatsAppCatalogImportPayload, ctx: JobContext): Promise<JobRunResult>;