@doswiftly/cli 0.1.18 → 0.1.20
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 +23 -323
- package/dist/commands/check.js +1 -1
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/deploy.d.ts +20 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +249 -17
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.js +3 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +4 -4
- package/dist/commands/sdk.js +5 -5
- package/dist/commands/sdk.js.map +1 -1
- package/dist/commands/template.js +4 -4
- package/dist/commands/template.js.map +1 -1
- package/dist/commands/types.js +5 -5
- package/dist/commands/types.js.map +1 -1
- package/dist/commands/verify.js +2 -2
- package/dist/commands/verify.js.map +1 -1
- package/dist/lib/package-manager.d.ts +1 -1
- package/dist/lib/package-manager.js +1 -1
- package/package.json +4 -4
- package/templates/storefront-minimal/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-minimal/wrangler.toml +11 -0
- package/templates/storefront-nextjs/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-nextjs/README.md +16 -12
- package/templates/storefront-nextjs/app/account/orders/page.tsx +2 -2
- package/templates/storefront-nextjs/app/account/page.tsx +2 -2
- package/templates/storefront-nextjs/app/auth/login/page.tsx +1 -1
- package/templates/storefront-nextjs/app/auth/register/page.tsx +1 -1
- package/templates/storefront-nextjs/app/cart/page.tsx +1 -1
- package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +2 -2
- package/templates/storefront-nextjs/app/categories/page.tsx +1 -1
- package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +1 -1
- package/templates/storefront-nextjs/app/collections/page.tsx +1 -1
- package/templates/storefront-nextjs/app/page.tsx +1 -1
- package/templates/storefront-nextjs/app/products/[slug]/page.tsx +1 -1
- package/templates/storefront-nextjs/app/products/page.tsx +2 -2
- package/templates/storefront-nextjs/app/search/page.tsx +1 -1
- package/templates/storefront-nextjs/components/auth/auth-guard.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +2 -2
- package/templates/storefront-nextjs/components/commerce/product-filters.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/product-price.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/search-input.tsx +1 -1
- package/templates/storefront-nextjs/components/commerce/sort-select.tsx +1 -1
- package/templates/storefront-nextjs/components/providers.tsx +1 -1
- package/templates/storefront-nextjs/lib/currency.tsx +3 -3
- package/templates/storefront-nextjs/lib/format.ts +1 -1
- package/templates/storefront-nextjs/lib/graphql-queries.ts +3 -3
- package/templates/storefront-nextjs/package.dev.json +1 -1
- package/templates/storefront-nextjs/package.json +1 -1
- package/templates/storefront-nextjs/package.json.template +1 -1
- package/templates/storefront-nextjs/wrangler.toml +11 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +10 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +47 -0
- package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +47 -0
- package/templates/storefront-nextjs-shadcn/CLAUDE.md +172 -35
- package/templates/storefront-nextjs-shadcn/README.md +29 -162
- package/templates/storefront-nextjs-shadcn/app/{about → [locale]/about}/page.tsx +17 -14
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/addresses/page.tsx +226 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/error.tsx +46 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/loading.tsx +19 -0
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/loyalty/page.tsx +89 -193
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/[id]/loading.tsx +60 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/[id]/page.tsx +119 -0
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/orders/[id]/tracking/page.tsx +27 -25
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/orders/page.tsx +101 -0
- package/templates/storefront-nextjs-shadcn/app/{account → [locale]/account}/page.tsx +9 -7
- package/templates/storefront-nextjs-shadcn/app/[locale]/account/settings/page.tsx +208 -0
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/forgot-password/page.tsx +24 -17
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/login/page.tsx +5 -2
- package/templates/storefront-nextjs-shadcn/app/{auth → [locale]/auth}/register/page.tsx +5 -2
- package/templates/storefront-nextjs-shadcn/app/[locale]/blog/[slug]/loading.tsx +17 -0
- package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/[slug]/page.tsx +44 -3
- package/templates/storefront-nextjs-shadcn/app/[locale]/blog/loading.tsx +19 -0
- package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/page.tsx +2 -1
- package/templates/storefront-nextjs-shadcn/app/[locale]/cart/loading.tsx +26 -0
- package/templates/storefront-nextjs-shadcn/app/{cart → [locale]/cart}/page.tsx +20 -13
- package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/category-products-client.tsx +58 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/loading.tsx +32 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/categories/[slug]/page.tsx +95 -0
- package/templates/storefront-nextjs-shadcn/app/{categories → [locale]/categories}/page.tsx +21 -12
- package/templates/storefront-nextjs-shadcn/app/[locale]/checkout/error.tsx +43 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/checkout/loading.tsx +31 -0
- package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/page.tsx +334 -253
- package/templates/storefront-nextjs-shadcn/app/{checkout → [locale]/checkout}/success/[orderId]/page.tsx +36 -34
- package/templates/storefront-nextjs-shadcn/app/[locale]/collections/[handle]/loading.tsx +19 -0
- package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/[handle]/page.tsx +6 -4
- package/templates/storefront-nextjs-shadcn/app/[locale]/collections/loading.tsx +18 -0
- package/templates/storefront-nextjs-shadcn/app/{collections → [locale]/collections}/page.tsx +20 -12
- package/templates/storefront-nextjs-shadcn/app/{contact → [locale]/contact}/page.tsx +24 -21
- package/templates/storefront-nextjs-shadcn/app/{error.tsx → [locale]/error.tsx} +13 -8
- package/templates/storefront-nextjs-shadcn/app/[locale]/layout.tsx +92 -0
- package/templates/storefront-nextjs-shadcn/app/{not-found.tsx → [locale]/not-found.tsx} +13 -18
- package/templates/storefront-nextjs-shadcn/app/{page.tsx → [locale]/page.tsx} +8 -4
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/[slug]/error.tsx +43 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/[slug]/loading.tsx +29 -0
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/page.tsx +17 -14
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/[slug]/product-client.tsx +18 -62
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/loading.tsx +32 -0
- package/templates/storefront-nextjs-shadcn/app/{products → [locale]/products}/page.tsx +6 -3
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/products-client.tsx +450 -0
- package/templates/storefront-nextjs-shadcn/app/[locale]/search/loading.tsx +18 -0
- package/templates/storefront-nextjs-shadcn/app/{wishlist → [locale]/wishlist}/page.tsx +27 -28
- package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +2 -86
- package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +2 -124
- package/templates/storefront-nextjs-shadcn/app/global-error.tsx +117 -0
- package/templates/storefront-nextjs-shadcn/app/globals.css +8 -0
- package/templates/storefront-nextjs-shadcn/app/layout.tsx +8 -35
- package/templates/storefront-nextjs-shadcn/codegen.ts +48 -31
- package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +25 -20
- package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +11 -10
- package/templates/storefront-nextjs-shadcn/components/account/customer-info.fragment.graphql +36 -0
- package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +17 -13
- package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +42 -30
- package/templates/storefront-nextjs-shadcn/components/account/order-summary.fragment.graphql +36 -0
- package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +18 -16
- package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +37 -58
- package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +85 -66
- package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +10 -6
- package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +9 -6
- package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +8 -6
- package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +53 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +38 -20
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +15 -25
- package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +9 -6
- package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +7 -5
- package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +8 -5
- package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +6 -4
- package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +10 -9
- package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +35 -11
- package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +9 -6
- package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +22 -12
- package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +18 -15
- package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +53 -28
- package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +7 -5
- package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +5 -5
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +19 -15
- package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +13 -10
- package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +10 -6
- package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +21 -0
- package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +3 -13
- package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +12 -8
- package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +13 -8
- package/templates/storefront-nextjs-shadcn/components/home/index.ts +0 -1
- package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +10 -8
- package/templates/storefront-nextjs-shadcn/components/hydrated.tsx +24 -0
- package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +41 -16
- package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +22 -0
- package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +24 -23
- package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +52 -34
- package/templates/storefront-nextjs-shadcn/components/layout/language-switcher.tsx +54 -0
- package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +33 -30
- package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +27 -24
- package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +2 -11
- package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +8 -25
- package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +32 -42
- package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +17 -41
- package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +2 -29
- package/templates/storefront-nextjs-shadcn/components/order/index.ts +6 -1
- package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +6 -14
- package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +4 -2
- package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +72 -0
- package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +87 -0
- package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +140 -0
- package/templates/storefront-nextjs-shadcn/components/product/index.ts +9 -2
- package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +49 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +11 -37
- package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +52 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +179 -124
- package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +3 -5
- package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +3 -7
- package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +2 -2
- package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +5 -4
- package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +44 -19
- package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +8 -23
- package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +51 -0
- package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +26 -34
- package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +17 -2
- package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +3 -2
- package/templates/storefront-nextjs-shadcn/components/providers/index.ts +1 -1
- package/templates/storefront-nextjs-shadcn/components/providers/language-sync-provider.tsx +27 -0
- package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +63 -0
- package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/returns/index.ts +2 -2
- package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +59 -72
- package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +3 -2
- package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +12 -9
- package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +23 -12
- package/templates/storefront-nextjs-shadcn/components/ui/form.tsx +174 -0
- package/templates/storefront-nextjs-shadcn/components/ui/index.ts +30 -2
- package/templates/storefront-nextjs-shadcn/components/ui/progress.tsx +40 -0
- package/templates/storefront-nextjs-shadcn/components/ui/sheet.tsx +107 -0
- package/templates/storefront-nextjs-shadcn/components/ui/slider.tsx +33 -0
- package/templates/storefront-nextjs-shadcn/components/ui/textarea.tsx +24 -0
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +7 -4
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +4 -2
- package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +2 -10
- package/templates/storefront-nextjs-shadcn/generated/graphql.ts +13387 -0
- package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +159 -0
- package/templates/storefront-nextjs-shadcn/hooks/index.ts +3 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-auth-sync.ts +42 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +17 -295
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +34 -229
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-di.ts +67 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +16 -12
- package/templates/storefront-nextjs-shadcn/i18n/navigation.ts +12 -0
- package/templates/storefront-nextjs-shadcn/i18n/request.ts +17 -0
- package/templates/storefront-nextjs-shadcn/i18n/routing.ts +17 -0
- package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +4 -17
- package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +22 -99
- package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +33 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/fragments.ts +34 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +720 -632
- package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +88 -0
- package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +132 -182
- package/templates/storefront-nextjs-shadcn/lib/graphql/types.ts +62 -0
- package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +0 -17
- package/templates/storefront-nextjs-shadcn/messages/en.json +869 -0
- package/templates/storefront-nextjs-shadcn/messages/pl.json +869 -0
- package/templates/storefront-nextjs-shadcn/next-env.d.ts +6 -0
- package/templates/storefront-nextjs-shadcn/next.config.ts +6 -5
- package/templates/storefront-nextjs-shadcn/package.dev.json +1 -3
- package/templates/storefront-nextjs-shadcn/package.json +14 -14
- package/templates/storefront-nextjs-shadcn/package.json.template +6 -7
- package/templates/storefront-nextjs-shadcn/proxy.ts +115 -47
- package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +24 -56
- package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +64 -75
- package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +178 -177
- package/templates/storefront-nextjs-shadcn/tsconfig.json +23 -5
- package/templates/storefront-nextjs-shadcn/wrangler.toml +11 -0
- package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +0 -282
- package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +0 -190
- package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +0 -263
- package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +0 -135
- package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +0 -142
- package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +0 -448
- package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +0 -307
- package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +0 -245
- package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +0 -215
- package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +0 -128
- package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +0 -80
- package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +0 -171
- package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +0 -78
- package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +0 -192
- package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +0 -103
- package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +0 -168
- package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +0 -160
- package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +0 -220
- package/templates/storefront-nextjs-shadcn/lib/config.ts +0 -46
- package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +0 -254
- package/templates/storefront-nextjs-shadcn/lib/currency/README.md +0 -464
- package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +0 -328
- package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +0 -295
- package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +0 -27
- package/templates/storefront-nextjs-shadcn/lib/format.ts +0 -226
- package/templates/storefront-nextjs-shadcn/lib/hooks.ts +0 -30
- package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +0 -66
- package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +0 -103
- /package/templates/storefront-nextjs-shadcn/app/{blog → [locale]/blog}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{brands → [locale]/brands}/[slug]/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{returns → [locale]/returns}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/page.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{search → [locale]/search}/search-client.tsx +0 -0
- /package/templates/storefront-nextjs-shadcn/app/{shipping → [locale]/shipping}/page.tsx +0 -0
|
@@ -15,13 +15,8 @@ import { Textarea } from '@/components/ui/textarea';
|
|
|
15
15
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
16
16
|
import { cn } from '@/lib/utils';
|
|
17
17
|
import { toast } from 'sonner';
|
|
18
|
+
import { useTranslations } from 'next-intl';
|
|
18
19
|
|
|
19
|
-
// Ensure Textarea exists or create a simple version
|
|
20
|
-
const TextareaComponent = typeof Textarea === 'undefined'
|
|
21
|
-
? ({ className, ...props }: React.TextareaHTMLAttributes<HTMLTextAreaElement>) => (
|
|
22
|
-
<textarea className={cn('flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', className)} {...props} />
|
|
23
|
-
)
|
|
24
|
-
: Textarea;
|
|
25
20
|
|
|
26
21
|
interface ReviewFormProps {
|
|
27
22
|
productId: string;
|
|
@@ -51,6 +46,7 @@ export function ReviewForm({
|
|
|
51
46
|
orderId,
|
|
52
47
|
className,
|
|
53
48
|
}: ReviewFormProps) {
|
|
49
|
+
const t = useTranslations('product.review');
|
|
54
50
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
55
51
|
const [rating, setRating] = useState(0);
|
|
56
52
|
const [hoverRating, setHoverRating] = useState(0);
|
|
@@ -89,17 +85,17 @@ export function ReviewForm({
|
|
|
89
85
|
e.preventDefault();
|
|
90
86
|
|
|
91
87
|
if (rating === 0) {
|
|
92
|
-
toast.error('
|
|
88
|
+
toast.error(t('selectRating'));
|
|
93
89
|
return;
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
if (!content.trim()) {
|
|
97
|
-
toast.error('
|
|
93
|
+
toast.error(t('writeReview'));
|
|
98
94
|
return;
|
|
99
95
|
}
|
|
100
96
|
|
|
101
97
|
if (!authorName.trim()) {
|
|
102
|
-
toast.error('
|
|
98
|
+
toast.error(t('enterName'));
|
|
103
99
|
return;
|
|
104
100
|
}
|
|
105
101
|
|
|
@@ -127,9 +123,9 @@ export function ReviewForm({
|
|
|
127
123
|
setAuthorName('');
|
|
128
124
|
setAuthorEmail('');
|
|
129
125
|
|
|
130
|
-
toast.success('
|
|
126
|
+
toast.success(t('thankYou'));
|
|
131
127
|
} catch (error) {
|
|
132
|
-
toast.error('
|
|
128
|
+
toast.error(t('failed'));
|
|
133
129
|
} finally {
|
|
134
130
|
setIsSubmitting(false);
|
|
135
131
|
}
|
|
@@ -138,16 +134,16 @@ export function ReviewForm({
|
|
|
138
134
|
return (
|
|
139
135
|
<Card className={className}>
|
|
140
136
|
<CardHeader>
|
|
141
|
-
<CardTitle>
|
|
137
|
+
<CardTitle>{t('addReview')}</CardTitle>
|
|
142
138
|
<p className="text-sm text-muted-foreground">
|
|
143
|
-
|
|
139
|
+
{t('shareOpinion', { productTitle })}
|
|
144
140
|
</p>
|
|
145
141
|
</CardHeader>
|
|
146
142
|
<CardContent>
|
|
147
143
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
148
144
|
{/* Rating */}
|
|
149
145
|
<div>
|
|
150
|
-
<Label className="mb-2 block">
|
|
146
|
+
<Label className="mb-2 block">{t('rating')} *</Label>
|
|
151
147
|
<div className="flex items-center gap-1">
|
|
152
148
|
{[1, 2, 3, 4, 5].map((star) => (
|
|
153
149
|
<button
|
|
@@ -170,11 +166,7 @@ export function ReviewForm({
|
|
|
170
166
|
))}
|
|
171
167
|
{rating > 0 && (
|
|
172
168
|
<span className="ml-2 text-sm text-muted-foreground">
|
|
173
|
-
{rating
|
|
174
|
-
{rating === 2 && 'Słabo'}
|
|
175
|
-
{rating === 3 && 'Średnio'}
|
|
176
|
-
{rating === 4 && 'Dobrze'}
|
|
177
|
-
{rating === 5 && 'Doskonale'}
|
|
169
|
+
{t(`ratingLabels.${rating}` as 'ratingLabels.1' | 'ratingLabels.2' | 'ratingLabels.3' | 'ratingLabels.4' | 'ratingLabels.5')}
|
|
178
170
|
</span>
|
|
179
171
|
)}
|
|
180
172
|
</div>
|
|
@@ -182,12 +174,12 @@ export function ReviewForm({
|
|
|
182
174
|
|
|
183
175
|
{/* Title */}
|
|
184
176
|
<div>
|
|
185
|
-
<Label htmlFor="title">
|
|
177
|
+
<Label htmlFor="title">{t('title')}</Label>
|
|
186
178
|
<Input
|
|
187
179
|
id="title"
|
|
188
180
|
value={title}
|
|
189
181
|
onChange={(e) => setTitle(e.target.value)}
|
|
190
|
-
placeholder=
|
|
182
|
+
placeholder={t('titlePlaceholder')}
|
|
191
183
|
maxLength={100}
|
|
192
184
|
className="mt-1.5"
|
|
193
185
|
/>
|
|
@@ -195,12 +187,12 @@ export function ReviewForm({
|
|
|
195
187
|
|
|
196
188
|
{/* Content */}
|
|
197
189
|
<div>
|
|
198
|
-
<Label htmlFor="content">
|
|
199
|
-
<
|
|
190
|
+
<Label htmlFor="content">{t('content')} *</Label>
|
|
191
|
+
<Textarea
|
|
200
192
|
id="content"
|
|
201
193
|
value={content}
|
|
202
194
|
onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setContent(e.target.value)}
|
|
203
|
-
placeholder=
|
|
195
|
+
placeholder={t('contentPlaceholder')}
|
|
204
196
|
rows={4}
|
|
205
197
|
className="mt-1.5"
|
|
206
198
|
required
|
|
@@ -209,12 +201,12 @@ export function ReviewForm({
|
|
|
209
201
|
|
|
210
202
|
{/* Pros */}
|
|
211
203
|
<div>
|
|
212
|
-
<Label>
|
|
204
|
+
<Label>{t('pros')}</Label>
|
|
213
205
|
<div className="flex gap-2 mt-1.5">
|
|
214
206
|
<Input
|
|
215
207
|
value={newPro}
|
|
216
208
|
onChange={(e) => setNewPro(e.target.value)}
|
|
217
|
-
placeholder=
|
|
209
|
+
placeholder={t('addPro')}
|
|
218
210
|
maxLength={50}
|
|
219
211
|
onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), handleAddPro())}
|
|
220
212
|
/>
|
|
@@ -251,12 +243,12 @@ export function ReviewForm({
|
|
|
251
243
|
|
|
252
244
|
{/* Cons */}
|
|
253
245
|
<div>
|
|
254
|
-
<Label>
|
|
246
|
+
<Label>{t('cons')}</Label>
|
|
255
247
|
<div className="flex gap-2 mt-1.5">
|
|
256
248
|
<Input
|
|
257
249
|
value={newCon}
|
|
258
250
|
onChange={(e) => setNewCon(e.target.value)}
|
|
259
|
-
placeholder=
|
|
251
|
+
placeholder={t('addCon')}
|
|
260
252
|
maxLength={50}
|
|
261
253
|
onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), handleAddCon())}
|
|
262
254
|
/>
|
|
@@ -294,7 +286,7 @@ export function ReviewForm({
|
|
|
294
286
|
{/* Author Info */}
|
|
295
287
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
296
288
|
<div>
|
|
297
|
-
<Label htmlFor="authorName">
|
|
289
|
+
<Label htmlFor="authorName">{t('yourName')} *</Label>
|
|
298
290
|
<Input
|
|
299
291
|
id="authorName"
|
|
300
292
|
value={authorName}
|
|
@@ -305,17 +297,17 @@ export function ReviewForm({
|
|
|
305
297
|
/>
|
|
306
298
|
</div>
|
|
307
299
|
<div>
|
|
308
|
-
<Label htmlFor="authorEmail">
|
|
300
|
+
<Label htmlFor="authorEmail">{t('emailOptional')}</Label>
|
|
309
301
|
<Input
|
|
310
302
|
id="authorEmail"
|
|
311
303
|
type="email"
|
|
312
304
|
value={authorEmail}
|
|
313
305
|
onChange={(e) => setAuthorEmail(e.target.value)}
|
|
314
|
-
placeholder=
|
|
306
|
+
placeholder={t('emailPlaceholder')}
|
|
315
307
|
className="mt-1.5"
|
|
316
308
|
/>
|
|
317
309
|
<p className="text-xs text-muted-foreground mt-1">
|
|
318
|
-
|
|
310
|
+
{t('emailNotPublic')}
|
|
319
311
|
</p>
|
|
320
312
|
</div>
|
|
321
313
|
</div>
|
|
@@ -325,10 +317,10 @@ export function ReviewForm({
|
|
|
325
317
|
{isSubmitting ? (
|
|
326
318
|
<>
|
|
327
319
|
<Loader2 className="h-4 w-4 mr-2 animate-spin" />
|
|
328
|
-
|
|
320
|
+
{t('submitting')}
|
|
329
321
|
</>
|
|
330
322
|
) : (
|
|
331
|
-
'
|
|
323
|
+
t('addReview')
|
|
332
324
|
)}
|
|
333
325
|
</Button>
|
|
334
326
|
</form>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { TrendingDown, DollarSign, Percent } from "lucide-react";
|
|
4
|
-
import { useCurrencyStore } from "
|
|
5
|
-
import { formatAmount } from "
|
|
4
|
+
import { useCurrencyStore } from "@doswiftly/storefront-sdk/react";
|
|
5
|
+
import { formatAmount } from "@doswiftly/storefront-sdk";
|
|
6
6
|
|
|
7
7
|
export interface SavingsDisplayProps {
|
|
8
8
|
originalPrice: number;
|
|
@@ -27,10 +27,15 @@ export function SavingsDisplay({
|
|
|
27
27
|
className = "",
|
|
28
28
|
}: SavingsDisplayProps) {
|
|
29
29
|
const preferredCurrency = useCurrencyStore((state) => state.currency);
|
|
30
|
+
const isLoaded = useCurrencyStore((state) => state.isLoaded);
|
|
30
31
|
const finalCurrency = currency || preferredCurrency || "PLN";
|
|
31
32
|
|
|
32
33
|
if (salePrice >= originalPrice) return null;
|
|
33
34
|
|
|
35
|
+
if (!isLoaded && !currency) {
|
|
36
|
+
return <span className={`inline-block h-4 w-20 animate-pulse rounded bg-muted ${className}`} />;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
const savingsAmount = originalPrice - salePrice;
|
|
35
40
|
const savingsPercentage = Math.round(
|
|
36
41
|
(savingsAmount / originalPrice) * 100
|
|
@@ -127,6 +132,7 @@ export function TotalSavings({
|
|
|
127
132
|
className = "",
|
|
128
133
|
}: TotalSavingsProps) {
|
|
129
134
|
const preferredCurrency = useCurrencyStore((state) => state.currency);
|
|
135
|
+
const isLoaded = useCurrencyStore((state) => state.isLoaded);
|
|
130
136
|
const finalCurrency = currency || preferredCurrency || "PLN";
|
|
131
137
|
|
|
132
138
|
const totalSavings = items.reduce((sum, item) => {
|
|
@@ -136,6 +142,10 @@ export function TotalSavings({
|
|
|
136
142
|
|
|
137
143
|
if (totalSavings <= 0) return null;
|
|
138
144
|
|
|
145
|
+
if (!isLoaded && !currency) {
|
|
146
|
+
return <span className={`inline-block h-5 w-24 animate-pulse rounded bg-muted ${className}`} />;
|
|
147
|
+
}
|
|
148
|
+
|
|
139
149
|
return (
|
|
140
150
|
<div
|
|
141
151
|
className={`flex items-center justify-between rounded-lg bg-green-50 dark:bg-green-900/20 px-4 py-3 ${className}`}
|
|
@@ -169,10 +179,15 @@ export function SavingsBreakdown({
|
|
|
169
179
|
className = "",
|
|
170
180
|
}: SavingsBreakdownProps) {
|
|
171
181
|
const preferredCurrency = useCurrencyStore((state) => state.currency);
|
|
182
|
+
const isLoaded = useCurrencyStore((state) => state.isLoaded);
|
|
172
183
|
const finalCurrency = currency || preferredCurrency || "PLN";
|
|
173
184
|
|
|
174
185
|
if (salePrice >= originalPrice) return null;
|
|
175
186
|
|
|
187
|
+
if (!isLoaded && !currency) {
|
|
188
|
+
return <span className={`inline-block h-24 w-full animate-pulse rounded bg-muted ${className}`} />;
|
|
189
|
+
}
|
|
190
|
+
|
|
176
191
|
const savingsAmount = originalPrice - salePrice;
|
|
177
192
|
const savingsPercentage = Math.round(
|
|
178
193
|
(savingsAmount / originalPrice) * 100
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { ProductCard
|
|
3
|
+
import { ProductCard } from "./product-card";
|
|
4
4
|
import { cn } from "@/lib/utils";
|
|
5
|
+
import type { ProductCardFields } from "@/lib/graphql/fragments";
|
|
5
6
|
|
|
6
7
|
export interface SimilarProductsProps {
|
|
7
|
-
products:
|
|
8
|
+
products: ProductCardFields[];
|
|
8
9
|
title?: string;
|
|
9
10
|
className?: string;
|
|
10
11
|
columns?: 2 | 3 | 4;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect } from "react";
|
|
4
|
+
import { useLanguageStore } from "@doswiftly/storefront-sdk/react";
|
|
5
|
+
|
|
6
|
+
interface LanguageSyncProviderProps {
|
|
7
|
+
locale: string;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Syncs the URL locale (from next-intl) with the SDK language store.
|
|
13
|
+
*
|
|
14
|
+
* Flow: URL (/en) -> next-intl -> LanguageSyncProvider -> SDK store -> X-Lang header -> backend
|
|
15
|
+
*/
|
|
16
|
+
export function LanguageSyncProvider({
|
|
17
|
+
locale,
|
|
18
|
+
children,
|
|
19
|
+
}: LanguageSyncProviderProps) {
|
|
20
|
+
const setLanguage = useLanguageStore((s) => s.setLanguage);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setLanguage(locale);
|
|
24
|
+
}, [locale, setLanguage]);
|
|
25
|
+
|
|
26
|
+
return <>{children}</>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRef, type ReactNode } from 'react';
|
|
4
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { createCartStore, CartProvider } from '@/stores/cart-store';
|
|
6
|
+
import { CheckoutProvider, createCheckoutStore } from '@/stores/checkout-store';
|
|
7
|
+
import { WishlistProvider, createWishlistStore } from '@/stores/wishlist-store';
|
|
8
|
+
import { useCartDI } from '@/hooks/use-cart-di';
|
|
9
|
+
import { queryKeys } from '@/lib/graphql/query-keys';
|
|
10
|
+
import { toast } from 'sonner';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Provides Context-based Zustand stores to the component tree.
|
|
14
|
+
*
|
|
15
|
+
* Creates store instances once via useRef (stable across re-renders)
|
|
16
|
+
* and wraps children in Provider components.
|
|
17
|
+
*
|
|
18
|
+
* Cart store uses SDK DI pattern — template provides CartActions implementation,
|
|
19
|
+
* SDK orchestrates state (init, mutations, error handling).
|
|
20
|
+
*
|
|
21
|
+
* Must be placed inside StorefrontProvider (SDK stores) and QueryProvider.
|
|
22
|
+
*/
|
|
23
|
+
export function StoresProvider({ children }: { children: ReactNode }) {
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
const cartActions = useCartDI();
|
|
26
|
+
const actionsRef = useRef(cartActions);
|
|
27
|
+
actionsRef.current = cartActions;
|
|
28
|
+
|
|
29
|
+
const cartStoreRef = useRef<ReturnType<typeof createCartStore> | null>(null);
|
|
30
|
+
if (!cartStoreRef.current) {
|
|
31
|
+
cartStoreRef.current = createCartStore({
|
|
32
|
+
getActions: () => actionsRef.current,
|
|
33
|
+
onMutationSuccess: (action) => {
|
|
34
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.cart.all() });
|
|
35
|
+
if (action === 'addToCart') {
|
|
36
|
+
toast.success('Added to cart');
|
|
37
|
+
} else if (action === 'removeFromCart') {
|
|
38
|
+
toast.success('Removed from cart');
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
onMutationError: (_action, error) => {
|
|
42
|
+
const message = error instanceof Error ? error.message : 'Cart operation failed';
|
|
43
|
+
toast.error(message);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const checkoutStoreRef = useRef<ReturnType<typeof createCheckoutStore> | null>(null);
|
|
49
|
+
if (!checkoutStoreRef.current) checkoutStoreRef.current = createCheckoutStore();
|
|
50
|
+
|
|
51
|
+
const wishlistStoreRef = useRef<ReturnType<typeof createWishlistStore> | null>(null);
|
|
52
|
+
if (!wishlistStoreRef.current) wishlistStoreRef.current = createWishlistStore();
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<CartProvider store={cartStoreRef.current}>
|
|
56
|
+
<CheckoutProvider store={checkoutStoreRef.current}>
|
|
57
|
+
<WishlistProvider store={wishlistStoreRef.current}>
|
|
58
|
+
{children}
|
|
59
|
+
</WishlistProvider>
|
|
60
|
+
</CheckoutProvider>
|
|
61
|
+
</CartProvider>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
|
5
|
-
import { type ThemeProviderProps } from "next-themes
|
|
5
|
+
import { type ThemeProviderProps } from "next-themes";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* ThemeProvider - Provides theme context (light/dark/system)
|