@doswiftly/cli 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +357 -0
- package/bin/doswiftly.js +2 -0
- package/dist/commands/auth-github.d.ts +6 -0
- package/dist/commands/auth-github.d.ts.map +1 -0
- package/dist/commands/auth-github.js +89 -0
- package/dist/commands/auth-github.js.map +1 -0
- package/dist/commands/auth-token.d.ts +12 -0
- package/dist/commands/auth-token.d.ts.map +1 -0
- package/dist/commands/auth-token.js +43 -0
- package/dist/commands/auth-token.js.map +1 -0
- package/dist/commands/auth.d.ts +22 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +348 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/check.d.ts +5 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +234 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +104 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/deploy.d.ts +37 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +580 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +8 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +83 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +363 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/domain.d.ts +13 -0
- package/dist/commands/domain.d.ts.map +1 -0
- package/dist/commands/domain.js +128 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/env.d.ts +25 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +228 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1028 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +12 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +162 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/migrate.d.ts +18 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +355 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/preview.d.ts +29 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +199 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/proxy.d.ts +9 -0
- package/dist/commands/proxy.d.ts.map +1 -0
- package/dist/commands/proxy.js +37 -0
- package/dist/commands/proxy.js.map +1 -0
- package/dist/commands/sdk.d.ts +5 -0
- package/dist/commands/sdk.d.ts.map +1 -0
- package/dist/commands/sdk.js +82 -0
- package/dist/commands/sdk.js.map +1 -0
- package/dist/commands/template.d.ts +107 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +1309 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/types.d.ts +5 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +82 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +103 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/upgrade.d.ts +18 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +55 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/verify.d.ts +5 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +232 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/whoami.d.ts +5 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +60 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config/types.d.ts +173 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +48 -0
- package/dist/config/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +416 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-url.d.ts +14 -0
- package/dist/lib/api-url.d.ts.map +1 -0
- package/dist/lib/api-url.js +24 -0
- package/dist/lib/api-url.js.map +1 -0
- package/dist/lib/api.d.ts +67 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +36 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +39 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +195 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/env-storage.d.ts +140 -0
- package/dist/lib/env-storage.d.ts.map +1 -0
- package/dist/lib/env-storage.js +464 -0
- package/dist/lib/env-storage.js.map +1 -0
- package/dist/lib/errors.d.ts +61 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +204 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/i18n.d.ts +99 -0
- package/dist/lib/i18n.d.ts.map +1 -0
- package/dist/lib/i18n.js +184 -0
- package/dist/lib/i18n.js.map +1 -0
- package/dist/lib/logger.d.ts +95 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +168 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/package-manager.d.ts +91 -0
- package/dist/lib/package-manager.d.ts.map +1 -0
- package/dist/lib/package-manager.js +205 -0
- package/dist/lib/package-manager.js.map +1 -0
- package/dist/lib/proxy-server.d.ts +24 -0
- package/dist/lib/proxy-server.d.ts.map +1 -0
- package/dist/lib/proxy-server.js +173 -0
- package/dist/lib/proxy-server.js.map +1 -0
- package/dist/lib/select-with-back.d.ts +34 -0
- package/dist/lib/select-with-back.d.ts.map +1 -0
- package/dist/lib/select-with-back.js +94 -0
- package/dist/lib/select-with-back.js.map +1 -0
- package/dist/lib/shared-api-client.d.ts +40 -0
- package/dist/lib/shared-api-client.d.ts.map +1 -0
- package/dist/lib/shared-api-client.js +92 -0
- package/dist/lib/shared-api-client.js.map +1 -0
- package/dist/lib/wizard-engine.d.ts +128 -0
- package/dist/lib/wizard-engine.d.ts.map +1 -0
- package/dist/lib/wizard-engine.js +168 -0
- package/dist/lib/wizard-engine.js.map +1 -0
- package/package.json +85 -0
- package/templates/storefront-minimal/.env.example +10 -0
- package/templates/storefront-minimal/.github/workflows/build-template.yml +109 -0
- package/templates/storefront-minimal/app/globals.css +18 -0
- package/templates/storefront-minimal/app/layout.tsx +26 -0
- package/templates/storefront-minimal/app/page.tsx +93 -0
- package/templates/storefront-minimal/lib/graphql-client.ts +23 -0
- package/templates/storefront-minimal/next.config.ts +15 -0
- package/templates/storefront-minimal/open-next.config.ts +3 -0
- package/templates/storefront-minimal/package.json +30 -0
- package/templates/storefront-minimal/postcss.config.mjs +5 -0
- package/templates/storefront-minimal/tailwind.config.ts +14 -0
- package/templates/storefront-minimal/tsconfig.json +27 -0
- package/templates/storefront-minimal/wrangler.toml +9 -0
- package/templates/storefront-nextjs/.env.example +68 -0
- package/templates/storefront-nextjs/.github/workflows/build-template.yml +109 -0
- package/templates/storefront-nextjs/.github/workflows/deploy.yml +25 -0
- package/templates/storefront-nextjs/.github/workflows/preview.yml +22 -0
- package/templates/storefront-nextjs/README.md +520 -0
- package/templates/storefront-nextjs/app/account/orders/page.tsx +216 -0
- package/templates/storefront-nextjs/app/account/page.tsx +167 -0
- package/templates/storefront-nextjs/app/auth/login/page.tsx +135 -0
- package/templates/storefront-nextjs/app/auth/register/page.tsx +228 -0
- package/templates/storefront-nextjs/app/cart/page.tsx +263 -0
- package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +200 -0
- package/templates/storefront-nextjs/app/categories/page.tsx +58 -0
- package/templates/storefront-nextjs/app/checkout/page.tsx +351 -0
- package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +158 -0
- package/templates/storefront-nextjs/app/collections/page.tsx +61 -0
- package/templates/storefront-nextjs/app/globals.css +98 -0
- package/templates/storefront-nextjs/app/layout.tsx +39 -0
- package/templates/storefront-nextjs/app/page.tsx +136 -0
- package/templates/storefront-nextjs/app/products/[slug]/page.tsx +119 -0
- package/templates/storefront-nextjs/app/products/page.tsx +107 -0
- package/templates/storefront-nextjs/app/search/page.tsx +127 -0
- package/templates/storefront-nextjs/components/auth/auth-guard.tsx +94 -0
- package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +77 -0
- package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +29 -0
- package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +217 -0
- package/templates/storefront-nextjs/components/commerce/pagination.tsx +62 -0
- package/templates/storefront-nextjs/components/commerce/product-actions.tsx +135 -0
- package/templates/storefront-nextjs/components/commerce/product-filters.tsx +109 -0
- package/templates/storefront-nextjs/components/commerce/product-price.tsx +375 -0
- package/templates/storefront-nextjs/components/commerce/search-input.tsx +178 -0
- package/templates/storefront-nextjs/components/commerce/sort-select.tsx +64 -0
- package/templates/storefront-nextjs/components/commerce/variant-selector.tsx +210 -0
- package/templates/storefront-nextjs/components/layout/footer.tsx +107 -0
- package/templates/storefront-nextjs/components/layout/header.tsx +104 -0
- package/templates/storefront-nextjs/components/providers.tsx +62 -0
- package/templates/storefront-nextjs/lib/auth/routes.ts +52 -0
- package/templates/storefront-nextjs/lib/currency.tsx +140 -0
- package/templates/storefront-nextjs/lib/format.ts +159 -0
- package/templates/storefront-nextjs/lib/graphql-queries.ts +629 -0
- package/templates/storefront-nextjs/lib/hooks.ts +30 -0
- package/templates/storefront-nextjs/middleware.ts +80 -0
- package/templates/storefront-nextjs/next.config.ts +37 -0
- package/templates/storefront-nextjs/open-next.config.ts +3 -0
- package/templates/storefront-nextjs/package.dev.json +30 -0
- package/templates/storefront-nextjs/package.json +32 -0
- package/templates/storefront-nextjs/package.json.template +32 -0
- package/templates/storefront-nextjs/postcss.config.mjs +8 -0
- package/templates/storefront-nextjs/tailwind.config.ts +111 -0
- package/templates/storefront-nextjs/tsconfig.json +27 -0
- package/templates/storefront-nextjs/wrangler.toml +9 -0
- package/templates/storefront-nextjs-shadcn/.env.example +68 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +109 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +25 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +22 -0
- package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +282 -0
- package/templates/storefront-nextjs-shadcn/CLAUDE.md +96 -0
- package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +190 -0
- package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +263 -0
- package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +135 -0
- package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +142 -0
- package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +448 -0
- package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +307 -0
- package/templates/storefront-nextjs-shadcn/README.md +195 -0
- package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +245 -0
- package/templates/storefront-nextjs-shadcn/app/about/page.tsx +34 -0
- package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +215 -0
- package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +484 -0
- package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +128 -0
- package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/tracking/page.tsx +206 -0
- package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +80 -0
- package/templates/storefront-nextjs-shadcn/app/account/page.tsx +107 -0
- package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +195 -0
- package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +87 -0
- package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +125 -0
- package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +131 -0
- package/templates/storefront-nextjs-shadcn/app/auth/login/page.tsx +24 -0
- package/templates/storefront-nextjs-shadcn/app/auth/register/page.tsx +20 -0
- package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +323 -0
- package/templates/storefront-nextjs-shadcn/app/blog/page.tsx +159 -0
- package/templates/storefront-nextjs-shadcn/app/brands/[slug]/page.tsx +170 -0
- package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +73 -0
- package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +165 -0
- package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +78 -0
- package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +75 -0
- package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +1752 -0
- package/templates/storefront-nextjs-shadcn/app/checkout/success/[orderId]/page.tsx +256 -0
- package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +74 -0
- package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +75 -0
- package/templates/storefront-nextjs-shadcn/app/contact/page.tsx +114 -0
- package/templates/storefront-nextjs-shadcn/app/error.tsx +90 -0
- package/templates/storefront-nextjs-shadcn/app/globals.css +125 -0
- package/templates/storefront-nextjs-shadcn/app/layout.tsx +57 -0
- package/templates/storefront-nextjs-shadcn/app/not-found.tsx +68 -0
- package/templates/storefront-nextjs-shadcn/app/page.tsx +21 -0
- package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +246 -0
- package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +343 -0
- package/templates/storefront-nextjs-shadcn/app/products/page.tsx +25 -0
- package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +192 -0
- package/templates/storefront-nextjs-shadcn/app/returns/page.tsx +77 -0
- package/templates/storefront-nextjs-shadcn/app/robots.ts +53 -0
- package/templates/storefront-nextjs-shadcn/app/search/page.tsx +16 -0
- package/templates/storefront-nextjs-shadcn/app/search/search-client.tsx +47 -0
- package/templates/storefront-nextjs-shadcn/app/shipping/page.tsx +62 -0
- package/templates/storefront-nextjs-shadcn/app/sitemap.ts +144 -0
- package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +179 -0
- package/templates/storefront-nextjs-shadcn/codegen.ts +51 -0
- package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +348 -0
- package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +144 -0
- package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +258 -0
- package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +107 -0
- package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +132 -0
- package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +188 -0
- package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +305 -0
- package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +240 -0
- package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +177 -0
- package/templates/storefront-nextjs-shadcn/components/blog/index.ts +8 -0
- package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +119 -0
- package/templates/storefront-nextjs-shadcn/components/brand/brand-grid.tsx +64 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +140 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +48 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +112 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +84 -0
- package/templates/storefront-nextjs-shadcn/components/cart/index.ts +17 -0
- package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +121 -0
- package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +162 -0
- package/templates/storefront-nextjs-shadcn/components/checkout/index.ts +25 -0
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +187 -0
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +160 -0
- package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +154 -0
- package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +225 -0
- package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +62 -0
- package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +158 -0
- package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +174 -0
- package/templates/storefront-nextjs-shadcn/components/commerce/variant-selector.tsx +210 -0
- package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +97 -0
- package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +187 -0
- package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +151 -0
- package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +166 -0
- package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +245 -0
- package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +246 -0
- package/templates/storefront-nextjs-shadcn/components/discount/index.ts +19 -0
- package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +113 -0
- package/templates/storefront-nextjs-shadcn/components/error/index.ts +7 -0
- package/templates/storefront-nextjs-shadcn/components/filters/attribute-filter.tsx +153 -0
- package/templates/storefront-nextjs-shadcn/components/filters/checkbox-group-filter.tsx +167 -0
- package/templates/storefront-nextjs-shadcn/components/filters/color-swatch-filter.tsx +176 -0
- package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +220 -0
- package/templates/storefront-nextjs-shadcn/components/filters/index.ts +36 -0
- package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +193 -0
- package/templates/storefront-nextjs-shadcn/components/filters/toggle-filter.tsx +132 -0
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +321 -0
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +309 -0
- package/templates/storefront-nextjs-shadcn/components/gift-card/index.ts +24 -0
- package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +72 -0
- package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +107 -0
- package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +85 -0
- package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +34 -0
- package/templates/storefront-nextjs-shadcn/components/home/index.ts +8 -0
- package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +108 -0
- package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +133 -0
- package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +341 -0
- package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +128 -0
- package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +147 -0
- package/templates/storefront-nextjs-shadcn/components/layout/index.ts +9 -0
- package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +211 -0
- package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +95 -0
- package/templates/storefront-nextjs-shadcn/components/layout/theme-switcher.tsx +192 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/index.ts +11 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +93 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +177 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +250 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +217 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/tier-badge.tsx +106 -0
- package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +131 -0
- package/templates/storefront-nextjs-shadcn/components/order/delivery-estimate.tsx +196 -0
- package/templates/storefront-nextjs-shadcn/components/order/index.ts +11 -0
- package/templates/storefront-nextjs-shadcn/components/order/order-tracking.tsx +200 -0
- package/templates/storefront-nextjs-shadcn/components/order/shipment-card.tsx +407 -0
- package/templates/storefront-nextjs-shadcn/components/order/tracking-status.tsx +222 -0
- package/templates/storefront-nextjs-shadcn/components/order/tracking-timeline.tsx +205 -0
- package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +161 -0
- package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +250 -0
- package/templates/storefront-nextjs-shadcn/components/product/discount-badge.tsx +196 -0
- package/templates/storefront-nextjs-shadcn/components/product/index.ts +41 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +147 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +217 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-gallery.tsx +143 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +83 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +155 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +158 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-quantity-selector.tsx +111 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +238 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +58 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +169 -0
- package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +220 -0
- package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +338 -0
- package/templates/storefront-nextjs-shadcn/components/product/review-summary.tsx +143 -0
- package/templates/storefront-nextjs-shadcn/components/product/sale-countdown.tsx +166 -0
- package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +213 -0
- package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +57 -0
- package/templates/storefront-nextjs-shadcn/components/product/stock-indicator.tsx +91 -0
- package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +103 -0
- package/templates/storefront-nextjs-shadcn/components/providers/index.ts +8 -0
- package/templates/storefront-nextjs-shadcn/components/providers/query-provider.tsx +260 -0
- package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +13 -0
- package/templates/storefront-nextjs-shadcn/components/returns/index.ts +26 -0
- package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +608 -0
- package/templates/storefront-nextjs-shadcn/components/returns/return-status-card.tsx +554 -0
- package/templates/storefront-nextjs-shadcn/components/search/index.ts +8 -0
- package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +140 -0
- package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +58 -0
- package/templates/storefront-nextjs-shadcn/components/search/search-suggestions.tsx +43 -0
- package/templates/storefront-nextjs-shadcn/components/seo/index.ts +12 -0
- package/templates/storefront-nextjs-shadcn/components/seo/json-ld.tsx +56 -0
- package/templates/storefront-nextjs-shadcn/components/seo/product-json-ld.ts +167 -0
- package/templates/storefront-nextjs-shadcn/components/shipping/index.ts +16 -0
- package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +337 -0
- package/templates/storefront-nextjs-shadcn/components/ui/accordion.tsx +153 -0
- package/templates/storefront-nextjs-shadcn/components/ui/alert.tsx +59 -0
- package/templates/storefront-nextjs-shadcn/components/ui/badge.tsx +34 -0
- package/templates/storefront-nextjs-shadcn/components/ui/button.tsx +51 -0
- package/templates/storefront-nextjs-shadcn/components/ui/card.tsx +77 -0
- package/templates/storefront-nextjs-shadcn/components/ui/checkbox.tsx +30 -0
- package/templates/storefront-nextjs-shadcn/components/ui/dialog.tsx +137 -0
- package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +207 -0
- package/templates/storefront-nextjs-shadcn/components/ui/index.ts +67 -0
- package/templates/storefront-nextjs-shadcn/components/ui/input.tsx +65 -0
- package/templates/storefront-nextjs-shadcn/components/ui/label.tsx +26 -0
- package/templates/storefront-nextjs-shadcn/components/ui/pagination.tsx +205 -0
- package/templates/storefront-nextjs-shadcn/components/ui/radio-group.tsx +44 -0
- package/templates/storefront-nextjs-shadcn/components/ui/select.tsx +160 -0
- package/templates/storefront-nextjs-shadcn/components/ui/separator.tsx +28 -0
- package/templates/storefront-nextjs-shadcn/components/ui/skeleton.tsx +20 -0
- package/templates/storefront-nextjs-shadcn/components/ui/spinner.tsx +82 -0
- package/templates/storefront-nextjs-shadcn/components/ui/tabs.tsx +119 -0
- package/templates/storefront-nextjs-shadcn/components/ui/toast.tsx +96 -0
- package/templates/storefront-nextjs-shadcn/components/wishlist/index.ts +9 -0
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +148 -0
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +47 -0
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +165 -0
- package/templates/storefront-nextjs-shadcn/components.json +19 -0
- package/templates/storefront-nextjs-shadcn/generated/.gitkeep +2 -0
- package/templates/storefront-nextjs-shadcn/graphql/.gitkeep +31 -0
- package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +168 -0
- package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +160 -0
- package/templates/storefront-nextjs-shadcn/hooks/index.ts +9 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +310 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +286 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +110 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.test.ts +173 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.ts +298 -0
- package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +220 -0
- package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +57 -0
- package/templates/storefront-nextjs-shadcn/lib/config.ts +46 -0
- package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +254 -0
- package/templates/storefront-nextjs-shadcn/lib/currency/README.md +464 -0
- package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +328 -0
- package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +295 -0
- package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +27 -0
- package/templates/storefront-nextjs-shadcn/lib/format.test.ts +397 -0
- package/templates/storefront-nextjs-shadcn/lib/format.ts +226 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +109 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +1183 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +267 -0
- package/templates/storefront-nextjs-shadcn/lib/hooks.ts +30 -0
- package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +89 -0
- package/templates/storefront-nextjs-shadcn/lib/utils.ts +6 -0
- package/templates/storefront-nextjs-shadcn/next.config.ts +47 -0
- package/templates/storefront-nextjs-shadcn/open-next.config.ts +3 -0
- package/templates/storefront-nextjs-shadcn/package.dev.json +30 -0
- package/templates/storefront-nextjs-shadcn/package.json +60 -0
- package/templates/storefront-nextjs-shadcn/package.json.template +46 -0
- package/templates/storefront-nextjs-shadcn/postcss.config.mjs +8 -0
- package/templates/storefront-nextjs-shadcn/proxy.ts +80 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/apple-pay.svg +8 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/bank-transfer.svg +10 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/blik.svg +6 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/cash-on-delivery.svg +11 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/google-pay.svg +11 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/mastercard.svg +7 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/paypal.svg +7 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/payu.svg +7 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/przelewy24.svg +7 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/stripe.svg +4 -0
- package/templates/storefront-nextjs-shadcn/public/icons/payment/visa.svg +5 -0
- package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +66 -0
- package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +56 -0
- package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +184 -0
- package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +103 -0
- package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +291 -0
- package/templates/storefront-nextjs-shadcn/tailwind.config.ts +111 -0
- package/templates/storefront-nextjs-shadcn/tsconfig.json +27 -0
- package/templates/storefront-nextjs-shadcn/wrangler.toml +9 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CurrencySelector - Dropdown for selecting preferred currency
|
|
5
|
+
*
|
|
6
|
+
* This component:
|
|
7
|
+
* 1. Displays current currency with dropdown
|
|
8
|
+
* 2. Shows all supported currencies from Shop data
|
|
9
|
+
* 3. Updates currency store on selection
|
|
10
|
+
* 4. Invalidates React Query cache to trigger refetch with new currency
|
|
11
|
+
*
|
|
12
|
+
* The currency change triggers:
|
|
13
|
+
* - Store update (persisted to localStorage)
|
|
14
|
+
* - Cache invalidation (all queries refetch with new currency header)
|
|
15
|
+
* - UI updates (prices re-render in new currency)
|
|
16
|
+
*
|
|
17
|
+
* @module storefront-nextjs/components/layout/currency-selector
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { useState, useRef, useEffect } from 'react';
|
|
21
|
+
import { useCurrencyStore } from '@/stores/currency-store';
|
|
22
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
23
|
+
import { ChevronDown, Check, Globe } from 'lucide-react';
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// CURRENCY DATA
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Currency symbols for display
|
|
31
|
+
* Maps currency codes to their symbols
|
|
32
|
+
*/
|
|
33
|
+
const CURRENCY_SYMBOLS: Record<string, string> = {
|
|
34
|
+
PLN: 'zł',
|
|
35
|
+
EUR: '€',
|
|
36
|
+
USD: '$',
|
|
37
|
+
GBP: '£',
|
|
38
|
+
CHF: 'CHF',
|
|
39
|
+
CZK: 'Kč',
|
|
40
|
+
SEK: 'kr',
|
|
41
|
+
NOK: 'kr',
|
|
42
|
+
DKK: 'kr',
|
|
43
|
+
JPY: '¥',
|
|
44
|
+
CNY: '¥',
|
|
45
|
+
AUD: 'A$',
|
|
46
|
+
CAD: 'C$',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Currency names for display
|
|
51
|
+
* Maps currency codes to their full names
|
|
52
|
+
*/
|
|
53
|
+
const CURRENCY_NAMES: Record<string, string> = {
|
|
54
|
+
PLN: 'Polish Złoty',
|
|
55
|
+
EUR: 'Euro',
|
|
56
|
+
USD: 'US Dollar',
|
|
57
|
+
GBP: 'British Pound',
|
|
58
|
+
CHF: 'Swiss Franc',
|
|
59
|
+
CZK: 'Czech Koruna',
|
|
60
|
+
SEK: 'Swedish Krona',
|
|
61
|
+
NOK: 'Norwegian Krone',
|
|
62
|
+
DKK: 'Danish Krone',
|
|
63
|
+
JPY: 'Japanese Yen',
|
|
64
|
+
CNY: 'Chinese Yuan',
|
|
65
|
+
AUD: 'Australian Dollar',
|
|
66
|
+
CAD: 'Canadian Dollar',
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// TYPES
|
|
71
|
+
// ============================================================================
|
|
72
|
+
|
|
73
|
+
interface CurrencySelectorProps {
|
|
74
|
+
/**
|
|
75
|
+
* Additional CSS classes
|
|
76
|
+
*/
|
|
77
|
+
className?: string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Show currency symbol instead of code
|
|
81
|
+
* @default false
|
|
82
|
+
*/
|
|
83
|
+
showSymbol?: boolean;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Show globe icon
|
|
87
|
+
* @default true
|
|
88
|
+
*/
|
|
89
|
+
showIcon?: boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Visual variant
|
|
93
|
+
* @default 'default'
|
|
94
|
+
*/
|
|
95
|
+
variant?: 'default' | 'compact' | 'minimal';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ============================================================================
|
|
99
|
+
// COMPONENT
|
|
100
|
+
// ============================================================================
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* CurrencySelector - Dropdown for selecting preferred currency
|
|
104
|
+
*
|
|
105
|
+
* This component allows users to change their preferred currency.
|
|
106
|
+
* When a currency is selected:
|
|
107
|
+
* 1. The currency store is updated (persisted to localStorage)
|
|
108
|
+
* 2. React Query cache is invalidated
|
|
109
|
+
* 3. All queries refetch with new currency header
|
|
110
|
+
* 4. Prices update throughout the application
|
|
111
|
+
*
|
|
112
|
+
* The component handles:
|
|
113
|
+
* - Hydration mismatches (shows skeleton until loaded)
|
|
114
|
+
* - Keyboard navigation (Escape to close)
|
|
115
|
+
* - Click outside to close
|
|
116
|
+
* - Accessibility (ARIA attributes)
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```tsx
|
|
120
|
+
* // In Header component
|
|
121
|
+
* import { CurrencySelector } from '@/components/layout/currency-selector';
|
|
122
|
+
*
|
|
123
|
+
* export function Header() {
|
|
124
|
+
* return (
|
|
125
|
+
* <header>
|
|
126
|
+
* <nav>
|
|
127
|
+
* <CurrencySelector />
|
|
128
|
+
* </nav>
|
|
129
|
+
* </header>
|
|
130
|
+
* );
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```tsx
|
|
136
|
+
* // Compact variant in mobile menu
|
|
137
|
+
* <CurrencySelector variant="compact" showSymbol />
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @param props - Component props
|
|
141
|
+
* @param props.className - Additional CSS classes
|
|
142
|
+
* @param props.showSymbol - Show currency symbol instead of code
|
|
143
|
+
* @param props.showIcon - Show globe icon
|
|
144
|
+
* @param props.variant - Visual variant (default, compact, minimal)
|
|
145
|
+
*/
|
|
146
|
+
export function CurrencySelector({
|
|
147
|
+
className = '',
|
|
148
|
+
showSymbol = false,
|
|
149
|
+
showIcon = true,
|
|
150
|
+
variant = 'default',
|
|
151
|
+
}: CurrencySelectorProps) {
|
|
152
|
+
// Currency store state
|
|
153
|
+
const currency = useCurrencyStore((state) => state.currency);
|
|
154
|
+
const supportedCurrencies = useCurrencyStore((state) => state.supportedCurrencies);
|
|
155
|
+
const setCurrency = useCurrencyStore((state) => state.setCurrency);
|
|
156
|
+
const isLoaded = useCurrencyStore((state) => state.isLoaded);
|
|
157
|
+
|
|
158
|
+
// React Query client for cache invalidation
|
|
159
|
+
const queryClient = useQueryClient();
|
|
160
|
+
|
|
161
|
+
// Local state for dropdown
|
|
162
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
163
|
+
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
164
|
+
|
|
165
|
+
// Close dropdown on outside click
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
function handleClickOutside(event: MouseEvent) {
|
|
168
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
169
|
+
setIsOpen(false);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (isOpen) {
|
|
174
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
175
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
176
|
+
}
|
|
177
|
+
}, [isOpen]);
|
|
178
|
+
|
|
179
|
+
// Close on escape key
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
function handleEscape(event: KeyboardEvent) {
|
|
182
|
+
if (event.key === 'Escape') {
|
|
183
|
+
setIsOpen(false);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (isOpen) {
|
|
188
|
+
document.addEventListener('keydown', handleEscape);
|
|
189
|
+
return () => document.removeEventListener('keydown', handleEscape);
|
|
190
|
+
}
|
|
191
|
+
}, [isOpen]);
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Handle currency selection
|
|
195
|
+
*
|
|
196
|
+
* Updates store and invalidates cache to trigger refetch
|
|
197
|
+
* with new currency header.
|
|
198
|
+
*
|
|
199
|
+
* @param newCurrency - Selected currency code
|
|
200
|
+
*/
|
|
201
|
+
const handleChange = (newCurrency: string) => {
|
|
202
|
+
if (newCurrency === currency) {
|
|
203
|
+
setIsOpen(false);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Update store (persists to localStorage)
|
|
208
|
+
setCurrency(newCurrency);
|
|
209
|
+
|
|
210
|
+
// Invalidate all queries to trigger refetch with new currency
|
|
211
|
+
// This ensures all prices update to the new currency
|
|
212
|
+
queryClient.invalidateQueries();
|
|
213
|
+
|
|
214
|
+
// Close dropdown
|
|
215
|
+
setIsOpen(false);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Prevent SSR mismatch - show skeleton until hydrated
|
|
219
|
+
if (!isLoaded || !currency) {
|
|
220
|
+
return (
|
|
221
|
+
<div className={`inline-block ${className}`}>
|
|
222
|
+
<div className="px-3 py-2 bg-gray-100 dark:bg-gray-800 rounded-lg animate-pulse w-16 h-9" />
|
|
223
|
+
</div>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Display value (symbol or code)
|
|
228
|
+
const displayValue = showSymbol
|
|
229
|
+
? (CURRENCY_SYMBOLS[currency] || currency)
|
|
230
|
+
: currency;
|
|
231
|
+
|
|
232
|
+
// Variant-specific styles
|
|
233
|
+
const buttonStyles = {
|
|
234
|
+
default: 'px-3 py-2 text-sm',
|
|
235
|
+
compact: 'px-2 py-1.5 text-xs',
|
|
236
|
+
minimal: 'px-2 py-1 text-xs',
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const dropdownStyles = {
|
|
240
|
+
default: 'w-48',
|
|
241
|
+
compact: 'w-40',
|
|
242
|
+
minimal: 'w-36',
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<div ref={dropdownRef} className={`relative inline-block ${className}`}>
|
|
247
|
+
{/* Trigger Button */}
|
|
248
|
+
<button
|
|
249
|
+
type="button"
|
|
250
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
251
|
+
className={`
|
|
252
|
+
inline-flex items-center justify-between gap-2
|
|
253
|
+
bg-white dark:bg-gray-800
|
|
254
|
+
border border-gray-200 dark:border-gray-700
|
|
255
|
+
rounded-lg
|
|
256
|
+
text-gray-700 dark:text-gray-200
|
|
257
|
+
hover:bg-gray-50 dark:hover:bg-gray-700
|
|
258
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
259
|
+
transition-colors
|
|
260
|
+
${buttonStyles[variant]}
|
|
261
|
+
`}
|
|
262
|
+
aria-expanded={isOpen}
|
|
263
|
+
aria-haspopup="listbox"
|
|
264
|
+
aria-label="Select currency"
|
|
265
|
+
>
|
|
266
|
+
{showIcon && variant !== 'minimal' && (
|
|
267
|
+
<Globe className="w-4 h-4 text-gray-400" aria-hidden="true" />
|
|
268
|
+
)}
|
|
269
|
+
<span className="font-medium">{displayValue}</span>
|
|
270
|
+
<ChevronDown
|
|
271
|
+
className={`w-4 h-4 text-gray-400 transition-transform ${
|
|
272
|
+
isOpen ? 'rotate-180' : ''
|
|
273
|
+
}`}
|
|
274
|
+
aria-hidden="true"
|
|
275
|
+
/>
|
|
276
|
+
</button>
|
|
277
|
+
|
|
278
|
+
{/* Dropdown Menu */}
|
|
279
|
+
{isOpen && (
|
|
280
|
+
<div
|
|
281
|
+
className={`
|
|
282
|
+
absolute right-0 mt-2 z-50
|
|
283
|
+
bg-white dark:bg-gray-800
|
|
284
|
+
border border-gray-200 dark:border-gray-700
|
|
285
|
+
rounded-lg shadow-lg
|
|
286
|
+
overflow-hidden
|
|
287
|
+
${dropdownStyles[variant]}
|
|
288
|
+
`}
|
|
289
|
+
role="listbox"
|
|
290
|
+
aria-label="Currency options"
|
|
291
|
+
>
|
|
292
|
+
<div className="py-1 max-h-64 overflow-y-auto">
|
|
293
|
+
{supportedCurrencies.map((code) => {
|
|
294
|
+
const isSelected = code === currency;
|
|
295
|
+
const symbol = CURRENCY_SYMBOLS[code] || code;
|
|
296
|
+
const name = CURRENCY_NAMES[code] || code;
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<button
|
|
300
|
+
key={code}
|
|
301
|
+
type="button"
|
|
302
|
+
onClick={() => handleChange(code)}
|
|
303
|
+
className={`
|
|
304
|
+
w-full px-3 py-2 text-left
|
|
305
|
+
flex items-center justify-between gap-2
|
|
306
|
+
hover:bg-gray-100 dark:hover:bg-gray-700
|
|
307
|
+
transition-colors
|
|
308
|
+
${isSelected ? 'bg-blue-50 dark:bg-blue-900/20' : ''}
|
|
309
|
+
`}
|
|
310
|
+
role="option"
|
|
311
|
+
aria-selected={isSelected}
|
|
312
|
+
>
|
|
313
|
+
<div className="flex items-center gap-2">
|
|
314
|
+
<span className="w-6 text-center text-gray-400 font-mono text-sm">
|
|
315
|
+
{symbol}
|
|
316
|
+
</span>
|
|
317
|
+
<div>
|
|
318
|
+
<span className="font-medium text-gray-900 dark:text-gray-100">
|
|
319
|
+
{code}
|
|
320
|
+
</span>
|
|
321
|
+
{variant === 'default' && (
|
|
322
|
+
<span className="ml-2 text-xs text-gray-500 dark:text-gray-400">
|
|
323
|
+
{name}
|
|
324
|
+
</span>
|
|
325
|
+
)}
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
{isSelected && (
|
|
329
|
+
<Check className="w-4 h-4 text-blue-500" aria-hidden="true" />
|
|
330
|
+
)}
|
|
331
|
+
</button>
|
|
332
|
+
);
|
|
333
|
+
})}
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
)}
|
|
337
|
+
</div>
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export default CurrencySelector;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
|
|
3
|
+
export function Footer() {
|
|
4
|
+
const currentYear = new Date().getFullYear();
|
|
5
|
+
const siteName = process.env.NEXT_PUBLIC_SITE_NAME || "My Store";
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<footer className="border-t border-border bg-muted/50">
|
|
9
|
+
<div className="container mx-auto px-4 py-12">
|
|
10
|
+
<div className="grid grid-cols-1 gap-8 md:grid-cols-4">
|
|
11
|
+
{/* Brand */}
|
|
12
|
+
<div>
|
|
13
|
+
<Link href="/" className="text-xl font-bold text-primary hover:opacity-80 transition-opacity">
|
|
14
|
+
{siteName}
|
|
15
|
+
</Link>
|
|
16
|
+
<p className="mt-4 text-sm text-muted-foreground">
|
|
17
|
+
Quality products at affordable prices. Powered by DoSwiftly
|
|
18
|
+
Commerce.
|
|
19
|
+
</p>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{/* Shop */}
|
|
23
|
+
<div>
|
|
24
|
+
<h3 className="mb-4 font-semibold text-foreground">Shop</h3>
|
|
25
|
+
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
26
|
+
<li>
|
|
27
|
+
<Link href="/products" className="hover:text-primary transition-colors">
|
|
28
|
+
All Products
|
|
29
|
+
</Link>
|
|
30
|
+
</li>
|
|
31
|
+
<li>
|
|
32
|
+
<Link href="/collections" className="hover:text-primary transition-colors">
|
|
33
|
+
Collections
|
|
34
|
+
</Link>
|
|
35
|
+
</li>
|
|
36
|
+
<li>
|
|
37
|
+
<Link href="/categories" className="hover:text-primary transition-colors">
|
|
38
|
+
Categories
|
|
39
|
+
</Link>
|
|
40
|
+
</li>
|
|
41
|
+
<li>
|
|
42
|
+
<Link href="/search" className="hover:text-primary transition-colors">
|
|
43
|
+
Search
|
|
44
|
+
</Link>
|
|
45
|
+
</li>
|
|
46
|
+
</ul>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{/* Account */}
|
|
50
|
+
<div>
|
|
51
|
+
<h3 className="mb-4 font-semibold text-foreground">Account</h3>
|
|
52
|
+
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
53
|
+
<li>
|
|
54
|
+
<Link href="/auth/login" className="hover:text-primary transition-colors">
|
|
55
|
+
Sign In
|
|
56
|
+
</Link>
|
|
57
|
+
</li>
|
|
58
|
+
<li>
|
|
59
|
+
<Link href="/auth/register" className="hover:text-primary transition-colors">
|
|
60
|
+
Create Account
|
|
61
|
+
</Link>
|
|
62
|
+
</li>
|
|
63
|
+
<li>
|
|
64
|
+
<Link href="/account" className="hover:text-primary transition-colors">
|
|
65
|
+
My Account
|
|
66
|
+
</Link>
|
|
67
|
+
</li>
|
|
68
|
+
<li>
|
|
69
|
+
<Link href="/account/orders" className="hover:text-primary transition-colors">
|
|
70
|
+
Order History
|
|
71
|
+
</Link>
|
|
72
|
+
</li>
|
|
73
|
+
<li>
|
|
74
|
+
<Link href="/cart" className="hover:text-primary transition-colors">
|
|
75
|
+
Shopping Cart
|
|
76
|
+
</Link>
|
|
77
|
+
</li>
|
|
78
|
+
</ul>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
{/* Support */}
|
|
82
|
+
<div>
|
|
83
|
+
<h3 className="mb-4 font-semibold text-foreground">Support</h3>
|
|
84
|
+
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
85
|
+
<li>
|
|
86
|
+
<Link href="/contact" className="hover:text-primary transition-colors">
|
|
87
|
+
Contact Us
|
|
88
|
+
</Link>
|
|
89
|
+
</li>
|
|
90
|
+
<li>
|
|
91
|
+
<Link href="/about" className="hover:text-primary transition-colors">
|
|
92
|
+
About Us
|
|
93
|
+
</Link>
|
|
94
|
+
</li>
|
|
95
|
+
<li>
|
|
96
|
+
<Link href="/shipping" className="hover:text-primary transition-colors">
|
|
97
|
+
Shipping Info
|
|
98
|
+
</Link>
|
|
99
|
+
</li>
|
|
100
|
+
<li>
|
|
101
|
+
<Link href="/returns" className="hover:text-primary transition-colors">
|
|
102
|
+
Returns & Refunds
|
|
103
|
+
</Link>
|
|
104
|
+
</li>
|
|
105
|
+
</ul>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div className="mt-12 border-t border-border pt-8 text-center text-sm text-muted-foreground">
|
|
110
|
+
<p>
|
|
111
|
+
© {currentYear} {siteName}. All rights reserved.
|
|
112
|
+
</p>
|
|
113
|
+
<p className="mt-2">
|
|
114
|
+
Powered by{" "}
|
|
115
|
+
<a
|
|
116
|
+
href="https://doswiftly.pl"
|
|
117
|
+
target="_blank"
|
|
118
|
+
rel="noopener noreferrer"
|
|
119
|
+
className="text-primary hover:underline transition-colors"
|
|
120
|
+
>
|
|
121
|
+
DoSwiftly Commerce
|
|
122
|
+
</a>
|
|
123
|
+
</p>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</footer>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Menu, X } from "lucide-react";
|
|
6
|
+
import { CurrencySelector } from "@/components/commerce/currency-selector";
|
|
7
|
+
import { CartIcon } from "@/components/cart/cart-icon";
|
|
8
|
+
import { SearchInput } from "@/components/commerce/search-input";
|
|
9
|
+
import { Navigation } from "@/components/layout/navigation";
|
|
10
|
+
import { AccountMenu } from "@/components/auth/account-menu";
|
|
11
|
+
import { ThemeSwitcher } from "@/components/layout/theme-switcher";
|
|
12
|
+
import { useAuthStore } from "@/stores/auth-store";
|
|
13
|
+
|
|
14
|
+
export function Header() {
|
|
15
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
16
|
+
|
|
17
|
+
// Get authentication state from auth store
|
|
18
|
+
const { isAuthenticated, customer } = useAuthStore();
|
|
19
|
+
const customerName = customer
|
|
20
|
+
? `${customer.firstName || ""} ${customer.lastName || ""}`.trim() || customer.email
|
|
21
|
+
: undefined;
|
|
22
|
+
|
|
23
|
+
const navigationItems = [
|
|
24
|
+
{
|
|
25
|
+
label: "Products",
|
|
26
|
+
href: "/products",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "Collections",
|
|
30
|
+
href: "/collections",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
label: "Categories",
|
|
34
|
+
href: "/categories",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
label: "About",
|
|
38
|
+
href: "/about",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<header className="sticky top-0 z-50 border-b border-border bg-background shadow-sm">
|
|
44
|
+
<div className="container mx-auto px-4">
|
|
45
|
+
<div className="flex h-16 items-center justify-between">
|
|
46
|
+
{/* Logo */}
|
|
47
|
+
<Link href="/" className="text-xl font-bold text-primary hover:opacity-80 transition-opacity">
|
|
48
|
+
{process.env.NEXT_PUBLIC_SITE_NAME || "My Store"}
|
|
49
|
+
</Link>
|
|
50
|
+
|
|
51
|
+
{/* Desktop Navigation */}
|
|
52
|
+
<div className="hidden md:flex">
|
|
53
|
+
<Navigation items={navigationItems} />
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
{/* Search & Actions */}
|
|
57
|
+
<div className="flex items-center gap-3">
|
|
58
|
+
{/* Search */}
|
|
59
|
+
<div className="hidden w-64 lg:block">
|
|
60
|
+
<SearchInput placeholder="Search products..." />
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
{/* Currency Selector */}
|
|
64
|
+
<div className="hidden md:block">
|
|
65
|
+
<CurrencySelector variant="compact" />
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
{/* Theme Switcher */}
|
|
69
|
+
<div className="hidden md:block">
|
|
70
|
+
<ThemeSwitcher />
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
{/* Account Menu or Login Link */}
|
|
74
|
+
{isAuthenticated ? (
|
|
75
|
+
<AccountMenu customerName={customerName} />
|
|
76
|
+
) : (
|
|
77
|
+
<Link
|
|
78
|
+
href="/auth/login"
|
|
79
|
+
className="hidden md:inline-flex items-center rounded-md px-3 py-2 text-sm font-medium text-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
|
|
80
|
+
>
|
|
81
|
+
Sign In
|
|
82
|
+
</Link>
|
|
83
|
+
)}
|
|
84
|
+
|
|
85
|
+
{/* Cart Icon */}
|
|
86
|
+
<CartIcon />
|
|
87
|
+
|
|
88
|
+
{/* Mobile Menu Toggle */}
|
|
89
|
+
<button
|
|
90
|
+
className="p-2 text-foreground hover:text-primary md:hidden"
|
|
91
|
+
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
|
92
|
+
aria-label="Toggle menu"
|
|
93
|
+
aria-expanded={isMenuOpen}
|
|
94
|
+
>
|
|
95
|
+
{isMenuOpen ? (
|
|
96
|
+
<X className="h-5 w-5" />
|
|
97
|
+
) : (
|
|
98
|
+
<Menu className="h-5 w-5" />
|
|
99
|
+
)}
|
|
100
|
+
</button>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
{/* Mobile Navigation */}
|
|
105
|
+
{isMenuOpen && (
|
|
106
|
+
<nav className="border-t border-border py-4 md:hidden">
|
|
107
|
+
<div className="flex flex-col gap-4">
|
|
108
|
+
{/* Mobile Search */}
|
|
109
|
+
<div className="lg:hidden">
|
|
110
|
+
<SearchInput placeholder="Search products..." />
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
{/* Mobile Currency Selector */}
|
|
114
|
+
<div className="flex items-center justify-between">
|
|
115
|
+
<span className="text-sm font-medium text-muted-foreground">Currency</span>
|
|
116
|
+
<CurrencySelector variant="compact" />
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
{/* Mobile Navigation Links */}
|
|
120
|
+
{navigationItems.map((item) => (
|
|
121
|
+
<Link
|
|
122
|
+
key={item.href}
|
|
123
|
+
href={item.href}
|
|
124
|
+
className="text-foreground hover:text-primary transition-colors"
|
|
125
|
+
onClick={() => setIsMenuOpen(false)}
|
|
126
|
+
>
|
|
127
|
+
{item.label}
|
|
128
|
+
</Link>
|
|
129
|
+
))}
|
|
130
|
+
|
|
131
|
+
{/* Mobile Account Link */}
|
|
132
|
+
{!isAuthenticated && (
|
|
133
|
+
<Link
|
|
134
|
+
href="/auth/login"
|
|
135
|
+
className="text-foreground hover:text-primary transition-colors font-medium"
|
|
136
|
+
onClick={() => setIsMenuOpen(false)}
|
|
137
|
+
>
|
|
138
|
+
Sign In
|
|
139
|
+
</Link>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
</nav>
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
</header>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { Header } from './header';
|
|
2
|
+
export { Footer } from './footer';
|
|
3
|
+
export { Navigation } from './navigation';
|
|
4
|
+
export type { NavigationProps, NavigationItem } from './navigation';
|
|
5
|
+
export { MobileMenu } from './mobile-menu';
|
|
6
|
+
export type { MobileMenuProps, MobileMenuItem } from './mobile-menu';
|
|
7
|
+
export { Breadcrumbs, createBreadcrumbs } from './breadcrumbs';
|
|
8
|
+
export type { BreadcrumbsProps, BreadcrumbItem } from './breadcrumbs';
|
|
9
|
+
export { CurrencySelector } from './currency-selector';
|