@mohasinac/appkit 4.53.0 → 4.53.2

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 (520) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/scaffolds/AppShell.js +1 -1
  3. package/dist/_internal/client/theme/ThemeProvider.js +15 -1
  4. package/dist/_internal/server/features/auctions/og.d.ts +3 -1
  5. package/dist/_internal/server/features/auctions/og.js +3 -1
  6. package/dist/_internal/server/features/bundles/actions.js +1 -1
  7. package/dist/_internal/server/features/business-documents/download.d.ts +41 -0
  8. package/dist/_internal/server/features/business-documents/download.js +91 -0
  9. package/dist/_internal/server/features/categories/adapters.d.ts +1 -1
  10. package/dist/_internal/server/features/categories/adapters.js +10 -0
  11. package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
  12. package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
  13. package/dist/_internal/server/features/checkout/actions.d.ts +14 -0
  14. package/dist/_internal/server/features/checkout/actions.js +106 -12
  15. package/dist/_internal/server/features/checkout/bundle-expansion.js +17 -0
  16. package/dist/_internal/server/features/checkout/data.d.ts +22 -0
  17. package/dist/_internal/server/features/checkout/group-rule-revalidation.d.ts +34 -0
  18. package/dist/_internal/server/features/checkout/group-rule-revalidation.js +124 -0
  19. package/dist/_internal/server/features/checkout/supplier-identity.d.ts +55 -0
  20. package/dist/_internal/server/features/checkout/supplier-identity.js +81 -0
  21. package/dist/_internal/server/features/classified/metadata.js +1 -1
  22. package/dist/_internal/server/features/classified/og.d.ts +3 -1
  23. package/dist/_internal/server/features/classified/og.js +3 -1
  24. package/dist/_internal/server/features/digital-code/metadata.js +1 -1
  25. package/dist/_internal/server/features/digital-code/og.d.ts +3 -1
  26. package/dist/_internal/server/features/digital-code/og.js +3 -1
  27. package/dist/_internal/server/features/digital-code/pool.d.ts +19 -4
  28. package/dist/_internal/server/features/digital-code/pool.js +19 -4
  29. package/dist/_internal/server/features/live/metadata.js +1 -1
  30. package/dist/_internal/server/features/live/og.d.ts +3 -1
  31. package/dist/_internal/server/features/live/og.js +3 -1
  32. package/dist/_internal/server/features/messages/actions.js +1 -1
  33. package/dist/_internal/server/features/parts/og.js +1 -1
  34. package/dist/_internal/server/features/pre-orders/og.d.ts +3 -1
  35. package/dist/_internal/server/features/pre-orders/og.js +3 -1
  36. package/dist/_internal/server/features/price-index/market.d.ts +57 -0
  37. package/dist/_internal/server/features/price-index/market.js +120 -0
  38. package/dist/_internal/server/features/price-index/search.d.ts +18 -0
  39. package/dist/_internal/server/features/price-index/search.js +47 -7
  40. package/dist/_internal/server/features/prize-draws/og.d.ts +3 -1
  41. package/dist/_internal/server/features/prize-draws/og.js +3 -1
  42. package/dist/_internal/server/features/products/group-members.d.ts +26 -0
  43. package/dist/_internal/server/features/products/group-members.js +7 -1
  44. package/dist/_internal/server/features/products/list-public.d.ts +12 -0
  45. package/dist/_internal/server/features/products/list-public.js +10 -1
  46. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
  47. package/dist/_internal/server/features/products/listing-tab-counts.js +128 -10
  48. package/dist/_internal/server/features/products/og.d.ts +3 -1
  49. package/dist/_internal/server/features/products/og.js +3 -1
  50. package/dist/_internal/server/features/search/scoped-sources.d.ts +26 -0
  51. package/dist/_internal/server/features/search/scoped-sources.js +252 -0
  52. package/dist/_internal/server/features/search/search-everything.d.ts +57 -0
  53. package/dist/_internal/server/features/search/search-everything.js +70 -20
  54. package/dist/_internal/server/features/seo/sitemap.js +6 -0
  55. package/dist/_internal/server/features/shared/listing-adapters.js +4 -2
  56. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +11 -0
  57. package/dist/_internal/server/features/sticker-trace/adapters.js +1 -0
  58. package/dist/_internal/server/features/sticker-trace/promote-to-listings.d.ts +26 -0
  59. package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +264 -0
  60. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +3 -1
  61. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +32 -0
  62. package/dist/_internal/server/features/sticker-trace/storage.d.ts +20 -1
  63. package/dist/_internal/server/features/sticker-trace/storage.js +20 -1
  64. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  65. package/dist/_internal/server/features/stores/adapters.js +16 -0
  66. package/dist/_internal/server/features/stores/index.d.ts +1 -0
  67. package/dist/_internal/server/features/stores/index.js +1 -0
  68. package/dist/_internal/server/features/stores/tabs.d.ts +30 -0
  69. package/dist/_internal/server/features/stores/tabs.js +124 -0
  70. package/dist/_internal/shared/checkout/rules/_defaults.js +0 -2
  71. package/dist/_internal/shared/checkout/rules/_limits.d.ts +14 -1
  72. package/dist/_internal/shared/checkout/rules/_limits.js +14 -1
  73. package/dist/_internal/shared/checkout/rules/_registry.js +2 -0
  74. package/dist/_internal/shared/checkout/rules/auction.rule.js +9 -1
  75. package/dist/_internal/shared/checkout/rules/bundle.rule.js +13 -0
  76. package/dist/_internal/shared/checkout/rules/index.d.ts +2 -0
  77. package/dist/_internal/shared/checkout/rules/index.js +9 -0
  78. package/dist/_internal/shared/checkout/rules/offer.rule.js +0 -1
  79. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +26 -0
  80. package/dist/_internal/shared/checkout/rules/payment-gate.js +133 -0
  81. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +29 -8
  82. package/dist/_internal/shared/checkout/rules/spares.rule.d.ts +16 -0
  83. package/dist/_internal/shared/checkout/rules/spares.rule.js +5 -0
  84. package/dist/_internal/shared/checkout/rules/types.d.ts +26 -2
  85. package/dist/_internal/shared/config/schema.d.ts +122 -0
  86. package/dist/_internal/shared/features/cart/schema.js +3 -2
  87. package/dist/_internal/shared/features/products/group-rules.d.ts +75 -0
  88. package/dist/_internal/shared/features/products/group-rules.js +142 -0
  89. package/dist/_internal/shared/listing-types/_registry.d.ts +24 -0
  90. package/dist/_internal/shared/listing-types/_registry.js +39 -1
  91. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  92. package/dist/_internal/shared/listing-types/art/config.js +2 -0
  93. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  94. package/dist/_internal/shared/listing-types/auction/config.js +2 -0
  95. package/dist/_internal/shared/listing-types/availability.js +48 -0
  96. package/dist/_internal/shared/listing-types/capabilities.js +19 -0
  97. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  98. package/dist/_internal/shared/listing-types/classified/config.js +2 -0
  99. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  100. package/dist/_internal/shared/listing-types/digital-code/config.js +2 -0
  101. package/dist/_internal/shared/listing-types/feature-flags.js +1 -0
  102. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  103. package/dist/_internal/shared/listing-types/live/config.js +2 -0
  104. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  105. package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
  106. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  107. package/dist/_internal/shared/listing-types/prize-draw/config.js +2 -0
  108. package/dist/_internal/shared/listing-types/spares/config.d.ts +74 -0
  109. package/dist/_internal/shared/listing-types/spares/config.js +60 -0
  110. package/dist/_internal/shared/listing-types/spares/ctas.d.ts +1 -0
  111. package/dist/_internal/shared/listing-types/spares/ctas.js +4 -0
  112. package/dist/_internal/shared/listing-types/spares/og.js +1 -0
  113. package/dist/_internal/shared/listing-types/spares/schema.d.ts +2 -0
  114. package/dist/_internal/shared/listing-types/spares/schema.js +3 -0
  115. package/dist/_internal/shared/listing-types/spares/seed-factory.d.ts +1 -0
  116. package/dist/_internal/shared/listing-types/spares/seed-factory.js +1 -0
  117. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  118. package/dist/_internal/shared/listing-types/standard/config.js +2 -0
  119. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  120. package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
  121. package/dist/_internal/shared/search/match.d.ts +11 -0
  122. package/dist/_internal/shared/search/match.js +30 -3
  123. package/dist/_internal/shared/search/to-groups.d.ts +52 -0
  124. package/dist/_internal/shared/search/to-groups.js +141 -0
  125. package/dist/client.d.ts +8 -2
  126. package/dist/client.js +4 -1
  127. package/dist/constants/api-endpoints.d.ts +46 -15
  128. package/dist/constants/api-endpoints.js +35 -5
  129. package/dist/constants/cache-invalidation.js +3 -1
  130. package/dist/constants/field-names.d.ts +6 -0
  131. package/dist/constants/field-names.js +6 -0
  132. package/dist/features/about/components/PolicyPageView.d.ts +22 -2
  133. package/dist/features/about/components/PolicyPageView.js +14 -2
  134. package/dist/features/about/components/PublicProfileView.js +2 -1
  135. package/dist/features/about/components/ShippingPolicyView.js +42 -2
  136. package/dist/features/account/components/NotificationBell.js +1 -1
  137. package/dist/features/account/hooks/useProfileStats.js +5 -1
  138. package/dist/features/addresses/repository/addresses.repository.d.ts +16 -0
  139. package/dist/features/addresses/repository/addresses.repository.js +21 -0
  140. package/dist/features/admin/actions/admin-actions.js +16 -1
  141. package/dist/features/admin/components/AdminCategoryEditorView.js +19 -2
  142. package/dist/features/admin/components/AdminNavigationView.js +1 -1
  143. package/dist/features/admin/components/AdminPageHeader.js +1 -1
  144. package/dist/features/admin/components/AdminProductEditorView.js +17 -2
  145. package/dist/features/admin/components/AdminSidebar.js +1 -1
  146. package/dist/features/admin/components/AdminSiteSettingsView.js +39 -8
  147. package/dist/features/admin/components/AdminSparesView.d.ts +12 -0
  148. package/dist/features/admin/components/AdminSparesView.js +30 -0
  149. package/dist/features/admin/components/AdminUsersView.js +9 -7
  150. package/dist/features/admin/components/index.d.ts +2 -0
  151. package/dist/features/admin/components/index.js +1 -0
  152. package/dist/features/admin/components/sections/adminSectionsTypes.js +7 -0
  153. package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
  154. package/dist/features/admin/constants/filter-tabs.js +1 -0
  155. package/dist/features/admin/schemas/firestore.d.ts +26 -2
  156. package/dist/features/auctions/components/AuctionDetailPageView.js +12 -18
  157. package/dist/features/auth/repository/user.repository.d.ts +13 -0
  158. package/dist/features/auth/repository/user.repository.js +28 -0
  159. package/dist/features/auth/schemas/firestore.d.ts +2 -0
  160. package/dist/features/auth/schemas/firestore.js +2 -0
  161. package/dist/features/business-documents/repository/business-documents.repository.d.ts +58 -0
  162. package/dist/features/business-documents/repository/business-documents.repository.js +54 -0
  163. package/dist/features/business-documents/schemas/firestore.d.ts +105 -0
  164. package/dist/features/business-documents/schemas/firestore.js +75 -0
  165. package/dist/features/cart/actions/cart-actions.js +83 -6
  166. package/dist/features/cart/repository/cart.repository.js +32 -4
  167. package/dist/features/cart/schemas/firestore.d.ts +20 -0
  168. package/dist/features/cart/schemas/index.d.ts +2 -2
  169. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +1 -1
  170. package/dist/features/categories/api/[id]/price-guidance/route.d.ts +42 -0
  171. package/dist/features/categories/api/[id]/price-guidance/route.js +90 -0
  172. package/dist/features/categories/components/BrandDetailPageView.js +32 -8
  173. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
  174. package/dist/features/categories/components/BrandDetailTabs.js +28 -3
  175. package/dist/features/categories/components/BundleCollage.js +3 -2
  176. package/dist/features/categories/components/BundleItemsPicker.js +3 -4
  177. package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
  178. package/dist/features/categories/components/CategoryDetailPageView.js +157 -20
  179. package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
  180. package/dist/features/categories/components/CategoryDetailTabs.js +41 -7
  181. package/dist/features/categories/components/CategoryGrid.js +10 -1
  182. package/dist/features/categories/components/PriceGuidanceHint.d.ts +29 -0
  183. package/dist/features/categories/components/PriceGuidanceHint.js +61 -0
  184. package/dist/features/categories/components/SubcategoryCardRow.d.ts +27 -0
  185. package/dist/features/categories/components/SubcategoryCardRow.js +98 -0
  186. package/dist/features/categories/constants/category-tabs.d.ts +20 -25
  187. package/dist/features/categories/constants/category-tabs.js +22 -39
  188. package/dist/features/categories/repository/categories.repository.d.ts +12 -0
  189. package/dist/features/categories/repository/categories.repository.js +20 -0
  190. package/dist/features/categories/schemas/firestore.d.ts +22 -1
  191. package/dist/features/categories/schemas/firestore.js +10 -0
  192. package/dist/features/categories/schemas/index.d.ts +6 -0
  193. package/dist/features/categories/schemas/index.js +2 -0
  194. package/dist/features/categories/types/index.d.ts +8 -0
  195. package/dist/features/categories/utils/taxonomy-visual.d.ts +16 -3
  196. package/dist/features/categories/utils/taxonomy-visual.js +26 -10
  197. package/dist/features/classified/components/ClassifiedDetailPageView.js +14 -10
  198. package/dist/features/contact/components/ContactPageView.d.ts +33 -1
  199. package/dist/features/contact/components/ContactPageView.js +58 -28
  200. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +14 -10
  201. package/dist/features/grouped/components/GroupedListingDetailView.js +9 -1
  202. package/dist/features/grouped/schemas/firestore.d.ts +5 -0
  203. package/dist/features/homepage/actions/homepage-section-actions.d.ts +3 -3
  204. package/dist/features/homepage/components/CollectionCardsSection.d.ts +28 -6
  205. package/dist/features/homepage/components/CollectionCardsSection.js +43 -8
  206. package/dist/features/homepage/components/HowItWorksSection.d.ts +23 -6
  207. package/dist/features/homepage/components/HowItWorksSection.js +4 -4
  208. package/dist/features/homepage/components/PromoGrid.d.ts +31 -2
  209. package/dist/features/homepage/components/PromoGrid.js +12 -3
  210. package/dist/features/homepage/components/TestimonialsCarousel.d.ts +34 -2
  211. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  212. package/dist/features/homepage/components/index.d.ts +0 -20
  213. package/dist/features/homepage/components/index.js +0 -11
  214. package/dist/features/homepage/index.d.ts +0 -2
  215. package/dist/features/homepage/index.js +0 -2
  216. package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
  217. package/dist/features/homepage/lib/section-renderer.js +202 -58
  218. package/dist/features/homepage/repository/homepage-sections.repository.d.ts +35 -3
  219. package/dist/features/homepage/repository/homepage-sections.repository.js +58 -8
  220. package/dist/features/homepage/schemas/firestore.d.ts +106 -3
  221. package/dist/features/homepage/schemas/firestore.js +32 -2
  222. package/dist/features/homepage/schemas/index.d.ts +36 -7
  223. package/dist/features/homepage/schemas/index.js +39 -27
  224. package/dist/features/homepage/server.d.ts +0 -3
  225. package/dist/features/homepage/server.js +0 -3
  226. package/dist/features/homepage/types/index.d.ts +0 -47
  227. package/dist/features/homepage/types/index.js +49 -0
  228. package/dist/features/layout/AppLayoutShell.js +1 -1
  229. package/dist/features/layout/BottomNavItem.js +1 -1
  230. package/dist/features/layout/BottomSheet.js +1 -1
  231. package/dist/features/layout/TitleBarLayout.js +1 -1
  232. package/dist/features/live/components/LiveItemDetailPageView.js +14 -10
  233. package/dist/features/media/hooks/useMedia.js +17 -0
  234. package/dist/features/media/repository/media-assets.repository.d.ts +46 -0
  235. package/dist/features/media/repository/media-assets.repository.js +31 -0
  236. package/dist/features/media/trust-signals.d.ts +85 -0
  237. package/dist/features/media/trust-signals.js +126 -0
  238. package/dist/features/parts/components/PartDetailPageView.d.ts +14 -1
  239. package/dist/features/parts/components/PartDetailPageView.js +2 -2
  240. package/dist/features/parts/components/PartsIndexPageView.d.ts +11 -2
  241. package/dist/features/parts/components/PartsIndexPageView.js +2 -2
  242. package/dist/features/parts/components/PartsSearchBox.d.ts +9 -0
  243. package/dist/features/parts/components/PartsSearchBox.js +57 -0
  244. package/dist/features/parts/schemas/firestore.d.ts +149 -3
  245. package/dist/features/parts/schemas/firestore.js +184 -0
  246. package/dist/features/payments/repository/payout.repository.d.ts +15 -0
  247. package/dist/features/payments/repository/payout.repository.js +21 -0
  248. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -18
  249. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
  250. package/dist/features/price-index/components/PriceIndexToolView.d.ts +24 -1
  251. package/dist/features/price-index/components/PriceIndexToolView.js +299 -17
  252. package/dist/features/price-index/lookup-target.d.ts +48 -0
  253. package/dist/features/price-index/lookup-target.js +107 -0
  254. package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
  255. package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
  256. package/dist/features/products/components/CompareOverlay.d.ts +20 -2
  257. package/dist/features/products/components/CompareOverlay.js +23 -3
  258. package/dist/features/products/components/CustomSectionTabContent.d.ts +31 -0
  259. package/dist/features/products/components/CustomSectionTabContent.js +29 -3
  260. package/dist/features/products/components/GroupMemberPicker.d.ts +19 -1
  261. package/dist/features/products/components/GroupMemberPicker.js +46 -8
  262. package/dist/features/products/components/GroupSettingsPanel.d.ts +11 -1
  263. package/dist/features/products/components/GroupSettingsPanel.js +92 -3
  264. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  265. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +15 -1
  266. package/dist/features/products/components/PrizeDrawEntryActions.js +70 -8
  267. package/dist/features/products/components/ProductDetailPageView.js +81 -17
  268. package/dist/features/products/components/ProductForm.d.ts +13 -1
  269. package/dist/features/products/components/ProductForm.js +16 -2
  270. package/dist/features/products/components/ProductsIndexListing.d.ts +16 -1
  271. package/dist/features/products/components/ProductsIndexListing.js +3 -3
  272. package/dist/features/products/components/ShowGroupSection.js +15 -2
  273. package/dist/features/products/components/SparesListView.d.ts +7 -0
  274. package/dist/features/products/components/SparesListView.js +39 -0
  275. package/dist/features/products/components/SublistingCarouselSection.js +2 -1
  276. package/dist/features/products/constants/action-defs.d.ts +1 -0
  277. package/dist/features/products/constants/action-defs.js +1 -0
  278. package/dist/features/products/repository/products.repository.d.ts +99 -0
  279. package/dist/features/products/repository/products.repository.js +240 -18
  280. package/dist/features/products/schemas/firestore.d.ts +97 -4
  281. package/dist/features/products/schemas/firestore.js +104 -0
  282. package/dist/features/products/schemas/index.d.ts +10 -19
  283. package/dist/features/products/schemas/index.js +23 -6
  284. package/dist/features/products/types/index.d.ts +45 -1
  285. package/dist/features/products/utils/group-member-image.d.ts +46 -0
  286. package/dist/features/products/utils/group-member-image.js +4 -0
  287. package/dist/features/products/utils/listing-badge-variant.js +4 -0
  288. package/dist/features/reviews/components/ReviewsList.js +1 -1
  289. package/dist/features/scams/components/ScamProfileView.js +1 -1
  290. package/dist/features/search/components/EntityTypeahead.d.ts +44 -0
  291. package/dist/features/search/components/EntityTypeahead.js +92 -0
  292. package/dist/features/search/components/Search.d.ts +12 -1
  293. package/dist/features/search/components/Search.js +47 -3
  294. package/dist/features/search/components/SearchFacetRail.d.ts +11 -0
  295. package/dist/features/search/components/SearchFacetRail.js +92 -0
  296. package/dist/features/search/components/SearchResultsClient.d.ts +33 -0
  297. package/dist/features/search/components/SearchResultsClient.js +103 -0
  298. package/dist/features/search/components/SearchResultsPageView.d.ts +15 -1
  299. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  300. package/dist/features/search/components/index.d.ts +0 -6
  301. package/dist/features/search/components/index.js +0 -3
  302. package/dist/features/search/hooks/useNavSuggestions.d.ts +13 -0
  303. package/dist/features/search/hooks/useScopedSearch.d.ts +34 -0
  304. package/dist/features/search/hooks/useScopedSearch.js +114 -0
  305. package/dist/features/search/hooks/useSiteSearch.d.ts +26 -0
  306. package/dist/features/search/hooks/useSiteSearch.js +149 -0
  307. package/dist/features/search/index.d.ts +0 -4
  308. package/dist/features/search/index.js +0 -4
  309. package/dist/features/search/manifest.d.ts +12 -0
  310. package/dist/features/search/manifest.js +17 -2
  311. package/dist/features/search/server.d.ts +0 -3
  312. package/dist/features/search/server.js +0 -3
  313. package/dist/features/seller/components/SellerListingTypeView.d.ts +1 -1
  314. package/dist/features/seller/components/SellerListingTypeView.js +20 -0
  315. package/dist/features/seller/components/SellerPayoutSettingsView.js +35 -14
  316. package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
  317. package/dist/features/seller/components/SellerProductShell.js +2 -1
  318. package/dist/features/seller/components/SellerProductsView.js +3 -2
  319. package/dist/features/seller/components/SellerSidebar.js +1 -1
  320. package/dist/features/seller/components/SellerSparesView.d.ts +17 -0
  321. package/dist/features/seller/components/SellerSparesView.js +6 -0
  322. package/dist/features/seller/components/index.d.ts +2 -0
  323. package/dist/features/seller/components/index.js +1 -0
  324. package/dist/features/shell/CommandPalette.js +1 -1
  325. package/dist/features/sticker-trace/schemas/firestore.d.ts +19 -0
  326. package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
  327. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  328. package/dist/features/stores/components/StoreDetailLayoutView.js +7 -82
  329. package/dist/features/stores/components/StoreHeader.js +1 -2
  330. package/dist/features/stores/components/StoreSparesPageView.d.ts +27 -0
  331. package/dist/features/stores/components/StoreSparesPageView.js +48 -0
  332. package/dist/features/stores/schemas/firestore.d.ts +19 -0
  333. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +2 -0
  334. package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +96 -0
  335. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  336. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +392 -45
  337. package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +54 -32
  338. package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +3 -2
  339. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +2 -0
  340. package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +73 -0
  341. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +2 -0
  342. package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +340 -0
  343. package/dist/features/tester/seed-data/authored/index.js +16 -0
  344. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +1 -0
  345. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +57 -0
  346. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +2 -0
  347. package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +77 -0
  348. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +2 -0
  349. package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +58 -0
  350. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +5 -4
  351. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +384 -18
  352. package/dist/index.d.ts +17 -57
  353. package/dist/index.js +35 -96
  354. package/dist/next/routing/route-map.d.ts +42 -1
  355. package/dist/next/routing/route-map.js +45 -0
  356. package/dist/providers/db-firebase/base.repository.d.ts +22 -0
  357. package/dist/providers/db-firebase/base.repository.js +36 -0
  358. package/dist/schemas/registry.d.ts +15 -6
  359. package/dist/security/blind-index-tokens.d.ts +54 -0
  360. package/dist/security/blind-index-tokens.js +152 -0
  361. package/dist/security/index.d.ts +1 -1
  362. package/dist/security/index.js +1 -1
  363. package/dist/security/settings-encryption.d.ts +35 -0
  364. package/dist/security/settings-encryption.js +91 -0
  365. package/dist/seed/_helpers/brand-rows.js +38 -14
  366. package/dist/seed/_helpers/category-forest.js +73 -7
  367. package/dist/seed/_helpers/category-images-generated.d.ts +25 -6
  368. package/dist/seed/_helpers/category-images-generated.js +81 -6
  369. package/dist/seed/_helpers/category-models.d.ts +1 -1
  370. package/dist/seed/_helpers/category-models.js +7 -1
  371. package/dist/seed/_helpers/category-parts-glossary-map.js +8 -0
  372. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  373. package/dist/seed/_helpers/category-parts.js +50 -2
  374. package/dist/seed/_helpers/character-features.d.ts +1 -1
  375. package/dist/seed/_helpers/character-features.js +2 -1
  376. package/dist/seed/_helpers/franchise-rows.js +10 -2
  377. package/dist/seed/_helpers/media.d.ts +47 -0
  378. package/dist/seed/_helpers/media.js +34 -0
  379. package/dist/seed/authenticity-knowledge-seed-data.d.ts +49 -5
  380. package/dist/seed/authenticity-knowledge-seed-data.js +10001 -549
  381. package/dist/seed/categories-seed-data.js +124 -20
  382. package/dist/seed/grouped-listings-seed-data.js +16 -0
  383. package/dist/seed/homepage-sections-seed-data.js +94 -5
  384. package/dist/seed/index.d.ts +2 -3
  385. package/dist/seed/index.js +2 -2
  386. package/dist/seed/manifest.js +3 -0
  387. package/dist/seed/media-assets-seed-data.d.ts +1 -1
  388. package/dist/seed/media-assets-seed-data.js +746 -196
  389. package/dist/seed/model-composition-seed-data.js +122 -6
  390. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  391. package/dist/seed/part-glossary-seed-data.js +37219 -463
  392. package/dist/seed/products-art-seed-data.js +7 -18
  393. package/dist/seed/products-auctions-seed-data.js +56 -47
  394. package/dist/seed/products-beyblade-x-seed-data.d.ts +2 -0
  395. package/dist/seed/products-beyblade-x-seed-data.js +476 -0
  396. package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
  397. package/dist/seed/products-catalogue-seed-data.js +1500 -1240
  398. package/dist/seed/products-classifieds-seed-data.js +9 -27
  399. package/dist/seed/products-digital-codes-seed-data.js +9 -18
  400. package/dist/seed/products-live-items-seed-data.js +5 -13
  401. package/dist/seed/products-preorders-seed-data.js +67 -33
  402. package/dist/seed/products-prize-draws-seed-data.js +8 -17
  403. package/dist/seed/products-spares-seed-data.d.ts +2 -0
  404. package/dist/seed/products-spares-seed-data.js +368 -0
  405. package/dist/seed/products-standard-seed-data.js +39 -126
  406. package/dist/seed/products-stickers-seed-data.js +59 -15
  407. package/dist/seed/site-settings-seed-data.js +8 -0
  408. package/dist/seo/json-ld.d.ts +25 -0
  409. package/dist/seo/json-ld.js +28 -0
  410. package/dist/server-entry.d.ts +3 -1
  411. package/dist/server-entry.js +2 -2
  412. package/dist/server.d.ts +11 -9
  413. package/dist/server.js +35 -25
  414. package/dist/styles.css +202 -1
  415. package/dist/tailwind-input.css +31 -17
  416. package/dist/tailwind-utilities.css +1 -1
  417. package/dist/ui/components/Accordion.js +1 -1
  418. package/dist/ui/components/Breadcrumb.js +1 -1
  419. package/dist/ui/components/DetailPageGallery.js +0 -2
  420. package/dist/ui/components/DetailPageHero.js +0 -1
  421. package/dist/ui/components/DetailPageTabs.js +1 -1
  422. package/dist/ui/components/Divider.js +3 -3
  423. package/dist/ui/components/GatedPrice.js +5 -1
  424. package/dist/ui/components/HorizontalScroller.js +1 -1
  425. package/dist/ui/components/ListingLayout.js +3 -3
  426. package/dist/ui/components/MediaTabs.style.css +81 -0
  427. package/dist/ui/components/Pagination.js +1 -1
  428. package/dist/ui/components/PendingValue.d.ts +45 -0
  429. package/dist/ui/components/PendingValue.js +7 -0
  430. package/dist/ui/components/Radio.style.css +119 -0
  431. package/dist/ui/components/RatingDisplay.js +2 -2
  432. package/dist/ui/components/SettingsSection.js +0 -2
  433. package/dist/ui/components/SiteLogo.js +3 -0
  434. package/dist/ui/components/SiteMark.js +3 -0
  435. package/dist/ui/components/SortDropdown.js +1 -1
  436. package/dist/ui/components/SpecTable.d.ts +58 -0
  437. package/dist/ui/components/SpecTable.js +8 -0
  438. package/dist/ui/components/StarRating.js +1 -3
  439. package/dist/ui/components/SummaryCard.js +1 -1
  440. package/dist/ui/components/index.style.css +1 -0
  441. package/dist/ui/icons/icon-registry.d.ts +1 -0
  442. package/dist/ui/icons/icon-registry.js +9 -1
  443. package/dist/ui/index.d.ts +4 -0
  444. package/dist/ui/index.js +2 -0
  445. package/dist/utils/search-txt-query.d.ts +12 -0
  446. package/dist/utils/search-txt-query.js +12 -0
  447. package/package.json +1 -1
  448. package/scripts/dedupe-peer-deps.mjs +18 -0
  449. package/scripts/seed-cli.mjs +250 -35
  450. package/scripts/verify-css-build.mjs +118 -37
  451. package/dist/_internal/server/features/search/actions.d.ts +0 -7
  452. package/dist/_internal/server/features/search/actions.js +0 -21
  453. package/dist/_internal/server/features/search/data.d.ts +0 -15
  454. package/dist/_internal/server/features/search/data.js +0 -18
  455. package/dist/_internal/server/features/search/index.d.ts +0 -3
  456. package/dist/_internal/server/features/search/index.js +0 -2
  457. package/dist/features/homepage/api/[id]/route.d.ts +0 -23
  458. package/dist/features/homepage/api/[id]/route.js +0 -103
  459. package/dist/features/homepage/api/route.d.ts +0 -14
  460. package/dist/features/homepage/api/route.js +0 -140
  461. package/dist/features/homepage/api/sections/[id]/route.d.ts +0 -26
  462. package/dist/features/homepage/api/sections/[id]/route.js +0 -95
  463. package/dist/features/homepage/api/sections/route.d.ts +0 -13
  464. package/dist/features/homepage/api/sections/route.js +0 -82
  465. package/dist/features/homepage/components/AdvertisementBanner.d.ts +0 -14
  466. package/dist/features/homepage/components/AdvertisementBanner.js +0 -35
  467. package/dist/features/homepage/components/BeforeAfterCard.d.ts +0 -9
  468. package/dist/features/homepage/components/BeforeAfterCard.js +0 -73
  469. package/dist/features/homepage/components/FeaturedResultsSection.d.ts +0 -17
  470. package/dist/features/homepage/components/FeaturedResultsSection.js +0 -17
  471. package/dist/features/homepage/components/HeroBanner.d.ts +0 -7
  472. package/dist/features/homepage/components/HeroBanner.js +0 -43
  473. package/dist/features/homepage/components/HeroSection.d.ts +0 -7
  474. package/dist/features/homepage/components/HeroSection.js +0 -6
  475. package/dist/features/homepage/components/HomepageSkeleton.d.ts +0 -2
  476. package/dist/features/homepage/components/HomepageSkeleton.js +0 -21
  477. package/dist/features/homepage/components/HomepageView.d.ts +0 -25
  478. package/dist/features/homepage/components/HomepageView.js +0 -5
  479. package/dist/features/homepage/components/NewsletterBanner.d.ts +0 -23
  480. package/dist/features/homepage/components/NewsletterBanner.js +0 -37
  481. package/dist/features/homepage/components/SiteFeaturesSection.d.ts +0 -14
  482. package/dist/features/homepage/components/SiteFeaturesSection.js +0 -11
  483. package/dist/features/homepage/components/TrustBadges.d.ts +0 -6
  484. package/dist/features/homepage/components/TrustBadges.js +0 -46
  485. package/dist/features/homepage/components/TrustIndicatorsSection.d.ts +0 -12
  486. package/dist/features/homepage/components/TrustIndicatorsSection.js +0 -11
  487. package/dist/features/homepage/hooks/useHomepage.d.ts +0 -11
  488. package/dist/features/homepage/hooks/useHomepage.js +0 -17
  489. package/dist/features/homepage/hooks/useHomepageSections.d.ts +0 -2
  490. package/dist/features/homepage/hooks/useHomepageSections.js +0 -10
  491. package/dist/features/homepage/repository/homepage.repository.d.ts +0 -11
  492. package/dist/features/homepage/repository/homepage.repository.js +0 -25
  493. package/dist/features/search/actions/index.d.ts +0 -1
  494. package/dist/features/search/actions/index.js +0 -1
  495. package/dist/features/search/actions/search-actions.d.ts +0 -18
  496. package/dist/features/search/actions/search-actions.js +0 -43
  497. package/dist/features/search/api/route.d.ts +0 -22
  498. package/dist/features/search/api/route.js +0 -128
  499. package/dist/features/search/columns/index.d.ts +0 -17
  500. package/dist/features/search/columns/index.js +0 -49
  501. package/dist/features/search/components/SearchFiltersRow.d.ts +0 -22
  502. package/dist/features/search/components/SearchFiltersRow.js +0 -21
  503. package/dist/features/search/components/SearchResultsSection.d.ts +0 -53
  504. package/dist/features/search/components/SearchResultsSection.js +0 -35
  505. package/dist/features/search/components/SearchView.d.ts +0 -27
  506. package/dist/features/search/components/SearchView.js +0 -8
  507. package/dist/features/search/hooks/useSearch.d.ts +0 -21
  508. package/dist/features/search/hooks/useSearch.js +0 -33
  509. package/dist/features/search/repository/search.repository.d.ts +0 -14
  510. package/dist/features/search/repository/search.repository.js +0 -59
  511. package/dist/features/search/schemas/index.d.ts +0 -70
  512. package/dist/features/search/schemas/index.js +0 -36
  513. package/dist/features/search/types/index.d.ts +0 -48
  514. package/dist/features/stores/components/StoreScopedSearch.d.ts +0 -17
  515. package/dist/features/stores/components/StoreScopedSearch.js +0 -27
  516. package/dist/seed/defaults/homepage-sections.d.ts +0 -2
  517. package/dist/seed/defaults/homepage-sections.js +0 -60
  518. package/dist/seed/factories/homepage-section.factory.d.ts +0 -10
  519. package/dist/seed/factories/homepage-section.factory.js +0 -13
  520. /package/dist/{features/search/types/index.js → _internal/shared/listing-types/spares/og.d.ts} +0 -0
