@fayz-ai/storefront 0.9.0 → 0.10.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.
- package/README.md +3 -3
- package/dist/app/createStorefrontApp.d.ts +65 -0
- package/dist/app/createStorefrontApp.d.ts.map +1 -0
- package/dist/{define.d.ts → app/define.d.ts} +3 -3
- package/dist/app/define.d.ts.map +1 -0
- package/dist/app/hydration.d.ts +37 -0
- package/dist/app/hydration.d.ts.map +1 -0
- package/dist/app/prerender.d.ts +57 -0
- package/dist/app/prerender.d.ts.map +1 -0
- package/dist/{router.d.ts → app/router.d.ts} +140 -113
- package/dist/app/router.d.ts.map +1 -0
- package/dist/{scaffold.d.ts → app/scaffold.d.ts} +2 -2
- package/dist/app/scaffold.d.ts.map +1 -0
- package/dist/app/serving.d.ts +70 -0
- package/dist/app/serving.d.ts.map +1 -0
- package/dist/app/static-render.d.ts +46 -0
- package/dist/app/static-render.d.ts.map +1 -0
- package/dist/blocks/block-at-path.d.ts +59 -0
- package/dist/blocks/block-at-path.d.ts.map +1 -0
- package/dist/blocks/page-blocks.d.ts +163 -0
- package/dist/blocks/page-blocks.d.ts.map +1 -0
- package/dist/blocks/page-data.d.ts +105 -0
- package/dist/blocks/page-data.d.ts.map +1 -0
- package/dist/{blocks.d.ts → blocks/registry.d.ts} +1 -1
- package/dist/blocks/registry.d.ts.map +1 -0
- package/dist/{sections.d.ts → blocks/sections.d.ts} +40 -2
- package/dist/blocks/sections.d.ts.map +1 -0
- package/dist/chunk-6B7H3IZ6.js +10232 -0
- package/dist/chunk-6B7H3IZ6.js.map +1 -0
- package/dist/chunk-6IXTENLB.js +162 -0
- package/dist/chunk-6IXTENLB.js.map +1 -0
- package/dist/components/PaymentTerms.d.ts +34 -0
- package/dist/components/PaymentTerms.d.ts.map +1 -0
- package/dist/components/SmoothImage.d.ts +1 -1
- package/dist/components/SmoothImage.d.ts.map +1 -1
- package/dist/components/account/CustomerAccountShell.d.ts.map +1 -0
- package/dist/components/account/SignInModal.d.ts.map +1 -0
- package/dist/components/cart/CartDrawer.d.ts.map +1 -0
- package/dist/components/cart/QuantityInput.d.ts.map +1 -0
- package/dist/components/checkout/DeliveryEstimator.d.ts.map +1 -0
- package/dist/components/collection/CategoryShowcase.d.ts +44 -0
- package/dist/components/collection/CategoryShowcase.d.ts.map +1 -0
- package/dist/components/collection/FiltersPanel.d.ts +19 -0
- package/dist/components/collection/FiltersPanel.d.ts.map +1 -0
- package/dist/components/collection/ProductGrid.d.ts.map +1 -0
- package/dist/components/layout/PageBodyBlocks.d.ts +40 -0
- package/dist/components/layout/PageBodyBlocks.d.ts.map +1 -0
- package/dist/components/layout/SearchOverlay.d.ts +13 -0
- package/dist/components/layout/SearchOverlay.d.ts.map +1 -0
- package/dist/components/layout/StorefrontErrorBoundary.d.ts.map +1 -0
- package/dist/components/layout/StorefrontFooter.d.ts.map +1 -0
- package/dist/components/layout/StorefrontHeader.d.ts.map +1 -0
- package/dist/components/layout/Toaster.d.ts.map +1 -0
- package/dist/components/marketing/CollectionSections.d.ts +463 -0
- package/dist/components/marketing/CollectionSections.d.ts.map +1 -0
- package/dist/components/marketing/ConversionSections.d.ts +221 -0
- package/dist/components/marketing/ConversionSections.d.ts.map +1 -0
- package/dist/components/marketing/EditorialSections.d.ts +248 -0
- package/dist/components/marketing/EditorialSections.d.ts.map +1 -0
- package/dist/components/marketing/EntityList.d.ts +97 -0
- package/dist/components/marketing/EntityList.d.ts.map +1 -0
- package/dist/components/marketing/FormBlock.d.ts +167 -0
- package/dist/components/marketing/FormBlock.d.ts.map +1 -0
- package/dist/components/marketing/HeroSection.d.ts +125 -0
- package/dist/components/marketing/HeroSection.d.ts.map +1 -0
- package/dist/components/marketing/MediaCarousel.d.ts +135 -0
- package/dist/components/marketing/MediaCarousel.d.ts.map +1 -0
- package/dist/components/marketing/MiscSections.d.ts +252 -0
- package/dist/components/marketing/MiscSections.d.ts.map +1 -0
- package/dist/components/order/OrderTrackingTimeline.d.ts.map +1 -0
- package/dist/components/product/ProductCard.d.ts +14 -0
- package/dist/components/product/ProductCard.d.ts.map +1 -0
- package/dist/components/product/ProductEnquiryForm.d.ts.map +1 -0
- package/dist/components/product/ProductGallery.d.ts +36 -0
- package/dist/components/product/ProductGallery.d.ts.map +1 -0
- package/dist/components/{ProductOptionSelector.d.ts → product/ProductOptionSelector.d.ts} +1 -1
- package/dist/components/product/ProductOptionSelector.d.ts.map +1 -0
- package/dist/components/product/ProductRail.d.ts +93 -0
- package/dist/components/product/ProductRail.d.ts.map +1 -0
- package/dist/components/product/ProductReviews.d.ts +39 -0
- package/dist/components/product/ProductReviews.d.ts.map +1 -0
- package/dist/components/product/ProductSlider.d.ts +169 -0
- package/dist/components/product/ProductSlider.d.ts.map +1 -0
- package/dist/components/product/ProductSpecs.d.ts.map +1 -0
- package/dist/components/product/RelatedProducts.d.ts.map +1 -0
- package/dist/{auth.d.ts → data/auth.d.ts} +9 -0
- package/dist/data/auth.d.ts.map +1 -0
- package/dist/data/facets.d.ts +39 -0
- package/dist/data/facets.d.ts.map +1 -0
- package/dist/data/loaders.d.ts +56 -0
- package/dist/data/loaders.d.ts.map +1 -0
- package/dist/data/order-status.d.ts.map +1 -0
- package/dist/data/product-options.d.ts +36 -0
- package/dist/data/product-options.d.ts.map +1 -0
- package/dist/diagnostics/seo-audit.d.ts +54 -0
- package/dist/diagnostics/seo-audit.d.ts.map +1 -0
- package/dist/diagnostics/seo-audit.js +3 -0
- package/dist/diagnostics/seo-audit.js.map +1 -0
- package/dist/document/change.d.ts +100 -0
- package/dist/document/change.d.ts.map +1 -0
- package/dist/{config.d.ts → document/config.d.ts} +126 -7
- package/dist/document/config.d.ts.map +1 -0
- package/dist/document/describe.d.ts +135 -0
- package/dist/document/describe.d.ts.map +1 -0
- package/dist/document/overlay.d.ts +58 -0
- package/dist/document/overlay.d.ts.map +1 -0
- package/dist/{presets.d.ts → document/presets.d.ts} +2 -2
- package/dist/document/presets.d.ts.map +1 -0
- package/dist/document/render.d.ts +171 -0
- package/dist/document/render.d.ts.map +1 -0
- package/dist/document/round-trip.d.ts +46 -0
- package/dist/document/round-trip.d.ts.map +1 -0
- package/dist/document/sections.d.ts +194 -0
- package/dist/document/sections.d.ts.map +1 -0
- package/dist/document/upgrade.d.ts +112 -0
- package/dist/document/upgrade.d.ts.map +1 -0
- package/dist/document/validate.d.ts +24 -0
- package/dist/document/validate.d.ts.map +1 -0
- package/dist/{component-contracts.d.ts → extend/component-contracts.d.ts} +74 -22
- package/dist/extend/component-contracts.d.ts.map +1 -0
- package/dist/extend/component-override.d.ts +38 -0
- package/dist/extend/component-override.d.ts.map +1 -0
- package/dist/extend/component-selectors.d.ts.map +1 -0
- package/dist/extend/editor-bridge.d.ts +59 -0
- package/dist/extend/editor-bridge.d.ts.map +1 -0
- package/dist/extend/extension-points.d.ts +103 -0
- package/dist/extend/extension-points.d.ts.map +1 -0
- package/dist/extend/slots.d.ts +216 -0
- package/dist/extend/slots.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +25 -6
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/use-address.d.ts +26 -0
- package/dist/hooks/use-address.d.ts.map +1 -0
- package/dist/hooks/use-cart.d.ts +3 -0
- package/dist/hooks/use-cart.d.ts.map +1 -0
- package/dist/hooks/use-catalog.d.ts +24 -0
- package/dist/hooks/use-catalog.d.ts.map +1 -0
- package/dist/hooks/use-categories.d.ts +19 -0
- package/dist/hooks/use-categories.d.ts.map +1 -0
- package/dist/hooks/use-checkout.d.ts +41 -0
- package/dist/hooks/use-checkout.d.ts.map +1 -0
- package/dist/hooks/use-discount-validator.d.ts +20 -0
- package/dist/hooks/use-discount-validator.d.ts.map +1 -0
- package/dist/hooks/use-enquiry.d.ts +7 -0
- package/dist/hooks/use-enquiry.d.ts.map +1 -0
- package/dist/hooks/{useMyOrders.d.ts → use-my-orders.d.ts} +1 -1
- package/dist/hooks/use-my-orders.d.ts.map +1 -0
- package/dist/hooks/use-order.d.ts +17 -0
- package/dist/hooks/use-order.d.ts.map +1 -0
- package/dist/hooks/use-payment-methods.d.ts +19 -0
- package/dist/hooks/use-payment-methods.d.ts.map +1 -0
- package/dist/hooks/use-policies.d.ts +25 -0
- package/dist/hooks/use-policies.d.ts.map +1 -0
- package/dist/hooks/use-product.d.ts +15 -0
- package/dist/hooks/use-product.d.ts.map +1 -0
- package/dist/hooks/{useProducts.d.ts → use-products.d.ts} +1 -1
- package/dist/hooks/use-products.d.ts.map +1 -0
- package/dist/hooks/use-region.d.ts +15 -0
- package/dist/hooks/use-region.d.ts.map +1 -0
- package/dist/hooks/use-shipping.d.ts +29 -0
- package/dist/hooks/use-shipping.d.ts.map +1 -0
- package/dist/hooks/use-storefront-actions.d.ts +12 -0
- package/dist/hooks/use-storefront-actions.d.ts.map +1 -0
- package/dist/hooks/use-storefront-head.d.ts +19 -0
- package/dist/hooks/use-storefront-head.d.ts.map +1 -0
- package/dist/hooks/use-storefront.d.ts +3 -0
- package/dist/hooks/use-storefront.d.ts.map +1 -0
- package/dist/index.d.ts +123 -54
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1311 -5012
- package/dist/index.js.map +1 -1
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/motion.d.ts.map +1 -0
- package/dist/lib/seo.d.ts +26 -0
- package/dist/lib/seo.d.ts.map +1 -0
- package/dist/{testids.d.ts → lib/testids.d.ts} +21 -0
- package/dist/lib/testids.d.ts.map +1 -0
- package/dist/{theme.d.ts → lib/theme.d.ts} +41 -3
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/render.d.ts +5 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +359 -0
- package/dist/render.js.map +1 -0
- package/dist/stores/cart.store.d.ts +6 -2
- package/dist/stores/cart.store.d.ts.map +1 -1
- package/dist/stores/catalog.store.d.ts +11 -0
- package/dist/stores/catalog.store.d.ts.map +1 -1
- package/dist/views/CatalogPage.d.ts.map +1 -0
- package/dist/views/CheckoutPage.d.ts.map +1 -0
- package/dist/views/ContentPage.d.ts +11 -0
- package/dist/views/ContentPage.d.ts.map +1 -0
- package/dist/views/HomePage.d.ts +9 -0
- package/dist/views/HomePage.d.ts.map +1 -0
- package/dist/views/MyPurchasesPage.d.ts.map +1 -0
- package/dist/views/NotFoundPage.d.ts.map +1 -0
- package/dist/{pages → views}/OrderConfirmationPage.d.ts.map +1 -1
- package/dist/{pages → views}/PolicyPage.d.ts.map +1 -1
- package/dist/views/ProductDetailPage.d.ts.map +1 -0
- package/dist/views/StorefrontPage.d.ts +35 -0
- package/dist/views/StorefrontPage.d.ts.map +1 -0
- package/dist/workflows/checkout.d.ts +1 -1
- package/dist/workflows/checkout.d.ts.map +1 -1
- package/package.json +21 -14
- package/dist/auth.d.ts.map +0 -1
- package/dist/blocks.d.ts.map +0 -1
- package/dist/component-contracts.d.ts.map +0 -1
- package/dist/component-selectors.d.ts.map +0 -1
- package/dist/components/CartDrawer.d.ts.map +0 -1
- package/dist/components/CustomerAccountShell.d.ts.map +0 -1
- package/dist/components/DeliveryEstimator.d.ts.map +0 -1
- package/dist/components/FiltersPanel.d.ts +0 -3
- package/dist/components/FiltersPanel.d.ts.map +0 -1
- package/dist/components/OrderTrackingTimeline.d.ts.map +0 -1
- package/dist/components/ProductCard.d.ts +0 -4
- package/dist/components/ProductCard.d.ts.map +0 -1
- package/dist/components/ProductEnquiryForm.d.ts.map +0 -1
- package/dist/components/ProductGallery.d.ts +0 -22
- package/dist/components/ProductGallery.d.ts.map +0 -1
- package/dist/components/ProductGrid.d.ts.map +0 -1
- package/dist/components/ProductOptionSelector.d.ts.map +0 -1
- package/dist/components/ProductSpecs.d.ts.map +0 -1
- package/dist/components/QuantityInput.d.ts.map +0 -1
- package/dist/components/RelatedProducts.d.ts.map +0 -1
- package/dist/components/SignInModal.d.ts.map +0 -1
- package/dist/components/StorefrontErrorBoundary.d.ts.map +0 -1
- package/dist/components/StorefrontFooter.d.ts.map +0 -1
- package/dist/components/StorefrontHeader.d.ts.map +0 -1
- package/dist/components/Toaster.d.ts.map +0 -1
- package/dist/components/sections/CategoryShowcase.d.ts +0 -6
- package/dist/components/sections/CategoryShowcase.d.ts.map +0 -1
- package/dist/components/sections/HeroSection.d.ts +0 -9
- package/dist/components/sections/HeroSection.d.ts.map +0 -1
- package/dist/components/sections/MediaCarousel.d.ts +0 -11
- package/dist/components/sections/MediaCarousel.d.ts.map +0 -1
- package/dist/components/sections/MiscSections.d.ts +0 -33
- package/dist/components/sections/MiscSections.d.ts.map +0 -1
- package/dist/components/sections/ProductRail.d.ts +0 -9
- package/dist/components/sections/ProductRail.d.ts.map +0 -1
- package/dist/components/sections/ProductSlider.d.ts +0 -15
- package/dist/components/sections/ProductSlider.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/createStorefrontApp.d.ts +0 -28
- package/dist/createStorefrontApp.d.ts.map +0 -1
- package/dist/define.d.ts.map +0 -1
- package/dist/format.d.ts.map +0 -1
- package/dist/hooks/useCategories.d.ts +0 -6
- package/dist/hooks/useCategories.d.ts.map +0 -1
- package/dist/hooks/useDiscountValidator.d.ts +0 -14
- package/dist/hooks/useDiscountValidator.d.ts.map +0 -1
- package/dist/hooks/useMyOrders.d.ts.map +0 -1
- package/dist/hooks/useProduct.d.ts +0 -7
- package/dist/hooks/useProduct.d.ts.map +0 -1
- package/dist/hooks/useProducts.d.ts.map +0 -1
- package/dist/hooks/useStorefront.d.ts +0 -35
- package/dist/hooks/useStorefront.d.ts.map +0 -1
- package/dist/hooks/useStorefrontHead.d.ts +0 -11
- package/dist/hooks/useStorefrontHead.d.ts.map +0 -1
- package/dist/motion.d.ts.map +0 -1
- package/dist/order-status.d.ts.map +0 -1
- package/dist/pages/CatalogPage.d.ts.map +0 -1
- package/dist/pages/CheckoutPage.d.ts.map +0 -1
- package/dist/pages/HomePage.d.ts +0 -9
- package/dist/pages/HomePage.d.ts.map +0 -1
- package/dist/pages/MyPurchasesPage.d.ts.map +0 -1
- package/dist/pages/NotFoundPage.d.ts.map +0 -1
- package/dist/pages/ProductDetailPage.d.ts.map +0 -1
- package/dist/presets.d.ts.map +0 -1
- package/dist/product-options.d.ts +0 -12
- package/dist/product-options.d.ts.map +0 -1
- package/dist/router.d.ts.map +0 -1
- package/dist/scaffold.d.ts.map +0 -1
- package/dist/sections.d.ts.map +0 -1
- package/dist/testids.d.ts.map +0 -1
- package/dist/theme.d.ts.map +0 -1
- package/src/auth.ts +0 -227
- package/src/blocks.tsx +0 -51
- package/src/catalog.ts +0 -3
- package/src/component-contracts.ts +0 -154
- package/src/component-selectors.ts +0 -31
- package/src/components/CartDrawer.tsx +0 -279
- package/src/components/CustomerAccountShell.tsx +0 -102
- package/src/components/DeliveryEstimator.tsx +0 -157
- package/src/components/FiltersPanel.tsx +0 -109
- package/src/components/OrderTrackingTimeline.tsx +0 -135
- package/src/components/Price.tsx +0 -32
- package/src/components/ProductCard.tsx +0 -120
- package/src/components/ProductEnquiryForm.tsx +0 -175
- package/src/components/ProductGallery.tsx +0 -174
- package/src/components/ProductGrid.tsx +0 -43
- package/src/components/ProductOptionSelector.tsx +0 -50
- package/src/components/ProductSpecs.tsx +0 -75
- package/src/components/QuantityInput.tsx +0 -52
- package/src/components/RelatedProducts.tsx +0 -40
- package/src/components/SignInModal.tsx +0 -120
- package/src/components/SmoothImage.tsx +0 -59
- package/src/components/StorefrontErrorBoundary.tsx +0 -51
- package/src/components/StorefrontFooter.tsx +0 -110
- package/src/components/StorefrontHeader.tsx +0 -477
- package/src/components/Toaster.tsx +0 -60
- package/src/components/sections/CategoryShowcase.tsx +0 -80
- package/src/components/sections/HeroSection.tsx +0 -193
- package/src/components/sections/MediaCarousel.tsx +0 -141
- package/src/components/sections/MiscSections.tsx +0 -158
- package/src/components/sections/ProductRail.tsx +0 -81
- package/src/components/sections/ProductSlider.tsx +0 -119
- package/src/config.ts +0 -229
- package/src/createStorefrontApp.tsx +0 -247
- package/src/define.ts +0 -34
- package/src/format.ts +0 -7
- package/src/hooks/index.ts +0 -6
- package/src/hooks/useCategories.ts +0 -26
- package/src/hooks/useDiscountValidator.ts +0 -43
- package/src/hooks/useMyOrders.ts +0 -41
- package/src/hooks/useProduct.ts +0 -36
- package/src/hooks/useProducts.ts +0 -39
- package/src/hooks/useStorefront.ts +0 -58
- package/src/hooks/useStorefrontHead.ts +0 -25
- package/src/index.ts +0 -202
- package/src/motion.tsx +0 -94
- package/src/order-status.ts +0 -33
- package/src/pages/CatalogPage.tsx +0 -118
- package/src/pages/CheckoutPage.tsx +0 -689
- package/src/pages/HomePage.tsx +0 -16
- package/src/pages/MyPurchasesPage.tsx +0 -311
- package/src/pages/NotFoundPage.tsx +0 -25
- package/src/pages/OrderConfirmationPage.tsx +0 -190
- package/src/pages/PolicyPage.tsx +0 -47
- package/src/pages/ProductDetailPage.tsx +0 -264
- package/src/presets.ts +0 -324
- package/src/product-options.ts +0 -63
- package/src/router.ts +0 -49
- package/src/scaffold.tsx +0 -115
- package/src/sections.ts +0 -116
- package/src/shop.ts +0 -4
- package/src/stores/cart.store.ts +0 -185
- package/src/stores/catalog.store.ts +0 -39
- package/src/stores/delivery.store.ts +0 -152
- package/src/stores/session.store.ts +0 -28
- package/src/stores/toast.store.ts +0 -43
- package/src/testids.ts +0 -136
- package/src/theme.ts +0 -194
- package/src/ui.ts +0 -5
- package/src/workflows/checkout.ts +0 -119
- /package/dist/components/{CustomerAccountShell.d.ts → account/CustomerAccountShell.d.ts} +0 -0
- /package/dist/components/{SignInModal.d.ts → account/SignInModal.d.ts} +0 -0
- /package/dist/components/{CartDrawer.d.ts → cart/CartDrawer.d.ts} +0 -0
- /package/dist/components/{QuantityInput.d.ts → cart/QuantityInput.d.ts} +0 -0
- /package/dist/components/{DeliveryEstimator.d.ts → checkout/DeliveryEstimator.d.ts} +0 -0
- /package/dist/components/{ProductGrid.d.ts → collection/ProductGrid.d.ts} +0 -0
- /package/dist/components/{StorefrontErrorBoundary.d.ts → layout/StorefrontErrorBoundary.d.ts} +0 -0
- /package/dist/components/{StorefrontFooter.d.ts → layout/StorefrontFooter.d.ts} +0 -0
- /package/dist/components/{StorefrontHeader.d.ts → layout/StorefrontHeader.d.ts} +0 -0
- /package/dist/components/{Toaster.d.ts → layout/Toaster.d.ts} +0 -0
- /package/dist/components/{OrderTrackingTimeline.d.ts → order/OrderTrackingTimeline.d.ts} +0 -0
- /package/dist/components/{ProductEnquiryForm.d.ts → product/ProductEnquiryForm.d.ts} +0 -0
- /package/dist/components/{ProductSpecs.d.ts → product/ProductSpecs.d.ts} +0 -0
- /package/dist/components/{RelatedProducts.d.ts → product/RelatedProducts.d.ts} +0 -0
- /package/dist/{order-status.d.ts → data/order-status.d.ts} +0 -0
- /package/dist/{component-selectors.d.ts → extend/component-selectors.d.ts} +0 -0
- /package/dist/{format.d.ts → lib/format.d.ts} +0 -0
- /package/dist/{motion.d.ts → lib/motion.d.ts} +0 -0
- /package/dist/{pages → views}/CatalogPage.d.ts +0 -0
- /package/dist/{pages → views}/CheckoutPage.d.ts +0 -0
- /package/dist/{pages → views}/MyPurchasesPage.d.ts +0 -0
- /package/dist/{pages → views}/NotFoundPage.d.ts +0 -0
- /package/dist/{pages → views}/OrderConfirmationPage.d.ts +0 -0
- /package/dist/{pages → views}/PolicyPage.d.ts +0 -0
- /package/dist/{pages → views}/ProductDetailPage.d.ts +0 -0
package/src/pages/HomePage.tsx
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { renderBlocks } from '@fayz-ai/core'
|
|
3
|
-
import type { StorefrontSection } from '../sections'
|
|
4
|
-
import { sectionsToBlocks } from '../blocks'
|
|
5
|
-
|
|
6
|
-
// The home page is now a block tree resolved through the universal block
|
|
7
|
-
// registry (see ../blocks). Section components and their props are unchanged;
|
|
8
|
-
// only the dispatch mechanism moved from a switch to the registry, so the same
|
|
9
|
-
// composition works from a pure-data AppManifest.
|
|
10
|
-
export function StorefrontSections({ sections }: { sections: readonly StorefrontSection[] }) {
|
|
11
|
-
return <main>{renderBlocks(sectionsToBlocks(sections))}</main>
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function HomePage({ sections }: { sections: readonly StorefrontSection[] }) {
|
|
15
|
-
return <StorefrontSections sections={sections} />
|
|
16
|
-
}
|
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
2
|
-
import { CreditCard, MapPin, Package, QrCode } from 'lucide-react'
|
|
3
|
-
import { getShopProvider } from '@fayz-ai/shop/runtime'
|
|
4
|
-
import { useSessionStore } from '../stores/session.store'
|
|
5
|
-
import { establishCustomerSession, signUpCustomer } from '../auth'
|
|
6
|
-
import { useMyOrders } from '../hooks/useMyOrders'
|
|
7
|
-
import { useStorefrontConfig } from '../config'
|
|
8
|
-
import { Link } from '../router'
|
|
9
|
-
import { formatMoney } from '../format'
|
|
10
|
-
import { TID } from '../testids'
|
|
11
|
-
import { CustomerAccountShell, type AccountSection } from '../components/CustomerAccountShell'
|
|
12
|
-
import { OrderTrackingTimeline } from '../components/OrderTrackingTimeline'
|
|
13
|
-
import { financialStatusBadge } from '../order-status'
|
|
14
|
-
import { useStorefrontHead } from '../hooks/useStorefrontHead'
|
|
15
|
-
import { SmoothImage } from '../components/SmoothImage'
|
|
16
|
-
|
|
17
|
-
function AuthForm() {
|
|
18
|
-
const [mode, setMode] = useState<'signin' | 'signup'>('signin')
|
|
19
|
-
const [email, setEmail] = useState('')
|
|
20
|
-
const [password, setPassword] = useState('')
|
|
21
|
-
const [name, setName] = useState('')
|
|
22
|
-
const [busy, setBusy] = useState(false)
|
|
23
|
-
const [error, setError] = useState<string | null>(null)
|
|
24
|
-
|
|
25
|
-
async function submit(e: React.FormEvent) {
|
|
26
|
-
e.preventDefault()
|
|
27
|
-
setError(null)
|
|
28
|
-
if (!email.trim() || !password) return
|
|
29
|
-
if (mode === 'signup' && !name.trim()) {
|
|
30
|
-
setError('Informe seu nome.')
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
setBusy(true)
|
|
34
|
-
try {
|
|
35
|
-
if (mode === 'signup') await signUpCustomer(email, password, name.trim())
|
|
36
|
-
else await establishCustomerSession(email, { password })
|
|
37
|
-
} catch (err) {
|
|
38
|
-
setError(err instanceof Error ? err.message : 'Não foi possível entrar. Verifique seus dados.')
|
|
39
|
-
} finally {
|
|
40
|
-
setBusy(false)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const tab = (id: 'signin' | 'signup', label: string, testId: string) => (
|
|
45
|
-
<button
|
|
46
|
-
type="button"
|
|
47
|
-
data-testid={testId}
|
|
48
|
-
onClick={() => {
|
|
49
|
-
setMode(id)
|
|
50
|
-
setError(null)
|
|
51
|
-
}}
|
|
52
|
-
className={`flex-1 border-b-2 pb-2.5 text-sm font-semibold transition-colors ${
|
|
53
|
-
mode === id ? 'border-primary text-primary' : 'border-transparent text-muted-foreground hover:text-foreground'
|
|
54
|
-
}`}
|
|
55
|
-
>
|
|
56
|
-
{label}
|
|
57
|
-
</button>
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<div className="mx-auto max-w-sm animate-fade-up border bg-card p-7" style={{ borderRadius: 'var(--sf-radius-card)' }}>
|
|
62
|
-
<h2 className="sf-heading text-xl font-semibold">Minha conta</h2>
|
|
63
|
-
<p className="mt-1 text-sm text-muted-foreground">
|
|
64
|
-
Acompanhe pedidos e acelere seus próximos checkouts.
|
|
65
|
-
</p>
|
|
66
|
-
<div className="mt-5 flex gap-2">
|
|
67
|
-
{tab('signin', 'Entrar', TID.authTabSignin)}
|
|
68
|
-
{tab('signup', 'Criar conta', TID.authTabSignup)}
|
|
69
|
-
</div>
|
|
70
|
-
<form className="mt-5 space-y-3" onSubmit={submit}>
|
|
71
|
-
{mode === 'signup' && (
|
|
72
|
-
<input
|
|
73
|
-
data-testid={TID.signinName}
|
|
74
|
-
type="text"
|
|
75
|
-
required
|
|
76
|
-
placeholder="Nome completo"
|
|
77
|
-
value={name}
|
|
78
|
-
onChange={(e) => setName(e.target.value)}
|
|
79
|
-
className="w-full border bg-background px-3 py-2.5 text-sm"
|
|
80
|
-
style={{ borderRadius: 'var(--sf-radius-input)' }}
|
|
81
|
-
/>
|
|
82
|
-
)}
|
|
83
|
-
<input
|
|
84
|
-
data-testid={TID.signinEmail}
|
|
85
|
-
type="email"
|
|
86
|
-
required
|
|
87
|
-
placeholder="voce@exemplo.com"
|
|
88
|
-
value={email}
|
|
89
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
90
|
-
className="w-full border bg-background px-3 py-2.5 text-sm"
|
|
91
|
-
style={{ borderRadius: 'var(--sf-radius-input)' }}
|
|
92
|
-
/>
|
|
93
|
-
<input
|
|
94
|
-
data-testid={TID.signinPassword}
|
|
95
|
-
type="password"
|
|
96
|
-
required
|
|
97
|
-
placeholder="Senha"
|
|
98
|
-
value={password}
|
|
99
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
100
|
-
className="w-full border bg-background px-3 py-2.5 text-sm"
|
|
101
|
-
style={{ borderRadius: 'var(--sf-radius-input)' }}
|
|
102
|
-
/>
|
|
103
|
-
{error && (
|
|
104
|
-
<p data-testid={TID.authError} className="text-sm text-destructive">{error}</p>
|
|
105
|
-
)}
|
|
106
|
-
<button
|
|
107
|
-
type="submit"
|
|
108
|
-
data-testid={TID.signinSubmit}
|
|
109
|
-
disabled={busy}
|
|
110
|
-
className="sf-cta w-full bg-primary py-3 font-semibold text-primary-foreground shadow-md transition-all hover:-translate-y-0.5 hover:shadow-lg disabled:opacity-60"
|
|
111
|
-
style={{ borderRadius: 'var(--sf-radius-button)' }}
|
|
112
|
-
>
|
|
113
|
-
{busy ? 'Entrando…' : mode === 'signup' ? 'Criar conta' : 'Entrar'}
|
|
114
|
-
</button>
|
|
115
|
-
</form>
|
|
116
|
-
</div>
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function OrdersPanel() {
|
|
121
|
-
const config = useStorefrontConfig()
|
|
122
|
-
const { orders, loading } = useMyOrders()
|
|
123
|
-
const money = (v: number) => formatMoney(v, config.currency, config.locale)
|
|
124
|
-
|
|
125
|
-
if (loading) return <div className="py-16 text-center text-muted-foreground">Carregando…</div>
|
|
126
|
-
if (orders.length === 0) {
|
|
127
|
-
return (
|
|
128
|
-
<div data-testid={TID.purchasesEmpty} className="rounded-2xl border bg-card py-16 text-center">
|
|
129
|
-
<Package className="mx-auto h-10 w-10 text-muted-foreground" />
|
|
130
|
-
<p className="mt-3 text-muted-foreground">Você ainda não tem pedidos.</p>
|
|
131
|
-
<Link to="/" className="mt-4 inline-block text-primary underline">Explorar a loja</Link>
|
|
132
|
-
</div>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
return (
|
|
136
|
-
<ul data-testid={TID.purchasesList} className="space-y-4">
|
|
137
|
-
{orders.map((order) => (
|
|
138
|
-
<li
|
|
139
|
-
key={order.id}
|
|
140
|
-
data-testid={TID.purchaseItem}
|
|
141
|
-
data-order-number={order.orderNumber}
|
|
142
|
-
className="rounded-2xl border bg-card p-5"
|
|
143
|
-
>
|
|
144
|
-
<div className="flex items-center justify-between">
|
|
145
|
-
<span className="font-semibold">Pedido #{order.orderNumber}</span>
|
|
146
|
-
<span className={`inline-flex rounded-full px-2.5 py-0.5 text-xs font-medium ${financialStatusBadge(order.financialStatus).className}`}>
|
|
147
|
-
{financialStatusBadge(order.financialStatus).label}
|
|
148
|
-
</span>
|
|
149
|
-
</div>
|
|
150
|
-
<p className="mt-0.5 text-xs text-muted-foreground">
|
|
151
|
-
{new Date(order.createdAt).toLocaleDateString(config.locale)}
|
|
152
|
-
</p>
|
|
153
|
-
<div className="mt-4">
|
|
154
|
-
<OrderTrackingTimeline order={order} compact />
|
|
155
|
-
</div>
|
|
156
|
-
<ul className="mt-3 flex flex-wrap gap-2">
|
|
157
|
-
{order.items.map((item) => (
|
|
158
|
-
<li key={item.id} className="flex items-center gap-2 rounded-lg border px-2 py-1 text-xs">
|
|
159
|
-
{item.imageUrl && <SmoothImage src={item.imageUrl} alt={item.name} className="h-6 w-6 rounded object-cover" />}
|
|
160
|
-
{item.name} × {item.quantity}
|
|
161
|
-
</li>
|
|
162
|
-
))}
|
|
163
|
-
</ul>
|
|
164
|
-
<div className="mt-3 flex items-center justify-between border-t pt-3 text-sm">
|
|
165
|
-
<Link to={`/order/${order.id}`} className="font-medium text-primary hover:underline">
|
|
166
|
-
Ver detalhes
|
|
167
|
-
</Link>
|
|
168
|
-
<span>
|
|
169
|
-
<span className="mr-2 text-muted-foreground">Total</span>
|
|
170
|
-
<span className="font-semibold" data-price={order.total.toFixed(2)}>{money(order.total)}</span>
|
|
171
|
-
</span>
|
|
172
|
-
</div>
|
|
173
|
-
</li>
|
|
174
|
-
))}
|
|
175
|
-
</ul>
|
|
176
|
-
)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function ProfilePanel() {
|
|
180
|
-
const session = useSessionStore()
|
|
181
|
-
const [name, setName] = useState(session.name ?? '')
|
|
182
|
-
const [saving, setSaving] = useState(false)
|
|
183
|
-
const [saved, setSaved] = useState(false)
|
|
184
|
-
|
|
185
|
-
async function save(e: React.FormEvent) {
|
|
186
|
-
e.preventDefault()
|
|
187
|
-
const trimmed = name.trim()
|
|
188
|
-
if (!trimmed) return
|
|
189
|
-
setSaving(true)
|
|
190
|
-
setSaved(false)
|
|
191
|
-
try {
|
|
192
|
-
if (session.customerId) {
|
|
193
|
-
const parts = trimmed.split(/\s+/).filter(Boolean)
|
|
194
|
-
await getShopProvider().updateCustomer(session.customerId, {
|
|
195
|
-
firstName: parts[0] ?? trimmed,
|
|
196
|
-
lastName: parts.slice(1).join(' '),
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
useSessionStore.setState({ name: trimmed })
|
|
200
|
-
setSaved(true)
|
|
201
|
-
} finally {
|
|
202
|
-
setSaving(false)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return (
|
|
207
|
-
<form onSubmit={save} className="max-w-md rounded-2xl border bg-card p-6">
|
|
208
|
-
<h2 className="sf-heading text-lg font-semibold">Perfil</h2>
|
|
209
|
-
<p className="mt-1 text-sm text-muted-foreground">Seus dados para os próximos checkouts.</p>
|
|
210
|
-
<label className="mt-5 block text-sm font-medium">
|
|
211
|
-
Nome completo
|
|
212
|
-
<input
|
|
213
|
-
value={name}
|
|
214
|
-
onChange={(e) => { setName(e.target.value); setSaved(false) }}
|
|
215
|
-
className="mt-1 w-full rounded-lg border bg-background px-3 py-2.5 text-sm"
|
|
216
|
-
placeholder="Seu nome"
|
|
217
|
-
/>
|
|
218
|
-
</label>
|
|
219
|
-
<label className="mt-4 block text-sm font-medium">
|
|
220
|
-
E-mail
|
|
221
|
-
<input
|
|
222
|
-
value={session.email ?? ''}
|
|
223
|
-
readOnly
|
|
224
|
-
className="mt-1 w-full cursor-not-allowed rounded-lg border bg-muted/40 px-3 py-2.5 text-sm text-muted-foreground"
|
|
225
|
-
/>
|
|
226
|
-
</label>
|
|
227
|
-
<div className="mt-5 flex items-center gap-3">
|
|
228
|
-
<button
|
|
229
|
-
type="submit"
|
|
230
|
-
disabled={saving}
|
|
231
|
-
className="sf-cta rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground disabled:opacity-60"
|
|
232
|
-
>
|
|
233
|
-
{saving ? 'Salvando…' : 'Salvar'}
|
|
234
|
-
</button>
|
|
235
|
-
{saved && <span className="text-sm font-medium text-emerald-700">Salvo</span>}
|
|
236
|
-
</div>
|
|
237
|
-
</form>
|
|
238
|
-
)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function AddressesPanel() {
|
|
242
|
-
return (
|
|
243
|
-
<div className="rounded-2xl border bg-card p-6">
|
|
244
|
-
<div className="flex items-center gap-2">
|
|
245
|
-
<MapPin className="h-5 w-5 text-primary" />
|
|
246
|
-
<h2 className="sf-heading text-lg font-semibold">Endereços</h2>
|
|
247
|
-
</div>
|
|
248
|
-
<p className="mt-2 text-sm text-muted-foreground">
|
|
249
|
-
Você informa o endereço de entrega no checkout. Em breve será possível salvar endereços para reutilizar
|
|
250
|
-
nas próximas compras.
|
|
251
|
-
</p>
|
|
252
|
-
<Link to="/" className="mt-4 inline-block text-sm font-semibold text-primary underline">
|
|
253
|
-
Continuar comprando
|
|
254
|
-
</Link>
|
|
255
|
-
</div>
|
|
256
|
-
)
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function PaymentsPanel() {
|
|
260
|
-
return (
|
|
261
|
-
<div className="rounded-2xl border bg-card p-6">
|
|
262
|
-
<div className="flex items-center gap-2">
|
|
263
|
-
<CreditCard className="h-5 w-5 text-primary" />
|
|
264
|
-
<h2 className="sf-heading text-lg font-semibold">Pagamentos</h2>
|
|
265
|
-
</div>
|
|
266
|
-
<p className="mt-2 text-sm text-muted-foreground">
|
|
267
|
-
Os pagamentos são processados com segurança no checkout — nenhum dado de pagamento fica salvo nesta conta.
|
|
268
|
-
</p>
|
|
269
|
-
<div className="mt-4 flex items-center gap-2 rounded-lg bg-muted/40 px-3 py-2.5 text-sm">
|
|
270
|
-
<QrCode className="h-4 w-4 text-primary" />
|
|
271
|
-
<span>Pix e cartão via Mercado Pago no momento da compra.</span>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
274
|
-
)
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const SECTION_SUBTITLE: Record<AccountSection, string> = {
|
|
278
|
-
profile: 'Seus dados de contato.',
|
|
279
|
-
orders: 'Acompanhe seus pedidos e entregas.',
|
|
280
|
-
addresses: 'Endereços de entrega.',
|
|
281
|
-
payments: 'Como você paga na loja.',
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export function MyPurchasesPage() {
|
|
285
|
-
const config = useStorefrontConfig()
|
|
286
|
-
const session = useSessionStore()
|
|
287
|
-
const [section, setSection] = useState<AccountSection>('orders')
|
|
288
|
-
useStorefrontHead({ title: `Minha conta — ${config.name}` })
|
|
289
|
-
|
|
290
|
-
if (!session.email) {
|
|
291
|
-
return (
|
|
292
|
-
<main className="mx-auto max-w-3xl px-4 py-12 sm:px-6">
|
|
293
|
-
<AuthForm />
|
|
294
|
-
</main>
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
return (
|
|
299
|
-
<CustomerAccountShell
|
|
300
|
-
title="Minha conta"
|
|
301
|
-
subtitle={SECTION_SUBTITLE[section]}
|
|
302
|
-
active={section}
|
|
303
|
-
onSelect={setSection}
|
|
304
|
-
>
|
|
305
|
-
{section === 'profile' && <ProfilePanel />}
|
|
306
|
-
{section === 'orders' && <OrdersPanel />}
|
|
307
|
-
{section === 'addresses' && <AddressesPanel />}
|
|
308
|
-
{section === 'payments' && <PaymentsPanel />}
|
|
309
|
-
</CustomerAccountShell>
|
|
310
|
-
)
|
|
311
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Link } from '../router'
|
|
3
|
-
import { useStorefrontConfig } from '../config'
|
|
4
|
-
import { useStorefrontHead } from '../hooks/useStorefrontHead'
|
|
5
|
-
|
|
6
|
-
/** Fallback for unknown routes. Previously these silently rendered the home/catalog page with a 200. */
|
|
7
|
-
export function NotFoundPage() {
|
|
8
|
-
const config = useStorefrontConfig()
|
|
9
|
-
useStorefrontHead({ title: `Página não encontrada — ${config.name}` })
|
|
10
|
-
return (
|
|
11
|
-
<main className="mx-auto flex min-h-[60vh] max-w-2xl flex-col items-center justify-center px-4 py-16 text-center">
|
|
12
|
-
<p className="sf-heading text-5xl font-bold tracking-tight text-primary">404</p>
|
|
13
|
-
<h1 className="mt-3 text-xl font-semibold">Página não encontrada</h1>
|
|
14
|
-
<p className="mt-2 text-sm text-muted-foreground">
|
|
15
|
-
O endereço que você tentou acessar não existe ou foi movido.
|
|
16
|
-
</p>
|
|
17
|
-
<Link
|
|
18
|
-
to={config.catalogPath}
|
|
19
|
-
className="mt-6 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition hover:opacity-90"
|
|
20
|
-
>
|
|
21
|
-
Ir para a loja
|
|
22
|
-
</Link>
|
|
23
|
-
</main>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react'
|
|
2
|
-
import { getShopProvider } from '@fayz-ai/shop/runtime'
|
|
3
|
-
import { prefersReducedMotion } from '../motion'
|
|
4
|
-
import type { Order } from '@fayz-ai/shop/types'
|
|
5
|
-
import { useStorefrontConfig } from '../config'
|
|
6
|
-
import { Link } from '../router'
|
|
7
|
-
import { formatMoney } from '../format'
|
|
8
|
-
import { TID } from '../testids'
|
|
9
|
-
import { CustomerAccountShell } from '../components/CustomerAccountShell'
|
|
10
|
-
import { OrderTrackingTimeline } from '../components/OrderTrackingTimeline'
|
|
11
|
-
import { financialStatusBadge } from '../order-status'
|
|
12
|
-
import { useStorefrontHead } from '../hooks/useStorefrontHead'
|
|
13
|
-
import { SmoothImage } from '../components/SmoothImage'
|
|
14
|
-
|
|
15
|
-
const CONFETTI_COLORS = ['hsl(var(--primary))', '#f59e0b', '#10b981', '#3b82f6', '#ec4899']
|
|
16
|
-
|
|
17
|
-
/** One-shot celebration: circle pops in, check draws itself, confetti rains. */
|
|
18
|
-
function SuccessMark() {
|
|
19
|
-
const reduced = prefersReducedMotion()
|
|
20
|
-
return (
|
|
21
|
-
<div className="relative mx-auto h-24 w-24">
|
|
22
|
-
{!reduced &&
|
|
23
|
-
Array.from({ length: 14 }, (_, i) => (
|
|
24
|
-
<span
|
|
25
|
-
key={i}
|
|
26
|
-
aria-hidden
|
|
27
|
-
className="absolute h-2 w-2 animate-confetti-fall rounded-sm"
|
|
28
|
-
style={{
|
|
29
|
-
left: `${(i * 7.3) % 100}%`,
|
|
30
|
-
top: '-4px',
|
|
31
|
-
backgroundColor: CONFETTI_COLORS[i % CONFETTI_COLORS.length],
|
|
32
|
-
animationDelay: `${200 + (i % 7) * 90}ms`,
|
|
33
|
-
}}
|
|
34
|
-
/>
|
|
35
|
-
))}
|
|
36
|
-
<span className={`absolute inset-0 rounded-full bg-emerald-100 ${reduced ? '' : 'animate-pop-in'}`} />
|
|
37
|
-
<svg viewBox="0 0 48 48" className="absolute inset-0 h-full w-full p-6" aria-hidden>
|
|
38
|
-
<path
|
|
39
|
-
d="M10 25 L20 35 L38 14"
|
|
40
|
-
fill="none"
|
|
41
|
-
stroke="rgb(5 150 105)"
|
|
42
|
-
strokeWidth="5"
|
|
43
|
-
strokeLinecap="round"
|
|
44
|
-
strokeLinejoin="round"
|
|
45
|
-
strokeDasharray="48"
|
|
46
|
-
className={reduced ? '' : 'animate-draw-check'}
|
|
47
|
-
/>
|
|
48
|
-
</svg>
|
|
49
|
-
</div>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function OrderConfirmationPage({ orderId }: { orderId: string }) {
|
|
54
|
-
const config = useStorefrontConfig()
|
|
55
|
-
const [order, setOrder] = useState<Order | null>(null)
|
|
56
|
-
const [loading, setLoading] = useState(true)
|
|
57
|
-
const money = (v: number) => formatMoney(v, config.currency, config.locale)
|
|
58
|
-
useStorefrontHead({ title: order ? `Pedido #${order.orderNumber} — ${config.name}` : config.name })
|
|
59
|
-
|
|
60
|
-
useEffect(() => {
|
|
61
|
-
let cancelled = false
|
|
62
|
-
getShopProvider()
|
|
63
|
-
.getOrder(orderId)
|
|
64
|
-
.then((o) => {
|
|
65
|
-
if (!cancelled) setOrder(o)
|
|
66
|
-
})
|
|
67
|
-
.finally(() => {
|
|
68
|
-
if (!cancelled) setLoading(false)
|
|
69
|
-
})
|
|
70
|
-
return () => {
|
|
71
|
-
cancelled = true
|
|
72
|
-
}
|
|
73
|
-
}, [orderId])
|
|
74
|
-
|
|
75
|
-
if (loading) {
|
|
76
|
-
return <main className="mx-auto max-w-2xl px-4 py-20 text-center text-muted-foreground">Carregando…</main>
|
|
77
|
-
}
|
|
78
|
-
if (!order) {
|
|
79
|
-
return (
|
|
80
|
-
<main className="mx-auto max-w-2xl px-4 py-20 text-center">
|
|
81
|
-
<p className="text-muted-foreground">Pedido não encontrado.</p>
|
|
82
|
-
<Link to="/" className="mt-4 inline-block text-primary underline">Voltar à loja</Link>
|
|
83
|
-
</main>
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<CustomerAccountShell
|
|
89
|
-
title="Detalhe do pedido"
|
|
90
|
-
subtitle="Compra confirmada e vinculada à sua conta."
|
|
91
|
-
active="orders"
|
|
92
|
-
>
|
|
93
|
-
<article data-testid={TID.orderDetail} className="animate-fade-up rounded-xl border bg-card p-6 sm:p-8">
|
|
94
|
-
<div className="grid gap-6 border-b pb-6 sm:grid-cols-[120px_minmax(0,1fr)]">
|
|
95
|
-
<SuccessMark />
|
|
96
|
-
<div className="text-center sm:text-left">
|
|
97
|
-
<h2 className="sf-heading text-3xl font-bold tracking-tight">
|
|
98
|
-
Pedido confirmado!
|
|
99
|
-
</h2>
|
|
100
|
-
<p className="mt-1 text-muted-foreground">
|
|
101
|
-
Obrigado pela compra, {order.customerName ?? 'cliente'}. Enviamos a confirmação para {order.customerEmail}.
|
|
102
|
-
</p>
|
|
103
|
-
<p className="mt-4 text-lg">
|
|
104
|
-
Pedido <span data-testid={TID.orderNumber} className="font-semibold">#{order.orderNumber}</span>{' '}
|
|
105
|
-
<span
|
|
106
|
-
data-testid={TID.orderStatus}
|
|
107
|
-
className={`ml-2 inline-flex rounded-full px-2.5 py-0.5 text-sm font-medium ${financialStatusBadge(order.financialStatus).className}`}
|
|
108
|
-
>
|
|
109
|
-
{financialStatusBadge(order.financialStatus).label}
|
|
110
|
-
</span>
|
|
111
|
-
</p>
|
|
112
|
-
</div>
|
|
113
|
-
</div>
|
|
114
|
-
|
|
115
|
-
<div className="mt-6 grid gap-4 rounded-xl border bg-muted/20 p-4 text-sm sm:grid-cols-3">
|
|
116
|
-
<div>
|
|
117
|
-
<p className="text-muted-foreground">Cliente</p>
|
|
118
|
-
<p className="mt-1 font-semibold">{order.customerName ?? 'Cliente'}</p>
|
|
119
|
-
<p className="text-muted-foreground">{order.customerEmail}</p>
|
|
120
|
-
</div>
|
|
121
|
-
<div>
|
|
122
|
-
<p className="text-muted-foreground">Entrega</p>
|
|
123
|
-
<p className="mt-1 font-semibold">{order.fulfillmentStatus === 'fulfilled' ? 'Enviado' : 'Preparando envio'}</p>
|
|
124
|
-
<p className="text-muted-foreground">{order.notes ?? 'Endereço salvo no pedido'}</p>
|
|
125
|
-
</div>
|
|
126
|
-
<div>
|
|
127
|
-
<p className="text-muted-foreground">Pagamento</p>
|
|
128
|
-
<p className="mt-1 font-semibold">{financialStatusBadge(order.financialStatus).label}</p>
|
|
129
|
-
<p className="text-muted-foreground">Processado no checkout</p>
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
132
|
-
|
|
133
|
-
<div className="mt-6">
|
|
134
|
-
<h3 className="mb-3 text-sm font-semibold uppercase text-muted-foreground">
|
|
135
|
-
Acompanhamento
|
|
136
|
-
</h3>
|
|
137
|
-
<OrderTrackingTimeline order={order} />
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
<ul className="mt-8 space-y-3 text-left">
|
|
141
|
-
{order.items.map((item) => (
|
|
142
|
-
<li key={item.id} className="flex items-center gap-3 text-sm">
|
|
143
|
-
{item.imageUrl && <SmoothImage src={item.imageUrl} alt={item.name} className="h-12 w-12 rounded-lg border object-cover" />}
|
|
144
|
-
<span className="flex-1">
|
|
145
|
-
{item.name} <span className="text-muted-foreground">× {item.quantity}</span>
|
|
146
|
-
</span>
|
|
147
|
-
<span data-price={item.total.toFixed(2)}>{money(item.total)}</span>
|
|
148
|
-
</li>
|
|
149
|
-
))}
|
|
150
|
-
</ul>
|
|
151
|
-
|
|
152
|
-
<dl className="mt-4 space-y-1.5 border-t pt-4 text-left text-sm">
|
|
153
|
-
<div className="flex justify-between">
|
|
154
|
-
<dt className="text-muted-foreground">Subtotal</dt>
|
|
155
|
-
<dd data-price={order.subtotal.toFixed(2)}>{money(order.subtotal)}</dd>
|
|
156
|
-
</div>
|
|
157
|
-
{order.discountTotal > 0 && (
|
|
158
|
-
<div className="flex justify-between text-emerald-700">
|
|
159
|
-
<dt>Desconto {order.discountCode ? `(${order.discountCode})` : ''}</dt>
|
|
160
|
-
<dd data-price={order.discountTotal.toFixed(2)}>−{money(order.discountTotal)}</dd>
|
|
161
|
-
</div>
|
|
162
|
-
)}
|
|
163
|
-
<div className="flex justify-between">
|
|
164
|
-
<dt className="text-muted-foreground">Frete</dt>
|
|
165
|
-
<dd data-price={order.shippingTotal.toFixed(2)}>
|
|
166
|
-
{order.shippingTotal === 0 ? 'Grátis' : money(order.shippingTotal)}
|
|
167
|
-
</dd>
|
|
168
|
-
</div>
|
|
169
|
-
<div className="flex justify-between border-t pt-2 text-base font-semibold">
|
|
170
|
-
<dt>Total</dt>
|
|
171
|
-
<dd data-testid={TID.orderTotal} data-price={order.total.toFixed(2)}>{money(order.total)}</dd>
|
|
172
|
-
</div>
|
|
173
|
-
</dl>
|
|
174
|
-
|
|
175
|
-
<div className="mt-8 flex flex-wrap gap-3">
|
|
176
|
-
<Link
|
|
177
|
-
to="/account"
|
|
178
|
-
data-testid={TID.viewPurchases}
|
|
179
|
-
className="rounded-xl bg-primary px-5 py-2.5 font-semibold text-primary-foreground hover:opacity-90"
|
|
180
|
-
>
|
|
181
|
-
Minhas compras
|
|
182
|
-
</Link>
|
|
183
|
-
<Link to="/" className="rounded-xl border px-5 py-2.5 font-semibold hover:bg-muted">
|
|
184
|
-
Continuar comprando
|
|
185
|
-
</Link>
|
|
186
|
-
</div>
|
|
187
|
-
</article>
|
|
188
|
-
</CustomerAccountShell>
|
|
189
|
-
)
|
|
190
|
-
}
|
package/src/pages/PolicyPage.tsx
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Link } from '../router'
|
|
3
|
-
import { useStorefrontConfig } from '../config'
|
|
4
|
-
import { useStorefrontHead } from '../hooks/useStorefrontHead'
|
|
5
|
-
|
|
6
|
-
const TITLES = {
|
|
7
|
-
privacy: 'Política de Privacidade',
|
|
8
|
-
terms: 'Termos de Uso',
|
|
9
|
-
returns: 'Trocas e Devoluções',
|
|
10
|
-
} as const
|
|
11
|
-
|
|
12
|
-
export type PolicyKind = keyof typeof TITLES
|
|
13
|
-
|
|
14
|
-
/** Institutional/legal pages. Content comes from config.legal; absent pages show
|
|
15
|
-
* a placeholder so the routes + footer links exist (no 404) before the store
|
|
16
|
-
* publishes its policy — a payment-processor / go-live requirement. */
|
|
17
|
-
export function PolicyPage({ kind }: { kind: PolicyKind }) {
|
|
18
|
-
const config = useStorefrontConfig()
|
|
19
|
-
const title = TITLES[kind]
|
|
20
|
-
const content = config.legal?.[kind]
|
|
21
|
-
const email = config.footer?.contact?.email
|
|
22
|
-
useStorefrontHead({ title: `${title} — ${config.name}` })
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<main className="mx-auto max-w-3xl px-4 py-12 sm:px-6">
|
|
26
|
-
<Link to={config.catalogPath} className="text-sm text-muted-foreground transition-colors hover:text-foreground">
|
|
27
|
-
← Voltar à loja
|
|
28
|
-
</Link>
|
|
29
|
-
<h1 className="sf-heading mt-4 text-3xl font-bold tracking-tight">{title}</h1>
|
|
30
|
-
<div className="mt-6 space-y-4 leading-relaxed text-muted-foreground">
|
|
31
|
-
{content ? (
|
|
32
|
-
content.split('\n').filter((line) => line.trim()).map((paragraph, i) => <p key={i}>{paragraph}</p>)
|
|
33
|
-
) : (
|
|
34
|
-
<>
|
|
35
|
-
<p>O conteúdo desta política ainda será publicado pela loja.</p>
|
|
36
|
-
{email && (
|
|
37
|
-
<p>
|
|
38
|
-
Em caso de dúvidas, fale com a gente em{' '}
|
|
39
|
-
<a href={`mailto:${email}`} className="text-primary underline">{email}</a>.
|
|
40
|
-
</p>
|
|
41
|
-
)}
|
|
42
|
-
</>
|
|
43
|
-
)}
|
|
44
|
-
</div>
|
|
45
|
-
</main>
|
|
46
|
-
)
|
|
47
|
-
}
|