@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
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { Suspense } from "react";
|
|
4
|
-
import { useSearchParams, useRouter } from "next/navigation";
|
|
5
|
-
import { ProductGrid } from "@/components/product/product-grid";
|
|
6
|
-
import { ProductFilters } from "@/components/product/product-filters";
|
|
7
|
-
import { ProductSort, type SortOption } from "@/components/product/product-sort";
|
|
8
|
-
import { Pagination } from "@/components/ui/pagination";
|
|
9
|
-
import { Skeleton } from "@/components/ui/skeleton";
|
|
10
|
-
import { useProducts, useCategories } from "@/lib/graphql/hooks";
|
|
11
|
-
|
|
12
|
-
export function ProductsClient() {
|
|
13
|
-
const searchParams = useSearchParams();
|
|
14
|
-
const router = useRouter();
|
|
15
|
-
|
|
16
|
-
// Parse URL parameters (all lowercase)
|
|
17
|
-
const page = parseInt(searchParams.get("page") || "1", 10);
|
|
18
|
-
const sort = (searchParams.get("sort") as SortOption) || "relevance";
|
|
19
|
-
const categories = searchParams.get("categories")?.split(",").filter(Boolean) || [];
|
|
20
|
-
const priceMin = searchParams.get("price_min");
|
|
21
|
-
const priceMax = searchParams.get("price_max");
|
|
22
|
-
|
|
23
|
-
const limit = 20;
|
|
24
|
-
|
|
25
|
-
// Fetch categories for filter sidebar
|
|
26
|
-
const { data: categoriesData } = useCategories();
|
|
27
|
-
const allCategories = categoriesData?.categories ?? [];
|
|
28
|
-
|
|
29
|
-
// Build GraphQL query string for filters
|
|
30
|
-
let queryString = "";
|
|
31
|
-
if (categories.length > 0) {
|
|
32
|
-
// Use category handles in query
|
|
33
|
-
queryString = categories.map(cat => `category:${cat}`).join(" OR ");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Fetch products using GraphQL
|
|
37
|
-
// Backend should normalize sort values (e.g., "price-asc" → PRICE + reverse: false)
|
|
38
|
-
const { data, isLoading, error } = useProducts({
|
|
39
|
-
first: limit,
|
|
40
|
-
query: queryString || undefined,
|
|
41
|
-
sortKey: sort as any, // Backend normalizes this
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const products = data?.products ?? [];
|
|
45
|
-
const totalCount = data?.totalCount ?? 0;
|
|
46
|
-
const totalPages = Math.ceil(totalCount / limit);
|
|
47
|
-
|
|
48
|
-
// Build selected filters object
|
|
49
|
-
const selectedFilters: Record<string, any> = {};
|
|
50
|
-
if (categories.length > 0) {
|
|
51
|
-
selectedFilters.categories = categories;
|
|
52
|
-
}
|
|
53
|
-
if (priceMin) {
|
|
54
|
-
selectedFilters.price_min = priceMin;
|
|
55
|
-
}
|
|
56
|
-
if (priceMax) {
|
|
57
|
-
selectedFilters.price_max = priceMax;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Update URL with new filters
|
|
61
|
-
const updateFilters = (updates: Record<string, any>) => {
|
|
62
|
-
const newParams = new URLSearchParams(searchParams.toString());
|
|
63
|
-
|
|
64
|
-
Object.entries(updates).forEach(([key, value]) => {
|
|
65
|
-
if (value === null || value === undefined || value === "") {
|
|
66
|
-
newParams.delete(key);
|
|
67
|
-
} else if (Array.isArray(value)) {
|
|
68
|
-
if (value.length > 0) {
|
|
69
|
-
newParams.set(key, value.join(","));
|
|
70
|
-
} else {
|
|
71
|
-
newParams.delete(key);
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
newParams.set(key, value.toString());
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Reset to page 1 when filters change
|
|
79
|
-
newParams.set("page", "1");
|
|
80
|
-
router.push(`/products?${newParams.toString()}`);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// Handle filter changes
|
|
84
|
-
const handleFilterChange = (filterId: string, value: any) => {
|
|
85
|
-
if (filterId === "categories") {
|
|
86
|
-
// Toggle category in array
|
|
87
|
-
const newCategories = categories.includes(value)
|
|
88
|
-
? categories.filter(c => c !== value)
|
|
89
|
-
: [...categories, value];
|
|
90
|
-
updateFilters({ categories: newCategories });
|
|
91
|
-
} else if (filterId === "price_min") {
|
|
92
|
-
updateFilters({ price_min: value });
|
|
93
|
-
} else if (filterId === "price_max") {
|
|
94
|
-
updateFilters({ price_max: value });
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// Build filter options from categories
|
|
99
|
-
const filterOptions = [
|
|
100
|
-
{
|
|
101
|
-
id: "categories",
|
|
102
|
-
label: "Categories",
|
|
103
|
-
type: "checkbox" as const,
|
|
104
|
-
options: allCategories.map((category: any) => ({
|
|
105
|
-
label: category.name,
|
|
106
|
-
value: category.slug,
|
|
107
|
-
count: category.productCount || 0,
|
|
108
|
-
})),
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
id: "price",
|
|
112
|
-
label: "Price Range",
|
|
113
|
-
type: "range" as const,
|
|
114
|
-
min: 0,
|
|
115
|
-
max: 1000,
|
|
116
|
-
},
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
return (
|
|
120
|
-
<div className="flex flex-col gap-8 lg:flex-row">
|
|
121
|
-
{/* Sidebar Filters */}
|
|
122
|
-
<aside className="w-full lg:w-64 lg:flex-shrink-0">
|
|
123
|
-
<div className="sticky top-4">
|
|
124
|
-
<h2 className="mb-4 text-lg font-semibold text-foreground">
|
|
125
|
-
Filters
|
|
126
|
-
</h2>
|
|
127
|
-
<Suspense fallback={<Skeleton className="h-96 w-full" />}>
|
|
128
|
-
<ProductFilters
|
|
129
|
-
filters={filterOptions}
|
|
130
|
-
selectedFilters={selectedFilters}
|
|
131
|
-
onFilterChange={handleFilterChange}
|
|
132
|
-
onClearAll={() => router.push("/products")}
|
|
133
|
-
/>
|
|
134
|
-
</Suspense>
|
|
135
|
-
</div>
|
|
136
|
-
</aside>
|
|
137
|
-
|
|
138
|
-
{/* Main Content */}
|
|
139
|
-
<div className="flex-1">
|
|
140
|
-
{/* Sort & Results Count */}
|
|
141
|
-
<div className="mb-6 flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
|
|
142
|
-
<p className="text-sm text-muted-foreground">
|
|
143
|
-
{totalCount > 0
|
|
144
|
-
? `Showing ${(page - 1) * limit + 1}-${Math.min(page * limit, totalCount)} of ${totalCount} products`
|
|
145
|
-
: "No products found"}
|
|
146
|
-
</p>
|
|
147
|
-
<ProductSort
|
|
148
|
-
value={sort}
|
|
149
|
-
onChange={(newSort) => {
|
|
150
|
-
const newParams = new URLSearchParams(searchParams.toString());
|
|
151
|
-
newParams.set("sort", newSort);
|
|
152
|
-
router.push(`/products?${newParams.toString()}`);
|
|
153
|
-
}}
|
|
154
|
-
/>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
{/* Products Grid */}
|
|
158
|
-
{isLoading ? (
|
|
159
|
-
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
160
|
-
{Array.from({ length: 6 }).map((_, i) => (
|
|
161
|
-
<Skeleton key={i} className="aspect-square w-full" />
|
|
162
|
-
))}
|
|
163
|
-
</div>
|
|
164
|
-
) : (
|
|
165
|
-
<ProductGrid
|
|
166
|
-
products={products}
|
|
167
|
-
columns={3}
|
|
168
|
-
priorityCount={6}
|
|
169
|
-
showBadges
|
|
170
|
-
emptyMessage="No products match your filters"
|
|
171
|
-
onResetFilters={() => router.push("/products")}
|
|
172
|
-
/>
|
|
173
|
-
)}
|
|
174
|
-
|
|
175
|
-
{/* Pagination */}
|
|
176
|
-
{totalPages > 1 && (
|
|
177
|
-
<div className="mt-8 flex justify-center">
|
|
178
|
-
<Pagination
|
|
179
|
-
currentPage={page}
|
|
180
|
-
totalPages={totalPages}
|
|
181
|
-
onPageChange={(newPage: number) => {
|
|
182
|
-
const newParams = new URLSearchParams(searchParams.toString());
|
|
183
|
-
newParams.set("page", newPage.toString());
|
|
184
|
-
router.push(`/products?${newParams.toString()}`);
|
|
185
|
-
}}
|
|
186
|
-
/>
|
|
187
|
-
</div>
|
|
188
|
-
)}
|
|
189
|
-
</div>
|
|
190
|
-
</div>
|
|
191
|
-
);
|
|
192
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* CurrencyProvider - Initializes currency store with Shop data
|
|
5
|
-
*
|
|
6
|
-
* This provider:
|
|
7
|
-
* 1. Receives Shop data from server (via root layout)
|
|
8
|
-
* 2. Initializes currency store on mount
|
|
9
|
-
* 3. Handles currency detection from:
|
|
10
|
-
* - localStorage (saved preference)
|
|
11
|
-
* - Browser locale (auto-detection)
|
|
12
|
-
* - Shop base currency (fallback)
|
|
13
|
-
*
|
|
14
|
-
* The currency store manages:
|
|
15
|
-
* - User's preferred currency
|
|
16
|
-
* - Supported currencies list
|
|
17
|
-
* - Base currency for the shop
|
|
18
|
-
* - Persistence to localStorage
|
|
19
|
-
*
|
|
20
|
-
* @module storefront-nextjs/components/providers/currency-provider
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { useEffect, type ReactNode } from 'react';
|
|
24
|
-
import { useCurrencyStore, type ShopCurrencyData } from '@/stores/currency-store';
|
|
25
|
-
|
|
26
|
-
// ============================================================================
|
|
27
|
-
// TYPES
|
|
28
|
-
// ============================================================================
|
|
29
|
-
|
|
30
|
-
interface CurrencyProviderProps {
|
|
31
|
-
/**
|
|
32
|
-
* Shop data containing currency configuration
|
|
33
|
-
* Fetched from GraphQL Shop query in root layout
|
|
34
|
-
*/
|
|
35
|
-
shopData: ShopCurrencyData;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Child components
|
|
39
|
-
*/
|
|
40
|
-
children: ReactNode;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ============================================================================
|
|
44
|
-
// COMPONENT
|
|
45
|
-
// ============================================================================
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* CurrencyProvider - Initializes currency store with Shop data
|
|
49
|
-
*
|
|
50
|
-
* This component should be placed in the root layout after fetching Shop data.
|
|
51
|
-
* It initializes the currency store once on mount, which triggers:
|
|
52
|
-
* 1. Loading saved currency from localStorage (if valid)
|
|
53
|
-
* 2. Auto-detecting currency from browser locale (if no saved preference)
|
|
54
|
-
* 3. Falling back to shop's base currency
|
|
55
|
-
*
|
|
56
|
-
* The initialization only happens once per session. Subsequent currency changes
|
|
57
|
-
* are handled by the currency store's setCurrency action.
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```tsx
|
|
61
|
-
* // app/layout.tsx
|
|
62
|
-
* import { fetchShop } from '@/lib/graphql/server';
|
|
63
|
-
* import { CurrencyProvider } from '@/components/providers/currency-provider';
|
|
64
|
-
*
|
|
65
|
-
* export default async function RootLayout({ children }) {
|
|
66
|
-
* const { shop } = await fetchShop();
|
|
67
|
-
*
|
|
68
|
-
* return (
|
|
69
|
-
* <html lang="en">
|
|
70
|
-
* <body>
|
|
71
|
-
* <QueryProvider>
|
|
72
|
-
* <CurrencyProvider shopData={shop}>
|
|
73
|
-
* <Header />
|
|
74
|
-
* <main>{children}</main>
|
|
75
|
-
* <Footer />
|
|
76
|
-
* </CurrencyProvider>
|
|
77
|
-
* </QueryProvider>
|
|
78
|
-
* </body>
|
|
79
|
-
* </html>
|
|
80
|
-
* );
|
|
81
|
-
* }
|
|
82
|
-
* ```
|
|
83
|
-
*
|
|
84
|
-
* @param props - Component props
|
|
85
|
-
* @param props.shopData - Shop currency configuration
|
|
86
|
-
* @param props.children - Child components to render
|
|
87
|
-
*/
|
|
88
|
-
export function CurrencyProvider({ shopData, children }: CurrencyProviderProps) {
|
|
89
|
-
const initialize = useCurrencyStore((state: any) => state.initialize);
|
|
90
|
-
|
|
91
|
-
useEffect(() => {
|
|
92
|
-
// Initialize currency store with Shop data
|
|
93
|
-
// This will:
|
|
94
|
-
// 1. Set base currency and supported currencies
|
|
95
|
-
// 2. Restore saved currency from localStorage (if valid)
|
|
96
|
-
// 3. Auto-detect from browser locale (if no saved preference)
|
|
97
|
-
// 4. Fall back to base currency
|
|
98
|
-
initialize(shopData);
|
|
99
|
-
}, [shopData, initialize]);
|
|
100
|
-
|
|
101
|
-
// Simply render children - the store initialization happens in the background
|
|
102
|
-
return <>{children}</>;
|
|
103
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { gql } from 'graphql-tag';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Example: Custom GraphQL query for collections
|
|
5
|
-
*
|
|
6
|
-
* This file demonstrates how to write custom GraphQL queries for collections
|
|
7
|
-
* that will be picked up by codegen and generate TypeScript types.
|
|
8
|
-
*
|
|
9
|
-
* To use this example:
|
|
10
|
-
* 1. Rename this file from collections.example.ts to collections.ts
|
|
11
|
-
* 2. Run `pnpm run codegen` to generate types
|
|
12
|
-
* 3. Import the generated query in your components
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// Example 1: Get featured collections
|
|
16
|
-
export const GET_FEATURED_COLLECTIONS = gql`
|
|
17
|
-
query GetFeaturedCollections($first: Int = 6) {
|
|
18
|
-
collections(first: $first, query: "featured:true") {
|
|
19
|
-
edges {
|
|
20
|
-
node {
|
|
21
|
-
id
|
|
22
|
-
handle
|
|
23
|
-
title
|
|
24
|
-
description
|
|
25
|
-
image {
|
|
26
|
-
url
|
|
27
|
-
altText
|
|
28
|
-
width
|
|
29
|
-
height
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
cursor
|
|
33
|
-
}
|
|
34
|
-
pageInfo {
|
|
35
|
-
hasNextPage
|
|
36
|
-
endCursor
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
`;
|
|
41
|
-
|
|
42
|
-
// Example 2: Get collection with products
|
|
43
|
-
export const GET_COLLECTION_WITH_PRODUCTS = gql`
|
|
44
|
-
query GetCollectionWithProducts(
|
|
45
|
-
$handle: String!
|
|
46
|
-
$first: Int = 20
|
|
47
|
-
$after: String
|
|
48
|
-
) {
|
|
49
|
-
collection(handle: $handle) {
|
|
50
|
-
id
|
|
51
|
-
title
|
|
52
|
-
description
|
|
53
|
-
descriptionHtml
|
|
54
|
-
image {
|
|
55
|
-
url
|
|
56
|
-
altText
|
|
57
|
-
}
|
|
58
|
-
seo {
|
|
59
|
-
title
|
|
60
|
-
description
|
|
61
|
-
}
|
|
62
|
-
products(
|
|
63
|
-
first: $first
|
|
64
|
-
after: $after
|
|
65
|
-
) {
|
|
66
|
-
edges {
|
|
67
|
-
node {
|
|
68
|
-
id
|
|
69
|
-
handle
|
|
70
|
-
title
|
|
71
|
-
description
|
|
72
|
-
featuredImage {
|
|
73
|
-
url
|
|
74
|
-
altText
|
|
75
|
-
}
|
|
76
|
-
priceRange {
|
|
77
|
-
minVariantPrice {
|
|
78
|
-
amount
|
|
79
|
-
currencyCode
|
|
80
|
-
baseAmount
|
|
81
|
-
baseCurrencyCode
|
|
82
|
-
isConverted
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
compareAtPriceRange {
|
|
86
|
-
minVariantPrice {
|
|
87
|
-
amount
|
|
88
|
-
currencyCode
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
vendor
|
|
92
|
-
productType
|
|
93
|
-
tags
|
|
94
|
-
totalInventory
|
|
95
|
-
}
|
|
96
|
-
cursor
|
|
97
|
-
}
|
|
98
|
-
pageInfo {
|
|
99
|
-
hasNextPage
|
|
100
|
-
hasPreviousPage
|
|
101
|
-
startCursor
|
|
102
|
-
endCursor
|
|
103
|
-
}
|
|
104
|
-
totalCount
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
`;
|
|
109
|
-
|
|
110
|
-
// Example 3: Get all collections with product counts
|
|
111
|
-
export const GET_ALL_COLLECTIONS = gql`
|
|
112
|
-
query GetAllCollections(
|
|
113
|
-
$first: Int = 50
|
|
114
|
-
$after: String
|
|
115
|
-
$sortKey: CollectionSortKeys = TITLE
|
|
116
|
-
) {
|
|
117
|
-
collections(first: $first, after: $after, sortKey: $sortKey) {
|
|
118
|
-
edges {
|
|
119
|
-
node {
|
|
120
|
-
id
|
|
121
|
-
handle
|
|
122
|
-
title
|
|
123
|
-
description
|
|
124
|
-
image {
|
|
125
|
-
url
|
|
126
|
-
altText
|
|
127
|
-
}
|
|
128
|
-
products(first: 1) {
|
|
129
|
-
totalCount
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
cursor
|
|
133
|
-
}
|
|
134
|
-
pageInfo {
|
|
135
|
-
hasNextPage
|
|
136
|
-
hasPreviousPage
|
|
137
|
-
startCursor
|
|
138
|
-
endCursor
|
|
139
|
-
}
|
|
140
|
-
totalCount
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
`;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Usage in components:
|
|
147
|
-
*
|
|
148
|
-
* // Server Component
|
|
149
|
-
* import { getClient } from '@/lib/graphql/server';
|
|
150
|
-
* import { GetFeaturedCollectionsDocument } from '@/generated/graphql';
|
|
151
|
-
*
|
|
152
|
-
* const client = getClient();
|
|
153
|
-
* const { collections } = await client.request(GetFeaturedCollectionsDocument);
|
|
154
|
-
*
|
|
155
|
-
* // Client Component
|
|
156
|
-
* import { useQuery } from '@tanstack/react-query';
|
|
157
|
-
* import { getGraphQLClient } from '@/lib/graphql/client';
|
|
158
|
-
* import { GetCollectionWithProductsDocument } from '@/generated/graphql';
|
|
159
|
-
*
|
|
160
|
-
* const client = getGraphQLClient();
|
|
161
|
-
* const { data } = useQuery({
|
|
162
|
-
* queryKey: ['Collection', handle],
|
|
163
|
-
* queryFn: () => client.request(GetCollectionWithProductsDocument, {
|
|
164
|
-
* handle,
|
|
165
|
-
* first: 20
|
|
166
|
-
* }),
|
|
167
|
-
* });
|
|
168
|
-
*/
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { gql } from 'graphql-tag';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Example: Custom GraphQL query for featured products
|
|
5
|
-
*
|
|
6
|
-
* This file demonstrates how to write custom GraphQL queries
|
|
7
|
-
* that will be picked up by codegen and generate TypeScript types.
|
|
8
|
-
*
|
|
9
|
-
* To use this example:
|
|
10
|
-
* 1. Rename this file from products.example.ts to products.ts
|
|
11
|
-
* 2. Run `pnpm run codegen` to generate types
|
|
12
|
-
* 3. Import the generated query in your components
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// Example 1: Get featured products with specific fields
|
|
16
|
-
export const GET_FEATURED_PRODUCTS = gql`
|
|
17
|
-
query GetFeaturedProducts($first: Int = 6) {
|
|
18
|
-
products(first: $first, query: "tag:featured") {
|
|
19
|
-
edges {
|
|
20
|
-
node {
|
|
21
|
-
id
|
|
22
|
-
handle
|
|
23
|
-
title
|
|
24
|
-
description
|
|
25
|
-
featuredImage {
|
|
26
|
-
url
|
|
27
|
-
altText
|
|
28
|
-
width
|
|
29
|
-
height
|
|
30
|
-
}
|
|
31
|
-
priceRange {
|
|
32
|
-
minVariantPrice {
|
|
33
|
-
amount
|
|
34
|
-
currencyCode
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
cursor
|
|
39
|
-
}
|
|
40
|
-
pageInfo {
|
|
41
|
-
hasNextPage
|
|
42
|
-
endCursor
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
`;
|
|
47
|
-
|
|
48
|
-
// Example 2: Get product with reviews
|
|
49
|
-
export const GET_PRODUCT_WITH_REVIEWS = gql`
|
|
50
|
-
query GetProductWithReviews($handle: String!) {
|
|
51
|
-
product(handle: $handle) {
|
|
52
|
-
id
|
|
53
|
-
title
|
|
54
|
-
description
|
|
55
|
-
descriptionHtml
|
|
56
|
-
averageRating
|
|
57
|
-
reviewCount
|
|
58
|
-
featuredImage {
|
|
59
|
-
url
|
|
60
|
-
altText
|
|
61
|
-
}
|
|
62
|
-
priceRange {
|
|
63
|
-
minVariantPrice {
|
|
64
|
-
amount
|
|
65
|
-
currencyCode
|
|
66
|
-
baseAmount
|
|
67
|
-
baseCurrencyCode
|
|
68
|
-
isConverted
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
variants(first: 10) {
|
|
72
|
-
id
|
|
73
|
-
title
|
|
74
|
-
price {
|
|
75
|
-
amount
|
|
76
|
-
currencyCode
|
|
77
|
-
}
|
|
78
|
-
available
|
|
79
|
-
quantityAvailable
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
`;
|
|
84
|
-
|
|
85
|
-
// Example 3: Search products with filters
|
|
86
|
-
export const SEARCH_PRODUCTS_WITH_FILTERS = gql`
|
|
87
|
-
query SearchProductsWithFilters(
|
|
88
|
-
$query: String!
|
|
89
|
-
$first: Int = 20
|
|
90
|
-
$after: String
|
|
91
|
-
$filters: ProductFilterInput
|
|
92
|
-
) {
|
|
93
|
-
products(
|
|
94
|
-
query: $query
|
|
95
|
-
first: $first
|
|
96
|
-
after: $after
|
|
97
|
-
filters: $filters
|
|
98
|
-
) {
|
|
99
|
-
edges {
|
|
100
|
-
node {
|
|
101
|
-
id
|
|
102
|
-
handle
|
|
103
|
-
title
|
|
104
|
-
vendor
|
|
105
|
-
productType
|
|
106
|
-
featuredImage {
|
|
107
|
-
url
|
|
108
|
-
altText
|
|
109
|
-
}
|
|
110
|
-
priceRange {
|
|
111
|
-
minVariantPrice {
|
|
112
|
-
amount
|
|
113
|
-
currencyCode
|
|
114
|
-
}
|
|
115
|
-
maxVariantPrice {
|
|
116
|
-
amount
|
|
117
|
-
currencyCode
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
compareAtPriceRange {
|
|
121
|
-
minVariantPrice {
|
|
122
|
-
amount
|
|
123
|
-
currencyCode
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
cursor
|
|
128
|
-
}
|
|
129
|
-
pageInfo {
|
|
130
|
-
hasNextPage
|
|
131
|
-
hasPreviousPage
|
|
132
|
-
startCursor
|
|
133
|
-
endCursor
|
|
134
|
-
}
|
|
135
|
-
totalCount
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
`;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Usage in components:
|
|
142
|
-
*
|
|
143
|
-
* // Server Component
|
|
144
|
-
* import { getClient } from '@/lib/graphql/server';
|
|
145
|
-
* import { GetFeaturedProductsDocument } from '@/generated/graphql';
|
|
146
|
-
*
|
|
147
|
-
* const client = getClient();
|
|
148
|
-
* const { products } = await client.request(GetFeaturedProductsDocument, { first: 6 });
|
|
149
|
-
*
|
|
150
|
-
* // Client Component
|
|
151
|
-
* import { useQuery } from '@tanstack/react-query';
|
|
152
|
-
* import { getGraphQLClient } from '@/lib/graphql/client';
|
|
153
|
-
* import { GetFeaturedProductsDocument } from '@/generated/graphql';
|
|
154
|
-
*
|
|
155
|
-
* const client = getGraphQLClient();
|
|
156
|
-
* const { data } = useQuery({
|
|
157
|
-
* queryKey: ['FeaturedProducts'],
|
|
158
|
-
* queryFn: () => client.request(GetFeaturedProductsDocument, { first: 6 }),
|
|
159
|
-
* });
|
|
160
|
-
*/
|