@@ -1,6 +1,38 @@
1
- import type { Testimonial } from "../types";
1
+ /**
2
+ * Promoted to a registered `SectionType` ("testimonials") 2026-10-19 — see
3
+ * `TestimonialsSectionConfig` in `schemas/firestore.ts`, which this prop shape
4
+ * mirrors (Firestore config must be a plain serialisable object).
5
+ *
6
+ * Three things fixed in the same pass, all required before this could render
7
+ * correctly on a real page rather than just compile:
8
+ *
9
+ * 1. **Testimonials are now INLINE in config**, not a read from the
10
+ * `testimonials` collection shape (`Testimonial` in `types/index.ts`, with
11
+ * `featured`/`sortOrder`/`active`). Those three fields are collection-row
12
+ * housekeeping with no meaning inside an ordered config array — the config
13
+ * IS the order, and every entry in it is already "featured" by virtue of
14
+ * being configured. `avatarUrl` is dropped too: declared on the old type,
15
+ * never rendered by this component.
16
+ * 2. **It is not a carousel** — no autoplay, no arrows, no dots, just a
17
+ * horizontally-scrolling wrapped row. So the config carries no
18
+ * `autoScroll`/`scrollInterval`/`loop` fields; adding them would be
19
+ * `NO-RENDERER` dead weight from day one.
20
+ * 3. **Every colour/font var below was undefined anywhere in the codebase**
21
+ * (`--section-bg`, `--card-bg`, `--card-border`, `--section-border`,
22
+ * `--section-title-color`, `--text-secondary`, `--color-red`,
23
+ * `--font-bangers`) — this component would have rendered with a
24
+ * transparent background, no borders and the browser's default font had
25
+ * it ever shipped. Migrated to the real `--appkit-*` token set (Root Cause
26
+ * #21); `--color-yellow` was the one survivor (a real token, `tokens.css`).
27
+ */
28
+ export interface TestimonialConfigItem {
29
+ id: string;
30
+ name: string;
31
+ rating: 1 | 2 | 3 | 4 | 5;
32
+ text: string;
33
+ }
2
34
  export interface TestimonialsCarouselProps {
3
- testimonials: Testimonial[];
35
+ testimonials: TestimonialConfigItem[];
4
36
  /** Eyebrow label. Default: "COLLECTOR REVIEWS". */
5
37
  eyebrow?: string;
6
38
  /** Section heading. Default: "WHAT OUR COLLECTORS SAY". */
@@ -3,5 +3,5 @@ import { Div, Heading, Stack, StarRating, Text } from "../../../ui/index.js";
3
3
  export function TestimonialsCarousel({ testimonials, eyebrow = "COLLECTOR REVIEWS", heading = "WHAT OUR COLLECTORS SAY", }) {
4
4
  if (testimonials.length === 0)
5
5
  return null;
6
- return (_jsx(Stack, { as: "section", justify: "center", className: "bg-[var(--section-bg)] [border-top:var(--section-border)] [border-bottom:var(--section-border)] min-h-[calc(100svh-var(--header-height,4rem))] [padding-block:clamp(3rem,6vh,5rem)]", children: _jsxs(Stack, { className: "mx-auto w-full max-w-7xl sm:px-[2rem] min-h-0", padding: "x-lg", children: [_jsxs(Div, { className: "mb-6 text-left shrink-0", children: [_jsx(Text, { className: "mb-1 font-black uppercase tracking-widest text-[var(--color-red)] tracking-[0.18em]", size: "xs", children: eyebrow }), _jsx(Heading, { level: 2, className: "[font-family:var(--font-bangers,Bangers,cursive)] text-[clamp(1.8rem,4vw,2.8rem)] tracking-[0.08em] text-[var(--section-title-color)] leading-none", children: heading })] }), _jsx(Stack, { wrap: true, className: "overflow-x-auto scrollbar-none max-h-[50svh] content-start", gap: "md", children: testimonials.map((t) => (_jsxs(Stack, { padding: "5", className: "shrink-0 w-[clamp(260px,28vw,360px)] bg-[var(--card-bg)] [border:var(--card-border)]", shadow: "card", gap: "3", children: [_jsx(StarRating, { value: t.rating, readOnly: true, size: "sm" }), _jsxs(Text, { className: "flex-1 leading-relaxed text-[var(--text-secondary)]", size: "sm", children: ["\u201C", t.text, "\u201D"] }), _jsxs(Text, { className: "font-black uppercase text-[var(--color-yellow)] tracking-[0.06em]", size: "xs", children: ["\u2014 ", t.name] })] }, t.id))) })] }) }));
6
+ return (_jsx(Stack, { as: "section", justify: "center", surface: "muted", border: "subtle", className: "min-h-[calc(100svh-var(--header-height,4rem))] [padding-block:clamp(3rem,6vh,5rem)]", children: _jsxs(Stack, { className: "mx-auto w-full max-w-7xl sm:px-[2rem] min-h-0", padding: "x-lg", children: [_jsxs(Div, { className: "mb-6 text-left shrink-0", children: [_jsx(Text, { className: "mb-1 font-black uppercase tracking-widest text-error tracking-[0.18em]", size: "xs", children: eyebrow }), _jsx(Heading, { level: 2, family: "display", className: "tracking-[0.08em] leading-none", size: "2xl", mdSize: "3xl", weight: "bold", color: "primary", children: heading })] }), _jsx(Stack, { wrap: true, className: "overflow-x-auto scrollbar-none max-h-[50svh] content-start", gap: "md", children: testimonials.map((t) => (_jsxs(Stack, { padding: "5", surface: "card", border: "subtle", className: "shrink-0 w-[clamp(260px,28vw,360px)]", shadow: "card", gap: "3", children: [_jsx(StarRating, { value: t.rating, readOnly: true, size: "sm" }), _jsxs(Text, { className: "flex-1 leading-relaxed", size: "sm", color: "muted", children: ["\u201C", t.text, "\u201D"] }), _jsxs(Text, { className: "font-black uppercase text-[var(--color-yellow)] tracking-[0.06em]", size: "xs", children: ["\u2014 ", t.name] })] }, t.id))) })] }) }));
7
7
  }
@@ -1,24 +1,13 @@
1
- export { HeroSection } from "./HeroSection";
2
1
  export type { CharacterHotspotProps } from "./CharacterHotspot";
3
2
  export { CharacterHotspot } from "./CharacterHotspot";
4
3
  export type { CharacterHotspotFormProps } from "./CharacterHotspotForm";
5
4
  export { CharacterHotspotForm } from "./CharacterHotspotForm";
6
- export type { HeroBannerProps } from "./HeroBanner";
7
- export { HeroBanner } from "./HeroBanner";
8
5
  export type { HeroCarouselProps } from "./HeroCarousel";
9
6
  export { HeroCarousel } from "./HeroCarousel";
10
7
  export type { PromoGridProps } from "./PromoGrid";
11
8
  export { PromoGrid } from "./PromoGrid";
12
- export type { TrustBadgesProps } from "./TrustBadges";
13
- export { TrustBadges } from "./TrustBadges";
14
9
  export type { TestimonialsCarouselProps } from "./TestimonialsCarousel";
15
10
  export { TestimonialsCarousel } from "./TestimonialsCarousel";
16
- export type { BeforeAfterCardProps } from "./BeforeAfterCard";
17
- export { BeforeAfterCard } from "./BeforeAfterCard";
18
- export type { NewsletterBannerProps } from "./NewsletterBanner";
19
- export { NewsletterBanner } from "./NewsletterBanner";
20
- export { HomepageView } from "./HomepageView";
21
- export type { HomepageViewProps } from "./HomepageView";
22
11
  export { MarketplaceHomepageView } from "./MarketplaceHomepageView";
23
12
  export type { MarketplaceHomepageViewProps, MarketplaceHomepageViewAdSlots, } from "./MarketplaceHomepageView";
24
13
  export type { SectionCarouselProps } from "./SectionCarousel";
@@ -37,19 +26,10 @@ export type { FAQItem, FAQTab, FAQSectionProps } from "./FAQSection";
37
26
  export { FAQSection } from "./FAQSection";
38
27
  export type { NewsletterSectionProps } from "./NewsletterSection";
39
28
  export { NewsletterSection } from "./NewsletterSection";
40
- export type { AdvertisementBannerProps } from "./AdvertisementBanner";
41
- export { AdvertisementBanner } from "./AdvertisementBanner";
42
29
  export type { SecurityHighlightItem, SecurityHighlightsSectionProps, } from "./SecurityHighlightsSection";
43
30
  export { SecurityHighlightsSection } from "./SecurityHighlightsSection";
44
- export type { SiteFeatureItem, SiteFeaturesSectionProps, } from "./SiteFeaturesSection";
45
- export { SiteFeaturesSection } from "./SiteFeaturesSection";
46
- export type { TrustIndicatorItem, TrustIndicatorsSectionProps, } from "./TrustIndicatorsSection";
47
- export { TrustIndicatorsSection } from "./TrustIndicatorsSection";
48
31
  export type { WhatsAppCommunitySectionProps } from "./WhatsAppCommunitySection";
49
32
  export { WhatsAppCommunitySection } from "./WhatsAppCommunitySection";
50
- export { HomepageSkeleton } from "./HomepageSkeleton";
51
- export type { FeaturedResultItem, FeaturedResultsSectionProps, } from "./FeaturedResultsSection";
52
- export { FeaturedResultsSection } from "./FeaturedResultsSection";
53
33
  export type { AnnouncementBarProps } from "./AnnouncementBar";
54
34
  export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar";
55
35
  export type { ShopByCategorySectionProps } from "./ShopByCategorySection";
@@ -1,14 +1,8 @@
1
- export { HeroSection } from "./HeroSection.js";
2
1
  export { CharacterHotspot } from "./CharacterHotspot.js";
3
2
  export { CharacterHotspotForm } from "./CharacterHotspotForm.js";
4
- export { HeroBanner } from "./HeroBanner.js";
5
3
  export { HeroCarousel } from "./HeroCarousel.js";
6
4
  export { PromoGrid } from "./PromoGrid.js";
7
- export { TrustBadges } from "./TrustBadges.js";
8
5
  export { TestimonialsCarousel } from "./TestimonialsCarousel.js";
9
- export { BeforeAfterCard } from "./BeforeAfterCard.js";
10
- export { NewsletterBanner } from "./NewsletterBanner.js";
11
- export { HomepageView } from "./HomepageView.js";
12
6
  export { MarketplaceHomepageView } from "./MarketplaceHomepageView.js";
13
7
  export { SectionCarousel } from "./SectionCarousel.js";
14
8
  export { WelcomeSection } from "./WelcomeSection.js";
@@ -18,13 +12,8 @@ export { HowItWorksSection } from "./HowItWorksSection.js";
18
12
  export { CustomerReviewsSection } from "./CustomerReviewsSection.js";
19
13
  export { FAQSection } from "./FAQSection.js";
20
14
  export { NewsletterSection } from "./NewsletterSection.js";
21
- export { AdvertisementBanner } from "./AdvertisementBanner.js";
22
15
  export { SecurityHighlightsSection } from "./SecurityHighlightsSection.js";
23
- export { SiteFeaturesSection } from "./SiteFeaturesSection.js";
24
- export { TrustIndicatorsSection } from "./TrustIndicatorsSection.js";
25
16
  export { WhatsAppCommunitySection } from "./WhatsAppCommunitySection.js";
26
- export { HomepageSkeleton } from "./HomepageSkeleton.js";
27
- export { FeaturedResultsSection } from "./FeaturedResultsSection.js";
28
17
  export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar.js";
29
18
  export { ShopByCategorySection } from "./ShopByCategorySection.js";
30
19
  export { FeaturedProductsSection } from "./FeaturedProductsSection.js";
@@ -1,6 +1,4 @@
1
1
  export * from "./types";
2
- export * from "./hooks/useHomepage";
3
- export * from "./hooks/useHomepageSections";
4
2
  export * from "./hooks/useHeroCarousel";
5
3
  export * from "./hooks/useFeaturedProducts";
6
4
  export * from "./hooks/useFeaturedAuctions";
@@ -1,6 +1,4 @@
1
1
  export * from "./types/index.js";
2
- export * from "./hooks/useHomepage.js";
3
- export * from "./hooks/useHomepageSections.js";
4
2
  export * from "./hooks/useHeroCarousel.js";
5
3
  export * from "./hooks/useFeaturedProducts.js";
6
4
  export * from "./hooks/useFeaturedAuctions.js";
@@ -47,5 +47,14 @@ export interface HomepageBrand {
47
47
  /** Short mark shown in the hero panel, e.g. "LT". */
48
48
  shortName?: string;
49
49
  }
50
+ /**
51
+ * Every surface a `SectionDef` may be mounted on.
52
+ *
53
+ * `"homepage"` is the only one any renderer currently receives data for — see
54
+ * the note on `SectionDef.surfaces` below. The others are declared now so a
55
+ * reuse decision has somewhere reviewable to live, ahead of the data-loading
56
+ * work that would make them real.
57
+ */
58
+ export type SectionSurface = "homepage" | "category" | "brand" | "product" | "store";
50
59
  export declare function renderSection(section: HomepageSectionDocument, adSlots: MarketplaceHomepageViewAdSlots | undefined, newsletterFormSlot: React.ReactNode, faqItems: FaqItem[], slides: CarouselSlide[], liveStats: LiveStatsMap, sectionData?: SectionData, brand?: HomepageBrand): React.ReactNode;
51
60
  export { AnnouncementBar, hashBannerMessage };
@@ -35,31 +35,55 @@ import { HomepageSectionBoundary } from "../components/HomepageSectionBoundary.j
35
35
  import { PrizeDrawsSection } from "../../products/components/PrizeDrawsSection.js";
36
36
  import { EventRafflesSection } from "../../events/components/EventRafflesSection.js";
37
37
  import { CollectionCardsSection } from "../components/CollectionCardsSection.js";
38
+ import { HowItWorksSection } from "../components/HowItWorksSection.js";
39
+ import { TestimonialsCarousel } from "../components/TestimonialsCarousel.js";
40
+ import { PromoGrid } from "../components/PromoGrid.js";
38
41
  const AD_SLOT_MAP = {
39
42
  carousel: "afterHero",
40
43
  products: "afterFeaturedProducts",
41
44
  reviews: "afterReviews",
42
45
  faq: "afterFAQ",
43
46
  };
44
- function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liveStats, sectionData, brand) {
45
- const { type, config } = section;
46
- switch (type) {
47
- case "carousel": {
47
+ /**
48
+ * One entry per `SectionType`, replacing the 25-arm `switch` this registry is
49
+ * carved from verbatim — every case body below is byte-identical to its
50
+ * switch arm, only re-homed into an object property.
51
+ *
52
+ * `Record<SectionType, SectionDef>` is EXHAUSTIVE: a `SectionType` added to
53
+ * the union without an entry here is a compile error, where the switch's
54
+ * `default: return null` let a listed-but-unhandled type render nothing with
55
+ * no signal anywhere. `audit-homepage-config-coverage` still passes with zero
56
+ * changes — it does a bare name-presence `test()` against this file as a flat
57
+ * string, and every config field name below is exactly where it always was.
58
+ */
59
+ const SECTION_REGISTRY = {
60
+ carousel: {
61
+ surfaces: ["homepage"],
62
+ render: ({ config, slides }) => {
48
63
  const cfg = config;
49
64
  return (_jsx(HeroCarousel, { initialSlides: slides, title: cfg?.title, height: cfg?.height, defaultAutoplayDelayMs: cfg?.defaultAutoplayDelayMs, pauseOnHover: cfg?.pauseOnHover, showDots: cfg?.showDots, showArrows: cfg?.showArrows }));
50
- }
51
- case "welcome": {
65
+ },
66
+ },
67
+ welcome: {
68
+ surfaces: ["homepage"],
69
+ render: ({ config, brand }) => {
52
70
  const cfg = config;
53
71
  return (_jsx(WelcomeSection, { title: cleanTitle(cfg?.h1) || SECTION_TITLE.welcome,
54
72
  // A real `subtitle` wins; `description` is the legacy source and is
55
73
  // still parsed for documents that only carry it.
56
74
  subtitle: cfg?.subtitle?.trim() || parseWelcomeDescription(cfg?.description), pillLabel: cfg?.pillLabel || SECTION_COPY.welcomePill, showCTA: cfg?.showCTA ?? true, ctaLabel: cfg?.ctaText || SECTION_COPY.welcomePrimaryCta, ctaHref: cfg?.ctaLink || ROUTES.PUBLIC.PRODUCTS, secondaryCtaLabel: cfg?.secondaryCtaText || SECTION_COPY.welcomeSecondaryCta, secondaryCtaHref: cfg?.secondaryCtaLink || ROUTES.PUBLIC.PRODUCTS, trustChips: [...WELCOME_TRUST_CHIPS], brandLogoText: brand?.shortName }));
57
- }
58
- case "categories": {
75
+ },
76
+ },
77
+ categories: {
78
+ surfaces: ["homepage", "category", "brand"],
79
+ render: ({ config, sectionData }) => {
59
80
  const cfg = config;
60
81
  return (_jsx(ShopByCategorySection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.categories, viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.categories, initialItems: sectionData.categories, limit: cfg?.maxCategories, cta: cfg?.cta, filters: cfg?.filters, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
61
- }
62
- case "stats": {
82
+ },
83
+ },
84
+ stats: {
85
+ surfaces: ["homepage"],
86
+ render: ({ config, liveStats }) => {
63
87
  const cfg = config;
64
88
  const stats = Array.isArray(cfg?.stats)
65
89
  ? cfg.stats
@@ -85,44 +109,68 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
85
109
  if (stats.length === 0)
86
110
  return null;
87
111
  return _jsx(StatsCounterSection, { stats: stats, title: cleanTitle(cfg?.title) });
88
- }
89
- case "products": {
112
+ },
113
+ },
114
+ products: {
115
+ surfaces: ["homepage", "category", "brand", "product"],
116
+ render: ({ config, sectionData }) => {
90
117
  const cfg = config;
91
118
  return (_jsx(FeaturedProductsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.products, description: cfg?.subtitle, viewMoreHref: ROUTES.PUBLIC.PRODUCTS, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.products, filterByBrand: cfg?.filterByBrand, initialItems: sectionData.products, rows: cfg?.rows,
92
119
  // `maxProducts` is what the admin builder's "Max items" input writes;
93
120
  // `maxItems` is the schema's own name. The two never met, so the
94
121
  // control had no effect. Read both, newest name first.
95
122
  maxItems: cfg?.maxItems ?? cfg?.maxProducts, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
96
- }
97
- case "auctions": {
123
+ },
124
+ },
125
+ auctions: {
126
+ surfaces: ["homepage", "category", "brand"],
127
+ render: ({ config, sectionData }) => {
98
128
  const cfg = config;
99
129
  return (_jsx(FeaturedAuctionsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.auctions, description: cfg?.subtitle, viewMoreHref: ROUTES.PUBLIC.AUCTIONS, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.auctions, filterByBrand: cfg?.filterByBrand, initialItems: sectionData.auctions, rows: cfg?.rows, maxItems: cfg?.maxAuctions, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
100
- }
101
- case "pre-orders": {
130
+ },
131
+ },
132
+ "pre-orders": {
133
+ surfaces: ["homepage", "category", "brand"],
134
+ render: ({ config, sectionData }) => {
102
135
  const cfg = config;
103
136
  return (_jsx(FeaturedPreOrdersSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.preOrders, description: cfg?.subtitle, viewMoreHref: ROUTES.PUBLIC.PRE_ORDERS, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.preOrders, filterByBrand: cfg?.filterByBrand, initialItems: sectionData.preOrders, rows: cfg?.rows, maxItems: cfg?.maxItems, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
104
- }
105
- case "stores": {
137
+ },
138
+ },
139
+ stores: {
140
+ surfaces: ["homepage", "category", "brand"],
141
+ render: ({ config, sectionData }) => {
106
142
  const cfg = config;
107
143
  return (_jsx(FeaturedStoresSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.stores, description: cfg?.subtitle, viewMoreHref: ROUTES.PUBLIC.STORES, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.stores, initialItems: sectionData.stores, limit: cfg?.maxStores, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
108
- }
109
- case "events": {
144
+ },
145
+ },
146
+ events: {
147
+ surfaces: ["homepage"],
148
+ render: ({ config, sectionData }) => {
110
149
  const cfg = config;
111
150
  return (_jsx(EventsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.events, description: cfg?.subtitle, viewMoreHref: ROUTES.PUBLIC.EVENTS, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.events, initialItems: sectionData.events, limit: cfg?.maxEvents, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
112
- }
113
- case "reviews": {
151
+ },
152
+ },
153
+ reviews: {
154
+ surfaces: ["homepage", "category", "brand", "product"],
155
+ render: ({ config }) => {
114
156
  const cfg = config;
115
157
  return (_jsx(HomepageCustomerReviewsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.reviews, viewMoreHref: ROUTES.PUBLIC.REVIEWS, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.reviews, maxReviews: cfg?.maxReviews, itemsPerView: cfg?.itemsPerView, mobileItemsPerView: cfg?.mobileItemsPerView, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
116
- }
117
- case "banner": {
158
+ },
159
+ },
160
+ banner: {
161
+ surfaces: ["homepage", "category", "brand", "product"],
162
+ render: ({ config }) => {
118
163
  const cfg = config;
119
164
  // CTAs come from the configured buttons; the component's own neutral
120
165
  // defaults fill in when none are set. Previously both labels and both
121
166
  // hrefs were hardcoded here and `buttons[]` was ignored entirely.
122
167
  const [primaryBtn, secondaryBtn] = cfg?.buttons ?? [];
123
168
  return (_jsx(CTABannerSection, { title: cfg?.content?.title || SECTION_TITLE.banner, subtitle: cfg?.content?.subtitle, description: cfg?.content?.description, height: cfg?.height, backgroundImage: cfg?.backgroundImage, primaryLabel: primaryBtn?.text, primaryHref: primaryBtn?.link, secondaryLabel: secondaryBtn?.text, secondaryHref: secondaryBtn?.link }));
124
- }
125
- case "trust-indicators": {
169
+ },
170
+ },
171
+ "trust-indicators": {
172
+ surfaces: ["homepage", "category", "brand"],
173
+ render: ({ config, brand }) => {
126
174
  const cfg = config;
127
175
  const configured = (cfg?.indicators ?? [])
128
176
  .filter((ind) => ind?.title?.trim())
@@ -134,8 +182,11 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
134
182
  }));
135
183
  return (_jsx(TrustFeaturesSection, { title: cleanTitle(cfg?.title) ||
136
184
  (brand?.name ? `Why Buyers Trust ${brand.name}` : SECTION_TITLE.trustIndicators), items: configured.length > 0 ? configured : DEFAULT_TRUST_FEATURES }));
137
- }
138
- case "features": {
185
+ },
186
+ },
187
+ features: {
188
+ surfaces: ["homepage"],
189
+ render: ({ config }) => {
139
190
  const cfg = config;
140
191
  // `items` is the real shape; `features: string[]` is the legacy one and
141
192
  // becomes title-only cards. Neither reached the component before — it
@@ -146,15 +197,21 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
146
197
  .map((label, index) => ({ key: `feature-${index}`, title: label, description: "" })) ??
147
198
  [];
148
199
  return (_jsx(SecurityHighlightsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.features, pillLabel: cfg?.pillLabel || SECTION_COPY.featuresPill, items: configured.length > 0 ? configured : DEFAULT_SECURITY_ITEMS, learnMoreHref: cfg?.learnMoreLink || ROUTES.PUBLIC.SECURITY, learnMoreLabel: cfg?.learnMoreLabel || SECTION_COPY.featuresLearnMore }));
149
- }
150
- case "whatsapp-community": {
200
+ },
201
+ },
202
+ "whatsapp-community": {
203
+ surfaces: ["homepage"],
204
+ render: ({ config }) => {
151
205
  const cfg = config;
152
206
  return (_jsx(WhatsAppCommunitySection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.whatsappCommunity, descriptionHtml: cfg?.description || SECTION_COPY.whatsappDescription,
153
207
  // No `|| 5000` fallback: inventing a member count the site cannot
154
208
  // verify is a fabricated social-proof number.
155
209
  memberCount: cfg?.memberCount, groupLink: cfg?.groupLink || "https://chat.whatsapp.com/", benefits: cfg?.benefits ?? [], testimonial: cfg?.testimonial, buttonText: cfg?.buttonText }));
156
- }
157
- case "faq": {
210
+ },
211
+ },
212
+ faq: {
213
+ surfaces: ["homepage", "category", "brand", "product"],
214
+ render: ({ config, faqItems }) => {
158
215
  const cfg = config;
159
216
  if (!cfg?.showOnHomepage || faqItems.length === 0)
160
217
  return null;
@@ -177,55 +234,142 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
177
234
  const totalFaqs = faqItems.length;
178
235
  const hasMore = totalFaqs > slicedItems.length || readSaturated;
179
236
  return (_jsx(FAQSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.faq, subtitle: cfg?.subtitle, tabs: tabs, showCategoryTabs: cfg?.showCategoryTabs ?? false, allowMultipleOpen: cfg?.allowMultipleOpen ?? false, defaultOpenCount: cfg?.defaultOpenCount ?? 0, items: slicedItems, viewMoreHref: cfg?.linkToFullPage ? ROUTES.PUBLIC.FAQS : undefined, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.faq, hasMore: hasMore, moreCount: readSaturated ? 0 : totalFaqs - slicedItems.length }));
180
- }
181
- case "blog-articles": {
237
+ },
238
+ },
239
+ "blog-articles": {
240
+ surfaces: ["homepage", "category", "brand"],
241
+ render: ({ config, sectionData }) => {
182
242
  const cfg = config;
183
243
  return (_jsx(BlogArticlesSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.blogArticles, viewMoreHref: ROUTES.BLOG.LIST, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.blogArticles, initialItems: sectionData.blog, limit: cfg?.maxArticles, showReadTime: cfg?.showReadTime, showAuthor: cfg?.showAuthor, showThumbnails: cfg?.showThumbnails }));
184
- }
185
- case "newsletter": {
244
+ },
245
+ },
246
+ newsletter: {
247
+ surfaces: ["homepage", "category", "brand"],
248
+ render: ({ config, newsletterFormSlot }) => {
186
249
  const cfg = config;
187
250
  return (_jsx(NewsletterSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.newsletter, subtitle: cfg?.description, privacyLabel: cfg?.privacyText, privacyHref: cfg?.privacyLink, renderForm: () => newsletterFormSlot ?? null }));
188
- }
189
- case "brands": {
251
+ },
252
+ },
253
+ brands: {
254
+ // Homepage-only, not category/brand: a rail of OTHER brands reads as
255
+ // intended cross-sell on the homepage, but on a BRAND's own detail page it
256
+ // would compete with that brand's reason for being there. A category page
257
+ // has `BrandsSection` reachable via its own tabs/grid already.
258
+ surfaces: ["homepage"],
259
+ render: ({ config, sectionData }) => {
190
260
  const cfg = config;
191
261
  return (_jsx(BrandsSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.brands, subtitle: cfg?.subtitle, limit: cfg?.maxBrands || 12, viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: cfg?.viewMoreLabel || VIEW_MORE_LABEL.brands, initialItems: sectionData.brands, cta: cfg?.cta, filters: cfg?.filters, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
192
- }
193
- case "social-feed": {
262
+ },
263
+ },
264
+ "social-feed": {
265
+ surfaces: ["homepage"],
266
+ render: ({ config }) => {
194
267
  const cfg = config;
195
268
  const hasStaticPosts = Array.isArray(cfg?.posts) && cfg.posts.length > 0;
196
269
  if (!cfg?.platform || (!cfg?.handle && !hasStaticPosts))
197
270
  return null;
198
271
  return (_jsx(SocialFeedSection, { title: cleanTitle(cfg.title) || "", subtitle: cfg.subtitle, platform: cfg.platform, handle: cfg.handle ?? "", postType: cfg.postType || "all", count: cfg.count || 9, layout: cfg.layout || "grid", showCaption: cfg.showCaption ?? true, showStats: cfg.showStats ?? true, posts: cfg.posts }));
199
- }
200
- case "custom-cards": {
272
+ },
273
+ },
274
+ "custom-cards": {
275
+ surfaces: ["homepage", "category", "brand"],
276
+ render: ({ config }) => {
201
277
  const cfg = config;
202
278
  if (!cfg?.cards?.length)
203
279
  return null;
204
280
  return (_jsx(CustomCardsSection, { title: cleanTitle(cfg.title), layout: cfg.layout ?? "grid", columns: cfg.columns ?? 3, cards: cfg.cards, autoScroll: cfg.autoScroll, scrollIntervalMs: cfg.scrollIntervalMs, loop: cfg.loop }));
205
- }
206
- case "google-reviews": {
281
+ },
282
+ },
283
+ "google-reviews": {
284
+ surfaces: ["homepage"],
285
+ render: ({ config }) => {
207
286
  const cfg = config;
208
287
  return (_jsx(GoogleReviewsSection, { placeId: cfg?.placeId ?? "", maxReviews: cfg?.maxReviews ?? 6, minRating: cfg?.minRating ?? 0, layout: cfg?.layout ?? "grid", showRating: cfg?.showRating ?? true, showDate: cfg?.showDate ?? true, linkToGoogleMaps: cfg?.linkToGoogleMaps ?? true, googleMapsUrl: cfg?.googleMapsUrl }));
209
- }
210
- case "featured-bundles": {
288
+ },
289
+ },
290
+ "featured-bundles": {
291
+ surfaces: ["homepage", "category", "brand"],
292
+ render: ({ config, sectionData }) => {
211
293
  const cfg = config;
212
294
  return (_jsx(FeaturedBundlesSection, { title: cleanTitle(cfg?.title) || SECTION_TITLE.featuredBundles, description: cfg?.subtitle, initialItems: sectionData.bundles, maxItems: cfg?.maxItems, showSavingsBadge: cfg?.showSavingsBadge, viewMoreLabel: cfg?.viewMoreLabel }));
213
- }
214
- case "prize-draws": {
295
+ },
296
+ },
297
+ "prize-draws": {
298
+ surfaces: ["homepage", "category", "brand"],
299
+ render: ({ config }) => {
215
300
  const cfg = config;
216
301
  return _jsx(PrizeDrawsSection, { config: cfg ?? {} });
217
- }
218
- case "event-raffles": {
302
+ },
303
+ },
304
+ "event-raffles": {
305
+ surfaces: ["homepage"],
306
+ render: ({ config }) => {
219
307
  const cfg = config;
220
308
  return _jsx(EventRafflesSection, { config: cfg ?? {} });
221
- }
222
- case "collection-cards": {
223
- const cfg = config;
224
- return (_jsx(CollectionCardsSection, { config: cfg ?? { collections: [] } }));
225
- }
226
- default:
227
- return null;
228
- }
309
+ },
310
+ },
311
+ "collection-cards": {
312
+ surfaces: ["homepage", "category", "brand"],
313
+ render: ({ config, sectionData }) => {
314
+ const cfg = config;
315
+ return (_jsx(CollectionCardsSection, { config: cfg ?? { collections: [] },
316
+ // The `categories`/`brands`/`stores` arrays homepage already fetches
317
+ // for ITS OWN same-named sections — zero extra round-trips. See the
318
+ // component's own docstring for why only these three are wired.
319
+ sectionData: {
320
+ categories: sectionData.categories,
321
+ brands: sectionData.brands,
322
+ stores: sectionData.stores,
323
+ } }));
324
+ },
325
+ },
326
+ // Promoted out of the orphan-component set 2026-10-19 (see each component's
327
+ // own docstring for the config-serialisability fixes this required).
328
+ "how-it-works": {
329
+ surfaces: ["homepage"],
330
+ render: ({ config }) => {
331
+ const cfg = config;
332
+ if (!cfg?.title || !Array.isArray(cfg.steps) || cfg.steps.length === 0)
333
+ return null;
334
+ return (_jsx(HowItWorksSection, { title: cfg.title, subtitle: cfg.subtitle, pillLabel: cfg.pillLabel, ctaLabel: cfg.ctaLabel, ctaLink: cfg.ctaLink, steps: cfg.steps }));
335
+ },
336
+ },
337
+ testimonials: {
338
+ surfaces: ["homepage"],
339
+ render: ({ config }) => {
340
+ const cfg = config;
341
+ if (!Array.isArray(cfg?.testimonials) || cfg.testimonials.length === 0)
342
+ return null;
343
+ return (_jsx(TestimonialsCarousel, { eyebrow: cfg.eyebrow, heading: cfg.heading, testimonials: cfg.testimonials }));
344
+ },
345
+ },
346
+ "promo-grid": {
347
+ surfaces: ["homepage"],
348
+ render: ({ config }) => {
349
+ const cfg = config;
350
+ if (!Array.isArray(cfg?.banners) || cfg.banners.length === 0)
351
+ return null;
352
+ return (_jsx(PromoGrid, { eyebrow: cfg.eyebrow, heading: cfg.heading, banners: cfg.banners }));
353
+ },
354
+ },
355
+ };
356
+ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liveStats, sectionData, brand) {
357
+ const def = SECTION_REGISTRY[section.type];
358
+ // No `default` arm left to fall through to — an unmapped `SectionType` is a
359
+ // compile error on the registry object above, not a runtime `null`. This
360
+ // branch only guards a value that bypassed the type system (a raw Firestore
361
+ // read of a document whose `type` predates the current union).
362
+ if (!def)
363
+ return null;
364
+ return def.render({
365
+ config: section.config,
366
+ newsletterFormSlot,
367
+ faqItems,
368
+ slides,
369
+ liveStats,
370
+ sectionData,
371
+ brand,
372
+ });
229
373
  }
230
374
  export function renderSection(section, adSlots, newsletterFormSlot, faqItems, slides, liveStats, sectionData = {}, brand) {
231
375
  const sectionElement = renderSectionElement(section, newsletterFormSlot, faqItems, slides, liveStats, sectionData, brand);
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import type { JsonValue } from "@mohasinac/appkit";
7
7
  import { BaseRepository, type FirebaseSieveFields, type FirebaseSieveResult, type SieveModel } from "../../../providers/db-firebase";
8
- import { type HomepageSectionCreateInput, type HomepageSectionDocument, type SectionType } from "../schemas";
8
+ import { type HomepageSectionCreateInput, type HomepageSectionDocument, type SectionSurface, type SectionType } from "../schemas";
9
9
  export declare class HomepageSectionsRepository extends BaseRepository<HomepageSectionDocument> {
10
10
  constructor();
11
11
  static readonly SIEVE_FIELDS: FirebaseSieveFields;
@@ -34,9 +34,41 @@ export declare class HomepageSectionsRepository extends BaseRepository<HomepageS
34
34
  * below deliberately keeps replace semantics — that is its whole purpose.
35
35
  */
36
36
  update(id: string, data: Partial<HomepageSectionDocument>): Promise<HomepageSectionDocument>;
37
- getEnabledSections(): Promise<HomepageSectionDocument[]>;
37
+ /**
38
+ * Enabled sections for one surface, in `order`.
39
+ *
40
+ * 🛑 The parameter DEFAULTS to `"homepage"`, and that default is the safety
41
+ * property, not a convenience. This method previously returned every enabled
42
+ * row regardless of surface — so the moment a category-surface row exists,
43
+ * an unfiltered homepage would render it. Defaulting here means the existing
44
+ * homepage call site is correct with no change at all, and a caller that
45
+ * wants another surface has to say so.
46
+ *
47
+ * 🛑 The surface is matched IN MEMORY, deliberately. The only composite index
48
+ * on this collection is `(enabled, order)`;
49
+ * `where(enabled).where(surface).orderBy(order)` is a three-field composite it
50
+ * does not cover, and Firestore throws FAILED_PRECONDITION at RUNTIME rather
51
+ * than at build time. `MarketplaceHomepageView` already filters sections in
52
+ * memory for the listing-type gate — this follows that precedent. Section
53
+ * counts are tens, so the read is unchanged in cost.
54
+ */
55
+ getEnabledSections(surface?: SectionSurface): Promise<HomepageSectionDocument[]>;
38
56
  getDisabledSections(): Promise<HomepageSectionDocument[]>;
39
- getSectionByType(type: SectionType): Promise<HomepageSectionDocument | null>;
57
+ /**
58
+ * 🛑 `surface` is NOT optional in spirit, even though it defaults.
59
+ *
60
+ * This was `where(type == X).limit(1)`, which assumed ONE document per type.
61
+ * With surfaces that assumption is false — a `products` section can exist on
62
+ * the homepage AND on a category page — and `limit(1)` would return whichever
63
+ * Firestore happened to order first. An arbitrary-but-plausible answer is the
64
+ * worst failure shape available here, because nothing errors.
65
+ *
66
+ * The surface is matched IN MEMORY rather than added as a second `where`: the
67
+ * only composite index on this collection is `(enabled, order)`, and
68
+ * `where(type).where(surface)` needs one that does not exist. Fetching the few
69
+ * rows of a type and picking by surface costs nothing at these counts.
70
+ */
71
+ getSectionByType(type: SectionType, surface?: SectionSurface): Promise<HomepageSectionDocument | null>;
40
72
  enableSection(sectionId: string): Promise<HomepageSectionDocument>;
41
73
  disableSection(sectionId: string): Promise<HomepageSectionDocument>;
42
74
  toggleSection(sectionId: string): Promise<HomepageSectionDocument>;