@fayz-ai/storefront 0.9.0 → 0.11.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 (391) hide show
  1. package/README.md +3 -3
  2. package/dist/app/createStorefrontApp.d.ts +65 -0
  3. package/dist/app/createStorefrontApp.d.ts.map +1 -0
  4. package/dist/{define.d.ts → app/define.d.ts} +3 -3
  5. package/dist/app/define.d.ts.map +1 -0
  6. package/dist/app/hydration.d.ts +37 -0
  7. package/dist/app/hydration.d.ts.map +1 -0
  8. package/dist/app/prerender.d.ts +57 -0
  9. package/dist/app/prerender.d.ts.map +1 -0
  10. package/dist/{router.d.ts → app/router.d.ts} +140 -113
  11. package/dist/app/router.d.ts.map +1 -0
  12. package/dist/{scaffold.d.ts → app/scaffold.d.ts} +2 -2
  13. package/dist/app/scaffold.d.ts.map +1 -0
  14. package/dist/app/serving.d.ts +70 -0
  15. package/dist/app/serving.d.ts.map +1 -0
  16. package/dist/app/static-render.d.ts +46 -0
  17. package/dist/app/static-render.d.ts.map +1 -0
  18. package/dist/blocks/block-at-path.d.ts +59 -0
  19. package/dist/blocks/block-at-path.d.ts.map +1 -0
  20. package/dist/blocks/page-blocks.d.ts +163 -0
  21. package/dist/blocks/page-blocks.d.ts.map +1 -0
  22. package/dist/blocks/page-data.d.ts +105 -0
  23. package/dist/blocks/page-data.d.ts.map +1 -0
  24. package/dist/{blocks.d.ts → blocks/registry.d.ts} +1 -1
  25. package/dist/blocks/registry.d.ts.map +1 -0
  26. package/dist/{sections.d.ts → blocks/sections.d.ts} +40 -2
  27. package/dist/blocks/sections.d.ts.map +1 -0
  28. package/dist/chunk-6IXTENLB.js +162 -0
  29. package/dist/chunk-6IXTENLB.js.map +1 -0
  30. package/dist/chunk-SX3J3QIT.js +11046 -0
  31. package/dist/chunk-SX3J3QIT.js.map +1 -0
  32. package/dist/components/PaymentTerms.d.ts +34 -0
  33. package/dist/components/PaymentTerms.d.ts.map +1 -0
  34. package/dist/components/Skeleton.d.ts +17 -0
  35. package/dist/components/Skeleton.d.ts.map +1 -0
  36. package/dist/components/SmoothImage.d.ts +1 -1
  37. package/dist/components/SmoothImage.d.ts.map +1 -1
  38. package/dist/components/account/CustomerAccountShell.d.ts +17 -0
  39. package/dist/components/account/CustomerAccountShell.d.ts.map +1 -0
  40. package/dist/components/account/SignInModal.d.ts.map +1 -0
  41. package/dist/components/account/section.d.ts +15 -0
  42. package/dist/components/account/section.d.ts.map +1 -0
  43. package/dist/components/cart/CartDrawer.d.ts.map +1 -0
  44. package/dist/components/cart/QuantityInput.d.ts.map +1 -0
  45. package/dist/components/checkout/CheckoutPayment.d.ts +17 -0
  46. package/dist/components/checkout/CheckoutPayment.d.ts.map +1 -0
  47. package/dist/components/checkout/CheckoutSteps.d.ts +9 -0
  48. package/dist/components/checkout/CheckoutSteps.d.ts.map +1 -0
  49. package/dist/components/checkout/DeliveryEstimator.d.ts.map +1 -0
  50. package/dist/components/collection/CategoryShowcase.d.ts +44 -0
  51. package/dist/components/collection/CategoryShowcase.d.ts.map +1 -0
  52. package/dist/components/collection/FiltersPanel.d.ts +19 -0
  53. package/dist/components/collection/FiltersPanel.d.ts.map +1 -0
  54. package/dist/components/collection/ProductGrid.d.ts.map +1 -0
  55. package/dist/components/layout/PageBodyBlocks.d.ts +40 -0
  56. package/dist/components/layout/PageBodyBlocks.d.ts.map +1 -0
  57. package/dist/components/layout/SearchOverlay.d.ts +13 -0
  58. package/dist/components/layout/SearchOverlay.d.ts.map +1 -0
  59. package/dist/components/layout/StorefrontErrorBoundary.d.ts.map +1 -0
  60. package/dist/components/layout/StorefrontFooter.d.ts.map +1 -0
  61. package/dist/components/layout/StorefrontHeader.d.ts.map +1 -0
  62. package/dist/components/layout/Toaster.d.ts.map +1 -0
  63. package/dist/components/marketing/CollectionSections.d.ts +463 -0
  64. package/dist/components/marketing/CollectionSections.d.ts.map +1 -0
  65. package/dist/components/marketing/ConversionSections.d.ts +221 -0
  66. package/dist/components/marketing/ConversionSections.d.ts.map +1 -0
  67. package/dist/components/marketing/EditorialSections.d.ts +248 -0
  68. package/dist/components/marketing/EditorialSections.d.ts.map +1 -0
  69. package/dist/components/marketing/EntityList.d.ts +97 -0
  70. package/dist/components/marketing/EntityList.d.ts.map +1 -0
  71. package/dist/components/marketing/FormBlock.d.ts +167 -0
  72. package/dist/components/marketing/FormBlock.d.ts.map +1 -0
  73. package/dist/components/marketing/HeroSection.d.ts +125 -0
  74. package/dist/components/marketing/HeroSection.d.ts.map +1 -0
  75. package/dist/components/marketing/MediaCarousel.d.ts +135 -0
  76. package/dist/components/marketing/MediaCarousel.d.ts.map +1 -0
  77. package/dist/components/marketing/MiscSections.d.ts +252 -0
  78. package/dist/components/marketing/MiscSections.d.ts.map +1 -0
  79. package/dist/components/order/OrderTrackingTimeline.d.ts.map +1 -0
  80. package/dist/components/order/SuccessMark.d.ts +10 -0
  81. package/dist/components/order/SuccessMark.d.ts.map +1 -0
  82. package/dist/components/product/ProductCard.d.ts +14 -0
  83. package/dist/components/product/ProductCard.d.ts.map +1 -0
  84. package/dist/components/product/ProductEnquiryForm.d.ts.map +1 -0
  85. package/dist/components/product/ProductGallery.d.ts +36 -0
  86. package/dist/components/product/ProductGallery.d.ts.map +1 -0
  87. package/dist/components/{ProductOptionSelector.d.ts → product/ProductOptionSelector.d.ts} +1 -1
  88. package/dist/components/product/ProductOptionSelector.d.ts.map +1 -0
  89. package/dist/components/product/ProductRail.d.ts +93 -0
  90. package/dist/components/product/ProductRail.d.ts.map +1 -0
  91. package/dist/components/product/ProductReviews.d.ts +39 -0
  92. package/dist/components/product/ProductReviews.d.ts.map +1 -0
  93. package/dist/components/product/ProductSlider.d.ts +169 -0
  94. package/dist/components/product/ProductSlider.d.ts.map +1 -0
  95. package/dist/components/product/ProductSpecs.d.ts.map +1 -0
  96. package/dist/components/product/RelatedProducts.d.ts.map +1 -0
  97. package/dist/{auth.d.ts → data/auth.d.ts} +9 -0
  98. package/dist/data/auth.d.ts.map +1 -0
  99. package/dist/data/facets.d.ts +39 -0
  100. package/dist/data/facets.d.ts.map +1 -0
  101. package/dist/data/loaders.d.ts +52 -0
  102. package/dist/data/loaders.d.ts.map +1 -0
  103. package/dist/data/local-orders.d.ts +5 -0
  104. package/dist/data/local-orders.d.ts.map +1 -0
  105. package/dist/data/order-status.d.ts.map +1 -0
  106. package/dist/data/product-options.d.ts +36 -0
  107. package/dist/data/product-options.d.ts.map +1 -0
  108. package/dist/data/shipping-items.d.ts +20 -0
  109. package/dist/data/shipping-items.d.ts.map +1 -0
  110. package/dist/diagnostics/seo-audit.d.ts +54 -0
  111. package/dist/diagnostics/seo-audit.d.ts.map +1 -0
  112. package/dist/diagnostics/seo-audit.js +3 -0
  113. package/dist/diagnostics/seo-audit.js.map +1 -0
  114. package/dist/document/change.d.ts +100 -0
  115. package/dist/document/change.d.ts.map +1 -0
  116. package/dist/document/config.d.ts +311 -0
  117. package/dist/document/config.d.ts.map +1 -0
  118. package/dist/document/describe.d.ts +135 -0
  119. package/dist/document/describe.d.ts.map +1 -0
  120. package/dist/document/overlay.d.ts +58 -0
  121. package/dist/document/overlay.d.ts.map +1 -0
  122. package/dist/{presets.d.ts → document/presets.d.ts} +2 -2
  123. package/dist/document/presets.d.ts.map +1 -0
  124. package/dist/document/render.d.ts +171 -0
  125. package/dist/document/render.d.ts.map +1 -0
  126. package/dist/document/round-trip.d.ts +46 -0
  127. package/dist/document/round-trip.d.ts.map +1 -0
  128. package/dist/document/sections.d.ts +194 -0
  129. package/dist/document/sections.d.ts.map +1 -0
  130. package/dist/document/store-policy.d.ts +29 -0
  131. package/dist/document/store-policy.d.ts.map +1 -0
  132. package/dist/document/upgrade.d.ts +112 -0
  133. package/dist/document/upgrade.d.ts.map +1 -0
  134. package/dist/document/validate.d.ts +24 -0
  135. package/dist/document/validate.d.ts.map +1 -0
  136. package/dist/{component-contracts.d.ts → extend/component-contracts.d.ts} +74 -22
  137. package/dist/extend/component-contracts.d.ts.map +1 -0
  138. package/dist/extend/component-override.d.ts +38 -0
  139. package/dist/extend/component-override.d.ts.map +1 -0
  140. package/dist/extend/component-selectors.d.ts.map +1 -0
  141. package/dist/extend/editor-bridge.d.ts +59 -0
  142. package/dist/extend/editor-bridge.d.ts.map +1 -0
  143. package/dist/extend/extension-points.d.ts +103 -0
  144. package/dist/extend/extension-points.d.ts.map +1 -0
  145. package/dist/extend/slots.d.ts +216 -0
  146. package/dist/extend/slots.d.ts.map +1 -0
  147. package/dist/hooks/index.d.ts +25 -6
  148. package/dist/hooks/index.d.ts.map +1 -1
  149. package/dist/hooks/use-address.d.ts +26 -0
  150. package/dist/hooks/use-address.d.ts.map +1 -0
  151. package/dist/hooks/use-cart.d.ts +3 -0
  152. package/dist/hooks/use-cart.d.ts.map +1 -0
  153. package/dist/hooks/use-catalog.d.ts +24 -0
  154. package/dist/hooks/use-catalog.d.ts.map +1 -0
  155. package/dist/hooks/use-categories.d.ts +19 -0
  156. package/dist/hooks/use-categories.d.ts.map +1 -0
  157. package/dist/hooks/use-checkout.d.ts +41 -0
  158. package/dist/hooks/use-checkout.d.ts.map +1 -0
  159. package/dist/hooks/use-discount-validator.d.ts +20 -0
  160. package/dist/hooks/use-discount-validator.d.ts.map +1 -0
  161. package/dist/hooks/use-enquiry.d.ts +7 -0
  162. package/dist/hooks/use-enquiry.d.ts.map +1 -0
  163. package/dist/hooks/{useMyOrders.d.ts → use-my-orders.d.ts} +1 -1
  164. package/dist/hooks/use-my-orders.d.ts.map +1 -0
  165. package/dist/hooks/use-order.d.ts +17 -0
  166. package/dist/hooks/use-order.d.ts.map +1 -0
  167. package/dist/hooks/use-payment-methods.d.ts +19 -0
  168. package/dist/hooks/use-payment-methods.d.ts.map +1 -0
  169. package/dist/hooks/use-policies.d.ts +25 -0
  170. package/dist/hooks/use-policies.d.ts.map +1 -0
  171. package/dist/hooks/use-product.d.ts +15 -0
  172. package/dist/hooks/use-product.d.ts.map +1 -0
  173. package/dist/hooks/{useProducts.d.ts → use-products.d.ts} +1 -1
  174. package/dist/hooks/use-products.d.ts.map +1 -0
  175. package/dist/hooks/use-region.d.ts +15 -0
  176. package/dist/hooks/use-region.d.ts.map +1 -0
  177. package/dist/hooks/use-shipping.d.ts +32 -0
  178. package/dist/hooks/use-shipping.d.ts.map +1 -0
  179. package/dist/hooks/use-storefront-actions.d.ts +12 -0
  180. package/dist/hooks/use-storefront-actions.d.ts.map +1 -0
  181. package/dist/hooks/use-storefront-head.d.ts +19 -0
  182. package/dist/hooks/use-storefront-head.d.ts.map +1 -0
  183. package/dist/hooks/use-storefront.d.ts +3 -0
  184. package/dist/hooks/use-storefront.d.ts.map +1 -0
  185. package/dist/index.d.ts +124 -54
  186. package/dist/index.d.ts.map +1 -1
  187. package/dist/index.js +1310 -5010
  188. package/dist/index.js.map +1 -1
  189. package/dist/lib/errors.d.ts +9 -0
  190. package/dist/lib/errors.d.ts.map +1 -0
  191. package/dist/lib/format.d.ts.map +1 -0
  192. package/dist/lib/motion.d.ts.map +1 -0
  193. package/dist/lib/seo.d.ts +26 -0
  194. package/dist/lib/seo.d.ts.map +1 -0
  195. package/dist/{testids.d.ts → lib/testids.d.ts} +33 -0
  196. package/dist/lib/testids.d.ts.map +1 -0
  197. package/dist/{theme.d.ts → lib/theme.d.ts} +41 -3
  198. package/dist/lib/theme.d.ts.map +1 -0
  199. package/dist/render.d.ts +5 -0
  200. package/dist/render.d.ts.map +1 -0
  201. package/dist/render.js +359 -0
  202. package/dist/render.js.map +1 -0
  203. package/dist/stores/cart.store.d.ts +34 -2
  204. package/dist/stores/cart.store.d.ts.map +1 -1
  205. package/dist/stores/catalog.store.d.ts +11 -0
  206. package/dist/stores/catalog.store.d.ts.map +1 -1
  207. package/dist/stores/delivery.store.d.ts +9 -0
  208. package/dist/stores/delivery.store.d.ts.map +1 -1
  209. package/dist/views/CatalogPage.d.ts.map +1 -0
  210. package/dist/views/CheckoutPage.d.ts.map +1 -0
  211. package/dist/views/ContentPage.d.ts +11 -0
  212. package/dist/views/ContentPage.d.ts.map +1 -0
  213. package/dist/views/HomePage.d.ts +9 -0
  214. package/dist/views/HomePage.d.ts.map +1 -0
  215. package/dist/views/MyPurchasesPage.d.ts.map +1 -0
  216. package/dist/views/NotFoundPage.d.ts.map +1 -0
  217. package/dist/views/OrderConfirmationPage.d.ts.map +1 -0
  218. package/dist/{pages → views}/PolicyPage.d.ts.map +1 -1
  219. package/dist/views/ProductDetailPage.d.ts.map +1 -0
  220. package/dist/views/StorefrontPage.d.ts +35 -0
  221. package/dist/views/StorefrontPage.d.ts.map +1 -0
  222. package/dist/workflows/checkout.d.ts +1 -1
  223. package/dist/workflows/checkout.d.ts.map +1 -1
  224. package/package.json +21 -14
  225. package/dist/auth.d.ts.map +0 -1
  226. package/dist/blocks.d.ts.map +0 -1
  227. package/dist/component-contracts.d.ts.map +0 -1
  228. package/dist/component-selectors.d.ts.map +0 -1
  229. package/dist/components/CartDrawer.d.ts.map +0 -1
  230. package/dist/components/CustomerAccountShell.d.ts +0 -13
  231. package/dist/components/CustomerAccountShell.d.ts.map +0 -1
  232. package/dist/components/DeliveryEstimator.d.ts.map +0 -1
  233. package/dist/components/FiltersPanel.d.ts +0 -3
  234. package/dist/components/FiltersPanel.d.ts.map +0 -1
  235. package/dist/components/OrderTrackingTimeline.d.ts.map +0 -1
  236. package/dist/components/ProductCard.d.ts +0 -4
  237. package/dist/components/ProductCard.d.ts.map +0 -1
  238. package/dist/components/ProductEnquiryForm.d.ts.map +0 -1
  239. package/dist/components/ProductGallery.d.ts +0 -22
  240. package/dist/components/ProductGallery.d.ts.map +0 -1
  241. package/dist/components/ProductGrid.d.ts.map +0 -1
  242. package/dist/components/ProductOptionSelector.d.ts.map +0 -1
  243. package/dist/components/ProductSpecs.d.ts.map +0 -1
  244. package/dist/components/QuantityInput.d.ts.map +0 -1
  245. package/dist/components/RelatedProducts.d.ts.map +0 -1
  246. package/dist/components/SignInModal.d.ts.map +0 -1
  247. package/dist/components/StorefrontErrorBoundary.d.ts.map +0 -1
  248. package/dist/components/StorefrontFooter.d.ts.map +0 -1
  249. package/dist/components/StorefrontHeader.d.ts.map +0 -1
  250. package/dist/components/Toaster.d.ts.map +0 -1
  251. package/dist/components/sections/CategoryShowcase.d.ts +0 -6
  252. package/dist/components/sections/CategoryShowcase.d.ts.map +0 -1
  253. package/dist/components/sections/HeroSection.d.ts +0 -9
  254. package/dist/components/sections/HeroSection.d.ts.map +0 -1
  255. package/dist/components/sections/MediaCarousel.d.ts +0 -11
  256. package/dist/components/sections/MediaCarousel.d.ts.map +0 -1
  257. package/dist/components/sections/MiscSections.d.ts +0 -33
  258. package/dist/components/sections/MiscSections.d.ts.map +0 -1
  259. package/dist/components/sections/ProductRail.d.ts +0 -9
  260. package/dist/components/sections/ProductRail.d.ts.map +0 -1
  261. package/dist/components/sections/ProductSlider.d.ts +0 -15
  262. package/dist/components/sections/ProductSlider.d.ts.map +0 -1
  263. package/dist/config.d.ts +0 -174
  264. package/dist/config.d.ts.map +0 -1
  265. package/dist/createStorefrontApp.d.ts +0 -28
  266. package/dist/createStorefrontApp.d.ts.map +0 -1
  267. package/dist/define.d.ts.map +0 -1
  268. package/dist/format.d.ts.map +0 -1
  269. package/dist/hooks/useCategories.d.ts +0 -6
  270. package/dist/hooks/useCategories.d.ts.map +0 -1
  271. package/dist/hooks/useDiscountValidator.d.ts +0 -14
  272. package/dist/hooks/useDiscountValidator.d.ts.map +0 -1
  273. package/dist/hooks/useMyOrders.d.ts.map +0 -1
  274. package/dist/hooks/useProduct.d.ts +0 -7
  275. package/dist/hooks/useProduct.d.ts.map +0 -1
  276. package/dist/hooks/useProducts.d.ts.map +0 -1
  277. package/dist/hooks/useStorefront.d.ts +0 -35
  278. package/dist/hooks/useStorefront.d.ts.map +0 -1
  279. package/dist/hooks/useStorefrontHead.d.ts +0 -11
  280. package/dist/hooks/useStorefrontHead.d.ts.map +0 -1
  281. package/dist/motion.d.ts.map +0 -1
  282. package/dist/order-status.d.ts.map +0 -1
  283. package/dist/pages/CatalogPage.d.ts.map +0 -1
  284. package/dist/pages/CheckoutPage.d.ts.map +0 -1
  285. package/dist/pages/HomePage.d.ts +0 -9
  286. package/dist/pages/HomePage.d.ts.map +0 -1
  287. package/dist/pages/MyPurchasesPage.d.ts.map +0 -1
  288. package/dist/pages/NotFoundPage.d.ts.map +0 -1
  289. package/dist/pages/OrderConfirmationPage.d.ts.map +0 -1
  290. package/dist/pages/ProductDetailPage.d.ts.map +0 -1
  291. package/dist/presets.d.ts.map +0 -1
  292. package/dist/product-options.d.ts +0 -12
  293. package/dist/product-options.d.ts.map +0 -1
  294. package/dist/router.d.ts.map +0 -1
  295. package/dist/scaffold.d.ts.map +0 -1
  296. package/dist/sections.d.ts.map +0 -1
  297. package/dist/testids.d.ts.map +0 -1
  298. package/dist/theme.d.ts.map +0 -1
  299. package/src/auth.ts +0 -227
  300. package/src/blocks.tsx +0 -51
  301. package/src/catalog.ts +0 -3
  302. package/src/component-contracts.ts +0 -154
  303. package/src/component-selectors.ts +0 -31
  304. package/src/components/CartDrawer.tsx +0 -279
  305. package/src/components/CustomerAccountShell.tsx +0 -102
  306. package/src/components/DeliveryEstimator.tsx +0 -157
  307. package/src/components/FiltersPanel.tsx +0 -109
  308. package/src/components/OrderTrackingTimeline.tsx +0 -135
  309. package/src/components/Price.tsx +0 -32
  310. package/src/components/ProductCard.tsx +0 -120
  311. package/src/components/ProductEnquiryForm.tsx +0 -175
  312. package/src/components/ProductGallery.tsx +0 -174
  313. package/src/components/ProductGrid.tsx +0 -43
  314. package/src/components/ProductOptionSelector.tsx +0 -50
  315. package/src/components/ProductSpecs.tsx +0 -75
  316. package/src/components/QuantityInput.tsx +0 -52
  317. package/src/components/RelatedProducts.tsx +0 -40
  318. package/src/components/SignInModal.tsx +0 -120
  319. package/src/components/SmoothImage.tsx +0 -59
  320. package/src/components/StorefrontErrorBoundary.tsx +0 -51
  321. package/src/components/StorefrontFooter.tsx +0 -110
  322. package/src/components/StorefrontHeader.tsx +0 -477
  323. package/src/components/Toaster.tsx +0 -60
  324. package/src/components/sections/CategoryShowcase.tsx +0 -80
  325. package/src/components/sections/HeroSection.tsx +0 -193
  326. package/src/components/sections/MediaCarousel.tsx +0 -141
  327. package/src/components/sections/MiscSections.tsx +0 -158
  328. package/src/components/sections/ProductRail.tsx +0 -81
  329. package/src/components/sections/ProductSlider.tsx +0 -119
  330. package/src/config.ts +0 -229
  331. package/src/createStorefrontApp.tsx +0 -247
  332. package/src/define.ts +0 -34
  333. package/src/format.ts +0 -7
  334. package/src/hooks/index.ts +0 -6
  335. package/src/hooks/useCategories.ts +0 -26
  336. package/src/hooks/useDiscountValidator.ts +0 -43
  337. package/src/hooks/useMyOrders.ts +0 -41
  338. package/src/hooks/useProduct.ts +0 -36
  339. package/src/hooks/useProducts.ts +0 -39
  340. package/src/hooks/useStorefront.ts +0 -58
  341. package/src/hooks/useStorefrontHead.ts +0 -25
  342. package/src/index.ts +0 -202
  343. package/src/motion.tsx +0 -94
  344. package/src/order-status.ts +0 -33
  345. package/src/pages/CatalogPage.tsx +0 -118
  346. package/src/pages/CheckoutPage.tsx +0 -689
  347. package/src/pages/HomePage.tsx +0 -16
  348. package/src/pages/MyPurchasesPage.tsx +0 -311
  349. package/src/pages/NotFoundPage.tsx +0 -25
  350. package/src/pages/OrderConfirmationPage.tsx +0 -190
  351. package/src/pages/PolicyPage.tsx +0 -47
  352. package/src/pages/ProductDetailPage.tsx +0 -264
  353. package/src/presets.ts +0 -324
  354. package/src/product-options.ts +0 -63
  355. package/src/router.ts +0 -49
  356. package/src/scaffold.tsx +0 -115
  357. package/src/sections.ts +0 -116
  358. package/src/shop.ts +0 -4
  359. package/src/stores/cart.store.ts +0 -185
  360. package/src/stores/catalog.store.ts +0 -39
  361. package/src/stores/delivery.store.ts +0 -152
  362. package/src/stores/session.store.ts +0 -28
  363. package/src/stores/toast.store.ts +0 -43
  364. package/src/testids.ts +0 -136
  365. package/src/theme.ts +0 -194
  366. package/src/ui.ts +0 -5
  367. package/src/workflows/checkout.ts +0 -119
  368. /package/dist/components/{SignInModal.d.ts → account/SignInModal.d.ts} +0 -0
  369. /package/dist/components/{CartDrawer.d.ts → cart/CartDrawer.d.ts} +0 -0
  370. /package/dist/components/{QuantityInput.d.ts → cart/QuantityInput.d.ts} +0 -0
  371. /package/dist/components/{DeliveryEstimator.d.ts → checkout/DeliveryEstimator.d.ts} +0 -0
  372. /package/dist/components/{ProductGrid.d.ts → collection/ProductGrid.d.ts} +0 -0
  373. /package/dist/components/{StorefrontErrorBoundary.d.ts → layout/StorefrontErrorBoundary.d.ts} +0 -0
  374. /package/dist/components/{StorefrontFooter.d.ts → layout/StorefrontFooter.d.ts} +0 -0
  375. /package/dist/components/{StorefrontHeader.d.ts → layout/StorefrontHeader.d.ts} +0 -0
  376. /package/dist/components/{Toaster.d.ts → layout/Toaster.d.ts} +0 -0
  377. /package/dist/components/{OrderTrackingTimeline.d.ts → order/OrderTrackingTimeline.d.ts} +0 -0
  378. /package/dist/components/{ProductEnquiryForm.d.ts → product/ProductEnquiryForm.d.ts} +0 -0
  379. /package/dist/components/{ProductSpecs.d.ts → product/ProductSpecs.d.ts} +0 -0
  380. /package/dist/components/{RelatedProducts.d.ts → product/RelatedProducts.d.ts} +0 -0
  381. /package/dist/{order-status.d.ts → data/order-status.d.ts} +0 -0
  382. /package/dist/{component-selectors.d.ts → extend/component-selectors.d.ts} +0 -0
  383. /package/dist/{format.d.ts → lib/format.d.ts} +0 -0
  384. /package/dist/{motion.d.ts → lib/motion.d.ts} +0 -0
  385. /package/dist/{pages → views}/CatalogPage.d.ts +0 -0
  386. /package/dist/{pages → views}/CheckoutPage.d.ts +0 -0
  387. /package/dist/{pages → views}/MyPurchasesPage.d.ts +0 -0
  388. /package/dist/{pages → views}/NotFoundPage.d.ts +0 -0
  389. /package/dist/{pages → views}/OrderConfirmationPage.d.ts +0 -0
  390. /package/dist/{pages → views}/PolicyPage.d.ts +0 -0
  391. /package/dist/{pages → views}/ProductDetailPage.d.ts +0 -0
