@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,279 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { X, Trash2 } from 'lucide-react'
3
- import {
4
- useCartStore,
5
- selectSubtotal,
6
- selectDiscountTotal,
7
- selectShipping,
8
- selectTotal,
9
- } from '../stores/cart.store'
10
- import { useDiscountValidator } from '../hooks/useDiscountValidator'
11
- import { toast } from '../stores/toast.store'
12
- import { getStorefrontComponents, useStorefrontConfig } from '../config'
13
- import { navigateTo } from '../router'
14
- import { formatMoney } from '../format'
15
- import { QuantityInput } from './QuantityInput'
16
- import { formatPostalCode } from '@fayz-ai/core'
17
- import { useDeliveryStore } from '../stores/delivery.store'
18
- import { DeliveryEstimator } from './DeliveryEstimator'
19
- import { TID } from '../testids'
20
- import { SmoothImage } from './SmoothImage'
21
-
22
- export function CartDrawer() {
23
- const config = useStorefrontConfig()
24
- const cart = useCartStore()
25
- const components = getStorefrontComponents(config)
26
- const FooterExtra = components.CartDrawerFooterExtra
27
- const validate = useDiscountValidator()
28
- const [code, setCode] = useState('')
29
- const [discountError, setDiscountError] = useState<string | null>(null)
30
- const [applying, setApplying] = useState(false)
31
-
32
- // a11y: close on Escape while the drawer is open.
33
- useEffect(() => {
34
- if (!cart.isOpen) return
35
- const onKey = (e: KeyboardEvent) => {
36
- if (e.key === 'Escape') cart.closeDrawer()
37
- }
38
- document.addEventListener('keydown', onKey)
39
- return () => document.removeEventListener('keydown', onKey)
40
- }, [cart.isOpen, cart.closeDrawer])
41
-
42
- // Subscribed, not just read: selectShipping consults this store through
43
- // getState(), which does not subscribe, so without this hook a fresh quote
44
- // would change the price and leave the drawer showing the old one.
45
- const delivery = useDeliveryStore()
46
-
47
- const subtotal = selectSubtotal(cart)
48
- const discountTotal = selectDiscountTotal(cart)
49
- const shipping = selectShipping(cart, config)
50
-
51
- const total = selectTotal(cart, config)
52
- const money = (v: number) => formatMoney(v, config.currency, config.locale)
53
-
54
- async function applyCode() {
55
- setApplying(true)
56
- setDiscountError(null)
57
- try {
58
- const result = await validate(code)
59
- if (result.valid) {
60
- const applied = code.trim().toUpperCase()
61
- cart.applyDiscount(applied, result.percent)
62
- setCode('')
63
- toast.success('Cupom aplicado!', `${applied} • ${result.percent}% de desconto`)
64
- } else {
65
- setDiscountError(result.message ?? 'Cupom inválido.')
66
- toast.error('Cupom inválido', result.message ?? 'Verifique o código e tente novamente.')
67
- }
68
- } finally {
69
- setApplying(false)
70
- }
71
- }
72
-
73
- if (!cart.isOpen) return null
74
-
75
- // Free-shipping nudge: how far from the threshold this cart is
76
- const freeAbove = config.shipping.freeAbove
77
- const missingForFree = freeAbove != null && subtotal < freeAbove ? freeAbove - subtotal : 0
78
- const progress = freeAbove != null ? Math.min(100, (subtotal / freeAbove) * 100) : 0
79
-
80
- return (
81
- <div className="fixed inset-0 z-50">
82
- <div
83
- className="absolute inset-0 animate-fade-in bg-black/40"
84
- aria-hidden
85
- onClick={cart.closeDrawer}
86
- />
87
- <div
88
- data-testid={TID.cartDrawer}
89
- role="dialog"
90
- aria-label="Carrinho"
91
- className="absolute right-0 top-0 flex h-full w-full max-w-md animate-slide-in-from-right flex-col bg-background shadow-2xl"
92
- >
93
- <div className="flex items-center justify-between border-b px-5 py-4">
94
- <h2 className="text-lg font-semibold">Carrinho</h2>
95
- <button
96
- type="button"
97
- aria-label="Fechar carrinho"
98
- onClick={cart.closeDrawer}
99
- className="rounded-full p-1.5 hover:bg-muted"
100
- >
101
- <X className="h-5 w-5" />
102
- </button>
103
- </div>
104
-
105
- {cart.lines.length === 0 ? (
106
- <div data-testid={TID.cartEmpty} className="flex flex-1 items-center justify-center p-8 text-center text-muted-foreground">
107
- Seu carrinho está vazio.
108
- </div>
109
- ) : (
110
- <>
111
- {freeAbove != null && (
112
- <div data-testid={TID.shippingProgress} className="border-b bg-muted/40 px-5 py-3">
113
- <p className="text-xs font-medium">
114
- {missingForFree > 0 ? (
115
- <>Faltam <strong>{money(missingForFree)}</strong> para frete grátis 🚚</>
116
- ) : (
117
- <>🎉 Você ganhou <strong>frete grátis</strong>!</>
118
- )}
119
- </p>
120
- <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-border">
121
- <div
122
- className="h-full rounded-full bg-primary transition-all duration-500 ease-out"
123
- style={{ width: `${progress}%` }}
124
- />
125
- </div>
126
- </div>
127
- )}
128
- <div className="flex-1 space-y-4 overflow-y-auto px-5 py-4">
129
- {cart.lines.map((line) => (
130
- <div
131
- key={line.lineId ?? line.productId}
132
- data-testid={TID.cartLine}
133
- data-product-id={line.productId}
134
- data-line-id={line.lineId ?? line.productId}
135
- className={`flex animate-fade-up gap-3 rounded-lg p-1.5 transition-all hover:bg-muted/40 ${
136
- (line.lineId ?? line.productId) === cart.justAddedLineId
137
- ? 'bg-primary/5 ring-1 ring-primary/30'
138
- : ''
139
- }`}
140
- >
141
- {line.imageUrl && (
142
- <SmoothImage src={line.imageUrl} alt={line.name} className="h-20 w-20 shrink-0 rounded-lg border object-cover" />
143
- )}
144
- <div className="flex flex-1 flex-col">
145
- <div className="flex items-start justify-between gap-2">
146
- <span className="text-sm font-medium leading-snug">{line.name}</span>
147
- <button
148
- type="button"
149
- data-testid={TID.lineRemove}
150
- aria-label={`Remover ${line.name}`}
151
- onClick={() => cart.removeItem(line.lineId ?? line.productId)}
152
- className="text-muted-foreground hover:text-destructive"
153
- >
154
- <Trash2 className="h-4 w-4" />
155
- </button>
156
- </div>
157
- <span className="text-xs text-muted-foreground">{line.sku}</span>
158
- {line.optionsLabel && (
159
- <span className="text-xs text-muted-foreground">{line.optionsLabel}</span>
160
- )}
161
- <div className="mt-auto flex items-center justify-between pt-2">
162
- <QuantityInput
163
- value={line.quantity}
164
- max={line.maxQuantity || undefined}
165
- onChange={(n) => cart.setQuantity(line.lineId ?? line.productId, n)}
166
- testId={TID.lineQty}
167
- incTestId={TID.lineInc}
168
- decTestId={TID.lineDec}
169
- />
170
- <span
171
- className="text-sm font-semibold"
172
- data-price={(line.unitPrice * line.quantity).toFixed(2)}
173
- >
174
- {money(line.unitPrice * line.quantity)}
175
- </span>
176
- </div>
177
- </div>
178
- </div>
179
- ))}
180
- </div>
181
-
182
- <div className="space-y-3 border-t px-5 py-4">
183
- {config.features.discounts && (
184
- <div className="space-y-1">
185
- <div className="flex gap-2">
186
- <input
187
- data-testid={TID.discountInput}
188
- type="text"
189
- placeholder="Cupom de desconto"
190
- value={code}
191
- onChange={(e) => setCode(e.target.value)}
192
- className="flex-1 rounded-lg border bg-background px-3 py-2 text-sm uppercase"
193
- />
194
- <button
195
- type="button"
196
- data-testid={TID.discountApply}
197
- onClick={applyCode}
198
- disabled={applying || !code.trim()}
199
- className="rounded-lg border px-3 py-2 text-sm font-medium hover:bg-muted disabled:opacity-50"
200
- >
201
- Aplicar
202
- </button>
203
- </div>
204
- {discountError && (
205
- <p data-testid={TID.discountError} className="text-xs text-destructive">
206
- {discountError}
207
- </p>
208
- )}
209
- </div>
210
- )}
211
-
212
- {/* Second chance to give a CEP for anyone who added to cart from
213
- the catalogue and never opened a product page. */}
214
- <div className="mb-3">
215
- <DeliveryEstimator compact />
216
- </div>
217
-
218
- <dl className="space-y-1.5 text-sm">
219
- <div className="flex justify-between">
220
- <dt className="text-muted-foreground">Subtotal</dt>
221
- <dd data-testid={TID.cartSubtotal} data-price={subtotal.toFixed(2)}>{money(subtotal)}</dd>
222
- </div>
223
- {discountTotal > 0 && (
224
- <div className="flex justify-between text-emerald-700" data-testid={TID.discountRow}>
225
- <dt>
226
- Desconto{' '}
227
- <button
228
- type="button"
229
- onClick={cart.clearDiscount}
230
- className="text-xs text-muted-foreground underline"
231
- >
232
- ({cart.discountCode} ✕)
233
- </button>
234
- </dt>
235
- <dd data-price={discountTotal.toFixed(2)}>−{money(discountTotal)}</dd>
236
- </div>
237
- )}
238
- <div className="flex justify-between">
239
- <dt className="text-muted-foreground">
240
- Frete
241
- {delivery.status === 'served' && delivery.postalCode && (
242
- <span className="ml-1 text-xs">
243
- · {formatPostalCode(delivery.postalCode)}
244
- </span>
245
- )}
246
- </dt>
247
- <dd data-testid={TID.cartShipping} data-price={shipping.toFixed(2)}>
248
- {shipping === 0 ? 'Grátis' : money(shipping)}
249
- </dd>
250
- </div>
251
- <div className="flex justify-between border-t pt-2 text-base font-semibold">
252
- <dt>Total</dt>
253
- <dd data-testid={TID.cartTotal} data-price={total.toFixed(2)}>{money(total)}</dd>
254
- </div>
255
- </dl>
256
-
257
- <button
258
- type="button"
259
- data-testid={TID.goCheckout}
260
- onClick={() => {
261
- cart.closeDrawer()
262
- navigateTo('/checkout')
263
- }}
264
- className="sf-cta w-full bg-primary py-3.5 font-semibold text-primary-foreground shadow-md transition-all hover:-translate-y-0.5 hover:shadow-lg"
265
- style={{ borderRadius: 'var(--sf-radius-button)' }}
266
- >
267
- Finalizar compra
268
- </button>
269
-
270
- {FooterExtra && (
271
- <FooterExtra cart={cart} config={config} commerceMode={config.commerceMode} />
272
- )}
273
- </div>
274
- </>
275
- )}
276
- </div>
277
- </div>
278
- )
279
- }
@@ -1,102 +0,0 @@
1
- import React from 'react'
2
- import { CreditCard, LogOut, MapPin, Package, ShieldCheck, User } from 'lucide-react'
3
- import { signOutCustomer } from '../auth'
4
- import { useStorefrontConfig } from '../config'
5
- import { Link } from '../router'
6
- import { useSessionStore } from '../stores/session.store'
7
- import { TID } from '../testids'
8
-
9
- export type AccountSection = 'profile' | 'orders' | 'addresses' | 'payments'
10
-
11
- interface CustomerAccountShellProps {
12
- title: string
13
- subtitle?: string
14
- active: AccountSection
15
- /** Switch the active section in-place. */
16
- onSelect?: (section: AccountSection) => void
17
- children: React.ReactNode
18
- }
19
-
20
- const menuItems = [
21
- { id: 'profile', label: 'Perfil', icon: User },
22
- { id: 'orders', label: 'Meus pedidos', icon: Package },
23
- { id: 'addresses', label: 'Endereços', icon: MapPin },
24
- { id: 'payments', label: 'Pagamentos', icon: CreditCard },
25
- ] as const
26
-
27
- export function CustomerAccountShell({ title, subtitle, active, onSelect, children }: CustomerAccountShellProps) {
28
- const config = useStorefrontConfig()
29
- const session = useSessionStore()
30
- const displayName = session.name || session.email?.split('@')[0] || 'Cliente'
31
- const displayEmail = session.email || 'Conta criada no checkout'
32
-
33
- return (
34
- <main data-testid={TID.customerAccountShell} className="mx-auto max-w-6xl px-4 py-8 sm:px-6">
35
- <div className="mb-6 flex flex-wrap items-center justify-between gap-4">
36
- <div>
37
- <p className="text-sm font-medium text-muted-foreground">{config.name}</p>
38
- <h1 className="sf-heading text-3xl font-bold tracking-tight">{title}</h1>
39
- {subtitle && <p className="mt-1 text-sm text-muted-foreground">{subtitle}</p>}
40
- </div>
41
- <Link to={config.catalogPath} className="rounded-lg border px-4 py-2 text-sm font-semibold hover:bg-muted">
42
- Voltar à loja
43
- </Link>
44
- </div>
45
-
46
- <div className="grid gap-6 lg:grid-cols-[260px_minmax(0,1fr)]">
47
- <aside className="h-fit rounded-xl border bg-card p-4">
48
- <div className="flex items-center gap-3 border-b pb-4">
49
- <div className="flex h-11 w-11 items-center justify-center rounded-full bg-primary/10 font-bold text-primary">
50
- {displayName.slice(0, 1).toUpperCase()}
51
- </div>
52
- <div className="min-w-0">
53
- <p className="truncate font-semibold">{displayName}</p>
54
- <p className="truncate text-xs text-muted-foreground">{displayEmail}</p>
55
- </div>
56
- </div>
57
-
58
- <nav data-testid={TID.customerAccountMenu} className="mt-4 space-y-1" aria-label="Área do cliente">
59
- {menuItems.map((item) => {
60
- const Icon = item.icon
61
- const selected = item.id === active
62
- return (
63
- <button
64
- key={item.id}
65
- type="button"
66
- aria-current={selected ? 'page' : undefined}
67
- onClick={() => onSelect?.(item.id)}
68
- className={`flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm font-semibold transition ${
69
- selected ? 'bg-primary/10 text-primary' : 'text-muted-foreground hover:bg-muted hover:text-foreground'
70
- }`}
71
- >
72
- <Icon className="h-4 w-4" />
73
- {item.label}
74
- </button>
75
- )
76
- })}
77
- </nav>
78
-
79
- <div className="mt-4 rounded-lg bg-muted/40 p-3 text-xs text-muted-foreground">
80
- <div className="flex items-center gap-2 font-semibold text-foreground">
81
- <ShieldCheck className="h-4 w-4 text-primary" />
82
- Conta protegida
83
- </div>
84
- <p className="mt-1">Pedidos, pagamentos e endereços ficam organizados para próximas compras.</p>
85
- </div>
86
-
87
- <button
88
- type="button"
89
- data-testid={TID.signout}
90
- onClick={() => void signOutCustomer()}
91
- className="mt-4 flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-semibold text-muted-foreground transition hover:bg-muted hover:text-foreground"
92
- >
93
- <LogOut className="h-4 w-4" />
94
- Sair
95
- </button>
96
- </aside>
97
-
98
- <section className="min-w-0">{children}</section>
99
- </div>
100
- </main>
101
- )
102
- }
@@ -1,157 +0,0 @@
1
- import React, { useState } from 'react'
2
- import { MapPin, Truck } from 'lucide-react'
3
- import { formatPostalCode } from '@fayz-ai/core'
4
- import { useDeliveryStore, resolveOptionRate } from '../stores/delivery.store'
5
- import { useCartStore, selectSubtotal } from '../stores/cart.store'
6
- import { useStorefrontConfig } from '../config'
7
- import { formatMoney } from '../format'
8
- import { TID } from '../testids'
9
-
10
- /**
11
- * "Do you deliver to me, for how much, and when" — asked on the product page,
12
- * before the shopper has invested anything in a cart.
13
- *
14
- * The CEP is kept in the delivery store, so the answer follows them to the cart
15
- * and lands at checkout with street/district/city/UF already filled. That is
16
- * the actual payoff: the buyer types a house number instead of an address.
17
- *
18
- * `subtotal` is the PRE-discount cart subtotal, the same number shop_place_order
19
- * uses to resolve free-above thresholds. Quoting against anything else is how
20
- * the cart and the order end up disagreeing (see migration 0017).
21
- */
22
- export function DeliveryEstimator({ compact = false }: { compact?: boolean }) {
23
- const config = useStorefrontConfig()
24
- const cart = useCartStore()
25
- const delivery = useDeliveryStore()
26
- const [draft, setDraft] = useState(() => formatPostalCode(delivery.postalCode))
27
-
28
- const subtotal = selectSubtotal(cart)
29
- const money = (value: number) => formatMoney(value, config.currency, config.locale)
30
- const loading = delivery.status === 'loading'
31
-
32
- async function submit(event: React.FormEvent) {
33
- event.preventDefault()
34
- await delivery.resolve(draft, subtotal)
35
- }
36
-
37
- function eta(option: { etaMinDays?: number; etaMaxDays?: number }): string | null {
38
- const { etaMinDays: min, etaMaxDays: max } = option
39
- if (min == null && max == null) return null
40
- if (min === 0 && (max === 0 || max === 1)) return 'hoje ou amanhã'
41
- if (min != null && max != null && min !== max) return `${min} a ${max} dias úteis`
42
- return `${max ?? min} dia(s) útil(eis)`
43
- }
44
-
45
- return (
46
- <section
47
- data-testid={TID.deliveryEstimator}
48
- className={compact ? 'rounded-lg border p-3' : 'mt-6 rounded-lg border p-4'}
49
- >
50
- <div className="flex items-center gap-2 text-sm font-semibold">
51
- <Truck className="h-4 w-4 text-primary" />
52
- Calcular entrega
53
- </div>
54
-
55
- <form onSubmit={submit} className="mt-3 flex gap-2">
56
- <input
57
- data-testid={TID.deliveryCepInput}
58
- aria-label="CEP"
59
- inputMode="numeric"
60
- autoComplete="postal-code"
61
- placeholder="00000-000"
62
- value={draft}
63
- onChange={(event) => setDraft(formatPostalCode(event.target.value))}
64
- className="min-w-0 flex-1 rounded-lg border bg-background px-3 py-2 text-sm outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/10"
65
- />
66
- <button
67
- type="submit"
68
- data-testid={TID.deliveryCepSubmit}
69
- disabled={loading}
70
- className="shrink-0 rounded-lg bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition hover:opacity-90 disabled:opacity-50"
71
- >
72
- {loading ? '...' : 'Calcular'}
73
- </button>
74
- </form>
75
-
76
- {/* Shown whenever there is one, including alongside a price: the range
77
- may be covered even though the CEP itself was mistyped. */}
78
- {delivery.error && (
79
- <p data-testid={TID.deliveryError} className="mt-3 text-sm text-destructive">
80
- {delivery.error}
81
- </p>
82
- )}
83
-
84
- {delivery.address && (
85
- <p data-testid={TID.deliveryAddress} className="mt-3 flex items-start gap-1.5 text-xs text-muted-foreground">
86
- <MapPin className="mt-0.5 h-3.5 w-3.5 shrink-0" />
87
- <span>
88
- {[delivery.address.street, delivery.address.district].filter(Boolean).join(', ')}
89
- {delivery.address.street || delivery.address.district ? ' — ' : ''}
90
- {delivery.address.city}/{delivery.address.state}
91
- </span>
92
- </p>
93
- )}
94
-
95
- {delivery.status === 'served' && (
96
- <ul className="mt-3 space-y-2">
97
- {delivery.options.map((option) => {
98
- const selected = delivery.selectedZoneId === option.zoneId
99
- const label = eta(option)
100
- // Resolved for the cart as it stands right now, not for whatever it
101
- // held when the CEP was typed — the same rule the server applies.
102
- const rate = resolveOptionRate(option, subtotal)
103
- return (
104
- <li key={option.zoneId}>
105
- <button
106
- type="button"
107
- data-testid={TID.deliveryOption}
108
- data-zone={option.zoneId}
109
- data-rate={rate.toFixed(2)}
110
- aria-pressed={selected}
111
- onClick={() => delivery.selectZone(option.zoneId)}
112
- className={`flex w-full items-center justify-between gap-3 rounded-lg border px-3 py-2 text-left text-sm transition ${
113
- selected ? 'border-primary bg-primary/5' : 'border-border hover:bg-muted/40'
114
- }`}
115
- >
116
- <span className="min-w-0">
117
- <span className="block truncate font-medium">
118
- {option.carrier ? `${option.carrier} · ${option.name}` : option.name}
119
- </span>
120
- {label && <span className="block text-xs text-muted-foreground">{label}</span>}
121
- </span>
122
- <span className="shrink-0 font-semibold">
123
- {rate === 0 ? 'Grátis' : money(rate)}
124
- </span>
125
- </button>
126
- </li>
127
- )
128
- })}
129
- </ul>
130
- )}
131
-
132
- {/*
133
- No options for a valid address. For a store that configured zones this
134
- means "outside our delivery area" and checkout will refuse the order, so
135
- it is said plainly here rather than at the end of the funnel. A store
136
- with no zones at all never reaches this state — it quotes nothing and
137
- keeps its flat rate.
138
- */}
139
- {delivery.status === 'unserved' && (
140
- <p data-testid={TID.deliveryUnserved} className="mt-3 text-sm text-destructive">
141
- Ainda não entregamos nesse CEP.
142
- </p>
143
- )}
144
-
145
- {delivery.postalCode && (
146
- <button
147
- type="button"
148
- data-testid={TID.deliveryClear}
149
- onClick={() => { delivery.clear(); setDraft('') }}
150
- className="mt-3 text-xs text-muted-foreground underline-offset-2 hover:underline"
151
- >
152
- Trocar CEP
153
- </button>
154
- )}
155
- </section>
156
- )
157
- }
@@ -1,109 +0,0 @@
1
- import React from 'react'
2
- import { useCatalogStore } from '../stores/catalog.store'
3
- import type { CatalogSort } from '../stores/catalog.store'
4
- import { useCategories } from '../hooks/useCategories'
5
- import { TID } from '../testids'
6
-
7
- export function FiltersPanel() {
8
- const { categories } = useCategories()
9
- const catalog = useCatalogStore()
10
-
11
- return (
12
- <aside className="w-full shrink-0 space-y-6 lg:w-56">
13
- {/* Sort */}
14
- <div className="space-y-2">
15
- <h3 className="text-sm font-semibold">Ordenar por</h3>
16
- <select
17
- data-testid={TID.sortSelect}
18
- value={catalog.sort}
19
- onChange={(e) => catalog.setSort(e.target.value as CatalogSort)}
20
- className="w-full rounded-lg border bg-background px-3 py-2 text-sm"
21
- >
22
- <option value="newest">Mais recentes</option>
23
- <option value="price-asc">Menor preço</option>
24
- <option value="price-desc">Maior preço</option>
25
- <option value="name">Nome (A–Z)</option>
26
- </select>
27
- </div>
28
-
29
- {/* Categories */}
30
- <div className="space-y-2">
31
- <h3 className="text-sm font-semibold">Categorias</h3>
32
- <ul className="space-y-1">
33
- <li>
34
- <button
35
- type="button"
36
- onClick={() => catalog.setCategoryId(null)}
37
- className={`w-full rounded-md px-2 py-1.5 text-left text-sm transition-colors ${
38
- catalog.categoryId === null ? 'bg-primary/10 font-medium text-primary' : 'hover:bg-muted'
39
- }`}
40
- >
41
- Todas
42
- </button>
43
- </li>
44
- {categories.map((c) => (
45
- <li key={c.id}>
46
- <button
47
- type="button"
48
- data-testid={TID.filterCategory(c.slug)}
49
- onClick={() => catalog.setCategoryId(catalog.categoryId === c.id ? null : c.id)}
50
- className={`w-full rounded-md px-2 py-1.5 text-left text-sm transition-colors ${
51
- catalog.categoryId === c.id ? 'bg-primary/10 font-medium text-primary' : 'hover:bg-muted'
52
- }`}
53
- >
54
- {c.name}
55
- </button>
56
- </li>
57
- ))}
58
- </ul>
59
- </div>
60
-
61
- {/* Price range */}
62
- <div className="space-y-2">
63
- <h3 className="text-sm font-semibold">Preço</h3>
64
- <div className="flex items-center gap-2">
65
- <input
66
- data-testid={TID.filterPriceMin}
67
- type="number"
68
- placeholder="Mín"
69
- min={0}
70
- value={catalog.priceMin ?? ''}
71
- onChange={(e) => catalog.setPriceMin(e.target.value === '' ? null : Number(e.target.value))}
72
- className="w-full rounded-lg border bg-background px-2.5 py-1.5 text-sm"
73
- />
74
- <span className="text-muted-foreground">–</span>
75
- <input
76
- data-testid={TID.filterPriceMax}
77
- type="number"
78
- placeholder="Máx"
79
- min={0}
80
- value={catalog.priceMax ?? ''}
81
- onChange={(e) => catalog.setPriceMax(e.target.value === '' ? null : Number(e.target.value))}
82
- className="w-full rounded-lg border bg-background px-2.5 py-1.5 text-sm"
83
- />
84
- </div>
85
- </div>
86
-
87
- {/* Availability */}
88
- <label className="flex cursor-pointer items-center gap-2 text-sm">
89
- <input
90
- data-testid={TID.filterInstock}
91
- type="checkbox"
92
- checked={catalog.inStockOnly}
93
- onChange={(e) => catalog.setInStockOnly(e.target.checked)}
94
- className="h-4 w-4 rounded border"
95
- />
96
- Somente em estoque
97
- </label>
98
-
99
- <button
100
- type="button"
101
- data-testid={TID.filtersClear}
102
- onClick={() => catalog.reset()}
103
- className="text-sm text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
104
- >
105
- Limpar filtros
106
- </button>
107
- </aside>
108
- )
109
- }