@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,16 @@
|
|
|
1
|
+
import { Suspense } from "react";
|
|
2
|
+
import { Breadcrumbs } from "@/components/layout/breadcrumbs";
|
|
3
|
+
import { Spinner } from "@/components/ui/spinner";
|
|
4
|
+
import { SearchClient } from "./search-client";
|
|
5
|
+
|
|
6
|
+
export default function SearchPage() {
|
|
7
|
+
return (
|
|
8
|
+
<div className="container mx-auto px-4 py-8">
|
|
9
|
+
<Breadcrumbs className="mb-6" />
|
|
10
|
+
|
|
11
|
+
<Suspense fallback={<Spinner />}>
|
|
12
|
+
<SearchClient />
|
|
13
|
+
</Suspense>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useSearchParams } from "next/navigation";
|
|
4
|
+
import { SearchResults } from "@/components/search/search-results";
|
|
5
|
+
import { SearchBar } from "@/components/search/search-bar";
|
|
6
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
7
|
+
import { useProducts } from "@/lib/graphql/hooks";
|
|
8
|
+
|
|
9
|
+
export function SearchClient() {
|
|
10
|
+
const searchParams = useSearchParams();
|
|
11
|
+
const query = searchParams.get("q") || "";
|
|
12
|
+
|
|
13
|
+
// Fetch search results using GraphQL
|
|
14
|
+
const { data, isLoading, error } = useProducts({
|
|
15
|
+
first: 20,
|
|
16
|
+
query: query || undefined,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const results = data?.products ?? [];
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
{/* Search Header */}
|
|
24
|
+
<div className="mb-8">
|
|
25
|
+
<h1 className="mb-4 text-3xl font-bold text-foreground">
|
|
26
|
+
{query ? `Search results for "${query}"` : "Search Products"}
|
|
27
|
+
</h1>
|
|
28
|
+
|
|
29
|
+
{/* Search Bar */}
|
|
30
|
+
<div className="mx-auto max-w-2xl">
|
|
31
|
+
<SearchBar defaultValue={query} />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
{/* Results */}
|
|
36
|
+
{isLoading ? (
|
|
37
|
+
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
|
38
|
+
{Array.from({ length: 8 }).map((_, i) => (
|
|
39
|
+
<Skeleton key={i} className="aspect-square w-full" />
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
) : (
|
|
43
|
+
<SearchResults query={query} results={results} />
|
|
44
|
+
)}
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Breadcrumbs } from "@/components/layout/breadcrumbs";
|
|
2
|
+
import { Truck, Package, Clock } from "lucide-react";
|
|
3
|
+
|
|
4
|
+
export default function ShippingPage() {
|
|
5
|
+
return (
|
|
6
|
+
<div className="container mx-auto px-4 py-8">
|
|
7
|
+
<Breadcrumbs className="mb-6" />
|
|
8
|
+
|
|
9
|
+
<div className="mx-auto max-w-3xl">
|
|
10
|
+
<h1 className="mb-6 text-4xl font-bold text-foreground">Shipping Information</h1>
|
|
11
|
+
|
|
12
|
+
<div className="space-y-8">
|
|
13
|
+
<div>
|
|
14
|
+
<div className="mb-4 flex items-center gap-3">
|
|
15
|
+
<Truck className="h-6 w-6 text-primary" />
|
|
16
|
+
<h2 className="text-2xl font-semibold text-foreground">Shipping Methods</h2>
|
|
17
|
+
</div>
|
|
18
|
+
<div className="space-y-4 text-muted-foreground">
|
|
19
|
+
<div className="rounded-lg border border-border p-4">
|
|
20
|
+
<h3 className="font-semibold text-foreground">Standard Shipping</h3>
|
|
21
|
+
<p className="mt-1 text-sm">Delivery in 3-5 business days</p>
|
|
22
|
+
<p className="mt-1 text-sm font-medium">Free on orders over $50</p>
|
|
23
|
+
</div>
|
|
24
|
+
<div className="rounded-lg border border-border p-4">
|
|
25
|
+
<h3 className="font-semibold text-foreground">Express Shipping</h3>
|
|
26
|
+
<p className="mt-1 text-sm">Delivery in 1-2 business days</p>
|
|
27
|
+
<p className="mt-1 text-sm font-medium">$15.00</p>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div>
|
|
33
|
+
<div className="mb-4 flex items-center gap-3">
|
|
34
|
+
<Package className="h-6 w-6 text-primary" />
|
|
35
|
+
<h2 className="text-2xl font-semibold text-foreground">Order Processing</h2>
|
|
36
|
+
</div>
|
|
37
|
+
<p className="text-muted-foreground">
|
|
38
|
+
Orders are processed within 1-2 business days. You will receive a confirmation email with tracking information once your order ships.
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div>
|
|
43
|
+
<div className="mb-4 flex items-center gap-3">
|
|
44
|
+
<Clock className="h-6 w-6 text-primary" />
|
|
45
|
+
<h2 className="text-2xl font-semibold text-foreground">Delivery Times</h2>
|
|
46
|
+
</div>
|
|
47
|
+
<p className="text-muted-foreground">
|
|
48
|
+
Delivery times are estimates and may vary based on your location and shipping method selected. International orders may take longer and are subject to customs processing.
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div>
|
|
53
|
+
<h2 className="mb-4 text-2xl font-semibold text-foreground">International Shipping</h2>
|
|
54
|
+
<p className="text-muted-foreground">
|
|
55
|
+
We ship to most countries worldwide. International shipping rates and delivery times vary by destination. Customs duties and taxes may apply and are the responsibility of the customer.
|
|
56
|
+
</p>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Sitemap Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a sitemap.xml with all products and collections for SEO.
|
|
5
|
+
* Uses ISR to regenerate hourly.
|
|
6
|
+
*
|
|
7
|
+
* Requirements: 13.4
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { MetadataRoute } from "next";
|
|
11
|
+
|
|
12
|
+
// ISR revalidation - regenerate sitemap every hour
|
|
13
|
+
export const revalidate = 3600;
|
|
14
|
+
|
|
15
|
+
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generate sitemap entries for the site
|
|
19
|
+
*
|
|
20
|
+
* Includes:
|
|
21
|
+
* - Homepage (priority 1.0)
|
|
22
|
+
* - Product pages (priority 0.8, daily changes)
|
|
23
|
+
* - Collection pages (priority 0.7, weekly changes)
|
|
24
|
+
* - Category pages (priority 0.6, weekly changes)
|
|
25
|
+
* - Static pages (priority 0.5, monthly changes)
|
|
26
|
+
*/
|
|
27
|
+
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
|
28
|
+
const entries: MetadataRoute.Sitemap = [];
|
|
29
|
+
|
|
30
|
+
// Homepage
|
|
31
|
+
entries.push({
|
|
32
|
+
url: SITE_URL,
|
|
33
|
+
lastModified: new Date(),
|
|
34
|
+
changeFrequency: "daily",
|
|
35
|
+
priority: 1.0,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Static pages
|
|
39
|
+
const staticPages = [
|
|
40
|
+
"/products",
|
|
41
|
+
"/collections",
|
|
42
|
+
"/about",
|
|
43
|
+
"/contact",
|
|
44
|
+
"/terms",
|
|
45
|
+
"/privacy",
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
for (const page of staticPages) {
|
|
49
|
+
entries.push({
|
|
50
|
+
url: `${SITE_URL}${page}`,
|
|
51
|
+
lastModified: new Date(),
|
|
52
|
+
changeFrequency: "monthly",
|
|
53
|
+
priority: 0.5,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Fetch products for sitemap
|
|
58
|
+
try {
|
|
59
|
+
const products = await fetchProductsForSitemap();
|
|
60
|
+
for (const product of products) {
|
|
61
|
+
entries.push({
|
|
62
|
+
url: `${SITE_URL}/products/${product.handle}`,
|
|
63
|
+
lastModified: product.updatedAt ? new Date(product.updatedAt) : new Date(),
|
|
64
|
+
changeFrequency: "daily",
|
|
65
|
+
priority: 0.8,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error("Failed to fetch products for sitemap:", error);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Fetch collections for sitemap
|
|
73
|
+
try {
|
|
74
|
+
const collections = await fetchCollectionsForSitemap();
|
|
75
|
+
for (const collection of collections) {
|
|
76
|
+
entries.push({
|
|
77
|
+
url: `${SITE_URL}/collections/${collection.handle}`,
|
|
78
|
+
lastModified: collection.updatedAt ? new Date(collection.updatedAt) : new Date(),
|
|
79
|
+
changeFrequency: "weekly",
|
|
80
|
+
priority: 0.7,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error("Failed to fetch collections for sitemap:", error);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Fetch categories for sitemap
|
|
88
|
+
try {
|
|
89
|
+
const categories = await fetchCategoriesForSitemap();
|
|
90
|
+
for (const category of categories) {
|
|
91
|
+
entries.push({
|
|
92
|
+
url: `${SITE_URL}/categories/${category.handle}`,
|
|
93
|
+
lastModified: category.updatedAt ? new Date(category.updatedAt) : new Date(),
|
|
94
|
+
changeFrequency: "weekly",
|
|
95
|
+
priority: 0.6,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error("Failed to fetch categories for sitemap:", error);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return entries;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Fetch all products with pagination
|
|
107
|
+
* Limits to 10000 products to avoid timeout
|
|
108
|
+
*/
|
|
109
|
+
async function fetchProductsForSitemap(): Promise<Array<{ handle: string; updatedAt?: string }>> {
|
|
110
|
+
// TODO: Replace with actual GraphQL fetch using server client
|
|
111
|
+
// This is a placeholder that should be connected to the actual GraphQL API
|
|
112
|
+
//
|
|
113
|
+
// Example implementation:
|
|
114
|
+
// const { products } = await fetchProducts({ first: 250 });
|
|
115
|
+
// return products.map(p => ({ handle: p.handle, updatedAt: p.updatedAt }));
|
|
116
|
+
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Fetch all collections
|
|
122
|
+
*/
|
|
123
|
+
async function fetchCollectionsForSitemap(): Promise<Array<{ handle: string; updatedAt?: string }>> {
|
|
124
|
+
// TODO: Replace with actual GraphQL fetch using server client
|
|
125
|
+
//
|
|
126
|
+
// Example implementation:
|
|
127
|
+
// const { collections } = await fetchCollections({ first: 100 });
|
|
128
|
+
// return collections.map(c => ({ handle: c.handle, updatedAt: c.updatedAt }));
|
|
129
|
+
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Fetch all categories
|
|
135
|
+
*/
|
|
136
|
+
async function fetchCategoriesForSitemap(): Promise<Array<{ handle: string; updatedAt?: string }>> {
|
|
137
|
+
// TODO: Replace with actual GraphQL fetch using server client
|
|
138
|
+
//
|
|
139
|
+
// Example implementation:
|
|
140
|
+
// const { categories } = await fetchCategories({ first: 100 });
|
|
141
|
+
// return categories.map(c => ({ handle: c.handle, updatedAt: c.updatedAt }));
|
|
142
|
+
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wishlist Page
|
|
5
|
+
*
|
|
6
|
+
* Displays customer's saved products with price tracking
|
|
7
|
+
* and quick add to cart functionality.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Heart, ShoppingCart, Trash2 } from 'lucide-react';
|
|
11
|
+
import { Button } from '@/components/ui/button';
|
|
12
|
+
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
13
|
+
import { EmptyState } from '@/components/ui/empty-state';
|
|
14
|
+
import { Breadcrumbs } from '@/components/layout/breadcrumbs';
|
|
15
|
+
import { WishlistItem } from '@/components/wishlist/wishlist-item';
|
|
16
|
+
import { useWishlistStore } from '@/stores/wishlist-store';
|
|
17
|
+
import { useCartActions } from '@/hooks/use-cart-actions';
|
|
18
|
+
import { toast } from 'sonner';
|
|
19
|
+
|
|
20
|
+
export default function WishlistPage() {
|
|
21
|
+
const {
|
|
22
|
+
wishlists,
|
|
23
|
+
getActiveWishlist,
|
|
24
|
+
clearWishlist,
|
|
25
|
+
isHydrated,
|
|
26
|
+
} = useWishlistStore();
|
|
27
|
+
|
|
28
|
+
const { addToCart } = useCartActions();
|
|
29
|
+
|
|
30
|
+
const activeWishlist = getActiveWishlist();
|
|
31
|
+
const items = activeWishlist?.items || [];
|
|
32
|
+
|
|
33
|
+
const handleClearWishlist = () => {
|
|
34
|
+
if (activeWishlist) {
|
|
35
|
+
clearWishlist(activeWishlist.id);
|
|
36
|
+
toast.success('Lista życzeń została wyczyszczona');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleAddAllToCart = async () => {
|
|
41
|
+
if (!activeWishlist) return;
|
|
42
|
+
|
|
43
|
+
for (const item of items) {
|
|
44
|
+
try {
|
|
45
|
+
await addToCart({
|
|
46
|
+
variantId: item.variantId || item.productId,
|
|
47
|
+
productId: item.productId,
|
|
48
|
+
productTitle: item.productTitle,
|
|
49
|
+
variantTitle: item.variantTitle || '',
|
|
50
|
+
price: item.price,
|
|
51
|
+
image: item.image,
|
|
52
|
+
available: true,
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
// Individual item errors are handled by addToCart (shows toast)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
toast.success(`Dodano ${items.length} produktów do koszyka`);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// Show loading state while hydrating from localStorage
|
|
63
|
+
if (!isHydrated) {
|
|
64
|
+
return (
|
|
65
|
+
<div className="container max-w-4xl py-8">
|
|
66
|
+
<div className="animate-pulse space-y-4">
|
|
67
|
+
<div className="h-8 w-48 bg-muted rounded" />
|
|
68
|
+
<div className="h-32 bg-muted rounded" />
|
|
69
|
+
<div className="h-32 bg-muted rounded" />
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div className="container max-w-4xl py-8">
|
|
77
|
+
<Breadcrumbs
|
|
78
|
+
items={[
|
|
79
|
+
{ label: 'Strona główna', href: '/' },
|
|
80
|
+
{ label: 'Lista życzeń' },
|
|
81
|
+
]}
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<div className="mt-6 mb-8 flex items-center justify-between">
|
|
85
|
+
<div>
|
|
86
|
+
<h1 className="text-3xl font-bold tracking-tight flex items-center gap-3">
|
|
87
|
+
<Heart className="h-8 w-8 text-red-500" />
|
|
88
|
+
Lista życzeń
|
|
89
|
+
</h1>
|
|
90
|
+
<p className="text-muted-foreground mt-1">
|
|
91
|
+
{items.length === 0
|
|
92
|
+
? 'Twoja lista życzeń jest pusta'
|
|
93
|
+
: `${items.length} ${items.length === 1 ? 'produkt' : 'produktów'}`}
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
{items.length > 0 && (
|
|
98
|
+
<div className="flex gap-2">
|
|
99
|
+
<Button variant="outline" size="sm" onClick={handleClearWishlist}>
|
|
100
|
+
<Trash2 className="h-4 w-4 mr-2" />
|
|
101
|
+
Wyczyść
|
|
102
|
+
</Button>
|
|
103
|
+
<Button size="sm" onClick={handleAddAllToCart}>
|
|
104
|
+
<ShoppingCart className="h-4 w-4 mr-2" />
|
|
105
|
+
Dodaj wszystko do koszyka
|
|
106
|
+
</Button>
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
{items.length === 0 ? (
|
|
112
|
+
<EmptyState
|
|
113
|
+
icon={<Heart className="h-12 w-12" />}
|
|
114
|
+
title="Lista życzeń jest pusta"
|
|
115
|
+
description="Dodaj produkty do listy życzeń, aby śledzić ich ceny i szybko dodawać do koszyka."
|
|
116
|
+
action={{
|
|
117
|
+
label: 'Przeglądaj produkty',
|
|
118
|
+
href: '/products',
|
|
119
|
+
}}
|
|
120
|
+
/>
|
|
121
|
+
) : (
|
|
122
|
+
<div className="space-y-4">
|
|
123
|
+
{/* Price change summary */}
|
|
124
|
+
<PriceChangeSummary items={items} />
|
|
125
|
+
|
|
126
|
+
{/* Wishlist items */}
|
|
127
|
+
{activeWishlist && items.map((item) => (
|
|
128
|
+
<WishlistItem
|
|
129
|
+
key={item.id}
|
|
130
|
+
item={item}
|
|
131
|
+
wishlistId={activeWishlist.id}
|
|
132
|
+
/>
|
|
133
|
+
))}
|
|
134
|
+
</div>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Shows summary of price changes for all items
|
|
142
|
+
*/
|
|
143
|
+
function PriceChangeSummary({ items }: { items: Array<{ price: { amount: string }; priceAtAdd: { amount: string } }> }) {
|
|
144
|
+
const itemsWithPriceDrops = items.filter((item) => {
|
|
145
|
+
const current = parseFloat(item.price.amount);
|
|
146
|
+
const original = parseFloat(item.priceAtAdd.amount);
|
|
147
|
+
return current < original;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const totalSavings = itemsWithPriceDrops.reduce((sum, item) => {
|
|
151
|
+
const current = parseFloat(item.price.amount);
|
|
152
|
+
const original = parseFloat(item.priceAtAdd.amount);
|
|
153
|
+
return sum + (original - current);
|
|
154
|
+
}, 0);
|
|
155
|
+
|
|
156
|
+
if (itemsWithPriceDrops.length === 0) return null;
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<Card className="border-green-200 bg-green-50 dark:border-green-900 dark:bg-green-950">
|
|
160
|
+
<CardHeader className="pb-2">
|
|
161
|
+
<CardTitle className="text-green-700 dark:text-green-400 text-lg flex items-center gap-2">
|
|
162
|
+
🎉 Dobre wieści!
|
|
163
|
+
</CardTitle>
|
|
164
|
+
</CardHeader>
|
|
165
|
+
<CardContent>
|
|
166
|
+
<p className="text-green-700 dark:text-green-400">
|
|
167
|
+
{itemsWithPriceDrops.length} {itemsWithPriceDrops.length === 1 ? 'produkt obniżył' : 'produktów obniżyło'} cenę!
|
|
168
|
+
Możesz zaoszczędzić łącznie{' '}
|
|
169
|
+
<span className="font-semibold">
|
|
170
|
+
{new Intl.NumberFormat('pl-PL', {
|
|
171
|
+
style: 'currency',
|
|
172
|
+
currency: 'PLN',
|
|
173
|
+
}).format(totalSavings)}
|
|
174
|
+
</span>
|
|
175
|
+
</p>
|
|
176
|
+
</CardContent>
|
|
177
|
+
</Card>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CodegenConfig } from '@graphql-codegen/cli';
|
|
2
|
+
import { loadEnvConfig } from '@next/env';
|
|
3
|
+
|
|
4
|
+
// Load environment variables from .env.local
|
|
5
|
+
loadEnvConfig(process.cwd());
|
|
6
|
+
|
|
7
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
|
|
8
|
+
const shopSlug = process.env.NEXT_PUBLIC_SHOP_SLUG || 'test-shop';
|
|
9
|
+
|
|
10
|
+
const config: CodegenConfig = {
|
|
11
|
+
// Schema from live API (introspection)
|
|
12
|
+
schema: [
|
|
13
|
+
{
|
|
14
|
+
[`${apiUrl}/storefront/graphql`]: {
|
|
15
|
+
headers: {
|
|
16
|
+
'X-Shop-Slug': shopSlug,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
// Operations: Backend SSOT + Developer Custom Queries
|
|
23
|
+
documents: [
|
|
24
|
+
'node_modules/@doswiftly/storefront-operations/**/*.graphql', // Backend operations
|
|
25
|
+
'graphql/**/*.{ts,tsx}', // Custom queries in code
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
// Output configuration
|
|
29
|
+
generates: {
|
|
30
|
+
'generated/graphql.ts': {
|
|
31
|
+
plugins: [
|
|
32
|
+
'typescript', // Generate TS types
|
|
33
|
+
'typescript-operations', // Generate operation types
|
|
34
|
+
'typed-document-node', // Generate TypedDocumentNode
|
|
35
|
+
],
|
|
36
|
+
config: {
|
|
37
|
+
skipTypename: false,
|
|
38
|
+
enumsAsTypes: true,
|
|
39
|
+
scalars: {
|
|
40
|
+
DateTime: 'string',
|
|
41
|
+
JSON: 'Record<string, any>',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
// Watch mode for development
|
|
48
|
+
watch: process.env.NODE_ENV === 'development',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default config;
|