@doswiftly/cli 0.2.1 → 0.2.5
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 +1 -1
- package/bin/doswiftly.js +0 -0
- package/dist/commands/dev.d.ts +7 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +110 -51
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +11 -1
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +5 -1
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/proxy.d.ts.map +1 -1
- package/dist/commands/proxy.js +7 -1
- package/dist/commands/proxy.js.map +1 -1
- package/dist/commands/template.js +1 -1
- package/dist/config/types.d.ts +8 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/api-url.d.ts +77 -8
- package/dist/lib/api-url.d.ts.map +1 -1
- package/dist/lib/api-url.js +54 -12
- package/dist/lib/api-url.js.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +9 -12
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/i18n.d.ts +24 -0
- package/dist/lib/i18n.d.ts.map +1 -1
- package/dist/lib/i18n.js +48 -0
- package/dist/lib/i18n.js.map +1 -1
- package/dist/lib/proxy-server.d.ts +26 -0
- package/dist/lib/proxy-server.d.ts.map +1 -1
- package/dist/lib/proxy-server.js +57 -0
- package/dist/lib/proxy-server.js.map +1 -1
- package/package.json +10 -11
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/[slug]/product-client.tsx +87 -2
- package/templates/storefront-nextjs-shadcn/app/[locale]/products/products-client.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/codegen.ts +1 -1
- package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +18 -0
- package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +17 -1
- package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +2 -1
- package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +2 -1
- package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +23 -3
- package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +1 -1
- package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +2 -1
- package/templates/storefront-nextjs-shadcn/components/product/product-configurator.fragment.graphql +43 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-configurator.tsx +282 -0
- package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +8 -1
- package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +7 -3
- package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +2 -1
- package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +100 -0
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +26 -5
- package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +26 -0
- package/templates/storefront-nextjs-shadcn/lib/image-loader.ts +12 -0
- package/templates/storefront-nextjs-shadcn/next.config.ts +6 -17
- package/templates/storefront-nextjs-shadcn/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../src/lib/proxy-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AACrE,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAsBrC,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACjC,MAAM;IACN,YAAY;IACZ,YAAY;IACZ,mBAAmB;IACnB,IAAI;IACJ,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,oBAAoB;CACrB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,oBAAoB,GAAG;IAC3B,cAAc;IACd,eAAe;IACf,kBAAkB;IAClB,eAAe;IACf,aAAa;IACb,sBAAsB;IACtB,kBAAkB;IAClB,yBAAyB;IACzB,cAAc;IACd,kBAAkB;IAClB,wBAAwB;IACxB,QAAQ;CACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAE5C,8EAA8E;AAC9E,iCAAiC;AACjC,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,iFAAiF;QACjF,yDAAyD;QACzD,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../src/lib/proxy-server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doswiftly/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "DoSwiftly CLI - Scaffold and deploy e-commerce storefronts",
|
|
5
5
|
"homepage": "https://doswiftly.pl",
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,14 +29,6 @@
|
|
|
29
29
|
"bin",
|
|
30
30
|
"templates"
|
|
31
31
|
],
|
|
32
|
-
"scripts": {
|
|
33
|
-
"build": "tsc",
|
|
34
|
-
"dev": "tsc --watch",
|
|
35
|
-
"clean": "rimraf dist",
|
|
36
|
-
"prepublishOnly": "pnpm run clean && pnpm run build",
|
|
37
|
-
"test": "vitest run",
|
|
38
|
-
"test:watch": "vitest"
|
|
39
|
-
},
|
|
40
32
|
"keywords": [
|
|
41
33
|
"doswiftly",
|
|
42
34
|
"cli",
|
|
@@ -50,7 +42,7 @@
|
|
|
50
42
|
"@clack/core": "^0.4.1",
|
|
51
43
|
"@clack/prompts": "^0.10.0",
|
|
52
44
|
"@inquirer/prompts": "^7.2.0",
|
|
53
|
-
"axios": "^1.
|
|
45
|
+
"axios": "^1.15.0",
|
|
54
46
|
"chalk": "^5.3.0",
|
|
55
47
|
"picocolors": "^1.1.1",
|
|
56
48
|
"chokidar": "^4.0.1",
|
|
@@ -81,5 +73,12 @@
|
|
|
81
73
|
"engines": {
|
|
82
74
|
"node": ">=18.0.0",
|
|
83
75
|
"pnpm": ">=9.0.0"
|
|
76
|
+
},
|
|
77
|
+
"scripts": {
|
|
78
|
+
"build": "tsc",
|
|
79
|
+
"dev": "tsc --watch",
|
|
80
|
+
"clean": "rimraf dist",
|
|
81
|
+
"test": "vitest run",
|
|
82
|
+
"test:watch": "vitest"
|
|
84
83
|
}
|
|
85
|
-
}
|
|
84
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect } from "react";
|
|
3
|
+
import { useState, useEffect, useMemo, useCallback } from "react";
|
|
4
4
|
import { useTranslations } from "next-intl";
|
|
5
|
+
import { toast } from "sonner";
|
|
5
6
|
import { useProduct } from "@/lib/graphql/hooks";
|
|
6
7
|
import { useCurrencyStore } from "@doswiftly/storefront-sdk/react";
|
|
7
8
|
import { ProductGallery } from "@/components/product/product-gallery";
|
|
@@ -9,6 +10,12 @@ import { ProductPrice } from "@/components/product/product-price";
|
|
|
9
10
|
import { ProductVariantSelector } from "@/components/product/product-variant-selector";
|
|
10
11
|
import { ProductQuantitySelector } from "@/components/product/product-quantity-selector";
|
|
11
12
|
import { AddToCartButton } from "@/components/product/add-to-cart-button";
|
|
13
|
+
import {
|
|
14
|
+
ProductConfigurator,
|
|
15
|
+
computeConfiguratorSurcharge,
|
|
16
|
+
findMissingRequiredFields,
|
|
17
|
+
type ProductConfiguratorSelection,
|
|
18
|
+
} from "@/components/product/product-configurator";
|
|
12
19
|
import { StockIndicator } from "@/components/product/stock-indicator";
|
|
13
20
|
import { SimilarProducts } from "@/components/product/similar-products";
|
|
14
21
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|
@@ -39,6 +46,12 @@ export function ProductClient({ product: initialProduct, similarProducts = [] }:
|
|
|
39
46
|
const t = useTranslations("productPage");
|
|
40
47
|
const [selectedVariant, setSelectedVariant] = useState(initialProduct.variants[0]);
|
|
41
48
|
const [quantity, setQuantity] = useState(1);
|
|
49
|
+
// Faza 1 — state konfiguratora (Finiszer, nr telefonu itd.) per attributeDefinitionId.
|
|
50
|
+
// Wysyłany do cartLinesAdd jako `attributeSelections`, backend waliduje + snapshotuje.
|
|
51
|
+
const [configuratorSelections, setConfiguratorSelections] = useState<
|
|
52
|
+
Record<string, ProductConfiguratorSelection>
|
|
53
|
+
>({});
|
|
54
|
+
const [showConfigValidation, setShowConfigValidation] = useState(false);
|
|
42
55
|
|
|
43
56
|
// Get user's preferred currency from store
|
|
44
57
|
const currency = useCurrencyStore((s) => s.currency);
|
|
@@ -102,6 +115,59 @@ export function ProductClient({ product: initialProduct, similarProducts = [] }:
|
|
|
102
115
|
parseFloat(selectedVariant.compareAtPrice.amount) >
|
|
103
116
|
parseFloat(selectedVariant.price.amount);
|
|
104
117
|
|
|
118
|
+
// Faza 1 — Customer-filled attributes z Product.attributes (CUSTOMER + BOTH).
|
|
119
|
+
// Puste gdy sklep nie używa konfiguratorów — sekcja nie renderuje się wtedy.
|
|
120
|
+
const configuratorAttributes = product.attributes ?? [];
|
|
121
|
+
|
|
122
|
+
const handleConfiguratorChange = useCallback(
|
|
123
|
+
(definitionId: string, selection: ProductConfiguratorSelection) => {
|
|
124
|
+
setConfiguratorSelections((prev) => ({ ...prev, [definitionId]: selection }));
|
|
125
|
+
// Wyczyść validation stan po każdej zmianie — użytkownik dostaje drugą szansę
|
|
126
|
+
// zamiast utrzymujących się czerwonych ramek.
|
|
127
|
+
if (showConfigValidation) setShowConfigValidation(false);
|
|
128
|
+
},
|
|
129
|
+
[showConfigValidation],
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Live surcharge preview — doliczane do ceny wariantu na przycisku (jak Shopify Dynamic Checkout).
|
|
133
|
+
const surcharge = useMemo(
|
|
134
|
+
() => computeConfiguratorSurcharge(configuratorAttributes, configuratorSelections),
|
|
135
|
+
[configuratorAttributes, configuratorSelections],
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const displayPrice = useMemo(() => {
|
|
139
|
+
if (surcharge === 0) return selectedVariant.price;
|
|
140
|
+
const base = parseFloat(selectedVariant.price.amount);
|
|
141
|
+
const total = base + surcharge / 100;
|
|
142
|
+
return {
|
|
143
|
+
amount: total.toFixed(2),
|
|
144
|
+
currencyCode: selectedVariant.price.currencyCode,
|
|
145
|
+
};
|
|
146
|
+
}, [selectedVariant.price, surcharge]);
|
|
147
|
+
|
|
148
|
+
const attributeSelectionsForCart = useMemo(
|
|
149
|
+
() =>
|
|
150
|
+
Object.values(configuratorSelections)
|
|
151
|
+
.filter((s) => s.optionId || s.textValue)
|
|
152
|
+
.map((s) => ({
|
|
153
|
+
attributeDefinitionId: s.attributeDefinitionId,
|
|
154
|
+
optionId: s.optionId ?? undefined,
|
|
155
|
+
optionIds: s.optionIds ?? undefined,
|
|
156
|
+
textValue: s.textValue ?? undefined,
|
|
157
|
+
})),
|
|
158
|
+
[configuratorSelections],
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const validateConfiguratorBeforeAdd = useCallback(() => {
|
|
162
|
+
const missing = findMissingRequiredFields(configuratorAttributes, configuratorSelections);
|
|
163
|
+
if (missing.length > 0) {
|
|
164
|
+
setShowConfigValidation(true);
|
|
165
|
+
toast.error(`Wypełnij wymagane pola: ${missing.join(", ")}`);
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
}, [configuratorAttributes, configuratorSelections]);
|
|
170
|
+
|
|
105
171
|
return (
|
|
106
172
|
<div className="space-y-16">
|
|
107
173
|
{/* Product Details */}
|
|
@@ -138,13 +204,19 @@ export function ProductClient({ product: initialProduct, similarProducts = [] }:
|
|
|
138
204
|
</div>
|
|
139
205
|
|
|
140
206
|
{/* Price - suppressHydrationWarning prevents mismatch during currency switch */}
|
|
207
|
+
{/* Faza 1 — displayPrice uwzględnia doliczone surcharge z konfiguratora (live preview). */}
|
|
141
208
|
<div suppressHydrationWarning>
|
|
142
209
|
<ProductPrice
|
|
143
|
-
price={
|
|
210
|
+
price={displayPrice}
|
|
144
211
|
compareAtPrice={selectedVariant.compareAtPrice || undefined}
|
|
145
212
|
showCompareAt
|
|
146
213
|
size="xl"
|
|
147
214
|
/>
|
|
215
|
+
{surcharge > 0 && (
|
|
216
|
+
<p className="mt-1 text-xs text-muted-foreground">
|
|
217
|
+
Cena zawiera dopłaty z konfiguratora poniżej.
|
|
218
|
+
</p>
|
|
219
|
+
)}
|
|
148
220
|
</div>
|
|
149
221
|
|
|
150
222
|
{/* Stock */}
|
|
@@ -169,6 +241,17 @@ export function ProductClient({ product: initialProduct, similarProducts = [] }:
|
|
|
169
241
|
/>
|
|
170
242
|
)}
|
|
171
243
|
|
|
244
|
+
{/* Faza 1 — Customer configurator (Finiszer, nr telefonu serwisu, itd.). */}
|
|
245
|
+
{configuratorAttributes.length > 0 && (
|
|
246
|
+
<ProductConfigurator
|
|
247
|
+
attributes={configuratorAttributes}
|
|
248
|
+
selections={configuratorSelections}
|
|
249
|
+
onChange={handleConfiguratorChange}
|
|
250
|
+
currency={selectedVariant.price.currencyCode}
|
|
251
|
+
showValidation={showConfigValidation}
|
|
252
|
+
/>
|
|
253
|
+
)}
|
|
254
|
+
|
|
172
255
|
{/* Quantity & Add to Cart */}
|
|
173
256
|
<div className="space-y-4">
|
|
174
257
|
<div className="flex items-center gap-4">
|
|
@@ -189,6 +272,8 @@ export function ProductClient({ product: initialProduct, similarProducts = [] }:
|
|
|
189
272
|
image={selectedVariant.image || product.images[0]}
|
|
190
273
|
available={selectedVariant.available}
|
|
191
274
|
quantity={quantity}
|
|
275
|
+
attributeSelections={attributeSelectionsForCart}
|
|
276
|
+
onBeforeAdd={validateConfiguratorBeforeAdd}
|
|
192
277
|
fullWidth
|
|
193
278
|
size="lg"
|
|
194
279
|
/>
|
|
@@ -25,7 +25,7 @@ import { cn } from "@/lib/utils";
|
|
|
25
25
|
/**
|
|
26
26
|
* ProductsClient — Dynamic product listing with API-driven filters.
|
|
27
27
|
*
|
|
28
|
-
* UX patterns
|
|
28
|
+
* UX patterns:
|
|
29
29
|
* - useTransition wraps all filter updates (non-blocking UI)
|
|
30
30
|
* - keepPreviousData prevents skeleton flash on filter changes
|
|
31
31
|
* - data-pending CSS opacity dimming during transitions
|
|
@@ -11,7 +11,7 @@ import type { CodegenConfig } from '@graphql-codegen/cli';
|
|
|
11
11
|
* No running backend needed — schema is synced as a file.
|
|
12
12
|
*
|
|
13
13
|
* Architecture decision: https://github.com/dotansimha/graphql-typed-document-node
|
|
14
|
-
*
|
|
14
|
+
* Approach: client-preset + TypedDocumentString (no runtime GraphQL dep).
|
|
15
15
|
*
|
|
16
16
|
* To update schema after backend changes:
|
|
17
17
|
* cd packages/@doswiftly/storefront-operations && pnpm run sync
|
|
@@ -66,6 +66,24 @@ export function CartItem({
|
|
|
66
66
|
{item.variantTitle}
|
|
67
67
|
</p>
|
|
68
68
|
)}
|
|
69
|
+
{/* Faza 1 — configurator selections z Product.attributes.
|
|
70
|
+
SEPARATE_LINE items są osobnymi fakturowanymi pozycjami; tutaj
|
|
71
|
+
pokazujemy snapshot dla klarownego feedback-u w koszyku. */}
|
|
72
|
+
{item.attributeSelections.length > 0 && (
|
|
73
|
+
<ul className="mt-2 space-y-0.5 text-xs text-muted-foreground">
|
|
74
|
+
{item.attributeSelections.map((sel) => (
|
|
75
|
+
<li key={sel.attributeDefinitionId} className="flex items-center gap-1">
|
|
76
|
+
<span className="font-medium text-foreground/80">{sel.attributeName}:</span>
|
|
77
|
+
<span>{sel.optionLabel ?? sel.textValue ?? "—"}</span>
|
|
78
|
+
{sel.billingMode === "SEPARATE_LINE" && sel.surchargeAmount > 0 && (
|
|
79
|
+
<span className="text-[10px] text-muted-foreground/80">
|
|
80
|
+
(+{formatAmount(sel.surchargeAmount / 100, item.price.currencyCode)} — osobna pozycja faktury)
|
|
81
|
+
</span>
|
|
82
|
+
)}
|
|
83
|
+
</li>
|
|
84
|
+
))}
|
|
85
|
+
</ul>
|
|
86
|
+
)}
|
|
69
87
|
</div>
|
|
70
88
|
|
|
71
89
|
{/* Remove button */}
|
|
@@ -28,8 +28,9 @@ fragment CartLineFields on CartLine {
|
|
|
28
28
|
currencyCode
|
|
29
29
|
}
|
|
30
30
|
image {
|
|
31
|
-
url
|
|
31
|
+
url(transform: { maxWidth: 300 })
|
|
32
32
|
altText
|
|
33
|
+
thumbhash
|
|
33
34
|
}
|
|
34
35
|
selectedOptions {
|
|
35
36
|
name
|
|
@@ -50,4 +51,19 @@ fragment CartLineFields on CartLine {
|
|
|
50
51
|
currencyCode
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
# Faza 1 — Customer-filled attributes snapshot per cart line.
|
|
55
|
+
# Rendered in cart-item.tsx so the shopper sees their configurator choices
|
|
56
|
+
# (Finiszer, service phone, etc.) with surcharge contribution to line total.
|
|
57
|
+
attributeSelections {
|
|
58
|
+
attributeDefinitionId
|
|
59
|
+
attributeName
|
|
60
|
+
type
|
|
61
|
+
fillingMode
|
|
62
|
+
billingMode
|
|
63
|
+
optionId
|
|
64
|
+
optionLabel
|
|
65
|
+
textValue
|
|
66
|
+
surchargeAmount
|
|
67
|
+
surchargeType
|
|
68
|
+
}
|
|
53
69
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useState, useRef, useEffect } from "react";
|
|
4
4
|
import { useTranslations } from "next-intl";
|
|
5
5
|
import { ShoppingCart, Check } from "lucide-react";
|
|
6
|
+
import type { CartAttributeSelectionInput } from "@doswiftly/storefront-sdk";
|
|
6
7
|
import { Button } from "@/components/ui/button";
|
|
7
8
|
import { Spinner } from "@/components/ui/spinner";
|
|
8
9
|
import { cn } from "@/lib/utils";
|
|
@@ -31,7 +32,21 @@ export interface AddToCartButtonProps {
|
|
|
31
32
|
className?: string;
|
|
32
33
|
size?: "sm" | "md" | "lg";
|
|
33
34
|
fullWidth?: boolean;
|
|
34
|
-
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Faza 1 — configurator selections captured on the product page.
|
|
38
|
+
* Przekazywane jako `cartLinesAdd.lines[].attributeSelections` do backendu
|
|
39
|
+
* (walidacja + snapshot surcharge/taxRate server-side).
|
|
40
|
+
*/
|
|
41
|
+
attributeSelections?: CartAttributeSelectionInput[];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Called before firing the mutation. Zwrócenie `false` anuluje dodanie —
|
|
45
|
+
* używane gdy rodzic waliduje required-fields konfiguratora i pokazuje błąd
|
|
46
|
+
* zamiast wywoływać backend.
|
|
47
|
+
*/
|
|
48
|
+
onBeforeAdd?: () => boolean;
|
|
49
|
+
|
|
35
50
|
// Optional custom handler (overrides default GraphQL behavior)
|
|
36
51
|
onAddToCart?: (variantId: string, quantity: number) => Promise<void>;
|
|
37
52
|
}
|
|
@@ -70,6 +85,8 @@ export function AddToCartButton({
|
|
|
70
85
|
available = true,
|
|
71
86
|
quantity = 1,
|
|
72
87
|
disabled = false,
|
|
88
|
+
attributeSelections,
|
|
89
|
+
onBeforeAdd,
|
|
73
90
|
onAddToCart,
|
|
74
91
|
className,
|
|
75
92
|
size = "md",
|
|
@@ -92,14 +109,17 @@ export function AddToCartButton({
|
|
|
92
109
|
const handleClick = async () => {
|
|
93
110
|
if (disabled || isLoading) return;
|
|
94
111
|
|
|
112
|
+
// Rodzic ma możliwość anulować akcję — np. configurator required-field walidacja.
|
|
113
|
+
if (onBeforeAdd && onBeforeAdd() === false) return;
|
|
114
|
+
|
|
95
115
|
try {
|
|
96
116
|
// Use custom handler if provided, otherwise use GraphQL integration
|
|
97
117
|
if (onAddToCart) {
|
|
98
118
|
await onAddToCart(variantId, quantity);
|
|
99
119
|
} else {
|
|
100
|
-
await addToCart(variantId, quantity);
|
|
120
|
+
await addToCart(variantId, quantity, attributeSelections);
|
|
101
121
|
}
|
|
102
|
-
|
|
122
|
+
|
|
103
123
|
setIsAdded(true);
|
|
104
124
|
|
|
105
125
|
// Clear any existing timeout
|
|
@@ -21,7 +21,7 @@ interface FilterActivePillsProps {
|
|
|
21
21
|
/**
|
|
22
22
|
* FilterActivePills - Shows active filters as removable badges
|
|
23
23
|
*
|
|
24
|
-
* Pattern
|
|
24
|
+
* Pattern:
|
|
25
25
|
* - Each pill shows "Label: Value" with X button
|
|
26
26
|
* - "Clear all" link at the end
|
|
27
27
|
* - Horizontally scrollable on mobile
|
|
@@ -23,7 +23,7 @@ interface FilterMobileSheetProps extends ProductFiltersProps {
|
|
|
23
23
|
/**
|
|
24
24
|
* FilterMobileSheet - Mobile filter panel (slides from left)
|
|
25
25
|
*
|
|
26
|
-
* Pattern
|
|
26
|
+
* Pattern:
|
|
27
27
|
* - Trigger button visible only on mobile (lg:hidden)
|
|
28
28
|
* - Sheet slides from left with full filter panel
|
|
29
29
|
* - Footer shows "Clear all" when filters active
|
package/templates/storefront-nextjs-shadcn/components/product/product-configurator.fragment.graphql
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Fragment for ProductConfigurator component.
|
|
2
|
+
#
|
|
3
|
+
# Renders customer-filled attribute fields on the product detail page:
|
|
4
|
+
# - SELECT / RADIO / CHECKBOX — rendered as option pickers with surcharge preview
|
|
5
|
+
# - TEXT / TEXTAREA / NUMBER / DATE — rendered as free-text inputs
|
|
6
|
+
#
|
|
7
|
+
# Fetched via Product.attributes(filter: { fillingMode: "CUSTOMER" }) — only
|
|
8
|
+
# fields the customer should fill at purchase time. MERCHANT-filled attributes
|
|
9
|
+
# (product metadata) are excluded.
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# import type { ProductConfiguratorFields } from '@/lib/graphql/fragments';
|
|
13
|
+
# interface Props { attributes: ProductConfiguratorFields[] }
|
|
14
|
+
|
|
15
|
+
fragment ProductConfiguratorOptionFields on ProductAttributeOption {
|
|
16
|
+
id
|
|
17
|
+
value
|
|
18
|
+
label
|
|
19
|
+
sortOrder
|
|
20
|
+
colorHex
|
|
21
|
+
surchargeAmount
|
|
22
|
+
surchargeType
|
|
23
|
+
isDefault
|
|
24
|
+
linkedVariantId
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fragment ProductConfiguratorFields on ProductAttributeDefinition {
|
|
28
|
+
id
|
|
29
|
+
name
|
|
30
|
+
slug
|
|
31
|
+
description
|
|
32
|
+
type
|
|
33
|
+
fillingMode
|
|
34
|
+
billingMode
|
|
35
|
+
taxClassId
|
|
36
|
+
isRequired
|
|
37
|
+
displayOrder
|
|
38
|
+
minValue
|
|
39
|
+
maxValue
|
|
40
|
+
options {
|
|
41
|
+
...ProductConfiguratorOptionFields
|
|
42
|
+
}
|
|
43
|
+
}
|