@cimplify/sdk 0.40.1 → 0.42.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/dist/cli/commands/deploy.mjs +561 -0
- package/dist/cli/commands/dev.mjs +434 -0
- package/dist/cli/commands/domains.mjs +479 -0
- package/dist/cli/commands/env.mjs +610 -0
- package/dist/cli/commands/link.mjs +325 -0
- package/dist/cli/commands/login.mjs +515 -0
- package/dist/cli/commands/logout.mjs +54 -0
- package/dist/cli/commands/logs.mjs +358 -0
- package/dist/cli/commands/projects.mjs +327 -0
- package/dist/cli/commands/rollback.mjs +477 -0
- package/dist/cli/commands/status.mjs +380 -0
- package/dist/cli/commands/unlink.mjs +58 -0
- package/dist/cli/commands/whoami.mjs +234 -0
- package/dist/dispatcher.mjs +94 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/templates/storefront-bakery/.env.example +5 -0
- package/templates/storefront-bakery/AGENTS.md +57 -0
- package/templates/storefront-bakery/app/about/page.tsx +21 -44
- package/templates/storefront-bakery/app/accessibility/page.tsx +11 -0
- package/templates/storefront-bakery/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-bakery/app/account/orders/page.tsx +21 -0
- package/templates/storefront-bakery/app/account/page.tsx +22 -0
- package/templates/storefront-bakery/app/account/settings/page.tsx +21 -0
- package/templates/storefront-bakery/app/categories/[slug]/page.tsx +2 -1
- package/templates/storefront-bakery/app/collections/[slug]/page.tsx +2 -1
- package/templates/storefront-bakery/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-bakery/app/contact/page.tsx +54 -0
- package/templates/storefront-bakery/app/error.tsx +60 -0
- package/templates/storefront-bakery/app/faq/page.tsx +13 -89
- package/templates/storefront-bakery/app/layout.tsx +37 -2
- package/templates/storefront-bakery/app/llms.txt/route.ts +94 -0
- package/templates/storefront-bakery/app/login/page.tsx +17 -0
- package/templates/storefront-bakery/app/not-found.tsx +39 -0
- package/templates/storefront-bakery/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-bakery/app/page.tsx +6 -6
- package/templates/storefront-bakery/app/privacy/page.tsx +24 -68
- package/templates/storefront-bakery/app/returns/page.tsx +11 -0
- package/templates/storefront-bakery/app/robots.ts +18 -0
- package/templates/storefront-bakery/app/search/page.tsx +38 -0
- package/templates/storefront-bakery/app/search/search-client.tsx +7 -0
- package/templates/storefront-bakery/app/shipping/page.tsx +16 -0
- package/templates/storefront-bakery/app/shop/page.tsx +3 -2
- package/templates/storefront-bakery/app/signup/page.tsx +17 -0
- package/templates/storefront-bakery/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-bakery/app/sitemap.ts +62 -0
- package/templates/storefront-bakery/app/terms/page.tsx +24 -82
- package/templates/storefront-bakery/app/track-order/page.tsx +24 -0
- package/templates/storefront-bakery/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-bakery/components/account-iframe.tsx +13 -0
- package/templates/storefront-bakery/components/footer.tsx +88 -130
- package/templates/storefront-bakery/components/header.tsx +8 -16
- package/templates/storefront-bakery/components/policy-page.tsx +49 -0
- package/templates/storefront-bakery/lib/brand.ts +568 -0
- package/templates/storefront-fashion/.env.example +16 -0
- package/templates/storefront-fashion/AGENTS.md +52 -0
- package/templates/storefront-fashion/README.md +77 -0
- package/templates/storefront-fashion/app/about/page.tsx +41 -0
- package/templates/storefront-fashion/app/accessibility/page.tsx +11 -0
- package/templates/storefront-fashion/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-fashion/app/account/orders/page.tsx +21 -0
- package/templates/storefront-fashion/app/account/page.tsx +22 -0
- package/templates/storefront-fashion/app/account/settings/page.tsx +21 -0
- package/templates/storefront-fashion/app/cart/page.tsx +9 -0
- package/templates/storefront-fashion/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-fashion/app/categories/[slug]/page.tsx +130 -0
- package/templates/storefront-fashion/app/checkout/page.tsx +17 -0
- package/templates/storefront-fashion/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-fashion/app/collections/[slug]/page.tsx +130 -0
- package/templates/storefront-fashion/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-fashion/app/contact/page.tsx +54 -0
- package/templates/storefront-fashion/app/error.tsx +61 -0
- package/templates/storefront-fashion/app/faq/page.tsx +46 -0
- package/templates/storefront-fashion/app/globals.css +46 -0
- package/templates/storefront-fashion/app/layout.tsx +76 -0
- package/templates/storefront-fashion/app/llms.txt/route.ts +94 -0
- package/templates/storefront-fashion/app/login/page.tsx +17 -0
- package/templates/storefront-fashion/app/lookbook/page.tsx +132 -0
- package/templates/storefront-fashion/app/not-found.tsx +39 -0
- package/templates/storefront-fashion/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-fashion/app/orders/[id]/page.tsx +24 -0
- package/templates/storefront-fashion/app/page.tsx +183 -0
- package/templates/storefront-fashion/app/privacy/page.tsx +44 -0
- package/templates/storefront-fashion/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-fashion/app/products/[slug]/product-detail.tsx +71 -0
- package/templates/storefront-fashion/app/returns/page.tsx +11 -0
- package/templates/storefront-fashion/app/robots.ts +18 -0
- package/templates/storefront-fashion/app/search/page.tsx +38 -0
- package/templates/storefront-fashion/app/search/search-client.tsx +7 -0
- package/templates/storefront-fashion/app/shipping/page.tsx +16 -0
- package/templates/storefront-fashion/app/shop/page.tsx +63 -0
- package/templates/storefront-fashion/app/shop/shop-client.tsx +32 -0
- package/templates/storefront-fashion/app/signup/page.tsx +17 -0
- package/templates/storefront-fashion/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-fashion/app/sitemap.ts +59 -0
- package/templates/storefront-fashion/app/size-guide/page.tsx +155 -0
- package/templates/storefront-fashion/app/terms/page.tsx +44 -0
- package/templates/storefront-fashion/app/track-order/page.tsx +24 -0
- package/templates/storefront-fashion/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-fashion/components/account-iframe.tsx +13 -0
- package/templates/storefront-fashion/components/brand-marquee.tsx +27 -0
- package/templates/storefront-fashion/components/cart-pill.tsx +32 -0
- package/templates/storefront-fashion/components/category-grid.tsx +28 -0
- package/templates/storefront-fashion/components/category-tiles.tsx +104 -0
- package/templates/storefront-fashion/components/collection-strip.tsx +45 -0
- package/templates/storefront-fashion/components/feature-hero.tsx +82 -0
- package/templates/storefront-fashion/components/footer.tsx +153 -0
- package/templates/storefront-fashion/components/header.tsx +43 -0
- package/templates/storefront-fashion/components/hero.tsx +28 -0
- package/templates/storefront-fashion/components/nav-link.tsx +20 -0
- package/templates/storefront-fashion/components/newsletter.tsx +50 -0
- package/templates/storefront-fashion/components/policy-page.tsx +49 -0
- package/templates/storefront-fashion/components/promo-banner.tsx +41 -0
- package/templates/storefront-fashion/components/providers.tsx +31 -0
- package/templates/storefront-fashion/components/section-heading.tsx +37 -0
- package/templates/storefront-fashion/components/store-product-card.tsx +83 -0
- package/templates/storefront-fashion/components/trade-in-cta.tsx +54 -0
- package/templates/storefront-fashion/components/trust-bar.tsx +66 -0
- package/templates/storefront-fashion/lib/brand.ts +516 -0
- package/templates/storefront-fashion/lib/cart.ts +27 -0
- package/templates/storefront-fashion/next.config.ts +40 -0
- package/templates/storefront-fashion/package.json +28 -0
- package/templates/storefront-fashion/postcss.config.mjs +7 -0
- package/templates/storefront-fashion/tsconfig.json +23 -0
- package/templates/storefront-grocery/.env.example +16 -0
- package/templates/storefront-grocery/AGENTS.md +39 -0
- package/templates/storefront-grocery/README.md +73 -0
- package/templates/storefront-grocery/app/about/page.tsx +38 -0
- package/templates/storefront-grocery/app/accessibility/page.tsx +11 -0
- package/templates/storefront-grocery/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-grocery/app/account/orders/page.tsx +21 -0
- package/templates/storefront-grocery/app/account/page.tsx +22 -0
- package/templates/storefront-grocery/app/account/settings/page.tsx +21 -0
- package/templates/storefront-grocery/app/cart/page.tsx +9 -0
- package/templates/storefront-grocery/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-grocery/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-grocery/app/checkout/page.tsx +17 -0
- package/templates/storefront-grocery/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-grocery/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-grocery/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-grocery/app/contact/page.tsx +54 -0
- package/templates/storefront-grocery/app/error.tsx +60 -0
- package/templates/storefront-grocery/app/faq/page.tsx +46 -0
- package/templates/storefront-grocery/app/globals.css +45 -0
- package/templates/storefront-grocery/app/layout.tsx +75 -0
- package/templates/storefront-grocery/app/llms.txt/route.ts +94 -0
- package/templates/storefront-grocery/app/login/page.tsx +17 -0
- package/templates/storefront-grocery/app/not-found.tsx +39 -0
- package/templates/storefront-grocery/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-grocery/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-grocery/app/page.tsx +97 -0
- package/templates/storefront-grocery/app/privacy/page.tsx +44 -0
- package/templates/storefront-grocery/app/returns/page.tsx +11 -0
- package/templates/storefront-grocery/app/robots.ts +18 -0
- package/templates/storefront-grocery/app/search/page.tsx +38 -0
- package/templates/storefront-grocery/app/search/search-client.tsx +7 -0
- package/templates/storefront-grocery/app/shipping/page.tsx +16 -0
- package/templates/storefront-grocery/app/shop/page.tsx +31 -0
- package/templates/storefront-grocery/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-grocery/app/signup/page.tsx +17 -0
- package/templates/storefront-grocery/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-grocery/app/sitemap.ts +62 -0
- package/templates/storefront-grocery/app/terms/page.tsx +44 -0
- package/templates/storefront-grocery/app/track-order/page.tsx +24 -0
- package/templates/storefront-grocery/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-grocery/components/account-iframe.tsx +13 -0
- package/templates/storefront-grocery/components/cart-pill.tsx +32 -0
- package/templates/storefront-grocery/components/category-grid.tsx +28 -0
- package/templates/storefront-grocery/components/collection-strip.tsx +45 -0
- package/templates/storefront-grocery/components/footer.tsx +148 -0
- package/templates/storefront-grocery/components/header.tsx +43 -0
- package/templates/storefront-grocery/components/hero.tsx +25 -0
- package/templates/storefront-grocery/components/nav-link.tsx +20 -0
- package/templates/storefront-grocery/components/policy-page.tsx +49 -0
- package/templates/storefront-grocery/components/providers.tsx +31 -0
- package/templates/storefront-grocery/components/store-product-card.tsx +83 -0
- package/templates/storefront-grocery/lib/brand.ts +373 -0
- package/templates/storefront-grocery/lib/cart.ts +27 -0
- package/templates/storefront-grocery/next.config.ts +40 -0
- package/templates/storefront-grocery/package.json +28 -0
- package/templates/storefront-grocery/postcss.config.mjs +7 -0
- package/templates/storefront-grocery/tsconfig.json +23 -0
- package/templates/storefront-restaurant/.env.example +16 -0
- package/templates/storefront-restaurant/AGENTS.md +39 -0
- package/templates/storefront-restaurant/README.md +73 -0
- package/templates/storefront-restaurant/app/about/page.tsx +38 -0
- package/templates/storefront-restaurant/app/accessibility/page.tsx +11 -0
- package/templates/storefront-restaurant/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-restaurant/app/account/orders/page.tsx +21 -0
- package/templates/storefront-restaurant/app/account/page.tsx +22 -0
- package/templates/storefront-restaurant/app/account/settings/page.tsx +21 -0
- package/templates/storefront-restaurant/app/cart/page.tsx +9 -0
- package/templates/storefront-restaurant/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-restaurant/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-restaurant/app/checkout/page.tsx +17 -0
- package/templates/storefront-restaurant/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-restaurant/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-restaurant/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-restaurant/app/contact/page.tsx +54 -0
- package/templates/storefront-restaurant/app/error.tsx +60 -0
- package/templates/storefront-restaurant/app/faq/page.tsx +46 -0
- package/templates/storefront-restaurant/app/globals.css +44 -0
- package/templates/storefront-restaurant/app/layout.tsx +80 -0
- package/templates/storefront-restaurant/app/llms.txt/route.ts +94 -0
- package/templates/storefront-restaurant/app/login/page.tsx +17 -0
- package/templates/storefront-restaurant/app/not-found.tsx +39 -0
- package/templates/storefront-restaurant/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-restaurant/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-restaurant/app/page.tsx +97 -0
- package/templates/storefront-restaurant/app/privacy/page.tsx +44 -0
- package/templates/storefront-restaurant/app/reservations/page.tsx +66 -0
- package/templates/storefront-restaurant/app/reservations/reservations-client.tsx +234 -0
- package/templates/storefront-restaurant/app/returns/page.tsx +11 -0
- package/templates/storefront-restaurant/app/robots.ts +18 -0
- package/templates/storefront-restaurant/app/search/page.tsx +38 -0
- package/templates/storefront-restaurant/app/search/search-client.tsx +7 -0
- package/templates/storefront-restaurant/app/shipping/page.tsx +16 -0
- package/templates/storefront-restaurant/app/shop/page.tsx +31 -0
- package/templates/storefront-restaurant/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-restaurant/app/signup/page.tsx +17 -0
- package/templates/storefront-restaurant/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-restaurant/app/sitemap.ts +62 -0
- package/templates/storefront-restaurant/app/terms/page.tsx +44 -0
- package/templates/storefront-restaurant/app/track-order/page.tsx +24 -0
- package/templates/storefront-restaurant/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-restaurant/components/account-iframe.tsx +13 -0
- package/templates/storefront-restaurant/components/cart-pill.tsx +32 -0
- package/templates/storefront-restaurant/components/category-grid.tsx +28 -0
- package/templates/storefront-restaurant/components/collection-strip.tsx +45 -0
- package/templates/storefront-restaurant/components/footer.tsx +148 -0
- package/templates/storefront-restaurant/components/header.tsx +43 -0
- package/templates/storefront-restaurant/components/hero.tsx +25 -0
- package/templates/storefront-restaurant/components/nav-link.tsx +20 -0
- package/templates/storefront-restaurant/components/policy-page.tsx +49 -0
- package/templates/storefront-restaurant/components/product-modal.tsx +105 -0
- package/templates/storefront-restaurant/components/providers.tsx +31 -0
- package/templates/storefront-restaurant/components/store-product-card.tsx +83 -0
- package/templates/storefront-restaurant/lib/brand.ts +375 -0
- package/templates/storefront-restaurant/lib/cart.ts +27 -0
- package/templates/storefront-restaurant/next.config.ts +40 -0
- package/templates/storefront-restaurant/package.json +28 -0
- package/templates/storefront-restaurant/postcss.config.mjs +7 -0
- package/templates/storefront-restaurant/tsconfig.json +23 -0
- package/templates/storefront-retail/.env.example +5 -0
- package/templates/storefront-retail/AGENTS.md +64 -0
- package/templates/storefront-retail/app/about/page.tsx +24 -54
- package/templates/storefront-retail/app/accessibility/page.tsx +11 -0
- package/templates/storefront-retail/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-retail/app/account/orders/page.tsx +21 -0
- package/templates/storefront-retail/app/account/page.tsx +22 -0
- package/templates/storefront-retail/app/account/settings/page.tsx +21 -0
- package/templates/storefront-retail/app/categories/[slug]/page.tsx +2 -1
- package/templates/storefront-retail/app/collections/[slug]/page.tsx +2 -1
- package/templates/storefront-retail/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-retail/app/contact/page.tsx +54 -0
- package/templates/storefront-retail/app/error.tsx +61 -0
- package/templates/storefront-retail/app/faq/page.tsx +11 -92
- package/templates/storefront-retail/app/layout.tsx +37 -8
- package/templates/storefront-retail/app/llms.txt/route.ts +94 -0
- package/templates/storefront-retail/app/login/page.tsx +17 -0
- package/templates/storefront-retail/app/not-found.tsx +39 -0
- package/templates/storefront-retail/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-retail/app/page.tsx +16 -73
- package/templates/storefront-retail/app/privacy/page.tsx +24 -81
- package/templates/storefront-retail/app/products/[slug]/page.tsx +165 -0
- package/templates/storefront-retail/app/products/[slug]/product-detail.tsx +71 -0
- package/templates/storefront-retail/app/returns/page.tsx +11 -0
- package/templates/storefront-retail/app/robots.ts +18 -0
- package/templates/storefront-retail/app/search/page.tsx +38 -0
- package/templates/storefront-retail/app/search/search-client.tsx +7 -0
- package/templates/storefront-retail/app/shipping/page.tsx +16 -0
- package/templates/storefront-retail/app/shop/page.tsx +3 -3
- package/templates/storefront-retail/app/signup/page.tsx +17 -0
- package/templates/storefront-retail/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-retail/app/sitemap.ts +59 -0
- package/templates/storefront-retail/app/terms/page.tsx +24 -97
- package/templates/storefront-retail/app/track-order/page.tsx +24 -0
- package/templates/storefront-retail/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-retail/components/account-iframe.tsx +13 -0
- package/templates/storefront-retail/components/brand-marquee.tsx +6 -15
- package/templates/storefront-retail/components/feature-hero.tsx +2 -1
- package/templates/storefront-retail/components/footer.tsx +85 -120
- package/templates/storefront-retail/components/header.tsx +10 -12
- package/templates/storefront-retail/components/newsletter.tsx +7 -9
- package/templates/storefront-retail/components/policy-page.tsx +49 -0
- package/templates/storefront-retail/components/promo-banner.tsx +12 -15
- package/templates/storefront-retail/components/store-product-card.tsx +7 -7
- package/templates/storefront-retail/components/trade-in-cta.tsx +11 -17
- package/templates/storefront-retail/components/trust-bar.tsx +45 -5
- package/templates/storefront-retail/lib/brand.ts +663 -0
- package/templates/storefront-services/.env.example +16 -0
- package/templates/storefront-services/AGENTS.md +41 -0
- package/templates/storefront-services/README.md +73 -0
- package/templates/storefront-services/app/about/page.tsx +38 -0
- package/templates/storefront-services/app/accessibility/page.tsx +11 -0
- package/templates/storefront-services/app/account/addresses/page.tsx +21 -0
- package/templates/storefront-services/app/account/orders/page.tsx +21 -0
- package/templates/storefront-services/app/account/page.tsx +22 -0
- package/templates/storefront-services/app/account/settings/page.tsx +21 -0
- package/templates/storefront-services/app/book/book-client.tsx +195 -0
- package/templates/storefront-services/app/book/page.tsx +65 -0
- package/templates/storefront-services/app/cart/page.tsx +9 -0
- package/templates/storefront-services/app/categories/[slug]/listing-client.tsx +19 -0
- package/templates/storefront-services/app/categories/[slug]/page.tsx +118 -0
- package/templates/storefront-services/app/checkout/page.tsx +17 -0
- package/templates/storefront-services/app/collections/[slug]/listing-client.tsx +20 -0
- package/templates/storefront-services/app/collections/[slug]/page.tsx +118 -0
- package/templates/storefront-services/app/contact/contact-form.tsx +109 -0
- package/templates/storefront-services/app/contact/page.tsx +54 -0
- package/templates/storefront-services/app/error.tsx +60 -0
- package/templates/storefront-services/app/faq/page.tsx +46 -0
- package/templates/storefront-services/app/globals.css +45 -0
- package/templates/storefront-services/app/layout.tsx +80 -0
- package/templates/storefront-services/app/llms.txt/route.ts +94 -0
- package/templates/storefront-services/app/login/page.tsx +17 -0
- package/templates/storefront-services/app/not-found.tsx +39 -0
- package/templates/storefront-services/app/opensearch.xml/route.ts +37 -0
- package/templates/storefront-services/app/orders/[id]/page.tsx +21 -0
- package/templates/storefront-services/app/page.tsx +97 -0
- package/templates/storefront-services/app/privacy/page.tsx +44 -0
- package/templates/storefront-services/app/returns/page.tsx +11 -0
- package/templates/storefront-services/app/robots.ts +18 -0
- package/templates/storefront-services/app/search/page.tsx +38 -0
- package/templates/storefront-services/app/search/search-client.tsx +7 -0
- package/templates/storefront-services/app/shipping/page.tsx +16 -0
- package/templates/storefront-services/app/shop/page.tsx +31 -0
- package/templates/storefront-services/app/shop/shop-client.tsx +27 -0
- package/templates/storefront-services/app/signup/page.tsx +17 -0
- package/templates/storefront-services/app/sitemap-page/page.tsx +167 -0
- package/templates/storefront-services/app/sitemap.ts +62 -0
- package/templates/storefront-services/app/terms/page.tsx +44 -0
- package/templates/storefront-services/app/track-order/page.tsx +24 -0
- package/templates/storefront-services/app/track-order/track-order-form.tsx +69 -0
- package/templates/storefront-services/components/account-iframe.tsx +13 -0
- package/templates/storefront-services/components/cart-pill.tsx +32 -0
- package/templates/storefront-services/components/category-grid.tsx +28 -0
- package/templates/storefront-services/components/collection-strip.tsx +45 -0
- package/templates/storefront-services/components/footer.tsx +148 -0
- package/templates/storefront-services/components/header.tsx +43 -0
- package/templates/storefront-services/components/hero.tsx +25 -0
- package/templates/storefront-services/components/nav-link.tsx +20 -0
- package/templates/storefront-services/components/policy-page.tsx +49 -0
- package/templates/storefront-services/components/product-modal.tsx +105 -0
- package/templates/storefront-services/components/providers.tsx +31 -0
- package/templates/storefront-services/components/store-product-card.tsx +83 -0
- package/templates/storefront-services/lib/brand.ts +394 -0
- package/templates/storefront-services/lib/cart.ts +27 -0
- package/templates/storefront-services/next.config.ts +40 -0
- package/templates/storefront-services/package.json +28 -0
- package/templates/storefront-services/postcss.config.mjs +7 -0
- package/templates/storefront-services/tsconfig.json +23 -0
- /package/templates/{storefront-retail → storefront-grocery}/components/product-modal.tsx +0 -0
|
@@ -1,70 +1,40 @@
|
|
|
1
1
|
import type { Metadata } from "next";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
2
3
|
|
|
3
4
|
export const metadata: Metadata = {
|
|
4
|
-
title:
|
|
5
|
-
description:
|
|
6
|
-
"Authorised dealer for Apple, Samsung, Sony, Bose. Serving Accra and West Africa with same-day delivery and a two-year warranty since 2017.",
|
|
5
|
+
title: `About — ${brand.name}`,
|
|
6
|
+
description: brand.description,
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export default function AboutPage() {
|
|
10
|
+
const a = brand.about;
|
|
11
|
+
// Title supports a single \n for a hard line break.
|
|
12
|
+
const titleParts = a.title.split("\n");
|
|
10
13
|
return (
|
|
11
14
|
<article className="max-w-3xl mx-auto px-8 py-16">
|
|
12
15
|
<p className="text-[11px] font-mono uppercase tracking-[0.16em] text-primary mb-2">
|
|
13
|
-
|
|
16
|
+
{a.eyebrow}
|
|
14
17
|
</p>
|
|
15
18
|
<h1 className="text-[clamp(2.25rem,5vw,3.5rem)] font-bold mb-6 -tracking-[0.025em] leading-tight">
|
|
16
|
-
|
|
19
|
+
{titleParts.map((line, i) => (
|
|
20
|
+
<span key={i}>
|
|
21
|
+
{line}
|
|
22
|
+
{i < titleParts.length - 1 && <br />}
|
|
23
|
+
</span>
|
|
24
|
+
))}
|
|
17
25
|
</h1>
|
|
18
26
|
<div className="prose prose-lg max-w-none space-y-5 text-foreground/90 leading-relaxed">
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
no refurbished-as-new, no "dual SIM Asia spec" on a US iPhone.
|
|
31
|
-
What you order is what we open in front of you on delivery.
|
|
32
|
-
</p>
|
|
33
|
-
<p>
|
|
34
|
-
We back everything with a two-year warranty (one year manufacturer +
|
|
35
|
-
one year Currents), free same-day Accra delivery, and a 14-day
|
|
36
|
-
no-questions-asked return on anything sealed.
|
|
37
|
-
</p>
|
|
38
|
-
|
|
39
|
-
<h2 className="text-2xl font-semibold mt-10 mb-3 -tracking-[0.02em]">
|
|
40
|
-
Trade-in
|
|
41
|
-
</h2>
|
|
42
|
-
<p>
|
|
43
|
-
Got an iPhone, Galaxy, or MacBook you no longer use? Bring it in or
|
|
44
|
-
ship it to us — we'll quote you within 48 hours and credit the
|
|
45
|
-
value toward your next purchase. We work with refurbishers across the
|
|
46
|
-
continent so your old kit stays in service for years more.
|
|
47
|
-
</p>
|
|
48
|
-
|
|
49
|
-
<h2 className="text-2xl font-semibold mt-10 mb-3 -tracking-[0.02em]">
|
|
50
|
-
Business sales
|
|
51
|
-
</h2>
|
|
52
|
-
<p>
|
|
53
|
-
Equipping a team or kitting out a co-working space? We do volume
|
|
54
|
-
quotes, delivery scheduling, asset tagging, and on-site setup. Email{" "}
|
|
55
|
-
<a
|
|
56
|
-
href="mailto:business@currentselectronics.test"
|
|
57
|
-
className="text-primary font-semibold hover:underline"
|
|
58
|
-
>
|
|
59
|
-
business@currentselectronics.test
|
|
60
|
-
</a>
|
|
61
|
-
.
|
|
62
|
-
</p>
|
|
63
|
-
|
|
64
|
-
<h2 className="text-2xl font-semibold mt-10 mb-3 -tracking-[0.02em]">
|
|
65
|
-
Visit
|
|
66
|
-
</h2>
|
|
67
|
-
<p>Atomic Junction, East Legon, Accra · Mon–Sat, 9am–8pm.</p>
|
|
27
|
+
{a.paragraphs.map((p, i) => (
|
|
28
|
+
<p key={i}>{p}</p>
|
|
29
|
+
))}
|
|
30
|
+
{a.sections.map((s) => (
|
|
31
|
+
<div key={s.heading}>
|
|
32
|
+
<h2 className="text-2xl font-semibold mt-10 mb-3 -tracking-[0.02em]">
|
|
33
|
+
{s.heading}
|
|
34
|
+
</h2>
|
|
35
|
+
<p>{s.body}</p>
|
|
36
|
+
</div>
|
|
37
|
+
))}
|
|
68
38
|
</div>
|
|
69
39
|
</article>
|
|
70
40
|
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
3
|
+
import { PolicyPage } from "@/components/policy-page";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `${brand.accessibility.title} — ${brand.name}`,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function AccessibilityPage() {
|
|
10
|
+
return <PolicyPage policy={brand.accessibility} />;
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { AccountIframe } from "@/components/account-iframe";
|
|
3
|
+
import { brand } from "@/lib/brand";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `Addresses — ${brand.name}`,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function AddressesPage() {
|
|
10
|
+
return (
|
|
11
|
+
<article className="max-w-5xl mx-auto px-6 sm:px-8 py-12">
|
|
12
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
13
|
+
Account
|
|
14
|
+
</p>
|
|
15
|
+
<h1 className="font-serif text-[clamp(2rem,4vw,2.75rem)] font-semibold mb-8 -tracking-[0.02em]">
|
|
16
|
+
Your addresses
|
|
17
|
+
</h1>
|
|
18
|
+
<AccountIframe section="addresses" />
|
|
19
|
+
</article>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { AccountIframe } from "@/components/account-iframe";
|
|
3
|
+
import { brand } from "@/lib/brand";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `Orders — ${brand.name}`,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function OrdersPage() {
|
|
10
|
+
return (
|
|
11
|
+
<article className="max-w-5xl mx-auto px-6 sm:px-8 py-12">
|
|
12
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
13
|
+
Account
|
|
14
|
+
</p>
|
|
15
|
+
<h1 className="font-serif text-[clamp(2rem,4vw,2.75rem)] font-semibold mb-8 -tracking-[0.02em]">
|
|
16
|
+
Your orders
|
|
17
|
+
</h1>
|
|
18
|
+
<AccountIframe section="orders" />
|
|
19
|
+
</article>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { AccountIframe } from "@/components/account-iframe";
|
|
3
|
+
import { brand } from "@/lib/brand";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `Account — ${brand.name}`,
|
|
7
|
+
description: brand.account.signupSubtitle,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function AccountPage() {
|
|
11
|
+
return (
|
|
12
|
+
<article className="max-w-5xl mx-auto px-6 sm:px-8 py-12">
|
|
13
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
14
|
+
{brand.account.accountEyebrow}
|
|
15
|
+
</p>
|
|
16
|
+
<h1 className="font-serif text-[clamp(2rem,4vw,2.75rem)] font-semibold mb-8 -tracking-[0.02em]">
|
|
17
|
+
{brand.account.accountTitle}
|
|
18
|
+
</h1>
|
|
19
|
+
<AccountIframe />
|
|
20
|
+
</article>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { AccountIframe } from "@/components/account-iframe";
|
|
3
|
+
import { brand } from "@/lib/brand";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `Settings — ${brand.name}`,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function SettingsPage() {
|
|
10
|
+
return (
|
|
11
|
+
<article className="max-w-5xl mx-auto px-6 sm:px-8 py-12">
|
|
12
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
13
|
+
Account
|
|
14
|
+
</p>
|
|
15
|
+
<h1 className="font-serif text-[clamp(2rem,4vw,2.75rem)] font-semibold mb-8 -tracking-[0.02em]">
|
|
16
|
+
Settings
|
|
17
|
+
</h1>
|
|
18
|
+
<AccountIframe section="settings" />
|
|
19
|
+
</article>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type Product,
|
|
11
11
|
} from "@cimplify/sdk/server";
|
|
12
12
|
import { ListingClient } from "./listing-client";
|
|
13
|
+
import { brand } from "@/lib/brand";
|
|
13
14
|
|
|
14
15
|
interface CategoryData {
|
|
15
16
|
category: Category;
|
|
@@ -42,7 +43,7 @@ export async function generateMetadata({
|
|
|
42
43
|
const data = await getCategory(slug);
|
|
43
44
|
if (!data) return {};
|
|
44
45
|
return {
|
|
45
|
-
title: `${data.category.name} —
|
|
46
|
+
title: `${data.category.name} — ${brand.name}`,
|
|
46
47
|
description: data.category.description ?? undefined,
|
|
47
48
|
};
|
|
48
49
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type Product,
|
|
11
11
|
} from "@cimplify/sdk/server";
|
|
12
12
|
import { ListingClient } from "./listing-client";
|
|
13
|
+
import { brand } from "@/lib/brand";
|
|
13
14
|
|
|
14
15
|
interface CollectionData {
|
|
15
16
|
collection: Collection;
|
|
@@ -42,7 +43,7 @@ export async function generateMetadata({
|
|
|
42
43
|
const data = await getCollection(slug);
|
|
43
44
|
if (!data) return {};
|
|
44
45
|
return {
|
|
45
|
-
title: `${data.collection.name} —
|
|
46
|
+
title: `${data.collection.name} — ${brand.name}`,
|
|
46
47
|
description: data.collection.description ?? undefined,
|
|
47
48
|
};
|
|
48
49
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Local-only contact form. On submit, fakes a successful response so the
|
|
7
|
+
* template ships a usable interaction. Wire to a real handler (Server
|
|
8
|
+
* Action posting to your CRM, support inbox, or Cimplify Support API)
|
|
9
|
+
* before going to production.
|
|
10
|
+
*/
|
|
11
|
+
export function ContactForm({ reasons }: { reasons: string[] }) {
|
|
12
|
+
const [submitted, setSubmitted] = useState(false);
|
|
13
|
+
const [reason, setReason] = useState(reasons[0] ?? "");
|
|
14
|
+
|
|
15
|
+
if (submitted) {
|
|
16
|
+
return (
|
|
17
|
+
<div className="rounded-2xl border border-border bg-card p-8">
|
|
18
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
19
|
+
✓ Sent
|
|
20
|
+
</p>
|
|
21
|
+
<h2 className="font-serif text-2xl font-semibold mb-2">Thanks — we'll be in touch.</h2>
|
|
22
|
+
<p className="text-muted-foreground">
|
|
23
|
+
We respond within one business day. Check your spam folder if you don't see a
|
|
24
|
+
reply by tomorrow.
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<form
|
|
32
|
+
onSubmit={(e) => {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
setSubmitted(true);
|
|
35
|
+
}}
|
|
36
|
+
className="space-y-5"
|
|
37
|
+
>
|
|
38
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
39
|
+
<Field label="Your name" name="name" required />
|
|
40
|
+
<Field label="Email" name="email" type="email" required />
|
|
41
|
+
</div>
|
|
42
|
+
<div>
|
|
43
|
+
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground block mb-1.5">
|
|
44
|
+
What's it about?
|
|
45
|
+
</label>
|
|
46
|
+
<select
|
|
47
|
+
name="reason"
|
|
48
|
+
value={reason}
|
|
49
|
+
onChange={(e) => setReason(e.target.value)}
|
|
50
|
+
className="w-full px-4 py-2.5 rounded-md bg-background border border-border focus:border-primary focus:ring-2 focus:ring-primary/20 outline-none text-sm"
|
|
51
|
+
>
|
|
52
|
+
{reasons.map((r) => (
|
|
53
|
+
<option key={r} value={r}>
|
|
54
|
+
{r}
|
|
55
|
+
</option>
|
|
56
|
+
))}
|
|
57
|
+
</select>
|
|
58
|
+
</div>
|
|
59
|
+
<Field label="Order number (optional)" name="order" />
|
|
60
|
+
<div>
|
|
61
|
+
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground block mb-1.5">
|
|
62
|
+
Message
|
|
63
|
+
</label>
|
|
64
|
+
<textarea
|
|
65
|
+
name="message"
|
|
66
|
+
required
|
|
67
|
+
rows={6}
|
|
68
|
+
className="w-full px-4 py-2.5 rounded-md bg-background border border-border focus:border-primary focus:ring-2 focus:ring-primary/20 outline-none text-sm resize-y"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
<button
|
|
72
|
+
type="submit"
|
|
73
|
+
className="inline-flex items-center justify-center px-5 py-3 rounded-md bg-primary text-primary-foreground font-semibold text-sm hover:bg-primary/90 transition-colors"
|
|
74
|
+
>
|
|
75
|
+
Send message
|
|
76
|
+
</button>
|
|
77
|
+
</form>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function Field({
|
|
82
|
+
label,
|
|
83
|
+
name,
|
|
84
|
+
type = "text",
|
|
85
|
+
required,
|
|
86
|
+
}: {
|
|
87
|
+
label: string;
|
|
88
|
+
name: string;
|
|
89
|
+
type?: string;
|
|
90
|
+
required?: boolean;
|
|
91
|
+
}) {
|
|
92
|
+
return (
|
|
93
|
+
<div>
|
|
94
|
+
<label
|
|
95
|
+
htmlFor={name}
|
|
96
|
+
className="text-xs font-semibold uppercase tracking-wider text-muted-foreground block mb-1.5"
|
|
97
|
+
>
|
|
98
|
+
{label}
|
|
99
|
+
</label>
|
|
100
|
+
<input
|
|
101
|
+
id={name}
|
|
102
|
+
name={name}
|
|
103
|
+
type={type}
|
|
104
|
+
required={required}
|
|
105
|
+
className="w-full px-4 py-2.5 rounded-md bg-background border border-border focus:border-primary focus:ring-2 focus:ring-primary/20 outline-none text-sm"
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { ContactForm } from "./contact-form";
|
|
3
|
+
import { brand } from "@/lib/brand";
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: `Contact — ${brand.name}`,
|
|
7
|
+
description: brand.contactPage.body,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function ContactPage() {
|
|
11
|
+
const c = brand.contactPage;
|
|
12
|
+
return (
|
|
13
|
+
<article className="max-w-5xl mx-auto px-6 sm:px-8 py-16">
|
|
14
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
15
|
+
{c.eyebrow}
|
|
16
|
+
</p>
|
|
17
|
+
<h1 className="font-serif text-[clamp(2.25rem,5vw,3.5rem)] font-semibold mb-4 -tracking-[0.02em]">
|
|
18
|
+
{c.title}
|
|
19
|
+
</h1>
|
|
20
|
+
<p className="text-lg text-muted-foreground max-w-2xl mb-12 leading-relaxed">{c.body}</p>
|
|
21
|
+
|
|
22
|
+
<div className="grid grid-cols-1 lg:grid-cols-[1.5fr_1fr] gap-10 items-start">
|
|
23
|
+
<ContactForm reasons={c.reasons} />
|
|
24
|
+
<aside className="space-y-5 lg:pl-10 lg:border-l border-border">
|
|
25
|
+
<div>
|
|
26
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground mb-3">
|
|
27
|
+
Direct lines
|
|
28
|
+
</p>
|
|
29
|
+
<ul className="space-y-3 list-none p-0 m-0">
|
|
30
|
+
{c.directLines.map((line) => (
|
|
31
|
+
<li key={line.label}>
|
|
32
|
+
<p className="text-xs text-muted-foreground m-0">{line.label}</p>
|
|
33
|
+
<a
|
|
34
|
+
href={line.href}
|
|
35
|
+
className="text-foreground hover:text-primary transition-colors"
|
|
36
|
+
>
|
|
37
|
+
{line.value}
|
|
38
|
+
</a>
|
|
39
|
+
</li>
|
|
40
|
+
))}
|
|
41
|
+
</ul>
|
|
42
|
+
</div>
|
|
43
|
+
<div>
|
|
44
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground mb-3">
|
|
45
|
+
Visit
|
|
46
|
+
</p>
|
|
47
|
+
<p className="text-foreground m-0">{brand.contact.address}</p>
|
|
48
|
+
<p className="text-xs text-muted-foreground mt-1">{brand.contact.hours}</p>
|
|
49
|
+
</div>
|
|
50
|
+
</aside>
|
|
51
|
+
</div>
|
|
52
|
+
</article>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Root error boundary. Next.js calls this whenever a thrown error escapes
|
|
8
|
+
* a Server Component without being caught by a closer `error.tsx`.
|
|
9
|
+
*
|
|
10
|
+
* Wire `reportError` (Sentry, Datadog, etc.) here so production failures
|
|
11
|
+
* surface — silently recovering hides real bugs.
|
|
12
|
+
*/
|
|
13
|
+
export default function GlobalError({
|
|
14
|
+
error,
|
|
15
|
+
reset,
|
|
16
|
+
}: {
|
|
17
|
+
error: Error & { digest?: string };
|
|
18
|
+
reset: () => void;
|
|
19
|
+
}) {
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
// TODO: replace with your error reporter
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
console.error("Storefront error:", error);
|
|
24
|
+
}, [error]);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<section className="max-w-2xl mx-auto px-6 sm:px-8 py-20 text-center">
|
|
28
|
+
<p className="text-[11px] font-mono uppercase tracking-[0.16em] text-primary mb-3">
|
|
29
|
+
Something broke
|
|
30
|
+
</p>
|
|
31
|
+
<h1 className="text-[clamp(2rem,4vw,3rem)] font-bold mb-4 -tracking-[0.025em]">
|
|
32
|
+
That wasn't supposed to happen.
|
|
33
|
+
</h1>
|
|
34
|
+
<p className="text-muted-foreground leading-relaxed mb-8">
|
|
35
|
+
We've been notified. Refresh the page, or head back home — most
|
|
36
|
+
of the time the second try just works.
|
|
37
|
+
</p>
|
|
38
|
+
{error.digest && (
|
|
39
|
+
<p className="text-xs font-mono text-muted-foreground mb-6">
|
|
40
|
+
Reference:{" "}
|
|
41
|
+
<code className="text-foreground">{error.digest}</code>
|
|
42
|
+
</p>
|
|
43
|
+
)}
|
|
44
|
+
<div className="flex flex-wrap items-center justify-center gap-3">
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
onClick={reset}
|
|
48
|
+
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-md bg-primary text-primary-foreground font-semibold text-sm hover:bg-primary/90 transition-colors"
|
|
49
|
+
>
|
|
50
|
+
Try again
|
|
51
|
+
</button>
|
|
52
|
+
<Link
|
|
53
|
+
href="/"
|
|
54
|
+
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-md border border-border hover:bg-muted transition-colors text-sm font-medium"
|
|
55
|
+
>
|
|
56
|
+
Back home
|
|
57
|
+
</Link>
|
|
58
|
+
</div>
|
|
59
|
+
</section>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -1,106 +1,25 @@
|
|
|
1
1
|
import type { Metadata } from "next";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
2
3
|
|
|
3
4
|
export const metadata: Metadata = {
|
|
4
|
-
title:
|
|
5
|
-
description:
|
|
6
|
-
"Shipping, warranty, repairs, returns, payment — answers to the questions we hear most often.",
|
|
5
|
+
title: `Support — ${brand.name}`,
|
|
6
|
+
description: "Shipping, warranty, repairs, returns, payment — answers to the questions we hear most often.",
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
interface QA {
|
|
10
|
-
q: string;
|
|
11
|
-
a: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const SECTIONS: { title: string; items: QA[] }[] = [
|
|
15
|
-
{
|
|
16
|
-
title: "Ordering & delivery",
|
|
17
|
-
items: [
|
|
18
|
-
{
|
|
19
|
-
q: "How fast is shipping?",
|
|
20
|
-
a: "Free same-day delivery within Greater Accra for orders placed before 4pm. Outside Accra, we use a partner courier — usually 1–3 business days, with tracking sent by SMS.",
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
q: "Can I pick up in store?",
|
|
24
|
-
a: "Yes. Choose 'Pickup' at checkout and we'll have your order boxed at our Atomic Junction store within 30 minutes. Bring a photo ID matching the order name.",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
q: "Do you ship internationally?",
|
|
28
|
-
a: "We ship across West Africa via DHL — rates and ETAs are calculated at checkout once you enter your destination.",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
q: "How do I track my order?",
|
|
32
|
-
a: "You'll get an SMS and email with a tracking link within 30 minutes of dispatch. Same-day Accra orders include the rider's phone number.",
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
title: "Warranty & repairs",
|
|
38
|
-
items: [
|
|
39
|
-
{
|
|
40
|
-
q: "What does the two-year warranty cover?",
|
|
41
|
-
a: "Manufacturing defects, electrical failures, and battery degradation below 80% within the first 24 months. Accidental damage, water damage, and software issues caused by user installs are excluded.",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
q: "Where do I send a faulty device?",
|
|
45
|
-
a: "Drop it at our Atomic Junction store, or request a free pickup from your address by emailing support@currentselectronics.test. Loaner devices are available for warranty claims while we diagnose.",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
q: "Can you fix devices bought elsewhere?",
|
|
49
|
-
a: "We offer paid repairs on Apple and Samsung devices regardless of where they were purchased. Expect a quote within 48 hours of inspection.",
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
title: "Trade-in & financing",
|
|
55
|
-
items: [
|
|
56
|
-
{
|
|
57
|
-
q: "How does trade-in work?",
|
|
58
|
-
a: "Tell us the model and condition of your device, get an instant estimate, and ship it free or drop it at our store. Once we verify, we credit your account or pay out via Mobile Money — your choice.",
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
q: "Do you offer instalment payments?",
|
|
62
|
-
a: "Yes. Pay in 3 (interest-free) or 6/12 monthly instalments via our partner Fidelity Bank. Available at checkout for orders over GH₵2,000.",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
q: "Are there bulk discounts for businesses?",
|
|
66
|
-
a: "Yes. Email business@currentselectronics.test with your shopping list and team size — most orders over 5 units qualify for a discount, plus free on-site setup.",
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
title: "Payment & returns",
|
|
72
|
-
items: [
|
|
73
|
-
{
|
|
74
|
-
q: "What payment methods do you accept?",
|
|
75
|
-
a: "Mobile Money (MTN, Telecel, AirtelTigo), Visa/Mastercard, instalments via Fidelity Bank, and cash on delivery for Accra orders.",
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
q: "What's your return policy?",
|
|
79
|
-
a: "14 days, no questions asked, on any sealed product. For opened items, returns are accepted within 7 days subject to a 10% restocking fee. We can't accept returns on activated SIM-bundled phones once the SIM is registered.",
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
q: "Are products genuine?",
|
|
83
|
-
a: "Yes. We're an authorised dealer for every brand we stock. Every product ships with the manufacturer's serial number registered to your name — verify it on the brand's official portal anytime.",
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
},
|
|
87
|
-
];
|
|
88
|
-
|
|
89
9
|
export default function FaqPage() {
|
|
10
|
+
const f = brand.faq;
|
|
90
11
|
return (
|
|
91
12
|
<article className="max-w-3xl mx-auto px-8 py-16">
|
|
92
13
|
<p className="text-[11px] font-mono uppercase tracking-[0.16em] text-primary mb-2">
|
|
93
|
-
|
|
14
|
+
{f.eyebrow}
|
|
94
15
|
</p>
|
|
95
16
|
<h1 className="text-[clamp(2.25rem,5vw,3.5rem)] font-bold mb-10 -tracking-[0.025em]">
|
|
96
|
-
|
|
17
|
+
{f.title}
|
|
97
18
|
</h1>
|
|
98
19
|
<div className="space-y-12">
|
|
99
|
-
{
|
|
20
|
+
{f.sections.map((section) => (
|
|
100
21
|
<section key={section.title}>
|
|
101
|
-
<h2 className="text-2xl font-semibold mb-5 -tracking-[0.02em]">
|
|
102
|
-
{section.title}
|
|
103
|
-
</h2>
|
|
22
|
+
<h2 className="text-2xl font-semibold mb-5 -tracking-[0.02em]">{section.title}</h2>
|
|
104
23
|
<dl className="space-y-6">
|
|
105
24
|
{section.items.map((item) => (
|
|
106
25
|
<div key={item.q}>
|
|
@@ -113,12 +32,12 @@ export default function FaqPage() {
|
|
|
113
32
|
))}
|
|
114
33
|
</div>
|
|
115
34
|
<p className="mt-12 pt-8 border-t border-border text-sm text-muted-foreground">
|
|
116
|
-
|
|
35
|
+
{f.contactPrompt}{" "}
|
|
117
36
|
<a
|
|
118
|
-
href=
|
|
37
|
+
href={`mailto:${f.contactEmail}`}
|
|
119
38
|
className="text-primary font-semibold hover:underline"
|
|
120
39
|
>
|
|
121
|
-
|
|
40
|
+
{f.contactEmail}
|
|
122
41
|
</a>{" "}
|
|
123
42
|
and a real human will reply within 24 hours.
|
|
124
43
|
</p>
|
|
@@ -4,8 +4,7 @@ import "./globals.css";
|
|
|
4
4
|
import { Providers } from "@/components/providers";
|
|
5
5
|
import { Header } from "@/components/header";
|
|
6
6
|
import { Footer } from "@/components/footer";
|
|
7
|
-
import {
|
|
8
|
-
import { Suspense } from "react";
|
|
7
|
+
import { brand } from "@/lib/brand";
|
|
9
8
|
|
|
10
9
|
const inter = Inter({
|
|
11
10
|
subsets: ["latin"],
|
|
@@ -19,10 +18,39 @@ const mono = JetBrains_Mono({
|
|
|
19
18
|
display: "swap",
|
|
20
19
|
});
|
|
21
20
|
|
|
21
|
+
const SITE_URL =
|
|
22
|
+
process.env.NEXT_PUBLIC_SITE_URL?.trim() || "https://example.com";
|
|
23
|
+
|
|
22
24
|
export const metadata: Metadata = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
metadataBase: new URL(SITE_URL),
|
|
26
|
+
title: {
|
|
27
|
+
default: brand.name,
|
|
28
|
+
template: `%s — ${brand.name}`,
|
|
29
|
+
},
|
|
30
|
+
description: brand.description,
|
|
31
|
+
openGraph: {
|
|
32
|
+
type: "website",
|
|
33
|
+
siteName: brand.name,
|
|
34
|
+
locale: brand.locale,
|
|
35
|
+
},
|
|
36
|
+
twitter: { card: "summary_large_image" },
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const ORGANIZATION_LD = {
|
|
40
|
+
"@context": "https://schema.org",
|
|
41
|
+
"@type": brand.schemaType,
|
|
42
|
+
name: brand.name,
|
|
43
|
+
url: SITE_URL,
|
|
44
|
+
description: brand.description,
|
|
45
|
+
email: brand.contact.email,
|
|
46
|
+
telephone: brand.contact.phoneTel,
|
|
47
|
+
address: {
|
|
48
|
+
"@type": "PostalAddress",
|
|
49
|
+
streetAddress: brand.contact.streetAddress,
|
|
50
|
+
addressLocality: brand.contact.city,
|
|
51
|
+
addressCountry: brand.contact.countryCode,
|
|
52
|
+
},
|
|
53
|
+
sameAs: brand.socials.map((s) => s.href),
|
|
26
54
|
};
|
|
27
55
|
|
|
28
56
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
@@ -32,13 +60,14 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
32
60
|
suppressHydrationWarning
|
|
33
61
|
className="min-h-screen flex flex-col bg-background text-foreground font-sans"
|
|
34
62
|
>
|
|
63
|
+
<script
|
|
64
|
+
type="application/ld+json"
|
|
65
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(ORGANIZATION_LD) }}
|
|
66
|
+
/>
|
|
35
67
|
<Providers>
|
|
36
68
|
<Header />
|
|
37
69
|
<main className="flex-1 pb-12 w-full">{children}</main>
|
|
38
70
|
<Footer />
|
|
39
|
-
<Suspense fallback={null}>
|
|
40
|
-
<ProductModal />
|
|
41
|
-
</Suspense>
|
|
42
71
|
</Providers>
|
|
43
72
|
</body>
|
|
44
73
|
</html>
|