@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
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brand & content configuration — single source of truth for every visible
|
|
3
|
+
* string. Edit this file to rebrand. See ../AGENTS.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface BrandSocial {
|
|
7
|
+
label: string;
|
|
8
|
+
href: string;
|
|
9
|
+
icon?: "instagram" | "x" | "tiktok" | "facebook" | "youtube" | "linkedin" | "whatsapp";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface BrandFaqEntry { q: string; a: string }
|
|
13
|
+
export interface BrandFaqSection { title: string; items: BrandFaqEntry[] }
|
|
14
|
+
export interface BrandPolicySection {
|
|
15
|
+
heading: string;
|
|
16
|
+
body: string | { intro: string; bullets: string[] };
|
|
17
|
+
}
|
|
18
|
+
export interface BrandSitemapSection { title: string; links: { label: string; href: string }[] }
|
|
19
|
+
|
|
20
|
+
export interface Brand {
|
|
21
|
+
name: string; shortName: string; microTag: string; description: string;
|
|
22
|
+
schemaType:
|
|
23
|
+
| "Store" | "Bakery" | "Restaurant" | "BeautySalon"
|
|
24
|
+
| "GroceryStore" | "LocalBusiness" | "Organization";
|
|
25
|
+
currency: string; locale: string;
|
|
26
|
+
contact: {
|
|
27
|
+
address: string; streetAddress: string; city: string; countryCode: string;
|
|
28
|
+
phone: string; phoneTel: string; email: string; privacyEmail: string;
|
|
29
|
+
supportEmail?: string; businessEmail?: string; hours: string;
|
|
30
|
+
};
|
|
31
|
+
socials: BrandSocial[];
|
|
32
|
+
header: { nav: { label: string; href: string }[] };
|
|
33
|
+
hero: {
|
|
34
|
+
badge: string; title: string; subtitle: string;
|
|
35
|
+
primaryCtaLabel: string;
|
|
36
|
+
secondaryCtaLabel?: string; secondaryCtaHref?: string;
|
|
37
|
+
};
|
|
38
|
+
trustItems?: { label: string; value: string; description: string; iconKey: string }[];
|
|
39
|
+
brandStrip?: { headline: string; brands: string[] };
|
|
40
|
+
promo?: { badge: string; title: string; body: string; ctaLabel: string; ctaHref: string };
|
|
41
|
+
tradeIn?: {
|
|
42
|
+
eyebrow: string; title: string; body: string;
|
|
43
|
+
primaryCtaLabel: string; primaryCtaHref: string;
|
|
44
|
+
secondaryCtaLabel: string; secondaryCtaHref: string;
|
|
45
|
+
steps: { step: string; title: string; body: string }[];
|
|
46
|
+
};
|
|
47
|
+
newsletter: {
|
|
48
|
+
eyebrow: string; title: string; body: string; placeholder: string;
|
|
49
|
+
submitLabel: string; successLabel: string;
|
|
50
|
+
};
|
|
51
|
+
about: {
|
|
52
|
+
eyebrow: string; title: string; paragraphs: string[];
|
|
53
|
+
sections: { heading: string; body: string }[];
|
|
54
|
+
};
|
|
55
|
+
faq: {
|
|
56
|
+
eyebrow: string; title: string; sections: BrandFaqSection[];
|
|
57
|
+
contactPrompt: string; contactEmail: string;
|
|
58
|
+
};
|
|
59
|
+
terms: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
|
|
60
|
+
privacy: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
|
|
61
|
+
shipping: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
|
|
62
|
+
returns: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
|
|
63
|
+
accessibility: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
|
|
64
|
+
account: {
|
|
65
|
+
loginEyebrow: string; loginTitle: string; loginSubtitle: string;
|
|
66
|
+
signupEyebrow: string; signupTitle: string; signupSubtitle: string;
|
|
67
|
+
accountEyebrow: string; accountTitle: string;
|
|
68
|
+
};
|
|
69
|
+
contactPage: {
|
|
70
|
+
eyebrow: string; title: string; body: string;
|
|
71
|
+
reasons: string[];
|
|
72
|
+
directLines: { label: string; value: string; href: string }[];
|
|
73
|
+
};
|
|
74
|
+
trackOrder: { eyebrow: string; title: string; body: string };
|
|
75
|
+
footer: {
|
|
76
|
+
blurb: string; sitemap: BrandSitemapSection[];
|
|
77
|
+
poweredBy?: { label: string; href: string };
|
|
78
|
+
};
|
|
79
|
+
llms: { summary: string };
|
|
80
|
+
mock: { seed: string; businessId: string };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const brand: Brand = {
|
|
84
|
+
name: "FreshMart",
|
|
85
|
+
shortName: "FreshMart",
|
|
86
|
+
microTag: "GROCER · ACCRA",
|
|
87
|
+
description:
|
|
88
|
+
"Local produce, weekly basket boxes, and pantry staples — delivered to your door across Greater Accra.",
|
|
89
|
+
schemaType: "GroceryStore",
|
|
90
|
+
|
|
91
|
+
currency: "GHS",
|
|
92
|
+
locale: "en_GH",
|
|
93
|
+
|
|
94
|
+
contact: {
|
|
95
|
+
address: "Achimota Market, Accra",
|
|
96
|
+
streetAddress: "Achimota Market",
|
|
97
|
+
city: "Accra",
|
|
98
|
+
countryCode: "GH",
|
|
99
|
+
phone: "+233 244 555 100",
|
|
100
|
+
phoneTel: "+233244555100",
|
|
101
|
+
email: "hello@freshmart.test",
|
|
102
|
+
privacyEmail: "privacy@freshmart.test",
|
|
103
|
+
hours: "Mon–Sat · 7am–9pm · Sun 8am–7pm",
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
socials: [
|
|
107
|
+
{ label: "Instagram", href: "https://instagram.com/freshmart", icon: "instagram" },
|
|
108
|
+
{ label: "Facebook", href: "https://facebook.com/freshmart", icon: "facebook" },
|
|
109
|
+
{ label: "WhatsApp", href: "https://wa.me/233244555100", icon: "whatsapp" },
|
|
110
|
+
],
|
|
111
|
+
|
|
112
|
+
header: {
|
|
113
|
+
nav: [
|
|
114
|
+
{ label: "Shop", href: "/shop" },
|
|
115
|
+
{ label: "Weekly box", href: "/categories/baskets" },
|
|
116
|
+
{ label: "Deals", href: "/categories/deals" },
|
|
117
|
+
{ label: "About", href: "/about" },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
hero: {
|
|
122
|
+
badge: "Free delivery over GH₵150",
|
|
123
|
+
title: "Fresh today.\nIn your kitchen by 5pm.",
|
|
124
|
+
subtitle:
|
|
125
|
+
"Local produce, weekly basket boxes, and pantry staples — sourced from Ghanaian farms, packed this morning, delivered today.",
|
|
126
|
+
primaryCtaLabel: "Shop the aisle",
|
|
127
|
+
secondaryCtaLabel: "Build a basket box",
|
|
128
|
+
secondaryCtaHref: "/categories/baskets",
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
trustItems: [
|
|
132
|
+
{ label: "Delivery", value: "Same-day in Accra", description: "Order before 2pm, in your kitchen by 5pm.", iconKey: "delivery" },
|
|
133
|
+
{ label: "Sourcing", value: "Direct from farms", description: "70% of produce from Volta + Eastern Region.", iconKey: "verified" },
|
|
134
|
+
{ label: "Returns", value: "Anything off, refund", description: "Quality-guaranteed, no questions asked.", iconKey: "warranty" },
|
|
135
|
+
{ label: "Subscribe", value: "Weekly basket box", description: "Pause or skip any week.", iconKey: "support" },
|
|
136
|
+
],
|
|
137
|
+
|
|
138
|
+
promo: {
|
|
139
|
+
badge: "This week",
|
|
140
|
+
title: "Tomato season — GH₵12/kg, today only.",
|
|
141
|
+
body: "Roma, plum, and Volta cherry — direct from Akwapim farmers, picked this morning. Stock up while it's at peak. Limit 5kg per order.",
|
|
142
|
+
ctaLabel: "Shop tomatoes",
|
|
143
|
+
ctaHref: "/categories/produce",
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
newsletter: {
|
|
147
|
+
eyebrow: "FreshMart weekly",
|
|
148
|
+
title: "What's in season, every Sunday.",
|
|
149
|
+
body: "We email a one-page roundup every Sunday: this week's deals, new produce, recipe of the week. Unsubscribe in one click.",
|
|
150
|
+
placeholder: "you@email.com",
|
|
151
|
+
submitLabel: "Get the weekly",
|
|
152
|
+
successLabel: "Subscribed ✓",
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
about: {
|
|
156
|
+
eyebrow: "About FreshMart",
|
|
157
|
+
title: "Local food,\nactually.",
|
|
158
|
+
paragraphs: [
|
|
159
|
+
"FreshMart started in 2022 as a stall at Achimota Market with one delivery rider and a notebook. Today we run a 600-square-metre warehouse and a fleet of nine refrigerated bikes, with one rule: if it's not in season locally, it doesn't lead our shelves.",
|
|
160
|
+
"70% of our produce comes from Ghanaian farms — Akwapim tomatoes, Volta-region pineapple, Brong-Ahafo yam, Nkawkaw plantain. The remaining 30% (citrus, certain herbs, dairy) we source from a tight set of partners we visit quarterly.",
|
|
161
|
+
"Order online by 2pm; we deliver same-day across Greater Accra. Subscribe to our weekly basket box and we'll curate a mix of in-season produce, dairy, and pantry staples every Tuesday or Friday.",
|
|
162
|
+
],
|
|
163
|
+
sections: [
|
|
164
|
+
{
|
|
165
|
+
heading: "The basket box",
|
|
166
|
+
body: "GH₵180 for the small (feeds 2 for a week), GH₵320 for the family (feeds 4). Tuesday or Friday delivery. Pause, skip, or cancel any week from your account.",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
heading: "Wholesale",
|
|
170
|
+
body: "Cafés, restaurants, and meal-prep operations: we deliver tiered-priced, predictable orders. Email wholesale@freshmart.test with your weekly volume and we'll quote.",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
heading: "Visit",
|
|
174
|
+
body: "Achimota Market, Stalls 14–22. Mon–Sat 7am–9pm, Sun 8am–7pm.",
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
faq: {
|
|
180
|
+
eyebrow: "Q&A",
|
|
181
|
+
title: "Things people ask.",
|
|
182
|
+
sections: [
|
|
183
|
+
{
|
|
184
|
+
title: "Ordering & delivery",
|
|
185
|
+
items: [
|
|
186
|
+
{ q: "When will my order arrive?", a: "Order before 2pm — same-day delivery, in your kitchen by 5pm. After 2pm, next-day before 11am." },
|
|
187
|
+
{ q: "Where do you deliver?", a: "Greater Accra, free over GH₵150. Outside Accra, next-day shipping via partner courier." },
|
|
188
|
+
{ q: "Can I choose a delivery slot?", a: "Yes — 12pm, 3pm, or 5pm windows in Accra. Subscriber boxes deliver Tuesday or Friday morning." },
|
|
189
|
+
{ q: "What if I'm not home?", a: "We coordinate with you by SMS and call. If there's no one, we hold the order at the warehouse and re-attempt the next day at no charge." },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
title: "Quality & sourcing",
|
|
194
|
+
items: [
|
|
195
|
+
{ q: "How fresh is your produce?", a: "Most produce is picked the same day or the day before. We email batch dates with every order." },
|
|
196
|
+
{ q: "Is it organic?", a: "We label every product clearly: \"organic\", \"low-spray\", or conventional. About 30% of our produce is certified organic; another 50% is low-spray traceable to specific farms." },
|
|
197
|
+
{ q: "What if something arrives off?", a: "Send us a photo within 24 hours. We refund or replace, no questions asked." },
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
title: "Subscriptions",
|
|
202
|
+
items: [
|
|
203
|
+
{ q: "How does the basket box work?", a: "Pick small or family. Pick Tuesday or Friday delivery. We curate a mix of in-season produce, dairy, and pantry. Pause, skip, or cancel any week from your account." },
|
|
204
|
+
{ q: "Can I customise the box?", a: "Yes — toggle dietary preferences (vegetarian, no-spice, low-carb) and exclude up to 3 items per week." },
|
|
205
|
+
{ q: "What if I'm travelling?", a: "Pause the box for any number of weeks. We won't bill while paused." },
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
contactPrompt: "Other questions? Message us:",
|
|
210
|
+
contactEmail: "hello@freshmart.test",
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
terms: {
|
|
214
|
+
eyebrow: "Terms of service",
|
|
215
|
+
title: "Terms of Service",
|
|
216
|
+
lastUpdated: "1 May 2026",
|
|
217
|
+
sections: [
|
|
218
|
+
{ heading: "1. Who we are", body: "FreshMart (\"we\", \"us\") is a grocery business operating from Achimota Market, Accra. By placing an order, you (\"you\", \"customer\") agree to these terms." },
|
|
219
|
+
{ heading: "2. Pricing & weights", body: "Prices in GH₵, by weight or unit as marked. Final price computed at checkout based on actual packed weight; we never charge more than 10% over the listed estimate." },
|
|
220
|
+
{ heading: "3. Delivery", body: "Same-day in Greater Accra (orders before 2pm); next-day for orders after. Free over GH₵150." },
|
|
221
|
+
{ heading: "4. Quality guarantee", body: "Anything off — wrong, spoiled, or not as described — refund or replacement, on us. Photo evidence within 24 hours." },
|
|
222
|
+
{ heading: "5. Subscriptions", body: "Weekly basket boxes auto-renew. Pause, skip, or cancel before the next billing date with no penalty." },
|
|
223
|
+
{ heading: "6. Liability", body: "Maximum liability for any order is its value. We're not liable for indirect or consequential losses." },
|
|
224
|
+
{ heading: "7. Governing law", body: "These terms are governed by the laws of Ghana." },
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
privacy: {
|
|
229
|
+
eyebrow: "Privacy",
|
|
230
|
+
title: "Privacy Policy",
|
|
231
|
+
lastUpdated: "1 May 2026",
|
|
232
|
+
sections: [
|
|
233
|
+
{ heading: "What we collect", body: "Order details (name, address, phone, email), delivery preferences, dietary toggles for subscriptions, and payment data via our processors. We do not store payment cards." },
|
|
234
|
+
{ heading: "How we use it", body: { intro: "We use your data to:", bullets: [
|
|
235
|
+
"Pack and deliver your order.",
|
|
236
|
+
"Send delivery updates by SMS.",
|
|
237
|
+
"Curate weekly basket boxes (only for active subscribers).",
|
|
238
|
+
"Send our weekly roundup (only if you opted in).",
|
|
239
|
+
] } },
|
|
240
|
+
{ heading: "Who we share it with", body: "Payment processors (Paystack, Stripe), delivery riders, and our SMS provider. No one else." },
|
|
241
|
+
{ heading: "Your rights", body: "Under the Ghana Data Protection Act, 2012 (Act 843), you can access, correct, or delete your data. Email privacy@freshmart.test." },
|
|
242
|
+
{ heading: "Retention", body: "Order records: 7 years (tax). Subscription preferences: until you cancel + 90 days." },
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
shipping: {
|
|
247
|
+
eyebrow: "Delivery",
|
|
248
|
+
title: "Delivery & Pickup",
|
|
249
|
+
lastUpdated: "1 May 2026",
|
|
250
|
+
sections: [
|
|
251
|
+
{ heading: "Same-day Greater Accra", body: "Order before 2pm — in your kitchen by 5pm. Free over GH₵150." },
|
|
252
|
+
{ heading: "Slot windows", body: "Choose 12pm, 3pm, or 5pm in Accra. Subscriber boxes deliver Tuesday or Friday morning." },
|
|
253
|
+
{ heading: "Outside Accra", body: "Next-day shipping via partner courier; rates and ETA at checkout." },
|
|
254
|
+
{ heading: "Pickup", body: "Achimota Market, stalls 14–22. Free; ready 30 minutes after order." },
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
returns: {
|
|
259
|
+
eyebrow: "Quality guarantee",
|
|
260
|
+
title: "Quality Guarantee & Refunds",
|
|
261
|
+
lastUpdated: "1 May 2026",
|
|
262
|
+
sections: [
|
|
263
|
+
{ heading: "Anything off, refund", body: "Wrong, spoiled, or not as described — we refund or replace, no questions asked. Send a photo within 24 hours of delivery." },
|
|
264
|
+
{ heading: "Pricing by weight", body: "Final price is computed at packing. We never charge more than 10% over the listed estimate; if the actual is more, we trim or call you." },
|
|
265
|
+
{ heading: "Subscription pause", body: "Pause, skip, or cancel any week before the next billing date." },
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
accessibility: {
|
|
270
|
+
eyebrow: "Accessibility",
|
|
271
|
+
title: "Accessibility Statement",
|
|
272
|
+
lastUpdated: "1 May 2026",
|
|
273
|
+
sections: [
|
|
274
|
+
{ heading: "Online", body: "We aim for WCAG 2.1 AA on this site." },
|
|
275
|
+
{ heading: "At Achimota Market", body: "Our stalls are at ground level. The market itself has step-free pathways; ask any staff member to direct you." },
|
|
276
|
+
{ heading: "Reporting issues", body: "Email accessibility@freshmart.test. We respond within 5 business days." },
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
account: {
|
|
281
|
+
loginEyebrow: "Welcome back",
|
|
282
|
+
loginTitle: "Sign in to FreshMart",
|
|
283
|
+
loginSubtitle: "Manage orders, your weekly box, and your delivery preferences.",
|
|
284
|
+
signupEyebrow: "Welcome",
|
|
285
|
+
signupTitle: "Create your account",
|
|
286
|
+
signupSubtitle: "Save addresses, set dietary preferences, and manage your weekly basket box.",
|
|
287
|
+
accountEyebrow: "Your account",
|
|
288
|
+
accountTitle: "Welcome back",
|
|
289
|
+
},
|
|
290
|
+
|
|
291
|
+
contactPage: {
|
|
292
|
+
eyebrow: "Contact",
|
|
293
|
+
title: "How can we help?",
|
|
294
|
+
body: "Order question, subscription change, or wholesale enquiry — we'll reply within a business day.",
|
|
295
|
+
reasons: ["General question", "An order issue", "Weekly box subscription", "Wholesale", "Press / partnerships", "Something else"],
|
|
296
|
+
directLines: [
|
|
297
|
+
{ label: "Email", value: "hello@freshmart.test", href: "mailto:hello@freshmart.test" },
|
|
298
|
+
{ label: "Phone", value: "+233 244 555 100", href: "tel:+233244555100" },
|
|
299
|
+
{ label: "WhatsApp", value: "+233 244 555 100", href: "https://wa.me/233244555100" },
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
trackOrder: {
|
|
304
|
+
eyebrow: "Track an order",
|
|
305
|
+
title: "Where's my order?",
|
|
306
|
+
body: "Enter your order number and the email used at checkout. We'll show the picking status, the rider, and the live ETA.",
|
|
307
|
+
},
|
|
308
|
+
|
|
309
|
+
footer: {
|
|
310
|
+
blurb:
|
|
311
|
+
"Local produce, weekly basket boxes, and pantry staples. Sourced from Ghanaian farms, delivered same-day across Accra.",
|
|
312
|
+
sitemap: [
|
|
313
|
+
{
|
|
314
|
+
title: "Shop",
|
|
315
|
+
links: [
|
|
316
|
+
{ label: "All products", href: "/shop" },
|
|
317
|
+
{ label: "Produce", href: "/categories/produce" },
|
|
318
|
+
{ label: "Dairy & eggs", href: "/categories/dairy" },
|
|
319
|
+
{ label: "Pantry", href: "/categories/pantry" },
|
|
320
|
+
{ label: "Frozen", href: "/categories/frozen" },
|
|
321
|
+
{ label: "Deals", href: "/categories/deals" },
|
|
322
|
+
],
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
title: "Subscribe",
|
|
326
|
+
links: [
|
|
327
|
+
{ label: "Weekly basket box", href: "/categories/baskets" },
|
|
328
|
+
{ label: "How it works", href: "/about" },
|
|
329
|
+
{ label: "Manage subscription", href: "/about" },
|
|
330
|
+
],
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
title: "Help",
|
|
334
|
+
links: [
|
|
335
|
+
{ label: "Contact", href: "/contact" },
|
|
336
|
+
{ label: "Track an order", href: "/track-order" },
|
|
337
|
+
{ label: "Delivery", href: "/shipping" },
|
|
338
|
+
{ label: "Quality guarantee", href: "/returns" },
|
|
339
|
+
{ label: "FAQ", href: "/faq" },
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
title: "Account",
|
|
344
|
+
links: [
|
|
345
|
+
{ label: "Sign in", href: "/login" },
|
|
346
|
+
{ label: "Create account", href: "/signup" },
|
|
347
|
+
{ label: "Your orders", href: "/account/orders" },
|
|
348
|
+
{ label: "Settings", href: "/account/settings" },
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
title: "Legal",
|
|
353
|
+
links: [
|
|
354
|
+
{ label: "Terms of Service", href: "/terms" },
|
|
355
|
+
{ label: "Privacy Policy", href: "/privacy" },
|
|
356
|
+
{ label: "Accessibility", href: "/accessibility" },
|
|
357
|
+
{ label: "Sitemap", href: "/sitemap-page" },
|
|
358
|
+
],
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
poweredBy: { label: "Cimplify", href: "https://app.cimplify.io" },
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
llms: {
|
|
365
|
+
summary:
|
|
366
|
+
"FreshMart — grocery delivery from Achimota Market, Accra. Direct-from-farm produce, weekly basket box subscriptions, pantry staples. Same-day delivery in Greater Accra; free over GH₵150. Pause-anytime subscriptions for households and wholesale tiers for cafés.",
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
mock: {
|
|
370
|
+
seed: "grocery",
|
|
371
|
+
businessId: "bus_freshmart",
|
|
372
|
+
},
|
|
373
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useCimplifyClient } from "@cimplify/sdk/react";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tiny hook for the live cart-count pill in the header. Re-fetches on
|
|
8
|
+
* mount and exposes a refresh callback. The SDK's `useCart` hook is
|
|
9
|
+
* fine-grained but heavier — this is enough for a header badge.
|
|
10
|
+
*/
|
|
11
|
+
export function useCartCount(): { count: number; refresh: () => void } {
|
|
12
|
+
const { client } = useCimplifyClient();
|
|
13
|
+
const [count, setCount] = useState(0);
|
|
14
|
+
|
|
15
|
+
const refresh = () => {
|
|
16
|
+
void client.cart.getCount().then((r) => {
|
|
17
|
+
if (r.ok) setCount(r.value);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
refresh();
|
|
23
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
24
|
+
}, [client]);
|
|
25
|
+
|
|
26
|
+
return { count, refresh };
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
const MOCK_URL = process.env.NEXT_PUBLIC_CIMPLIFY_API_URL?.trim() || "http://127.0.0.1:8787";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Same-origin proxy to the Cimplify mock so the browser never makes a
|
|
7
|
+
* cross-origin request in dev (no CORS preflights, no flaky `Origin`
|
|
8
|
+
* mismatches). The SDK's base URL stays empty/relative — requests go to
|
|
9
|
+
* `/api/v1/...` on the Next origin, then this rewrite forwards them to
|
|
10
|
+
* the mock at `127.0.0.1:8787`.
|
|
11
|
+
*
|
|
12
|
+
* In production, point `NEXT_PUBLIC_CIMPLIFY_API_URL` at your Cimplify
|
|
13
|
+
* host and the rewrite continues to work the same way (or remove it and
|
|
14
|
+
* pass the absolute URL through `<CimplifyProvider/>`).
|
|
15
|
+
*/
|
|
16
|
+
const nextConfig: NextConfig = {
|
|
17
|
+
// Enable Next 16's `cacheComponents` mode so we can use `'use cache'` +
|
|
18
|
+
// `cacheTag` / `cacheLife` for SSR caching. Cached chrome streams first,
|
|
19
|
+
// dynamic Suspense boundaries fill in when ready.
|
|
20
|
+
cacheComponents: true,
|
|
21
|
+
async rewrites() {
|
|
22
|
+
return [
|
|
23
|
+
{ source: "/api/v1/:path*", destination: `${MOCK_URL}/api/v1/:path*` },
|
|
24
|
+
{ source: "/img/:path*", destination: `${MOCK_URL}/img/:path*` },
|
|
25
|
+
{ source: "/elements/:path*", destination: `${MOCK_URL}/elements/:path*` },
|
|
26
|
+
{ source: "/_mock/:path*", destination: `${MOCK_URL}/_mock/:path*` },
|
|
27
|
+
];
|
|
28
|
+
},
|
|
29
|
+
images: {
|
|
30
|
+
remotePatterns: [
|
|
31
|
+
{ protocol: "http", hostname: "127.0.0.1", port: "8787", pathname: "/img/**" },
|
|
32
|
+
{ protocol: "http", hostname: "localhost", port: "8787", pathname: "/img/**" },
|
|
33
|
+
{ protocol: "http", hostname: "localhost", port: "3000", pathname: "/img/**" },
|
|
34
|
+
{ protocol: "https", hostname: "loremflickr.com", pathname: "/**" },
|
|
35
|
+
{ protocol: "https", hostname: "images.unsplash.com", pathname: "/**" },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default nextConfig;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__STOREFRONT_NAME__",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "concurrently -k -n mock,next -c blue,magenta \"bunx @cimplify/sdk --seed grocery --quiet\" \"next dev\"",
|
|
7
|
+
"dev:storefront": "next dev",
|
|
8
|
+
"dev:mock": "bunx @cimplify/sdk --seed grocery",
|
|
9
|
+
"build": "next build",
|
|
10
|
+
"start": "next start",
|
|
11
|
+
"lint": "next lint"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@cimplify/sdk": "^0.40.1",
|
|
15
|
+
"next": "^16.2.4",
|
|
16
|
+
"react": "^19.0.0",
|
|
17
|
+
"react-dom": "^19.0.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@tailwindcss/postcss": "^4.2.4",
|
|
21
|
+
"@types/node": "^22.10.0",
|
|
22
|
+
"@types/react": "^19.0.0",
|
|
23
|
+
"@types/react-dom": "^19.0.0",
|
|
24
|
+
"concurrently": "^9.0.0",
|
|
25
|
+
"tailwindcss": "^4.2.4",
|
|
26
|
+
"typescript": "^5.9.3"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": false,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Cimplify API base URL.
|
|
2
|
+
# Dev: leave empty so the SDK uses the current origin (localhost:3000),
|
|
3
|
+
# which Next.js rewrites to the mock at 127.0.0.1:8787 (see next.config.ts).
|
|
4
|
+
# Production: set to your Cimplify host (e.g. https://api.cimplify.io).
|
|
5
|
+
NEXT_PUBLIC_CIMPLIFY_API_URL=
|
|
6
|
+
|
|
7
|
+
# Tenant public key. The mock accepts any value.
|
|
8
|
+
NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY=mock-dev
|
|
9
|
+
|
|
10
|
+
# Business id used by the mock seed (restaurant: Mama's Kitchen).
|
|
11
|
+
NEXT_PUBLIC_CIMPLIFY_BUSINESS_ID=bus_mamas_kitchen
|
|
12
|
+
|
|
13
|
+
# Canonical public site URL — used by sitemap.xml, robots.txt, llms.txt,
|
|
14
|
+
# and OpenGraph metadata. Set this on production deploys (Vercel auto-injects
|
|
15
|
+
# via VERCEL_URL but Next prefers an explicit value).
|
|
16
|
+
NEXT_PUBLIC_SITE_URL=https://example.com
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# AGENTS.md — Restaurant storefront template
|
|
2
|
+
|
|
3
|
+
If you are an AI agent (Claude, Cursor, Aider, devin, …) working on this storefront, **start here.**
|
|
4
|
+
|
|
5
|
+
## TL;DR for rebranding
|
|
6
|
+
|
|
7
|
+
1. **Edit `lib/brand.ts`** — every visible string lives here.
|
|
8
|
+
2. **Edit `app/globals.css`** — `@theme { … }` for palette + radius.
|
|
9
|
+
3. **Edit `.env.local`** — `NEXT_PUBLIC_CIMPLIFY_BUSINESS_ID=bus_mamas_kitchen` for the bundled seed.
|
|
10
|
+
|
|
11
|
+
## Aesthetic
|
|
12
|
+
|
|
13
|
+
Boutique restaurant — Sweetgreen / chef-table feel:
|
|
14
|
+
|
|
15
|
+
- **Lora serif** for headings (warm, food-leaning).
|
|
16
|
+
- **Inter** for body and UI.
|
|
17
|
+
- **Forest green + cream**: deep sage primary, warm cream background, subtle warm accents.
|
|
18
|
+
- **Mid-radius**: `0.625rem` — softer than retail, tighter than spa.
|
|
19
|
+
|
|
20
|
+
## Industry-specific copy patterns
|
|
21
|
+
|
|
22
|
+
- `brand.hero.badge` is `"Tonight's special · Banku & Tilapia"` — a daily-special call-out.
|
|
23
|
+
- `brand.hero.primaryCtaLabel` is `"Reserve a table"`.
|
|
24
|
+
- `brand.tradeIn` is omitted.
|
|
25
|
+
- `brand.faq` covers reservations, dietary, delivery, allergens.
|
|
26
|
+
- Schema.org type is `Restaurant`.
|
|
27
|
+
|
|
28
|
+
## Mock seed
|
|
29
|
+
|
|
30
|
+
Wired to `--seed restaurant` (Mama's Kitchen).
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun install
|
|
36
|
+
bun dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Open <http://localhost:3000>.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# __STOREFRONT_NAME__
|
|
2
|
+
|
|
3
|
+
A Cimplify storefront scaffolded from the **bakery** template — Next.js 16 (App Router), React 19, Tailwind v4. Warm food-styled palette, Playfair Display + Inter typography, designed for bakeries, pâtisseries, and food businesses.
|
|
4
|
+
|
|
5
|
+
For a different industry, scaffold with `--template`:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bunx @cimplify/sdk init my-store --template retail # electronics / consumer goods
|
|
9
|
+
bunx @cimplify/sdk init my-store --template bakery # default — food / pâtisserie
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun install
|
|
16
|
+
bun dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Two things start in parallel:
|
|
20
|
+
|
|
21
|
+
- `bunx @cimplify/sdk` — the Cimplify mock API on `http://127.0.0.1:8787` (Akua's Bakery seeded by default).
|
|
22
|
+
- `next dev` — this storefront on `http://localhost:3000`.
|
|
23
|
+
|
|
24
|
+
Open the storefront in your browser. Edit `app/page.tsx` to start customising. The SDK ships full pages (`<CataloguePage>`, `<ProductPage>`, `<CartPage>`, `<CheckoutPage>`) and layouts (`<DefaultProductLayout>`, `<FoodProductLayout>`, etc.) that you can swap in.
|
|
25
|
+
|
|
26
|
+
## Structure
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
app/
|
|
30
|
+
layout.tsx # root layout, fonts, providers, header/footer/modal
|
|
31
|
+
page.tsx # home
|
|
32
|
+
shop/page.tsx # full catalogue (SDK <CataloguePage/>)
|
|
33
|
+
collections/[slug]/ # collection landing
|
|
34
|
+
categories/[slug]/ # category landing
|
|
35
|
+
cart/page.tsx # SDK <CartPage/>
|
|
36
|
+
checkout/page.tsx # SDK <CheckoutPage/>
|
|
37
|
+
orders/[id]/page.tsx # post-checkout thank-you
|
|
38
|
+
globals.css # Tailwind import + theme tokens
|
|
39
|
+
components/
|
|
40
|
+
providers.tsx # CimplifyProvider client wrapper
|
|
41
|
+
header.tsx, footer.tsx, hero.tsx
|
|
42
|
+
store-product-card.tsx # SDK <ProductCard/> wired to URL-driven modal
|
|
43
|
+
product-modal.tsx # ?product=<slug> deep-linkable modal
|
|
44
|
+
collection-strip.tsx # horizontal product strip
|
|
45
|
+
category-grid.tsx # SDK <CategoryGrid/> with router navigation
|
|
46
|
+
lib/
|
|
47
|
+
cart.ts # useCartCount() for the header pill
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Switch seed
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bunx @cimplify/sdk --seed restaurant # Mama's Kitchen
|
|
54
|
+
bunx @cimplify/sdk --seed retail # Currents Electronics
|
|
55
|
+
bunx @cimplify/sdk --seed services # Serene Spa
|
|
56
|
+
bunx @cimplify/sdk --seed grocery # FreshMart
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Update `NEXT_PUBLIC_CIMPLIFY_BUSINESS_ID` in `.env.local` to match the seeded business.
|
|
60
|
+
|
|
61
|
+
## Go live
|
|
62
|
+
|
|
63
|
+
```diff
|
|
64
|
+
# .env.local
|
|
65
|
+
- NEXT_PUBLIC_CIMPLIFY_API_URL=http://127.0.0.1:8787
|
|
66
|
+
+ NEXT_PUBLIC_CIMPLIFY_API_URL=https://api.cimplify.io
|
|
67
|
+
- NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY=mock-dev
|
|
68
|
+
+ NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY=<your tenant key>
|
|
69
|
+
- NEXT_PUBLIC_CIMPLIFY_BUSINESS_ID=bus_default_akua_bakery
|
|
70
|
+
+ NEXT_PUBLIC_CIMPLIFY_BUSINESS_ID=<your business id>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Deploy to Vercel with one click — `next.config.ts` already whitelists the SDK image hosts under `images.remotePatterns`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { brand } from "@/lib/brand";
|
|
3
|
+
|
|
4
|
+
export const metadata: Metadata = {
|
|
5
|
+
title: `About — ${brand.name}`,
|
|
6
|
+
description: brand.description,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function AboutPage() {
|
|
10
|
+
const a = brand.about;
|
|
11
|
+
const titleParts = a.title.split("\n");
|
|
12
|
+
return (
|
|
13
|
+
<article className="max-w-3xl mx-auto px-8 py-16">
|
|
14
|
+
<p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-primary mb-2">
|
|
15
|
+
{a.eyebrow}
|
|
16
|
+
</p>
|
|
17
|
+
<h1 className="font-serif text-[clamp(2.25rem,5vw,3.5rem)] font-semibold mb-6 -tracking-[0.02em]">
|
|
18
|
+
{titleParts.map((line, i) => (
|
|
19
|
+
<span key={i}>
|
|
20
|
+
{line}
|
|
21
|
+
{i < titleParts.length - 1 && <br />}
|
|
22
|
+
</span>
|
|
23
|
+
))}
|
|
24
|
+
</h1>
|
|
25
|
+
<div className="prose prose-lg max-w-none space-y-5 text-foreground/90 leading-relaxed">
|
|
26
|
+
{a.paragraphs.map((p, i) => (
|
|
27
|
+
<p key={i}>{p}</p>
|
|
28
|
+
))}
|
|
29
|
+
{a.sections.map((s) => (
|
|
30
|
+
<div key={s.heading}>
|
|
31
|
+
<h2 className="font-serif text-3xl font-semibold mt-10 mb-3">{s.heading}</h2>
|
|
32
|
+
<p>{s.body}</p>
|
|
33
|
+
</div>
|
|
34
|
+
))}
|
|
35
|
+
</div>
|
|
36
|
+
</article>
|
|
37
|
+
);
|
|
38
|
+
}
|