@flowselections/floriday-voorraad 1.0.82 → 1.0.84
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/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +53 -10
- package/dist-lib/hooks-entry.d.ts +1 -0
- package/dist-lib/hooks-entry.d.ts.map +1 -1
- package/dist-lib/hooks-entry.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +104 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.d.ts +5 -0
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +59 -50
- package/dist-lib/lib/publish-readiness.js +2 -2
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.d.ts +2 -0
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.d.ts.map +1 -0
- package/dist-lib/server-hooks/__tests__/trade-item-photo.test.js +19 -0
- package/dist-lib/server-hooks/trade-item-photo.d.ts +13 -0
- package/dist-lib/server-hooks/trade-item-photo.d.ts.map +1 -0
- package/dist-lib/server-hooks/trade-item-photo.js +354 -0
- package/package.json +10 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"AA6MA,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,cAAc,EACvB,WAAW,EACX,SAAS,EACT,WAAW,GACZ,GAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,+
|
|
1
|
+
{"version":3,"file":"ArtikelWizard.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ArtikelWizard.tsx"],"names":[],"mappings":"AA6MA,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,cAAc,EACvB,WAAW,EACX,SAAS,EACT,WAAW,GACZ,GAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,+BA6uEL"}
|
|
@@ -896,13 +896,27 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
896
896
|
return true;
|
|
897
897
|
return validateStepLocal(s.key, data).ok;
|
|
898
898
|
}), [steps, data, spec, regulatoryQuery.isLoading, regulatoryQuery.isError, regulatoryQuery.error]);
|
|
899
|
-
|
|
900
|
-
|
|
899
|
+
// Foto's zijn alleen verplicht om naar Floriday te publiceren
|
|
900
|
+
// (Floriday: "One or more product images"); opslaan als concept kan zonder.
|
|
901
|
+
const gateValidity = stepValidity.map((v, i) => v || (steps[i]?.key === "fotos" && !publishToFloriday));
|
|
902
|
+
const invalidStepCount = gateValidity.filter((v) => !v).length;
|
|
903
|
+
const firstInvalidIndex = gateValidity.findIndex((v) => !v);
|
|
901
904
|
const goTo = (i) => {
|
|
902
905
|
if (isEditing || i <= step || firstStepUnlocked)
|
|
903
906
|
setStep(i);
|
|
904
907
|
};
|
|
905
|
-
const
|
|
908
|
+
const [botanicalDraft, setBotanicalDraft] = useState("");
|
|
909
|
+
const next = () => {
|
|
910
|
+
const draft = botanicalDraft.trim();
|
|
911
|
+
if (draft) {
|
|
912
|
+
const names = data.botanicalName.split(";").map((x) => x.trim()).filter(Boolean);
|
|
913
|
+
if (!names.some((n) => n.toLowerCase() === draft.toLowerCase())) {
|
|
914
|
+
update("botanicalName", [...names, draft].join("; "));
|
|
915
|
+
}
|
|
916
|
+
setBotanicalDraft("");
|
|
917
|
+
}
|
|
918
|
+
setStep((s) => Math.min(s + 1, steps.length - 1));
|
|
919
|
+
};
|
|
906
920
|
// Autoscroll: bij wisselen van stap brengen we de open kaart in beeld zodat
|
|
907
921
|
// stappen onderaan (6-9) niet "verborgen" openen.
|
|
908
922
|
const stepRefs = useRef([]);
|
|
@@ -1750,7 +1764,7 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
1750
1764
|
? "border-primary bg-primary text-primary-foreground"
|
|
1751
1765
|
: status === "invalid"
|
|
1752
1766
|
? "border-destructive bg-destructive text-destructive-foreground"
|
|
1753
|
-
: "border-muted-foreground/30 text-muted-foreground"}`, children: status === "valid" ? (_jsx(Check, { className: "h-4 w-4" })) : status === "invalid" ? ("!") : (i + 1) }), _jsx("span", { className: `min-w-0 truncate font-medium ${status === "untouched" ? "text-muted-foreground" : ""}`, children: s.label }), !isOpen && summary && (_jsx("span", { className: `max-w-xs truncate text-xs ${status === "invalid" ? "text-destructive" : "text-muted-foreground"}`, children: status === "invalid" ? `Onvolledig — ${summary}` : summary }))] }), isOpen && (_jsxs(CardContent, { className: "space-y-4 pt-0", children: [_jsx("div", { "data-wizard-form-content": true, className: "w-full min-w-0", children: _jsx(StepBody, { stepKey: s.key, data: data, packingStatus: packingStatus, update: update, vbnProducts: vbnProducts, featureTypes: featureTypes, packagingTypes: packagingTypes, loadCarriers: loadCarriers, floridayCustomers: floridayCustomers, schemaQuery: schemaQuery, regulatoryQuery: regulatoryQuery, spec: spec, collectionsList: collectionsList, setCollectionsList: setCollectionsList, activeId: activeId, acceptedVbnCodes: acceptedVbnCodes, priceGroups: priceGroups, parentProductId: linkedProductId ?? draftId ?? null, parentFloridayId: draftFloridayId ?? tradeItemId ?? null, articleCodeLocked: Boolean(draftFloridayId || tradeItemId) }) }), isLastStep && !isEditingPublished && (_jsxs("div", { className: "rounded-lg border bg-muted/30 p-4 flex items-start gap-3", children: [_jsx("img", { src: floridayLogo, alt: "Floriday", className: "h-7 w-7 shrink-0 mt-0.5" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx(Label, { htmlFor: "publish-to-floriday", className: "font-medium cursor-pointer", children: "Publiceren naar Floriday" }), _jsx("p", { className: "text-xs text-muted-foreground mt-1", children: publishToFloriday
|
|
1767
|
+
: "border-muted-foreground/30 text-muted-foreground"}`, children: status === "valid" ? (_jsx(Check, { className: "h-4 w-4" })) : status === "invalid" ? ("!") : (i + 1) }), _jsx("span", { className: `min-w-0 truncate font-medium ${status === "untouched" ? "text-muted-foreground" : ""}`, children: s.label }), !isOpen && summary && (_jsx("span", { className: `max-w-xs truncate text-xs ${status === "invalid" ? "text-destructive" : "text-muted-foreground"}`, children: status === "invalid" ? `Onvolledig — ${summary}` : summary }))] }), isOpen && (_jsxs(CardContent, { className: "space-y-4 pt-0", children: [_jsx("div", { "data-wizard-form-content": true, className: "w-full min-w-0", children: _jsx(StepBody, { stepKey: s.key, data: data, packingStatus: packingStatus, update: update, vbnProducts: vbnProducts, featureTypes: featureTypes, packagingTypes: packagingTypes, loadCarriers: loadCarriers, floridayCustomers: floridayCustomers, schemaQuery: schemaQuery, regulatoryQuery: regulatoryQuery, spec: spec, collectionsList: collectionsList, setCollectionsList: setCollectionsList, activeId: activeId, acceptedVbnCodes: acceptedVbnCodes, priceGroups: priceGroups, parentProductId: linkedProductId ?? draftId ?? null, parentFloridayId: draftFloridayId ?? tradeItemId ?? null, articleCodeLocked: Boolean(draftFloridayId || tradeItemId), botanicalDraft: botanicalDraft, setBotanicalDraft: setBotanicalDraft }) }), isLastStep && !isEditingPublished && (_jsxs("div", { className: "rounded-lg border bg-muted/30 p-4 flex items-start gap-3", children: [_jsx("img", { src: floridayLogo, alt: "Floriday", className: "h-7 w-7 shrink-0 mt-0.5" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx(Label, { htmlFor: "publish-to-floriday", className: "font-medium cursor-pointer", children: "Publiceren naar Floriday" }), _jsx("p", { className: "text-xs text-muted-foreground mt-1", children: publishToFloriday
|
|
1754
1768
|
? "Het artikel wordt aangemaakt in Floriday en is binnen enkele minuten zichtbaar voor klanten."
|
|
1755
1769
|
: "Het artikel wordt alleen lokaal opgeslagen. Je kunt het later vanuit de voorraadlijst alsnog publiceren naar Floriday." })] }), _jsx(Switch, { id: "publish-to-floriday", checked: publishToFloriday, onCheckedChange: setPublishToFloriday })] })), (isLastStep || isEditing) && (_jsx(PublishReadinessCard, { report: readiness, loading: connLoading || connectionReadiness.isLoading || schemaQuery.isLoading, onGoToStep: goToStepKey })), publishJob && (_jsx(PublishProgressCard, { job: publishJob, steps: publishSteps, retrying: submitting, onRetry: () => void submit({ resumeJobId: publishJob.id }), onFixStep: (key) => goToStepKey(key === "trade-item" ? "eigenschappen" : "aanbod") })), (isLastStep || isEditing) && invalidStepCount > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive flex items-center justify-between gap-3", children: [_jsxs("span", { children: ["Nog ", invalidStepCount, " stap", invalidStepCount === 1 ? "" : "pen", " onvolledig"] }), firstInvalidIndex >= 0 && (_jsxs("button", { type: "button", onClick: () => setStep(firstInvalidIndex), className: "underline font-medium", children: ["Ga naar ", steps[firstInvalidIndex].label] }))] })), _jsx("div", { className: "flex justify-end pt-2", children: isLastStep || isEditing ? (_jsxs(Button, { onClick: () => void submit(), disabled: submitting || invalidStepCount > 0, children: [submitting ? (_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" })) : (_jsx(Check, { className: "mr-2 h-4 w-4" })), isEditingPublished
|
|
1756
1770
|
? "Wijzigingen opslaan"
|
|
@@ -1760,7 +1774,13 @@ export function ArtikelWizard({ draftId: initialDraftId, tradeItemId, productId,
|
|
|
1760
1774
|
: "Aanmaken en publiceren"
|
|
1761
1775
|
: isEditingDraft
|
|
1762
1776
|
? "Wijzigingen opslaan"
|
|
1763
|
-
: "Artikel aanmaken"] })) : (
|
|
1777
|
+
: "Artikel aanmaken"] })) : ((() => {
|
|
1778
|
+
const pendingBotanical = s.key === "paspoort" && botanicalDraft.trim() !== "";
|
|
1779
|
+
const canGo = isValid || s.key === "fotos" || pendingBotanical;
|
|
1780
|
+
const res = canGo ? null : validateStepLocal(s.key, data);
|
|
1781
|
+
const reasons = res && !res.ok ? res.errors : [];
|
|
1782
|
+
return (_jsxs("div", { className: "flex flex-col items-end gap-1", children: [_jsxs(Button, { onClick: next, disabled: !canGo, children: ["Volgende stap", _jsx(ArrowRight, { className: "ml-2 h-4 w-4" })] }), !canGo && reasons.length > 0 && (_jsxs("p", { className: "text-xs text-muted-foreground text-right", children: ["Nog nodig: ", reasons.join(" · ")] })), s.key === "fotos" && !isValid && (_jsx("p", { className: "text-xs text-muted-foreground text-right", children: "Je kunt verder zonder foto. Voor publiceren naar Floriday is minstens \u00E9\u00E9n foto nodig." }))] }));
|
|
1783
|
+
})()) })] }))] }) }, s.key));
|
|
1764
1784
|
}) }), _jsx(AlertDialog, { open: Boolean(conflict), onOpenChange: (open) => {
|
|
1765
1785
|
if (!open)
|
|
1766
1786
|
conflict?.resolve(false);
|
|
@@ -2088,7 +2108,25 @@ function StepArtikel({ data, update, collectionsList, setCollectionsList, articl
|
|
|
2088
2108
|
}
|
|
2089
2109
|
import { COUNTRIES } from "../../lib/countries.js";
|
|
2090
2110
|
import { ProductSalePriceField } from "./ProductSalePriceField.js";
|
|
2091
|
-
|
|
2111
|
+
/** Zoekbare keuzelijst voor lange waardelijsten (bijv. S62 land van herkomst).
|
|
2112
|
+
* Nederland (ISO-code NL) staat bovenaan als die waarde voorkomt. */
|
|
2113
|
+
function SearchableValuePicker({ values, value, onChange, }) {
|
|
2114
|
+
const [open, setOpen] = useState(false);
|
|
2115
|
+
const [q, setQ] = useState("");
|
|
2116
|
+
const ordered = useMemo(() => {
|
|
2117
|
+
const nl = values.filter((v) => v.code.toUpperCase() === "NL");
|
|
2118
|
+
return [...nl, ...values.filter((v) => v.code.toUpperCase() !== "NL")];
|
|
2119
|
+
}, [values]);
|
|
2120
|
+
const filtered = useMemo(() => {
|
|
2121
|
+
const t = q.trim().toLowerCase();
|
|
2122
|
+
if (!t)
|
|
2123
|
+
return ordered;
|
|
2124
|
+
return ordered.filter((v) => v.label.toLowerCase().includes(t) || v.code.toLowerCase().includes(t));
|
|
2125
|
+
}, [ordered, q]);
|
|
2126
|
+
const current = values.find((v) => v.code === value);
|
|
2127
|
+
return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 text-left text-sm", children: [_jsx("span", { className: current ? "" : "text-muted-foreground", children: current ? current.label : "Kies of zoek een waarde…" }), _jsx(ChevronDown, { className: "h-4 w-4 opacity-50" })] }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 4, className: "w-[var(--radix-popover-trigger-width)] p-0", children: [_jsxs("div", { className: "flex items-center gap-2 border-b px-3 py-2", children: [_jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), _jsx("input", { autoFocus: true, value: q, onChange: (e) => setQ(e.target.value), placeholder: "Zoek\u2026", className: "h-7 w-full border-0 bg-transparent text-sm outline-none placeholder:text-muted-foreground" })] }), _jsxs("div", { className: "max-h-72 overflow-y-auto py-1", children: [value && (_jsx("button", { type: "button", onClick: () => { onChange(""); setOpen(false); }, className: "flex w-full px-3 py-2 text-left text-sm text-muted-foreground hover:bg-muted", children: "\u2014 Wissen \u2014" })), filtered.length === 0 && (_jsx("div", { className: "px-3 py-3 text-sm text-muted-foreground", children: "Geen resultaten." })), filtered.slice(0, 500).map((v) => (_jsxs("button", { type: "button", onClick: () => { onChange(v.code); setOpen(false); setQ(""); }, className: `flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-muted ${v.code === value ? "font-medium" : ""}`, children: [_jsx("span", { children: v.label }), _jsx("span", { className: "font-mono text-xs text-muted-foreground", children: v.code })] }, v.code)))] })] })] }));
|
|
2128
|
+
}
|
|
2129
|
+
function StepPaspoort({ data, update, botanicalDraft: liftedDraft, setBotanicalDraft: setLiftedDraft }) {
|
|
2092
2130
|
const [countryOpen, setCountryOpen] = useState(false);
|
|
2093
2131
|
const [countryQuery, setCountryQuery] = useState("");
|
|
2094
2132
|
const selectedCountries = (data.countryOfOrigin || "")
|
|
@@ -2117,7 +2155,9 @@ function StepPaspoort({ data, update }) {
|
|
|
2117
2155
|
const botanicalNames = data.botanicalName.length > 0
|
|
2118
2156
|
? data.botanicalName.split(";").map((s) => s.trim()).filter(Boolean)
|
|
2119
2157
|
: [];
|
|
2120
|
-
const [
|
|
2158
|
+
const [localDraft, setLocalDraft] = useState("");
|
|
2159
|
+
const botanicalDraft = liftedDraft ?? localDraft;
|
|
2160
|
+
const setBotanicalDraft = setLiftedDraft ?? setLocalDraft;
|
|
2121
2161
|
const commitBotanical = (raw) => {
|
|
2122
2162
|
const value = raw.trim();
|
|
2123
2163
|
if (!value)
|
|
@@ -2137,7 +2177,7 @@ function StepPaspoort({ data, update }) {
|
|
|
2137
2177
|
e.preventDefault();
|
|
2138
2178
|
commitBotanical(botanicalDraft);
|
|
2139
2179
|
}
|
|
2140
|
-
}, placeholder: "", className: "flex-1" }), _jsx("button", { type: "button", "aria-label": "Voeg botanische naam toe", onClick: () => commitBotanical(botanicalDraft), className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-primary text-primary transition hover:bg-primary hover:text-primary-foreground", children: _jsx(Plus, { className: "h-4 w-4" }) })] }), botanicalNames.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 pt-1", children: botanicalNames.map((bn, idx) => (_jsxs("span", { className: "inline-flex items-center gap-2 rounded-md border border-input bg-background px-2.5 py-1 text-sm", children: [bn, _jsx("button", { type: "button", "aria-label": `Verwijder ${bn}`, onClick: () => removeBotanical(idx), className: "flex h-4 w-4 items-center justify-center rounded-full bg-muted-foreground/70 text-background transition hover:bg-destructive", children: _jsx(X, { className: "h-3 w-3" }) })] }, `${bn}-${idx}`))) }))] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { children: "Land van oorsprong" }), _jsxs(Popover, { open: countryOpen, onOpenChange: setCountryOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 text-left text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", children: [_jsx("span", { className: selectedCountries.length === 0
|
|
2180
|
+
}, onBlur: () => commitBotanical(botanicalDraft), placeholder: "Typ een naam en druk op Enter", className: "flex-1" }), _jsx("button", { type: "button", "aria-label": "Voeg botanische naam toe", onClick: () => commitBotanical(botanicalDraft), className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-primary text-primary transition hover:bg-primary hover:text-primary-foreground", children: _jsx(Plus, { className: "h-4 w-4" }) })] }), botanicalNames.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 pt-1", children: botanicalNames.map((bn, idx) => (_jsxs("span", { className: "inline-flex items-center gap-2 rounded-md border border-input bg-background px-2.5 py-1 text-sm", children: [bn, _jsx("button", { type: "button", "aria-label": `Verwijder ${bn}`, onClick: () => removeBotanical(idx), className: "flex h-4 w-4 items-center justify-center rounded-full bg-muted-foreground/70 text-background transition hover:bg-destructive", children: _jsx(X, { className: "h-3 w-3" }) })] }, `${bn}-${idx}`))) }))] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { children: "Land van oorsprong" }), _jsxs(Popover, { open: countryOpen, onOpenChange: setCountryOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 text-left text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", children: [_jsx("span", { className: selectedCountries.length === 0
|
|
2141
2181
|
? "text-muted-foreground"
|
|
2142
2182
|
: "truncate", children: countryLabel }), _jsx(ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })] }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 4, className: "w-[var(--radix-popover-trigger-width)] p-0", children: [_jsxs("div", { className: "flex items-center gap-2 border-b px-3 py-2", children: [_jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), _jsx("input", { autoFocus: true, value: countryQuery, onChange: (e) => setCountryQuery(e.target.value), placeholder: "Zoek land\u2026", className: "h-7 w-full border-0 bg-transparent text-sm outline-none placeholder:text-muted-foreground" })] }), _jsxs("div", { className: "max-h-72 overflow-y-auto py-1", children: [filteredCountries.length === 0 && (_jsx("div", { className: "px-3 py-3 text-sm text-muted-foreground", children: "Geen resultaten." })), filteredCountries.map((c) => {
|
|
2143
2183
|
const checked = selectedCountries.includes(c.code);
|
|
@@ -2259,7 +2299,7 @@ function CharacteristicField({ field, value, onChange, onRemove, }) {
|
|
|
2259
2299
|
const values = [...rawValues].sort((a, b) => compareByCode(a.code, b.code));
|
|
2260
2300
|
const CLEAR = "__clear__";
|
|
2261
2301
|
const invalidExistingValue = Boolean(value && values.length > 0 && !values.some((v) => v.code === value));
|
|
2262
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs(Label, { children: [field.label, field.required && _jsx("span", { className: "ml-1 text-destructive", children: "*" }), " ", _jsxs("span", { className: "font-mono text-xs text-muted-foreground", children: ["(", field.code, ")"] })] }), onRemove && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-muted-foreground hover:text-destructive", onClick: onRemove, "aria-label": `Verwijder ${field.label}`, children: _jsx(Trash2, { className: "h-4 w-4" }) }))] }), !hasSpecValues && codeListQuery.isLoading ? (_jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-2", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), "Waardelijst ", field.listName, " wordt geladen\u2026"] })) : values.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Select, { value: value || undefined, onValueChange: (v) => onChange(v === CLEAR ? "" : v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Selecteer een door Floriday toegestane waarde\u2026" }) }), _jsxs(SelectContent, { children: [value && (_jsx(SelectItem, { value: CLEAR, children: _jsx("span", { className: "text-muted-foreground", children: "\u2014 Wissen \u2014" }) })), values.slice(0, 1000).map((v) => (_jsxs(SelectItem, { value: v.code, children: [v.label, " ", _jsxs("span", { className: "font-mono text-xs text-muted-foreground", children: ["(", v.code, ")"] })] }, v.code)))] })] }), invalidExistingValue && (_jsxs("p", { className: "text-xs text-destructive", children: ["Huidige waarde \"", value, "\" komt niet voor in de door Floriday toegestane lijst. Kies een geldige waarde."] }))] })) : (_jsx("p", { className: "rounded-md border border-dashed border-muted-foreground/30 bg-muted/40 p-2 text-xs text-muted-foreground", children: "Geen toegestane waarden bekend voor deze karakteristiek. Laat leeg \u2014 vrije invoer wordt door Floriday niet geaccepteerd." }))] }));
|
|
2302
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs(Label, { children: [field.label, field.required && _jsx("span", { className: "ml-1 text-destructive", children: "*" }), " ", _jsxs("span", { className: "font-mono text-xs text-muted-foreground", children: ["(", field.code, ")"] })] }), onRemove && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-muted-foreground hover:text-destructive", onClick: onRemove, "aria-label": `Verwijder ${field.label}`, children: _jsx(Trash2, { className: "h-4 w-4" }) }))] }), !hasSpecValues && codeListQuery.isLoading ? (_jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-2", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), "Waardelijst ", field.listName, " wordt geladen\u2026"] })) : values.length > 0 ? (_jsxs(_Fragment, { children: [values.length > 20 ? (_jsx(SearchableValuePicker, { values: values, value: value, onChange: onChange })) : (_jsxs(Select, { value: value || undefined, onValueChange: (v) => onChange(v === CLEAR ? "" : v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Selecteer een door Floriday toegestane waarde\u2026" }) }), _jsxs(SelectContent, { children: [value && (_jsx(SelectItem, { value: CLEAR, children: _jsx("span", { className: "text-muted-foreground", children: "\u2014 Wissen \u2014" }) })), values.slice(0, 1000).map((v) => (_jsxs(SelectItem, { value: v.code, children: [v.label, " ", _jsxs("span", { className: "font-mono text-xs text-muted-foreground", children: ["(", v.code, ")"] })] }, v.code)))] })] })), invalidExistingValue && (_jsxs("p", { className: "text-xs text-destructive", children: ["Huidige waarde \"", value, "\" komt niet voor in de door Floriday toegestane lijst. Kies een geldige waarde."] }))] })) : (_jsx("p", { className: "rounded-md border border-dashed border-muted-foreground/30 bg-muted/40 p-2 text-xs text-muted-foreground", children: "Geen toegestane waarden bekend voor deze karakteristiek. Laat leeg \u2014 vrije invoer wordt door Floriday niet geaccepteerd." }))] }));
|
|
2263
2303
|
}
|
|
2264
2304
|
function StepKlanten({ data, update, floridayCustomers }) {
|
|
2265
2305
|
const [search, setSearch] = useState("");
|
|
@@ -2309,6 +2349,7 @@ function StepKlanten({ data, update, floridayCustomers }) {
|
|
|
2309
2349
|
})) }), _jsxs("p", { className: "text-xs text-muted-foreground", children: [filtered.length, " van ", floridayCustomers.length, " klanten getoond"] })] }));
|
|
2310
2350
|
}
|
|
2311
2351
|
function StepFotos({ data, update, activeId }) {
|
|
2352
|
+
const [uploadError, setUploadError] = useState(null);
|
|
2312
2353
|
const inputRef = useRef(null);
|
|
2313
2354
|
const [isDragging, setIsDragging] = useState(false);
|
|
2314
2355
|
const [uploading, setUploading] = useState(false);
|
|
@@ -2331,6 +2372,7 @@ function StepFotos({ data, update, activeId }) {
|
|
|
2331
2372
|
}
|
|
2332
2373
|
const fileArr = Array.from(files);
|
|
2333
2374
|
setUploading(true);
|
|
2375
|
+
setUploadError(null);
|
|
2334
2376
|
try {
|
|
2335
2377
|
const { data: { user }, } = await supabase.auth.getUser();
|
|
2336
2378
|
if (!user) {
|
|
@@ -2393,6 +2435,7 @@ function StepFotos({ data, update, activeId }) {
|
|
|
2393
2435
|
? e.message
|
|
2394
2436
|
: "Foto kon niet worden geüpload.";
|
|
2395
2437
|
console.error("[StepFotos] upload mislukt", { filename: f.name, message: msg, error: e });
|
|
2438
|
+
setUploadError({ message: `${f.name}: ${msg}`, detail: e?.adminDetail ?? null });
|
|
2396
2439
|
toast.error(`${f.name} — ${msg}`);
|
|
2397
2440
|
}
|
|
2398
2441
|
}
|
|
@@ -2411,7 +2454,7 @@ function StepFotos({ data, update, activeId }) {
|
|
|
2411
2454
|
setUploading(false);
|
|
2412
2455
|
}
|
|
2413
2456
|
};
|
|
2414
|
-
return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { onDragOver: (e) => {
|
|
2457
|
+
return (_jsxs("div", { className: "space-y-3", children: [uploadError && (_jsxs("div", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive space-y-1", children: [_jsx("p", { children: uploadError.message }), uploadError.detail && (_jsxs("details", { className: "text-xs text-muted-foreground", children: [_jsx("summary", { className: "cursor-pointer", children: "Details voor beheer" }), _jsx("p", { className: "mt-1 break-all font-mono", children: uploadError.detail })] }))] })), _jsxs("div", { onDragOver: (e) => {
|
|
2415
2458
|
e.preventDefault();
|
|
2416
2459
|
setIsDragging(true);
|
|
2417
2460
|
}, onDragLeave: () => setIsDragging(false), onDrop: (e) => {
|
|
@@ -8,4 +8,5 @@ export { handleFloridayContinuousStock } from "./server-hooks/floriday-continuou
|
|
|
8
8
|
export { handleFloridayContinuousStockPull } from "./server-hooks/floriday-continuous-stock-pull.js";
|
|
9
9
|
export { handleFloridayStockReconcile } from "./server-hooks/floriday-stock-reconcile.js";
|
|
10
10
|
export { handleLogisticsTasksRun } from "./server-hooks/logistics-tasks-run.js";
|
|
11
|
+
export { handleTradeItemPhoto } from "./server-hooks/trade-item-photo.js";
|
|
11
12
|
//# sourceMappingURL=hooks-entry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks-entry.d.ts","sourceRoot":"","sources":["../src/hooks-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAClG,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"hooks-entry.d.ts","sourceRoot":"","sources":["../src/hooks-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAClG,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist-lib/hooks-entry.js
CHANGED
|
@@ -8,3 +8,4 @@ export { handleFloridayContinuousStock } from "./server-hooks/floriday-continuou
|
|
|
8
8
|
export { handleFloridayContinuousStockPull } from "./server-hooks/floriday-continuous-stock-pull.js";
|
|
9
9
|
export { handleFloridayStockReconcile } from "./server-hooks/floriday-stock-reconcile.js";
|
|
10
10
|
export { handleLogisticsTasksRun } from "./server-hooks/logistics-tasks-run.js";
|
|
11
|
+
export { handleTradeItemPhoto } from "./server-hooks/trade-item-photo.js";
|
|
@@ -12421,6 +12421,39 @@ export type Database = {
|
|
|
12421
12421
|
};
|
|
12422
12422
|
Relationships: [];
|
|
12423
12423
|
};
|
|
12424
|
+
logistics_external_fulfillment: {
|
|
12425
|
+
Row: {
|
|
12426
|
+
applied_at: string;
|
|
12427
|
+
created_at: string;
|
|
12428
|
+
event_id: string | null;
|
|
12429
|
+
full_fulfilled: boolean;
|
|
12430
|
+
order_id: string;
|
|
12431
|
+
reason: string;
|
|
12432
|
+
sales_order_ids: string[];
|
|
12433
|
+
updated_at: string;
|
|
12434
|
+
};
|
|
12435
|
+
Insert: {
|
|
12436
|
+
applied_at?: string;
|
|
12437
|
+
created_at?: string;
|
|
12438
|
+
event_id?: string | null;
|
|
12439
|
+
full_fulfilled?: boolean;
|
|
12440
|
+
order_id: string;
|
|
12441
|
+
reason?: string;
|
|
12442
|
+
sales_order_ids?: string[];
|
|
12443
|
+
updated_at?: string;
|
|
12444
|
+
};
|
|
12445
|
+
Update: {
|
|
12446
|
+
applied_at?: string;
|
|
12447
|
+
created_at?: string;
|
|
12448
|
+
event_id?: string | null;
|
|
12449
|
+
full_fulfilled?: boolean;
|
|
12450
|
+
order_id?: string;
|
|
12451
|
+
reason?: string;
|
|
12452
|
+
sales_order_ids?: string[];
|
|
12453
|
+
updated_at?: string;
|
|
12454
|
+
};
|
|
12455
|
+
Relationships: [];
|
|
12456
|
+
};
|
|
12424
12457
|
logistics_floriday_carrier_map: {
|
|
12425
12458
|
Row: {
|
|
12426
12459
|
carrier_code: string;
|
|
@@ -28902,6 +28935,12 @@ export type Database = {
|
|
|
28902
28935
|
};
|
|
28903
28936
|
Returns: string;
|
|
28904
28937
|
};
|
|
28938
|
+
afh_order_floriday_afgehandeld: {
|
|
28939
|
+
Args: {
|
|
28940
|
+
p_order_id: string;
|
|
28941
|
+
};
|
|
28942
|
+
Returns: boolean;
|
|
28943
|
+
};
|
|
28905
28944
|
afh_pick_workdays: {
|
|
28906
28945
|
Args: {
|
|
28907
28946
|
p_from: string;
|
|
@@ -28944,6 +28983,14 @@ export type Database = {
|
|
|
28944
28983
|
};
|
|
28945
28984
|
Returns: Json;
|
|
28946
28985
|
};
|
|
28986
|
+
afh_signup_groups_wacht: {
|
|
28987
|
+
Args: {
|
|
28988
|
+
p_from: string;
|
|
28989
|
+
p_to: string;
|
|
28990
|
+
p_tz: string;
|
|
28991
|
+
};
|
|
28992
|
+
Returns: Json;
|
|
28993
|
+
};
|
|
28947
28994
|
afh_signup_mail: {
|
|
28948
28995
|
Args: {
|
|
28949
28996
|
g: Json;
|
|
@@ -28960,6 +29007,14 @@ export type Database = {
|
|
|
28960
29007
|
};
|
|
28961
29008
|
Returns: Json;
|
|
28962
29009
|
};
|
|
29010
|
+
afh_signup_mail_wacht: {
|
|
29011
|
+
Args: {
|
|
29012
|
+
g: Json;
|
|
29013
|
+
p_prev: number;
|
|
29014
|
+
p_tz: string;
|
|
29015
|
+
};
|
|
29016
|
+
Returns: Json;
|
|
29017
|
+
};
|
|
28963
29018
|
afh_signup_send_group: {
|
|
28964
29019
|
Args: {
|
|
28965
29020
|
g: Json;
|
|
@@ -31224,6 +31279,12 @@ export type Database = {
|
|
|
31224
31279
|
Args: never;
|
|
31225
31280
|
Returns: undefined;
|
|
31226
31281
|
};
|
|
31282
|
+
logistics_apply_external_fulfillment: {
|
|
31283
|
+
Args: {
|
|
31284
|
+
p_event_id: string;
|
|
31285
|
+
};
|
|
31286
|
+
Returns: string;
|
|
31287
|
+
};
|
|
31227
31288
|
logistics_apply_order_buffer: {
|
|
31228
31289
|
Args: {
|
|
31229
31290
|
p_order_id: string;
|
|
@@ -32243,6 +32304,17 @@ export type Database = {
|
|
|
32243
32304
|
ref: string;
|
|
32244
32305
|
}[];
|
|
32245
32306
|
};
|
|
32307
|
+
logistics_external_fulfillment_key_report: {
|
|
32308
|
+
Args: never;
|
|
32309
|
+
Returns: {
|
|
32310
|
+
ander_nummer: number;
|
|
32311
|
+
floriday_sales_order_id: string;
|
|
32312
|
+
order_id: string;
|
|
32313
|
+
order_number: string;
|
|
32314
|
+
regels: number;
|
|
32315
|
+
zonder_nummer: number;
|
|
32316
|
+
}[];
|
|
32317
|
+
};
|
|
32246
32318
|
logistics_fail_task: {
|
|
32247
32319
|
Args: {
|
|
32248
32320
|
p_error: string;
|
|
@@ -32491,6 +32563,13 @@ export type Database = {
|
|
|
32491
32563
|
};
|
|
32492
32564
|
Returns: boolean;
|
|
32493
32565
|
};
|
|
32566
|
+
logistics_item_external_fulfilled: {
|
|
32567
|
+
Args: {
|
|
32568
|
+
p_order_id: string;
|
|
32569
|
+
p_source_line_key: string;
|
|
32570
|
+
};
|
|
32571
|
+
Returns: boolean;
|
|
32572
|
+
};
|
|
32494
32573
|
logistics_key_product: {
|
|
32495
32574
|
Args: {
|
|
32496
32575
|
p_key: string;
|
|
@@ -32698,6 +32777,12 @@ export type Database = {
|
|
|
32698
32777
|
};
|
|
32699
32778
|
Returns: boolean;
|
|
32700
32779
|
};
|
|
32780
|
+
logistics_order_external_state: {
|
|
32781
|
+
Args: {
|
|
32782
|
+
p_order_id: string;
|
|
32783
|
+
};
|
|
32784
|
+
Returns: Json;
|
|
32785
|
+
};
|
|
32701
32786
|
logistics_order_finalize_enqueue: {
|
|
32702
32787
|
Args: {
|
|
32703
32788
|
p_order_id: string;
|
|
@@ -32890,6 +32975,12 @@ export type Database = {
|
|
|
32890
32975
|
state: string;
|
|
32891
32976
|
}[];
|
|
32892
32977
|
};
|
|
32978
|
+
logistics_order_plan_coverage_v165: {
|
|
32979
|
+
Args: {
|
|
32980
|
+
p_order_id: string;
|
|
32981
|
+
};
|
|
32982
|
+
Returns: Json;
|
|
32983
|
+
};
|
|
32893
32984
|
logistics_order_released: {
|
|
32894
32985
|
Args: {
|
|
32895
32986
|
p_order_ref: string;
|
|
@@ -33661,6 +33752,13 @@ export type Database = {
|
|
|
33661
33752
|
};
|
|
33662
33753
|
Returns: Json;
|
|
33663
33754
|
};
|
|
33755
|
+
logistics_sales_order_external_fulfilled: {
|
|
33756
|
+
Args: {
|
|
33757
|
+
p_order_id: string;
|
|
33758
|
+
p_sales_order_id: string;
|
|
33759
|
+
};
|
|
33760
|
+
Returns: boolean;
|
|
33761
|
+
};
|
|
33664
33762
|
logistics_scan_delays: {
|
|
33665
33763
|
Args: never;
|
|
33666
33764
|
Returns: number;
|
|
@@ -33920,6 +34018,12 @@ export type Database = {
|
|
|
33920
34018
|
pieces: number;
|
|
33921
34019
|
}[];
|
|
33922
34020
|
};
|
|
34021
|
+
logistics_sticker_external_fulfilled: {
|
|
34022
|
+
Args: {
|
|
34023
|
+
p_sticker_print_id: string;
|
|
34024
|
+
};
|
|
34025
|
+
Returns: boolean;
|
|
34026
|
+
};
|
|
33923
34027
|
logistics_sticker_follows_slip: {
|
|
33924
34028
|
Args: never;
|
|
33925
34029
|
Returns: boolean;
|