@@ -1,193 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react'
2
- import { ChevronLeft, ChevronRight } from 'lucide-react'
3
- import type { HeroSlide } from '../../sections'
4
- import type { HeroVariant } from '../../theme'
5
- import { bannerPlaceholder } from '../../sections'
6
- import { useStorefrontConfig } from '../../config'
7
- import { prefersReducedMotion } from '../../motion'
8
- import { Link } from '../../router'
9
- import { TID } from '../../testids'
10
- import { SmoothImage } from '../SmoothImage'
11
-
12
- function slideImage(slide: HeroSlide, w = 1600, h = 700): string {
13
- return slide.image ?? bannerPlaceholder(slide.title, slide.hue ?? 200, (slide.hue ?? 200) + 40, w, h)
14
- }
15
-
16
- function SlideCopy({ slide, active }: { slide: HeroSlide; active: boolean }) {
17
- const stagger = (i: number) =>
18
- active ? { className: 'animate-fade-up', style: { animationDelay: `${i * 120}ms` } } : { className: 'opacity-0' }
19
-
20
- const inner = (
21
- <>
22
- <h2 className={`sf-heading text-3xl font-bold leading-tight tracking-tight sm:text-5xl ${stagger(0).className}`} style={stagger(0).style}>
23
- {slide.title}
24
- </h2>
25
- {slide.subtitle && (
26
- <p className={`mt-3 max-w-md text-base sm:text-lg ${stagger(1).className}`} style={stagger(1).style}>
27
- {slide.subtitle}
28
- </p>
29
- )}
30
- {slide.cta && (
31
- <div className={stagger(2).className} style={stagger(2).style}>
32
- <Link
33
- to={slide.href ?? '/catalog'}
34
- className="sf-cta mt-6 inline-block bg-primary px-8 py-3.5 font-semibold text-primary-foreground shadow-lg transition-all hover:-translate-y-0.5 hover:shadow-xl"
35
- style={{ borderRadius: 'var(--sf-radius-button)' }}
36
- >
37
- {slide.cta}
38
- </Link>
39
- </div>
40
- )}
41
- </>
42
- )
43
- if (slide.boxed) {
44
- return (
45
- <div className="border border-foreground/30 bg-background/90 p-8 backdrop-blur-sm sm:p-10">{inner}</div>
46
- )
47
- }
48
- return <div className="text-white">{inner}</div>
49
- }
50
-
51
- export function HeroSection({
52
- variant,
53
- slides,
54
- height = 'tall',
55
- }: {
56
- variant: HeroVariant
57
- slides: HeroSlide[]
58
- height?: 'tall' | 'medium'
59
- }) {
60
- const [index, setIndex] = useState(0)
61
- const [loadedSlides, setLoadedSlides] = useState<Record<number, boolean>>({})
62
- const config = useStorefrontConfig()
63
- const interacted = useRef(false)
64
- const hClass = height === 'tall' ? 'h-[72vh] min-h-[440px]' : 'h-[48vh] min-h-[340px]'
65
- const revealImages = config.imageLoading.mode !== 'none'
66
- const revealStyle = (loaded: boolean): React.CSSProperties | undefined =>
67
- revealImages
68
- ? {
69
- filter: config.imageLoading.blur && !loaded ? 'blur(10px)' : 'blur(0px)',
70
- transition: `opacity 700ms ease, filter ${config.imageLoading.durationMs}ms ${config.imageLoading.easing}`,
71
- }
72
- : undefined
73
-
74
- // Auto-advance until the visitor takes over; never under reduced motion.
75
- useEffect(() => {
76
- if (variant !== 'slider' || slides.length < 2 || prefersReducedMotion()) return
77
- const timer = setInterval(() => {
78
- if (!interacted.current) setIndex((i) => (i + 1) % slides.length)
79
- }, 7000)
80
- return () => clearInterval(timer)
81
- }, [variant, slides.length])
82
-
83
- const goTo = (i: number) => {
84
- interacted.current = true
85
- setIndex((i + slides.length) % slides.length)
86
- }
87
-
88
- if (slides.length === 0) return null
89
-
90
- if (variant === 'split') {
91
- return (
92
- <section data-testid={TID.hero} className="grid gap-px sm:grid-cols-2">
93
- {slides.slice(0, 2).map((slide, i) => (
94
- <Link
95
- key={i}
96
- to={slide.href ?? '/catalog'}
97
- className="group relative block h-[42vh] min-h-[320px] overflow-hidden"
98
- >
99
- <SmoothImage
100
- src={slideImage(slide, 900, 700)}
101
- alt={slide.title}
102
- className="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-105"
103
- />
104
- <div className="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-t from-black/65 via-black/25 to-black/10 p-6 text-center text-white">
105
- <h2
106
- className="sf-heading animate-fade-up text-3xl font-bold uppercase tracking-wide drop-shadow-md sm:text-4xl"
107
- style={{ animationDelay: `${i * 150}ms` }}
108
- >
109
- {slide.title}
110
- </h2>
111
- {slide.subtitle && (
112
- <p className="animate-fade-up mt-2 max-w-sm drop-shadow" style={{ animationDelay: `${i * 150 + 120}ms` }}>
113
- {slide.subtitle}
114
- </p>
115
- )}
116
- <span className="mt-4 inline-block border-b-2 border-white/0 pb-0.5 text-sm font-semibold uppercase tracking-wider opacity-0 transition-all duration-300 group-hover:border-white group-hover:opacity-100">
117
- Explorar →
118
- </span>
119
- </div>
120
- </Link>
121
- ))}
122
- </section>
123
- )
124
- }
125
-
126
- const active = slides[Math.min(index, slides.length - 1)]!
127
-
128
- return (
129
- <section data-testid={TID.hero} className={`relative w-full overflow-hidden ${hClass}`}>
130
- {/* stacked slides, crossfade + Ken Burns on the active one */}
131
- {slides.map((slide, i) => (
132
- <img
133
- key={i}
134
- src={slideImage(slide)}
135
- alt={slide.title}
136
- aria-hidden={i !== index}
137
- loading={i === 0 ? 'eager' : 'lazy'}
138
- decoding="async"
139
- onLoad={() => setLoadedSlides((current) => ({ ...current, [i]: true }))}
140
- style={revealStyle(Boolean(loadedSlides[i]))}
141
- className={`absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ${
142
- i === index && (!revealImages || loadedSlides[i]) ? 'animate-kenburns opacity-100' : 'opacity-0'
143
- }`}
144
- />
145
- ))}
146
- <div
147
- className={`absolute inset-0 flex items-end p-6 sm:p-12 ${
148
- active.boxed ? '' : 'bg-gradient-to-t from-black/60 via-black/20 to-transparent'
149
- }`}
150
- >
151
- <div className="mx-auto w-full max-w-7xl">
152
- <div className="max-w-xl">
153
- <SlideCopy key={index} slide={active} active />
154
- </div>
155
- </div>
156
- </div>
157
-
158
- {variant === 'slider' && slides.length > 1 && (
159
- <>
160
- <button
161
- type="button"
162
- aria-label="Slide anterior"
163
- data-testid={TID.heroPrev}
164
- onClick={() => goTo(index - 1)}
165
- className="absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-white/85 p-2.5 shadow transition-transform hover:scale-110 hover:bg-white"
166
- >
167
- <ChevronLeft className="h-5 w-5 text-gray-900" />
168
- </button>
169
- <button
170
- type="button"
171
- aria-label="Próximo slide"
172
- data-testid={TID.heroNext}
173
- onClick={() => goTo(index + 1)}
174
- className="absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-white/85 p-2.5 shadow transition-transform hover:scale-110 hover:bg-white"
175
- >
176
- <ChevronRight className="h-5 w-5 text-gray-900" />
177
- </button>
178
- <div className="absolute bottom-4 left-1/2 flex -translate-x-1/2 gap-2">
179
- {slides.map((_, i) => (
180
- <button
181
- key={i}
182
- type="button"
183
- aria-label={`Ir para o slide ${i + 1}`}
184
- onClick={() => goTo(i)}
185
- className={`h-2 rounded-full transition-all duration-300 ${i === index ? 'w-7 bg-white' : 'w-2 bg-white/60 hover:bg-white/80'}`}
186
- />
187
- ))}
188
- </div>
189
- </>
190
- )}
191
- </section>
192
- )
193
- }
@@ -1,141 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react'
2
- import { ChevronLeft, ChevronRight } from 'lucide-react'
3
- import { Link } from '../../router'
4
- import { TID } from '../../testids'
5
- import { prefersReducedMotion } from '../../motion'
6
- import type { MediaCarouselItem } from '../../sections'
7
- import { useStorefrontConfig } from '../../config'
8
-
9
- export interface MediaCarouselProps {
10
- items: MediaCarouselItem[]
11
- height?: 'medium' | 'tall' | 'screen'
12
- autoplayMs?: number
13
- overlay?: 'dark' | 'soft' | 'none'
14
- className?: string
15
- }
16
-
17
- const heightClass = {
18
- medium: 'h-[58vh] min-h-[420px]',
19
- tall: 'h-[74vh] min-h-[520px]',
20
- screen: 'min-h-[calc(100vh-64px)]',
21
- }
22
-
23
- const alignClass = {
24
- start: 'items-start text-left',
25
- center: 'items-center text-center',
26
- end: 'items-end text-right',
27
- }
28
-
29
- export function MediaCarousel({
30
- items,
31
- height = 'tall',
32
- autoplayMs = 7000,
33
- overlay = 'dark',
34
- className = '',
35
- }: MediaCarouselProps) {
36
- const [index, setIndex] = useState(0)
37
- const [loadedItems, setLoadedItems] = useState<Record<number, boolean>>({})
38
- const config = useStorefrontConfig()
39
- const interacted = useRef(false)
40
- const revealImages = config.imageLoading.mode !== 'none'
41
- const revealStyle = (loaded: boolean): React.CSSProperties | undefined =>
42
- revealImages
43
- ? {
44
- filter: config.imageLoading.blur && !loaded ? 'blur(10px)' : 'blur(0px)',
45
- transition: `opacity 700ms ease, filter ${config.imageLoading.durationMs}ms ${config.imageLoading.easing}`,
46
- }
47
- : undefined
48
-
49
- useEffect(() => {
50
- if (items.length < 2 || autoplayMs <= 0 || prefersReducedMotion()) return
51
- const timer = setInterval(() => {
52
- if (!interacted.current) setIndex((i) => (i + 1) % items.length)
53
- }, autoplayMs)
54
- return () => clearInterval(timer)
55
- }, [autoplayMs, items.length])
56
-
57
- if (items.length === 0) return null
58
-
59
- const active = items[Math.min(index, items.length - 1)]!
60
- const goTo = (next: number) => {
61
- interacted.current = true
62
- setIndex((next + items.length) % items.length)
63
- }
64
- const overlayClass =
65
- overlay === 'dark'
66
- ? 'bg-gradient-to-r from-black/70 via-black/25 to-black/25'
67
- : overlay === 'soft'
68
- ? 'bg-gradient-to-t from-black/45 via-black/10 to-transparent'
69
- : ''
70
-
71
- return (
72
- <section data-testid={TID.mediaCarousel} className={`relative isolate overflow-hidden ${heightClass[height]} ${className}`}>
73
- {items.map((item, i) => (
74
- <img
75
- key={`${item.title}-${i}`}
76
- src={item.image}
77
- alt={item.imageAlt ?? item.title}
78
- aria-hidden={i !== index}
79
- loading={i === 0 ? 'eager' : 'lazy'}
80
- decoding="async"
81
- onLoad={() => setLoadedItems((current) => ({ ...current, [i]: true }))}
82
- style={revealStyle(Boolean(loadedItems[i]))}
83
- className={`absolute inset-0 -z-10 h-full w-full object-cover transition-opacity duration-700 ${
84
- i === index && (!revealImages || loadedItems[i]) ? 'opacity-100' : 'opacity-0'
85
- }`}
86
- />
87
- ))}
88
- <div className={`absolute inset-0 -z-10 ${overlayClass}`} />
89
- <div className={`flex h-full px-5 py-16 sm:px-10 lg:px-16 ${alignClass[active.align ?? 'start']}`}>
90
- <div className="my-auto max-w-2xl text-white drop-shadow-md">
91
- {active.eyebrow && (
92
- <p className="mb-4 text-xs font-semibold uppercase tracking-[0.24em] text-white/80">{active.eyebrow}</p>
93
- )}
94
- <h1 className="sf-heading text-5xl font-normal leading-[0.95] sm:text-7xl lg:text-8xl">{active.title}</h1>
95
- {active.subtitle && <p className="mt-5 max-w-xl text-base leading-8 text-white/88 sm:text-lg">{active.subtitle}</p>}
96
- {active.cta && (
97
- <Link
98
- to={active.href ?? '/catalog'}
99
- className="mt-8 inline-flex border border-white/75 px-6 py-3 text-xs font-semibold uppercase tracking-[0.18em] text-white transition hover:bg-white hover:text-black"
100
- >
101
- {active.cta}
102
- </Link>
103
- )}
104
- </div>
105
- </div>
106
- {items.length > 1 && (
107
- <>
108
- <button
109
- type="button"
110
- aria-label="Previous slide"
111
- data-testid={TID.mediaCarouselPrev}
112
- onClick={() => goTo(index - 1)}
113
- className="absolute left-4 top-1/2 inline-flex h-10 w-10 -translate-y-1/2 items-center justify-center border border-white/60 bg-black/20 text-white backdrop-blur transition hover:bg-white hover:text-black"
114
- >
115
- <ChevronLeft className="h-5 w-5" />
116
- </button>
117
- <button
118
- type="button"
119
- aria-label="Next slide"
120
- data-testid={TID.mediaCarouselNext}
121
- onClick={() => goTo(index + 1)}
122
- className="absolute right-4 top-1/2 inline-flex h-10 w-10 -translate-y-1/2 items-center justify-center border border-white/60 bg-black/20 text-white backdrop-blur transition hover:bg-white hover:text-black"
123
- >
124
- <ChevronRight className="h-5 w-5" />
125
- </button>
126
- <div className="absolute bottom-5 left-1/2 flex -translate-x-1/2 gap-2">
127
- {items.map((item, i) => (
128
- <button
129
- key={`${item.title}-dot-${i}`}
130
- type="button"
131
- aria-label={`Go to slide ${i + 1}`}
132
- onClick={() => goTo(i)}
133
- className={`h-2 rounded-full transition-all ${i === index ? 'w-8 bg-white' : 'w-2 bg-white/55 hover:bg-white'}`}
134
- />
135
- ))}
136
- </div>
137
- </>
138
- )}
139
- </section>
140
- )
141
- }
@@ -1,158 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { getLucideIcon } from '@fayz-ai/ui/icons'
3
- import { bannerPlaceholder } from '../../sections'
4
- import { Reveal } from '../../motion'
5
- import { Link } from '../../router'
6
- import { TID } from '../../testids'
7
- import { SmoothImage } from '../SmoothImage'
8
-
9
- function Icon({ name, className }: { name: string; className?: string }) {
10
- const C = getLucideIcon(name)
11
- return C ? <C className={className} /> : null
12
- }
13
-
14
- export function BenefitsRow({ items }: { items: Array<{ icon: string; title: string; text?: string }> }) {
15
- return (
16
- <section data-testid={TID.benefits} className="border-y bg-card">
17
- <div className="mx-auto grid max-w-7xl grid-cols-1 gap-6 px-4 py-9 sm:grid-cols-3 sm:px-6">
18
- {items.slice(0, 4).map((item, i) => (
19
- <Reveal key={i} delay={i * 120} className="flex items-center justify-center gap-3 text-center sm:text-left">
20
- <span className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-primary/10">
21
- <Icon name={item.icon} className="h-6 w-6 text-primary" />
22
- </span>
23
- <div>
24
- <p className="font-semibold">{item.title}</p>
25
- {item.text && <p className="text-sm text-muted-foreground">{item.text}</p>}
26
- </div>
27
- </Reveal>
28
- ))}
29
- </div>
30
- </section>
31
- )
32
- }
33
-
34
- export function PromoBanner({
35
- title,
36
- subtitle,
37
- eyebrow,
38
- cta,
39
- href,
40
- image,
41
- hue = 160,
42
- }: {
43
- title: string
44
- subtitle?: string
45
- eyebrow?: string
46
- cta?: string
47
- href?: string
48
- image?: string
49
- hue?: number
50
- }) {
51
- return (
52
- <section data-testid={TID.promoBanner} className="group relative my-12 overflow-hidden">
53
- <SmoothImage
54
- src={image ?? bannerPlaceholder(title, hue, hue + 50, 1600, 420)}
55
- alt={title}
56
- className="h-80 w-full object-cover transition-transform duration-700 ease-out group-hover:scale-105"
57
- />
58
- <div className="absolute inset-0 flex flex-col items-center justify-center bg-gradient-to-t from-black/65 via-black/35 to-black/20 p-6 text-center text-white">
59
- <Reveal>
60
- {eyebrow && (
61
- <p className="mb-2 text-xs font-semibold uppercase tracking-[0.25em] text-white/80">{eyebrow}</p>
62
- )}
63
- <h2 className="sf-heading text-3xl font-bold drop-shadow sm:text-5xl">{title}</h2>
64
- {subtitle && <p className="mt-3 max-w-lg text-white/90">{subtitle}</p>}
65
- {cta && (
66
- <Link
67
- to={href ?? '/catalog'}
68
- className="sf-cta mt-6 inline-block bg-white px-8 py-3 font-semibold text-gray-900 shadow-lg transition-all hover:-translate-y-0.5 hover:shadow-xl"
69
- style={{ borderRadius: 'var(--sf-radius-button)' }}
70
- >
71
- {cta}
72
- </Link>
73
- )}
74
- </Reveal>
75
- </div>
76
- </section>
77
- )
78
- }
79
-
80
- export function ManifestoBlock({ title, text }: { title?: string; text: string }) {
81
- return (
82
- <section data-testid={TID.manifesto} className="mx-auto max-w-3xl px-4 py-14 text-center sm:px-6">
83
- {title && <h2 className="sf-heading mb-5 text-2xl font-bold">{title}</h2>}
84
- <p className="sf-heading text-xl leading-relaxed text-muted-foreground sm:text-2xl">{text}</p>
85
- </section>
86
- )
87
- }
88
-
89
- export function Testimonials({ title, items }: { title?: string; items: Array<{ quote: string; author: string }> }) {
90
- return (
91
- <section data-testid={TID.testimonials} className="bg-muted/50 py-14">
92
- <div className="mx-auto max-w-7xl px-4 sm:px-6">
93
- {title && (
94
- <Reveal>
95
- <h2 className="sf-heading mb-10 text-center text-3xl font-bold">{title}</h2>
96
- </Reveal>
97
- )}
98
- <div className="grid gap-6 md:grid-cols-3">
99
- {items.slice(0, 3).map((t, i) => (
100
- <Reveal key={i} delay={i * 130}>
101
- <figure
102
- className="h-full bg-card p-7 shadow-sm transition-shadow hover:shadow-md"
103
- style={{ borderRadius: 'var(--sf-radius-card)' }}
104
- >
105
- <div className="mb-3 text-primary" aria-hidden>★★★★★</div>
106
- <blockquote className="leading-relaxed">“{t.quote}”</blockquote>
107
- <figcaption className="mt-4 text-sm font-semibold text-muted-foreground">— {t.author}</figcaption>
108
- </figure>
109
- </Reveal>
110
- ))}
111
- </div>
112
- </div>
113
- </section>
114
- )
115
- }
116
-
117
- export function NewsletterBand({ title, subtitle }: { title?: string; subtitle?: string }) {
118
- const [email, setEmail] = useState('')
119
- const [done, setDone] = useState(false)
120
- return (
121
- <section data-testid={TID.newsletter} className="bg-primary py-16 text-primary-foreground">
122
- <Reveal className="mx-auto max-w-xl px-4 text-center sm:px-6">
123
- <h2 className="sf-heading text-3xl font-bold">{title ?? 'Receba nossas novidades'}</h2>
124
- {subtitle && <p className="mt-2 opacity-90">{subtitle}</p>}
125
- {done ? (
126
- <p data-testid={TID.newsletterDone} className="mt-6 font-medium">Inscrição confirmada! 🎉</p>
127
- ) : (
128
- <form
129
- className="mt-6 flex gap-2"
130
- onSubmit={(e) => {
131
- e.preventDefault()
132
- if (email.trim()) setDone(true)
133
- }}
134
- >
135
- <input
136
- data-testid={TID.newsletterEmail}
137
- type="email"
138
- required
139
- placeholder="Seu e-mail"
140
- value={email}
141
- onChange={(e) => setEmail(e.target.value)}
142
- className="flex-1 border-0 bg-white/95 px-4 py-3 text-sm text-gray-900 outline-none"
143
- style={{ borderRadius: 'var(--sf-radius-input)' }}
144
- />
145
- <button
146
- type="submit"
147
- data-testid={TID.newsletterSubmit}
148
- className="sf-cta bg-foreground px-6 py-3 text-sm font-semibold text-background"
149
- style={{ borderRadius: 'var(--sf-radius-button)' }}
150
- >
151
- Assinar
152
- </button>
153
- </form>
154
- )}
155
- </Reveal>
156
- </section>
157
- )
158
- }
@@ -1,81 +0,0 @@
1
- import React, { useMemo } from 'react'
2
- import { useProducts } from '../../hooks/useProducts'
3
- import { getStorefrontComponents, useStorefrontConfig } from '../../config'
4
- import { useStorefrontActions } from '../../hooks/useStorefront'
5
- import { ProductCard } from '../ProductCard'
6
- import { Reveal } from '../../motion'
7
- import { Link } from '../../router'
8
- import { TID } from '../../testids'
9
-
10
- export function ProductRail({
11
- title,
12
- subtitle,
13
- eyebrow,
14
- filter = 'all',
15
- limit = 4,
16
- }: {
17
- title: string
18
- subtitle?: string
19
- eyebrow?: string
20
- filter?: 'sale' | 'new' | 'all'
21
- limit?: number
22
- }) {
23
- const config = useStorefrontConfig()
24
- const actions = useStorefrontActions()
25
- const components = getStorefrontComponents(config)
26
- const ProductCardComponent = components.ProductCard ?? ProductCard
27
- const { products, loading } = useProducts(
28
- filter === 'new'
29
- ? { status: 'active', orderBy: 'created_at', order: 'desc' }
30
- : { status: 'active' },
31
- )
32
-
33
- const visible = useMemo(() => {
34
- let list = products
35
- if (filter === 'sale') list = list.filter((p) => p.compareAtPrice != null && p.compareAtPrice > p.price)
36
- return list.slice(0, limit)
37
- }, [products, filter, limit])
38
-
39
- if (!loading && visible.length === 0) return null
40
-
41
- return (
42
- <section data-testid={TID.productRail} className="mx-auto max-w-7xl px-4 py-14 sm:px-6">
43
- <Reveal className="mb-10 text-center">
44
- {eyebrow && (
45
- <p className="mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-primary">{eyebrow}</p>
46
- )}
47
- <h2 className="sf-heading text-3xl font-bold tracking-tight">{title}</h2>
48
- {subtitle && <p className="mt-2 text-muted-foreground">{subtitle}</p>}
49
- </Reveal>
50
- {loading ? (
51
- <div className="grid grid-cols-2 gap-5 md:grid-cols-4">
52
- {Array.from({ length: limit }, (_, i) => (
53
- <div key={i} className="aspect-[3/4] animate-pulse bg-muted" style={{ borderRadius: 'var(--sf-radius-card)' }} />
54
- ))}
55
- </div>
56
- ) : (
57
- <div className="grid grid-cols-2 gap-5 md:grid-cols-4">
58
- {visible.map((p, i) => (
59
- <Reveal key={p.id} delay={i * 90}>
60
- <ProductCardComponent
61
- product={p}
62
- config={config}
63
- commerceMode={config.commerceMode}
64
- actions={actions}
65
- />
66
- </Reveal>
67
- ))}
68
- </div>
69
- )}
70
- <Reveal className="mt-10 text-center" delay={200}>
71
- <Link
72
- to={config.catalogPath}
73
- className="sf-cta inline-block border border-foreground/30 px-7 py-2.5 text-sm font-semibold transition-all hover:-translate-y-0.5 hover:bg-foreground hover:text-background hover:shadow"
74
- style={{ borderRadius: 'var(--sf-radius-button)' }}
75
- >
76
- Ver tudo
77
- </Link>
78
- </Reveal>
79
- </section>
80
- )
81
- }