@flowselections/logistiek-engine 1.0.193 → 1.0.199

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.
Files changed (59) hide show
  1. package/db/schema/logistiek-engine.sql +2782 -13
  2. package/dist-lib/components/BeheerPage.d.ts.map +1 -1
  3. package/dist-lib/components/BeheerPage.js +3 -1
  4. package/dist-lib/components/DataGereedheidCard.d.ts +47 -0
  5. package/dist-lib/components/DataGereedheidCard.d.ts.map +1 -0
  6. package/dist-lib/components/DataGereedheidCard.js +133 -0
  7. package/dist-lib/components/GeblokkeerdeOrdersCard.d.ts.map +1 -1
  8. package/dist-lib/components/GeblokkeerdeOrdersCard.js +3 -1
  9. package/dist-lib/components/GeblokkeerdeStickersCard.d.ts.map +1 -1
  10. package/dist-lib/components/GeblokkeerdeStickersCard.js +11 -1
  11. package/dist-lib/components/LadingdragerVoorstellenCard.d.ts +4 -0
  12. package/dist-lib/components/LadingdragerVoorstellenCard.d.ts.map +1 -0
  13. package/dist-lib/components/LadingdragerVoorstellenCard.js +44 -0
  14. package/dist-lib/components/LadingdragersPage.d.ts.map +1 -1
  15. package/dist-lib/components/LadingdragersPage.js +2 -1
  16. package/dist-lib/components/StartlijstCard.d.ts +2 -0
  17. package/dist-lib/components/StartlijstCard.d.ts.map +1 -0
  18. package/dist-lib/components/StartlijstCard.js +54 -0
  19. package/dist-lib/hooks/useGeblokkeerdeOrders.d.ts.map +1 -1
  20. package/dist-lib/hooks/useGeblokkeerdeOrders.js +2 -0
  21. package/dist-lib/index.d.ts +3 -0
  22. package/dist-lib/index.d.ts.map +1 -1
  23. package/dist-lib/index.js +3 -0
  24. package/dist-lib/integrations/supabase/types.d.ts +681 -121
  25. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  26. package/dist-lib/integrations/supabase/types.js +1 -0
  27. package/dist-lib/lib/beladingRegels.d.ts +22 -0
  28. package/dist-lib/lib/beladingRegels.d.ts.map +1 -1
  29. package/dist-lib/lib/beladingRegels.js +46 -4
  30. package/dist-lib/lib/dimensionData.server.js +15 -12
  31. package/dist-lib/lib/dimensionPlanner.d.ts +11 -0
  32. package/dist-lib/lib/dimensionPlanner.d.ts.map +1 -1
  33. package/dist-lib/lib/dimensionPlanner.js +30 -2
  34. package/dist-lib/lib/handlers/index.d.ts +1 -0
  35. package/dist-lib/lib/handlers/index.d.ts.map +1 -1
  36. package/dist-lib/lib/handlers/index.js +1 -0
  37. package/dist-lib/lib/handlers/logistics-plan-now.server.d.ts +18 -0
  38. package/dist-lib/lib/handlers/logistics-plan-now.server.d.ts.map +1 -0
  39. package/dist-lib/lib/handlers/logistics-plan-now.server.js +113 -0
  40. package/dist-lib/lib/handlers/logistics-tick.server.d.ts +5 -0
  41. package/dist-lib/lib/handlers/logistics-tick.server.d.ts.map +1 -1
  42. package/dist-lib/lib/handlers/logistics-tick.server.js +65 -26
  43. package/dist-lib/lib/invoerTeksten.d.ts +4 -0
  44. package/dist-lib/lib/invoerTeksten.d.ts.map +1 -0
  45. package/dist-lib/lib/invoerTeksten.js +19 -0
  46. package/dist-lib/lib/layoutPrint.server.d.ts +8 -0
  47. package/dist-lib/lib/layoutPrint.server.d.ts.map +1 -1
  48. package/dist-lib/lib/layoutPrint.server.js +32 -0
  49. package/dist-lib/lib/loadCarrierPlanning.server.d.ts +4 -0
  50. package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -1
  51. package/dist-lib/lib/loadCarrierPlanning.server.js +209 -12
  52. package/dist-lib/lib/moduleVersion.d.ts +1 -1
  53. package/dist-lib/lib/moduleVersion.js +1 -1
  54. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
  55. package/dist-lib/lib/ruleEngineSchema.js +14 -0
  56. package/dist-lib/lib/stickerQueue.server.d.ts +18 -0
  57. package/dist-lib/lib/stickerQueue.server.d.ts.map +1 -1
  58. package/dist-lib/lib/stickerQueue.server.js +63 -20
  59. package/package.json +11 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BeheerPage.d.ts","sourceRoot":"","sources":["../../src/components/BeheerPage.tsx"],"names":[],"mappings":"AA6JA,wBAAgB,UAAU,gCAkBzB"}
1
+ {"version":3,"file":"BeheerPage.d.ts","sourceRoot":"","sources":["../../src/components/BeheerPage.tsx"],"names":[],"mappings":"AA+JA,wBAAgB,UAAU,gCAoBzB"}
@@ -20,6 +20,8 @@ import { EtiketInstellenMelding } from "./EtiketInstellenMelding.js";
20
20
  import { VervoerderBewakingCard } from "./VervoerderBewakingCard.js";
21
21
  import { BeladingVerstuurderCard } from "./BeladingVerstuurderCard.js";
22
22
  import { DocumentkeuzeCard } from "./DocumentkeuzeCard.js";
23
+ import { DataGereedheidCard } from "./DataGereedheidCard.js";
24
+ import { StartlijstCard } from "./StartlijstCard.js";
23
25
  import { MinuutrondeStartMelding } from "./MinuutrondeStartMelding.js";
24
26
  import { ENGINE_TOEGANG } from "../hooks/useEngineRollen.js";
25
27
  function HerindelenBeheer() {
@@ -79,5 +81,5 @@ function HerindelenBeheer() {
79
81
  : `${voor?.geprintOfGepickt ?? 0} order(s) die al geprint of gepickt zijn, blijven ongemoeid.` })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsxs(AlertDialogAction, { onClick: () => void voerUit(), disabled: (voor?.aantal ?? 0) === 0, children: ["Ja, ", voor?.aantal ?? 0, " order(s) opnieuw indelen"] })] })] }) })] }));
80
82
  }
81
83
  export function BeheerPage() {
82
- return (_jsx(RolPoort, { rollen: ENGINE_TOEGANG.beheer, children: _jsxs("div", { className: "space-y-6 p-6", children: [_jsx(MinuutrondeStartMelding, {}), _jsx(HerindelenBeheer, {}), _jsx(HerindelingMeldingCard, {}), _jsx(VervoerderBewakingCard, {}), _jsx(EtiketInstellenMelding, {}), _jsx(GeblokkeerdeStickersCard, {}), _jsx(OudeOrderregelsCard, {}), _jsx(BeladingVerstuurderCard, {}), _jsx(DocumentkeuzeCard, {}), _jsx(AutomatischVersturenCard, {}), _jsx(OpruimlijstKarrenCard, {})] }) }));
84
+ return (_jsx(RolPoort, { rollen: ENGINE_TOEGANG.beheer, children: _jsxs("div", { className: "space-y-6 p-6", children: [_jsx(MinuutrondeStartMelding, {}), _jsx(StartlijstCard, {}), _jsx(HerindelenBeheer, {}), _jsx(HerindelingMeldingCard, {}), _jsx(VervoerderBewakingCard, {}), _jsx(EtiketInstellenMelding, {}), _jsx(DataGereedheidCard, {}), _jsx(GeblokkeerdeStickersCard, {}), _jsx(OudeOrderregelsCard, {}), _jsx(BeladingVerstuurderCard, {}), _jsx(DocumentkeuzeCard, {}), _jsx(AutomatischVersturenCard, {}), _jsx(OpruimlijstKarrenCard, {})] }) }));
83
85
  }
@@ -0,0 +1,47 @@
1
+ import { type FysiekOordeel } from "../lib/beladingRegels.js";
2
+ type Fust = {
3
+ id: string;
4
+ length_mm: number | null;
5
+ width_mm: number | null;
6
+ height_mm: number | null;
7
+ };
8
+ type Drager = {
9
+ code: string;
10
+ name: string | null;
11
+ layer_length_cm: number | null;
12
+ layer_width_cm: number | null;
13
+ max_height_cm: number | null;
14
+ max_crates_per_layer: number | null;
15
+ layers_per_carrier: number | null;
16
+ };
17
+ /** 1.0.197: fysieke controle per product met dezelfde regels als de planner. */
18
+ export declare function fysiekVoorRegel(r: Regel, fustIn: Fust | null, d: Drager | null): FysiekOordeel & {
19
+ layerspace: number | null;
20
+ };
21
+ type Voorstel = {
22
+ waarde: number;
23
+ bron: string;
24
+ berekening?: string;
25
+ };
26
+ type Regel = {
27
+ product_id: string;
28
+ product: string;
29
+ ladingdrager: string | null;
30
+ methode: string;
31
+ in_open_order: boolean;
32
+ ontbrekend: string[];
33
+ velden: Record<string, {
34
+ waarde: unknown;
35
+ bron: string | null;
36
+ nodig?: boolean;
37
+ grens_kg?: number | null;
38
+ naam?: string | null;
39
+ }>;
40
+ voorstel: Record<string, Voorstel> | null;
41
+ uitleg: string;
42
+ };
43
+ export declare const BRON_LABEL: Record<string, string>;
44
+ export declare const VELD_LABEL: Record<string, string>;
45
+ export declare function DataGereedheidCard(): import("react").JSX.Element;
46
+ export {};
47
+ //# sourceMappingURL=DataGereedheidCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataGereedheidCard.d.ts","sourceRoot":"","sources":["../../src/components/DataGereedheidCard.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,KAAK,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AACxG,KAAK,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAMzN,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG;IAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAuB9H;AAED,KAAK,QAAQ,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACtE,KAAK,KAAK,GAAG;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAClI,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAS7C,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ7C,CAAC;AAGF,wBAAgB,kBAAkB,gCAuKjC"}
@@ -0,0 +1,133 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/DataGereedheidCard.tsx — 1.0.196 (E4/E5) Gegevens voor karindeling
4
+ // ============================================================================
5
+ // Leest logistics_data_gereedheid(): per product welke velden ontbreken voor de
6
+ // actieve methode, de bron en een berekend voorstel. "Invullen" schrijft pas
7
+ // na bevestiging (logistics_data_vul_in, alleen beheer). Nooit stil aanvullen.
8
+ // GEEN <Header /> hier — die levert de shell.
9
+ // ============================================================================
10
+ import { useCallback, useEffect, useState } from "react";
11
+ import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Skeleton } from "@flowselections/core";
12
+ import { RefreshCw } from "lucide-react";
13
+ import { supabase } from "../integrations/supabase/moduleClient.js";
14
+ import { maxFustenPerLaag } from "../lib/dimensionPlanner.js";
15
+ import { fysiekeBelading } from "../lib/beladingRegels.js";
16
+ const num = (v) => {
17
+ const n = Number(v);
18
+ return v != null && Number.isFinite(n) && n > 0 ? n : null;
19
+ };
20
+ /** 1.0.197: fysieke controle per product met dezelfde regels als de planner. */
21
+ export function fysiekVoorRegel(r, fustIn, d) {
22
+ // 1.0.198: maten uit de ene bron (velden), anders het fusttype.
23
+ const fust = {
24
+ id: fustIn?.id ?? "",
25
+ length_mm: num(r.velden?.fust_length_mm?.waarde) ?? fustIn?.length_mm ?? null,
26
+ width_mm: num(r.velden?.fust_width_mm?.waarde) ?? fustIn?.width_mm ?? null,
27
+ height_mm: num(r.velden?.fust_height_mm?.waarde) ?? fustIn?.height_mm ?? null,
28
+ };
29
+ const ls = maxFustenPerLaag(d?.layer_length_cm, d?.layer_width_cm, fust?.length_mm ? fust.length_mm / 10 : null, fust?.width_mm ? fust.width_mm / 10 : null);
30
+ const o = fysiekeBelading({
31
+ product: r.product,
32
+ bron: String(r.velden?.crates_per_layer?.bron ?? "product"),
33
+ crates_per_layer: num(r.velden?.crates_per_layer?.waarde) ?? 0,
34
+ layers_per_cart: num(r.velden?.layers_per_cart?.waarde) ?? 0,
35
+ fust_hoogte_cm: fust?.height_mm ? fust.height_mm / 10 : null,
36
+ plant_hoogte_cm: num(r.velden?.plant_height_cm?.waarde),
37
+ layerspace_max: ls,
38
+ ladingdrager: d?.name ?? d?.code ?? "de ladingdrager",
39
+ ladingdrager_hoogte_cm: num(d?.max_height_cm),
40
+ max_crates_per_layer: num(d?.max_crates_per_layer),
41
+ standaard_lagen: num(d?.layers_per_carrier),
42
+ });
43
+ return { ...o, layerspace: ls };
44
+ }
45
+ export const BRON_LABEL = {
46
+ floricode: "Floricode",
47
+ floricode_s15: "Floricode S15 (transporthoogte)",
48
+ floricode_s02: "Floricode S02 (min. planthoogte incl. pot)",
49
+ floriday: "Floriday",
50
+ vbn: "Floriday (VBN-fustcode)",
51
+ handmatig: "handmatig",
52
+ product: "product",
53
+ onbekend: "onbekend",
54
+ };
55
+ const bronTekst = (b) => (typeof b === "string" && b ? BRON_LABEL[b] ?? b : "onbekend");
56
+ export const VELD_LABEL = {
57
+ plants_per_crate: "Planten per fust",
58
+ crates_per_layer: "Fusten per laag",
59
+ layers_per_cart: "Lagen per kar",
60
+ plant_height_cm: "Planthoogte inclusief pot (cm)",
61
+ fust_maten: "Fustmaten",
62
+ weight: "Gewicht per fust (kg)",
63
+ fust_type_id: "Fustsoort",
64
+ };
65
+ const INVULBAAR = new Set(["plants_per_crate", "crates_per_layer", "layers_per_cart", "plant_height_cm", "weight"]);
66
+ export function DataGereedheidCard() {
67
+ const [rijen, setRijen] = useState([]);
68
+ const [loading, setLoading] = useState(true);
69
+ const [fout, setFout] = useState(null);
70
+ const [invoer, setInvoer] = useState({});
71
+ const [bezig, setBezig] = useState(null);
72
+ const [fusten, setFusten] = useState(new Map());
73
+ const [dragers, setDragers] = useState(new Map());
74
+ const laden = useCallback(async () => {
75
+ setLoading(true);
76
+ setFout(null);
77
+ const { data, error } = await supabase.rpc("logistics_data_gereedheid", { p_product_ids: null });
78
+ if (error)
79
+ setFout(error.message);
80
+ const lijst = !error && Array.isArray(data) ? data : [];
81
+ if (!error)
82
+ setRijen(lijst);
83
+ const fustIds = Array.from(new Set(lijst.map((r) => r.velden?.fust_type_id?.waarde).filter((x) => typeof x === "string")));
84
+ const codes = Array.from(new Set(lijst.map((r) => r.ladingdrager).filter((x) => !!x)));
85
+ if (fustIds.length > 0) {
86
+ const { data: f } = await supabase.from("fust_types").select("id, length_mm, width_mm, height_mm").in("id", fustIds);
87
+ setFusten(new Map((Array.isArray(f) ? f : []).map((x) => [String(x.id), x])));
88
+ }
89
+ if (codes.length > 0) {
90
+ const { data: c } = await supabase
91
+ .from("load_carrier_types")
92
+ .select("code, name, layer_length_cm, layer_width_cm, max_height_cm, max_crates_per_layer, layers_per_carrier")
93
+ .in("code", codes);
94
+ setDragers(new Map((Array.isArray(c) ? c : []).map((x) => [String(x.code), x])));
95
+ }
96
+ setLoading(false);
97
+ }, []);
98
+ useEffect(() => {
99
+ void laden();
100
+ }, [laden]);
101
+ const opslaan = async (productId, veld) => {
102
+ const k = `${productId}:${veld}`;
103
+ const waarde = Number(String(invoer[k] ?? "").replace(",", "."));
104
+ if (!(waarde > 0)) {
105
+ setFout("Vul een getal groter dan 0 in.");
106
+ return;
107
+ }
108
+ setBezig(k);
109
+ const { error } = await supabase.rpc("logistics_data_vul_in", { p_product_id: productId, p_veld: veld, p_waarde: waarde });
110
+ setBezig(null);
111
+ if (error)
112
+ setFout(error.message);
113
+ else
114
+ await laden();
115
+ };
116
+ const metGaten = rijen.filter((r) => Array.isArray(r.ontbrekend) && r.ontbrekend.length > 0);
117
+ const fysiek = (r) => fysiekVoorRegel(r, typeof r.velden?.fust_type_id?.waarde === "string" ? fusten.get(r.velden.fust_type_id.waarde) ?? null : null, r.ladingdrager ? dragers.get(r.ladingdrager) ?? null : null);
118
+ return (_jsxs(Card, { id: "gegevens-voor-karindeling", children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Gegevens voor karindeling" }), _jsx(CardDescription, { children: "Producten in open orders waarvan een waarde ontbreekt. Een voorstel (berekend of van vergelijkbare producten) wordt pas gebruikt als je het hier invult en opslaat." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void laden(), disabled: loading, children: [_jsx(RefreshCw, { className: "h-4 w-4" }), "Verversen"] })] }), _jsxs(CardContent, { className: "space-y-3", children: [fout && _jsx("p", { className: "text-sm text-destructive", children: fout }), loading ? (_jsx(Skeleton, { className: "h-16 w-full" })) : metGaten.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Alle producten in open orders hebben de benodigde gegevens." })) : (metGaten.map((r) => (_jsxs("div", { className: "rounded-md border p-3 space-y-2", children: [_jsxs("div", { className: "flex flex-wrap items-baseline justify-between gap-2", children: [_jsx("span", { className: "font-medium", children: r.product }), _jsxs("span", { className: "text-xs text-muted-foreground", children: [r.in_open_order ? "In open order" : "Niet in open order", " \u00B7 methode ", r.methode, r.ladingdrager ? ` · ${r.ladingdrager}` : ""] })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: r.uitleg }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Fust ", String(r.velden?.fust_type_id?.naam ?? "onbekend"), " (", bronTekst(r.velden?.fust_type_id?.bron), ") \u00B7 maten", " ", ["fust_length_mm", "fust_width_mm", "fust_height_mm"]
119
+ .map((k) => `${r.velden?.[k]?.waarde ?? "?"} mm (${bronTekst(r.velden?.[k]?.bron)})`)
120
+ .join(" × "), " ", "\u00B7 planthoogte inclusief pot ", r.velden?.plant_height_cm?.waarde != null ? `${r.velden.plant_height_cm.waarde} cm` : "onbekend", " (", bronTekst(r.velden?.plant_height_cm?.bron), ")"] }), r.ontbrekend.map((veld) => {
121
+ const k = `${r.product_id}:${veld}`;
122
+ const ls = veld === "crates_per_layer" ? fysiek(r).layerspace : null;
123
+ const v = ls != null && ls > 0
124
+ ? { waarde: ls, bron: "berekend", berekening: "fustmaat × laagmaat met de laagindeling van de planner" }
125
+ : r.voorstel?.[veld];
126
+ return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 text-sm", children: [_jsx("span", { className: "w-44", children: VELD_LABEL[veld] ?? veld }), INVULBAAR.has(veld) ? (_jsxs(_Fragment, { children: [_jsx(Input, { className: "h-8 w-28", inputMode: "decimal", placeholder: v ? String(v.waarde) : "", value: invoer[k] ?? "", onChange: (e) => setInvoer((s) => ({ ...s, [k]: e.target.value })) }), v && (_jsxs(Button, { size: "sm", variant: "ghost", onClick: () => setInvoer((s) => ({ ...s, [k]: String(v.waarde) })), children: ["Voorstel ", v.waarde, " overnemen"] })), _jsx(Button, { size: "sm", disabled: bezig === k, onClick: () => void opslaan(r.product_id, veld), children: "Invullen" }), v?.berekening && _jsx("span", { className: "text-xs text-muted-foreground", children: v.berekening }), veld === "plant_height_cm" && (_jsx("span", { className: "text-xs text-muted-foreground", children: "Hoogte van de plant inclusief pot." })), veld === "weight" && r.velden?.weight?.grens_kg != null && (_jsxs("span", { className: "text-xs text-muted-foreground", children: ["Nodig: de ladingdrager heeft een grens van ", r.velden.weight.grens_kg, " kg."] }))] })) : (_jsx("span", { className: "text-xs text-muted-foreground", children: veld === "fust_maten"
127
+ ? "Niet in Floricode of Floriday gevonden: vul de maten in bij Voorraad → Fusten."
128
+ : "Kies de fustsoort bij het product in Voorraad." }))] }, veld));
129
+ })] }, r.product_id)))), !loading && rijen.length > 0 && (_jsxs("div", { className: "space-y-1 border-t pt-3", children: [_jsx("p", { className: "text-sm font-medium", children: "Fysieke controle belading" }), rijen.map((r) => {
130
+ const f = fysiek(r);
131
+ return (_jsxs("div", { className: "text-sm", children: [_jsx("span", { className: "font-medium", children: r.product }), ": ", f.status === "gecontroleerd" && _jsx("span", { className: "text-muted-foreground", children: "fysiek gecontroleerd" }), f.status === "niet_te_controleren" && (_jsxs("span", { className: "text-muted-foreground", children: ["niet te controleren (ontbreekt: ", f.ontbreekt.join(", "), ")"] })), f.status === "onmogelijk" && _jsxs("span", { className: "text-destructive", children: ["onmogelijk \u2014 ", f.blokkeren.join("; ")] })] }, `f-${r.product_id}`));
132
+ })] }))] })] }));
133
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"GeblokkeerdeOrdersCard.d.ts","sourceRoot":"","sources":["../../src/components/GeblokkeerdeOrdersCard.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,sBAAsB,gCAiMrC"}
1
+ {"version":3,"file":"GeblokkeerdeOrdersCard.d.ts","sourceRoot":"","sources":["../../src/components/GeblokkeerdeOrdersCard.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,sBAAsB,gCA6MrC"}
@@ -68,7 +68,9 @@ export function GeblokkeerdeOrdersCard() {
68
68
  setMelding(e?.message ? String(e.message) : "Opruimen is niet gelukt.");
69
69
  }
70
70
  };
71
- return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive" }), "Vastgelopen orders"] }), _jsx(CardDescription, { children: "Deze orders krijgen geen karrenindeling tot er iets aan de order verandert of je ze hier opnieuw aanbiedt." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [zichtbaar.length > 0 && (_jsxs(Button, { variant: "outline", size: "sm", disabled: busy, onClick: () => void opnieuw(zichtbaar.map((r) => r.orderId)), children: [_jsx(RotateCcw, { className: "mr-2 h-4 w-4" }), "Alles opnieuw proberen"] })), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => void refresh(), disabled: loading, children: _jsx(RefreshCw, { className: `h-4 w-4 ${loading ? "animate-spin" : ""}` }) })] })] }), _jsxs(CardContent, { className: "space-y-4", children: [overzicht?.tickStale && (_jsx("p", { className: "rounded-md bg-muted p-3 text-sm text-muted-foreground", children: "De verwerking op de achtergrond heeft zich langer dan tien minuten niet gemeld. Opnieuw proberen zet de order wel klaar, maar hij wordt pas opgepakt zodra de verwerking weer draait." })), error && _jsx("p", { className: "text-sm text-destructive", children: error }), melding && _jsx("p", { className: "text-sm text-muted-foreground", children: melding }), loading && safeRows.length === 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-6 w-full" }), _jsx(Skeleton, { className: "h-6 w-full" })] })) : safeRows.length === 0 ? (_jsxs("p", { className: "text-sm text-muted-foreground", children: ["Geen vastgelopen orders. Alles is ingedeeld of staat nog in de wachtrij", overzicht ? ` (${overzicht.pending} wachtend)` : "", "."] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Badge, { variant: filter === "" ? "default" : "outline", className: "cursor-pointer", onClick: () => setFilter(""), children: ["Alles (", safeRows.length, ")"] }), codes.map(([code, aantal]) => (_jsxs(Badge, { variant: filter === code ? "default" : "outline", className: "cursor-pointer", onClick: () => setFilter(code), children: [redenLabel(code), " (", aantal, ")"] }, code)))] }), _jsx("div", { className: "divide-y rounded-md border", children: zichtbaar.map((r) => (_jsxs("div", { className: "flex items-start justify-between gap-4 p-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: r.orderRef }), _jsx(Badge, { variant: "secondary", children: redenLabel(r.reasonCode) }), _jsx(Badge, { variant: "outline", children: "Wacht op actie" }), _jsxs("span", { className: "text-xs text-muted-foreground", children: ["Leverdatum ", datum(r.deliveryDate), " \u00B7 sinds ", datum(r.blockedSince)] })] }), r.reason && (_jsx("p", { className: "mt-1 line-clamp-2 text-sm text-muted-foreground", children: r.reason }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [r.reasonCode === "belading_onwaarschijnlijk" && (_jsx(Button, { size: "sm", disabled: busy, onClick: () => void bevestigen(r.orderId, r.orderRef), children: "Belading bevestigen" })), r.reasonCode === "dubbele_regels" && (_jsx(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void opruimen(r.orderId, r.orderRef), children: "Dubbele regels opruimen" })), _jsx(Button, { variant: "outline", size: "sm", disabled: busy, onClick: () => void opnieuw([r.orderId]), children: "Opnieuw" })] })] }, r.queueId))) })] })), _jsx(BeladingWaarschuwingen, {})] })] }));
71
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive" }), "Vastgelopen orders"] }), _jsx(CardDescription, { children: "Deze orders krijgen geen karrenindeling tot er iets aan de order verandert of je ze hier opnieuw aanbiedt." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [zichtbaar.length > 0 && (_jsxs(Button, { variant: "outline", size: "sm", disabled: busy, onClick: () => void opnieuw(zichtbaar.map((r) => r.orderId)), children: [_jsx(RotateCcw, { className: "mr-2 h-4 w-4" }), "Alles opnieuw proberen"] })), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => void refresh(), disabled: loading, children: _jsx(RefreshCw, { className: `h-4 w-4 ${loading ? "animate-spin" : ""}` }) })] })] }), _jsxs(CardContent, { className: "space-y-4", children: [overzicht?.tickStale && (_jsx("p", { className: "rounded-md bg-muted p-3 text-sm text-muted-foreground", children: "De verwerking op de achtergrond heeft zich langer dan tien minuten niet gemeld. Opnieuw proberen zet de order wel klaar, maar hij wordt pas opgepakt zodra de verwerking weer draait." })), error && _jsx("p", { className: "text-sm text-destructive", children: error }), melding && _jsx("p", { className: "text-sm text-muted-foreground", children: melding }), loading && safeRows.length === 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-6 w-full" }), _jsx(Skeleton, { className: "h-6 w-full" })] })) : safeRows.length === 0 ? (_jsxs("p", { className: "text-sm text-muted-foreground", children: ["Geen vastgelopen orders. Alles is ingedeeld of staat nog in de wachtrij", overzicht ? ` (${overzicht.pending} wachtend)` : "", "."] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Badge, { variant: filter === "" ? "default" : "outline", className: "cursor-pointer", onClick: () => setFilter(""), children: ["Alles (", safeRows.length, ")"] }), codes.map(([code, aantal]) => (_jsxs(Badge, { variant: filter === code ? "default" : "outline", className: "cursor-pointer", onClick: () => setFilter(code), children: [redenLabel(code), " (", aantal, ")"] }, code)))] }), _jsx("div", { className: "divide-y rounded-md border", children: zichtbaar.map((r) => (_jsxs("div", { className: "flex items-start justify-between gap-4 p-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "font-medium", children: r.orderRef }), _jsx(Badge, { variant: "secondary", children: redenLabel(r.reasonCode) }), _jsx(Badge, { variant: "outline", children: "Wacht op actie" }), _jsxs("span", { className: "text-xs text-muted-foreground", children: ["Leverdatum ", datum(r.deliveryDate), " \u00B7 sinds ", datum(r.blockedSince)] })] }), r.reason && (_jsx("p", { className: "mt-1 line-clamp-2 text-sm text-muted-foreground", children: r.reason }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [(["belading_onvolledig", "gewicht_onbekend"].includes(String(r.reasonCode)) ||
72
+ String(r.reason ?? "").startsWith("Belading fysiek onmogelijk")) && (_jsx("a", { className: "text-sm underline", href: "/logistiek-engine/beheer#gegevens-voor-karindeling", children: "Gegevens invullen" })), r.reasonCode === "ladingdrager_niet_in_beheer" && (_jsx("a", { className: "text-sm underline", href: "/logistiek-engine/ladingdragers", children: "Naar ladingdragers" })), r.reasonCode === "belading_onwaarschijnlijk" &&
73
+ !String(r.reason ?? "").startsWith("Belading fysiek onmogelijk") && (_jsx(Button, { size: "sm", disabled: busy, onClick: () => void bevestigen(r.orderId, r.orderRef), children: "Belading bevestigen" })), r.reasonCode === "dubbele_regels" && (_jsx(Button, { variant: "secondary", size: "sm", disabled: busy, onClick: () => void opruimen(r.orderId, r.orderRef), children: "Dubbele regels opruimen" })), _jsx(Button, { variant: "outline", size: "sm", disabled: busy, onClick: () => void opnieuw([r.orderId]), children: "Opnieuw" })] })] }, r.queueId))) })] })), _jsx(BeladingWaarschuwingen, {})] })] }));
72
74
  }
73
75
  /** 1.0.190: beladingen die wel zijn ingedeeld maar opvallen (alleen waarschuwing). */
74
76
  function BeladingWaarschuwingen() {
@@ -1 +1 @@
1
- {"version":3,"file":"GeblokkeerdeStickersCard.d.ts","sourceRoot":"","sources":["../../src/components/GeblokkeerdeStickersCard.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,wBAAwB,gCAyEvC"}
1
+ {"version":3,"file":"GeblokkeerdeStickersCard.d.ts","sourceRoot":"","sources":["../../src/components/GeblokkeerdeStickersCard.tsx"],"names":[],"mappings":"AAiCA,wBAAgB,wBAAwB,gCA2FvC"}
@@ -24,8 +24,18 @@ export function GeblokkeerdeStickersCard() {
24
24
  setRijen(Array.isArray(data) ? data : []);
25
25
  setLoading(false);
26
26
  }, []);
27
+ const [bezigId, setBezigId] = useState(null);
28
+ const opnieuw = useCallback(async (id) => {
29
+ setBezigId(id);
30
+ const { error } = await supabase.rpc("logistics_sticker_retry", { p_id: id });
31
+ setBezigId(null);
32
+ if (error)
33
+ setFout(error.message);
34
+ else
35
+ await laden();
36
+ }, [laden]);
27
37
  useEffect(() => {
28
38
  void laden();
29
39
  }, [laden]);
30
- return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Geblokkeerde klantstickers" }), _jsx(CardDescription, { children: "Deze Floriday-klantstickers worden niet geprint. De reden staat erbij; ze worden ook nooit in Floriday afgemeld." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void laden(), disabled: loading, children: [_jsx(RefreshCw, { className: "h-4 w-4" }), "Verversen"] })] }), _jsx(CardContent, { children: loading ? (_jsx(Skeleton, { className: "h-16 w-full" })) : fout ? (_jsx("p", { className: "text-sm text-destructive", children: fout })) : rijen.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Er zijn geen geblokkeerde klantstickers." })) : (_jsx("div", { className: "overflow-x-auto rounded-md border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-left", children: _jsxs("tr", { children: [_jsx("th", { className: "p-2", children: "Order" }), _jsx("th", { className: "p-2", children: "Kar" }), _jsx("th", { className: "p-2", children: "Floriday-sticker" }), _jsx("th", { className: "p-2", children: "Soort" }), _jsx("th", { className: "p-2", children: "Maat" }), _jsx("th", { className: "p-2", children: "Reden" })] }) }), _jsx("tbody", { children: rijen.map((r) => (_jsxs("tr", { className: "border-t align-top", children: [_jsx("td", { className: "p-2 font-medium", children: r.orderNumber ?? "—" }), _jsx("td", { className: "p-2", children: r.cartNumber ?? "—" }), _jsx("td", { className: "p-2 break-all text-xs", children: r.stickerId }), _jsx("td", { className: "p-2", children: r.stickerType ?? "—" }), _jsx("td", { className: "p-2", children: r.breedteMm && r.hoogteMm ? `${r.breedteMm} × ${r.hoogteMm} mm` : "—" }), _jsx("td", { className: "p-2 text-xs", children: r.reden ?? "—" })] }, r.id))) })] }) })) })] }));
40
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Geblokkeerde stickers" }), _jsx(CardDescription, { children: "Deze stickers (Floriday en eigen) worden niet geprint. De reden staat erbij; met \"Opnieuw proberen\" gaat hij terug naar de printronde. Ze worden nooit in Floriday afgemeld." })] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void laden(), disabled: loading, children: [_jsx(RefreshCw, { className: "h-4 w-4" }), "Verversen"] })] }), _jsx(CardContent, { children: loading ? (_jsx(Skeleton, { className: "h-16 w-full" })) : fout ? (_jsx("p", { className: "text-sm text-destructive", children: fout })) : rijen.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Er zijn geen geblokkeerde klantstickers." })) : (_jsx("div", { className: "overflow-x-auto rounded-md border", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-left", children: _jsxs("tr", { children: [_jsx("th", { className: "p-2", children: "Order" }), _jsx("th", { className: "p-2", children: "Kar" }), _jsx("th", { className: "p-2", children: "Floriday-sticker" }), _jsx("th", { className: "p-2", children: "Soort" }), _jsx("th", { className: "p-2", children: "Maat" }), _jsx("th", { className: "p-2", children: "Reden" }), _jsx("th", { className: "p-2" })] }) }), _jsx("tbody", { children: rijen.map((r) => (_jsxs("tr", { className: "border-t align-top", children: [_jsx("td", { className: "p-2 font-medium", children: r.orderNumber ?? "—" }), _jsx("td", { className: "p-2", children: r.cartNumber ?? "—" }), _jsx("td", { className: "p-2 break-all text-xs", children: r.stickerId }), _jsx("td", { className: "p-2", children: r.stickerType ?? "—" }), _jsx("td", { className: "p-2", children: r.breedteMm && r.hoogteMm ? `${r.breedteMm} × ${r.hoogteMm} mm` : "—" }), _jsx("td", { className: "p-2 text-xs", children: r.reden ?? "—" }), _jsx("td", { className: "p-2", children: _jsx(Button, { size: "sm", variant: "outline", disabled: bezigId === r.id, onClick: () => void opnieuw(r.id), children: "Opnieuw proberen" }) })] }, r.id))) })] }) })) })] }));
31
41
  }
@@ -0,0 +1,4 @@
1
+ export declare function LadingdragerVoorstellenCard({ onKlaar }: {
2
+ onKlaar?: () => void;
3
+ }): import("react").JSX.Element;
4
+ //# sourceMappingURL=LadingdragerVoorstellenCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LadingdragerVoorstellenCard.d.ts","sourceRoot":"","sources":["../../src/components/LadingdragerVoorstellenCard.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,2BAA2B,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,+BAuEhF"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/LadingdragerVoorstellenCard.tsx — 1.0.198 standaardmaten voorstellen
4
+ // ============================================================================
5
+ // Toont per ladingdrager (gekoppeld aan een bekend Floriday-type) het voorstel
6
+ // met de bron. De beheerder bevestigt per ladingdrager; alleen lege velden
7
+ // worden ingevuld. Nooit stil invullen, nooit overschrijven.
8
+ // GEEN <Header /> hier — die levert de shell.
9
+ // ============================================================================
10
+ import { useState } from "react";
11
+ import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from "@flowselections/core";
12
+ import { supabase } from "../integrations/supabase/moduleClient.js";
13
+ const VELD = { layer_length_cm: "Lengte laag (cm)", layer_width_cm: "Breedte laag (cm)" };
14
+ export function LadingdragerVoorstellenCard({ onKlaar }) {
15
+ const [rijen, setRijen] = useState(null);
16
+ const [bezig, setBezig] = useState(null);
17
+ const [melding, setMelding] = useState(null);
18
+ const laden = async () => {
19
+ setBezig("laden");
20
+ setMelding(null);
21
+ const { data, error } = await supabase.rpc("logistics_ladingdrager_voorstellen");
22
+ setBezig(null);
23
+ if (error)
24
+ return setMelding(error.message);
25
+ setRijen(Array.isArray(data) ? data : []);
26
+ };
27
+ const bevestig = async (code) => {
28
+ setBezig(code);
29
+ const { data, error } = await supabase.rpc("logistics_ladingdrager_voorstel_bevestigen", { p_code: code });
30
+ setBezig(null);
31
+ if (error)
32
+ return setMelding(error.message);
33
+ setMelding(`${Number(data?.ingevuld ?? 0)} veld(en) ingevuld bij ${code}.`);
34
+ onKlaar?.();
35
+ await laden();
36
+ };
37
+ const perCode = new Map();
38
+ for (const r of rijen ?? [])
39
+ perCode.set(r.code, [...(perCode.get(r.code) ?? []), r]);
40
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Standaardmaten voorstellen" }), _jsx(CardDescription, { children: "Voor ladingdragers die aan een bekend Floriday-type gekoppeld zijn. Je ziet het voorstel en de bron en bevestigt per ladingdrager. Alleen lege velden worden ingevuld. Hoogte en gewichtsgrens vul je zelf in, want daar bestaat geen algemene standaard voor." })] }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => void laden(), disabled: bezig !== null, children: "Standaardmaten voorstellen" })] }), _jsxs(CardContent, { className: "space-y-3", children: [melding && _jsx("p", { className: "text-sm", children: melding }), rijen && perCode.size === 0 && _jsx("p", { className: "text-sm text-muted-foreground", children: "Geen ladingdragers met een bekend Floriday-type." }), Array.from(perCode.entries()).map(([code, lijst]) => {
41
+ const teInvullen = lijst.some((r) => r.actie === "invullen");
42
+ return (_jsxs("div", { className: "rounded-md border p-3 space-y-1", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsxs("span", { className: "font-medium", children: [lijst[0].naam, " ", _jsxs("span", { className: "text-xs text-muted-foreground", children: ["(", lijst[0].floriday_code, ")"] })] }), _jsx(Button, { size: "sm", disabled: !teInvullen || bezig !== null, onClick: () => void bevestig(code), children: teInvullen ? "Bevestigen" : "Niets in te vullen" })] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Bron: ", lijst[0].bron] }), lijst.map((r) => (_jsxs("p", { className: "text-sm", children: [VELD[r.veld] ?? r.veld, ": nu ", r.huidig ?? "leeg", ", voorstel ", r.voorstel, r.actie === "afwijkend" && _jsx("span", { className: "text-muted-foreground", children: " \u2014 afwijkend, wordt niet overschreven" }), r.actie === "gelijk" && _jsx("span", { className: "text-muted-foreground", children: " \u2014 gelijk" })] }, r.veld)))] }, code));
43
+ })] })] }));
44
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"LadingdragersPage.d.ts","sourceRoot":"","sources":["../../src/components/LadingdragersPage.tsx"],"names":[],"mappings":"AAiIA,wBAAgB,iBAAiB,gCAyUhC"}
1
+ {"version":3,"file":"LadingdragersPage.d.ts","sourceRoot":"","sources":["../../src/components/LadingdragersPage.tsx"],"names":[],"mappings":"AAkIA,wBAAgB,iBAAiB,gCA2UhC"}
@@ -13,6 +13,7 @@ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitl
13
13
  import { Container, Pencil, Plus, RefreshCw, Trash2 } from "lucide-react";
14
14
  import { Link } from "@tanstack/react-router";
15
15
  import { useLadingdragers } from "../hooks/useLadingdragers.js";
16
+ import { LadingdragerVoorstellenCard } from "./LadingdragerVoorstellenCard.js";
16
17
  import { CAPACITY_MODEL_LABELS } from "../lib/loadCarrierTypes.js";
17
18
  const LEEG = {
18
19
  code: "",
@@ -101,5 +102,5 @@ export function LadingdragersPage() {
101
102
  };
102
103
  const set = (key, value) => setForm((prev) => ({ ...prev, [key]: value }));
103
104
  const toonLagen = form.capacity_model === "layered" || form.capacity_model === "stacked";
104
- return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Container, { className: "h-6 w-6 text-primary" }), "Ladingdragers"] }), _jsx("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: "Hier staat hoe groot elke ladingdrager is. De Beladingindeling gebruikt deze maten om te bepalen hoeveel fusten er per laag en per drager passen. In de Rule Engine bepaal je per strategie welke ladingdragers gebruikt mogen worden." })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: reload, disabled: loading, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Vernieuwen"] }), _jsxs(Button, { size: "sm", onClick: openNieuw, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Ladingdrager"] }), _jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/logistiek-engine", children: "Terug" }) })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Capaciteit per ladingdrager" }), _jsx(CardDescription, { children: "Lagen bepalen de hoogte: een product met vier lagen per drager neemt per laag 25% van de hoogte in." })] }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" })] })) : safeItems.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen ladingdragers ingesteld." })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Ladingdrager" }), _jsx(TableHead, { children: "Model" }), _jsx(TableHead, { className: "text-right", children: "Lagen" }), _jsx(TableHead, { className: "text-right", children: "Laagmaat" }), _jsx(TableHead, { className: "text-right", children: "Max dozen" }), _jsx(TableHead, { className: "text-right", children: "Max kg" }), _jsx(TableHead, { children: "Mengen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((row) => (_jsxs(TableRow, { className: row.is_active ? "" : "opacity-50", children: [_jsxs(TableCell, { children: [_jsx("div", { className: "font-medium", children: ladingdragerNaam(row.code, floricodeNamen, row.name) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: row.code }), row.is_default ? _jsx(Badge, { variant: "secondary", children: "Standaard" }) : null, !row.is_active ? _jsx(Badge, { variant: "outline", children: "Uit" }) : null] })] }), _jsx(TableCell, { className: "text-sm", children: CAPACITY_MODEL_LABELS[row.capacity_model] }), _jsx(TableCell, { className: "text-right", children: row.layers_per_carrier }), _jsxs(TableCell, { className: "text-right text-sm text-muted-foreground", children: [row.layer_length_cm, " \u00D7 ", row.layer_width_cm, " cm"] }), _jsx(TableCell, { className: "text-right", children: row.max_boxes ?? "—" }), _jsx(TableCell, { className: "text-right", children: row.max_weight_kg ?? "—" }), _jsx(TableCell, { children: _jsx(Badge, { variant: row.allow_mixing === false ? "outline" : "secondary", children: row.allow_mixing === false ? "Nooit mengen" : "Mengen mag" }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => openBewerk(row), children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => remove(row.id), children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, row.id))) })] })) })] }), _jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-lg", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: bewerkId ? "Ladingdrager bewerken" : "Nieuwe ladingdrager" }), _jsx(DialogDescription, { children: "Deze maten bepalen hoeveel er per laag en per drager past." })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "code", children: "Code" }), _jsx(Input, { id: "code", value: form.code, onChange: (e) => set("code", e.target.value), placeholder: "pallet", disabled: Boolean(bewerkId) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "name", children: "Naam" }), _jsx(Input, { id: "name", value: form.name, onChange: (e) => set("name", e.target.value) })] })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "Capaciteitsmodel" }), _jsxs(Select, { value: form.capacity_model, onValueChange: (v) => set("capacity_model", v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: Object.entries(CAPACITY_MODEL_LABELS).map(([value, label]) => (_jsx(SelectItem, { value: value, children: label }, value))) })] })] }), toonLagen ? (_jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lagen", children: "Lagen" }), _jsx(Input, { id: "lagen", type: "number", min: 1, value: form.layers_per_carrier, onChange: (e) => set("layers_per_carrier", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lengte", children: "Lengte (cm)" }), _jsx(Input, { id: "lengte", type: "number", min: 0, value: form.layer_length_cm, onChange: (e) => set("layer_length_cm", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "breedte", children: "Breedte (cm)" }), _jsx(Input, { id: "breedte", type: "number", min: 0, value: form.layer_width_cm, onChange: (e) => set("layer_width_cm", Number(e.target.value)) })] })] })) : null, _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxfust", children: "Max fusten per laag" }), _jsx(Input, { id: "maxfust", type: "number", min: 1, value: form.max_crates_per_layer, onChange: (e) => set("max_crates_per_layer", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxdozen", children: "Max dozen / fusten totaal" }), _jsx(Input, { id: "maxdozen", type: "number", min: 1, value: form.max_boxes, onChange: (e) => set("max_boxes", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxkg", children: "Max gewicht (kg)" }), _jsx(Input, { id: "maxkg", type: "number", min: 0, value: form.max_weight_kg, onChange: (e) => set("max_weight_kg", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxhoogte", children: "Max hoogte (cm)" }), _jsx(Input, { id: "maxhoogte", type: "number", min: 0, value: form.max_height_cm, onChange: (e) => set("max_height_cm", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxorders", children: "Max orders" }), _jsx(Input, { id: "maxorders", type: "number", min: 1, value: form.max_orders, onChange: (e) => set("max_orders", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxklanten", children: "Max klanten" }), _jsx(Input, { id: "maxklanten", type: "number", min: 1, value: form.max_customers, onChange: (e) => set("max_customers", e.target.value), placeholder: "Geen grens" })] })] }), _jsxs("div", { className: "space-y-3 rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "mengen", children: "Mengen van partijen toestaan" }), _jsx(Switch, { id: "mengen", checked: form.allow_mixing, onCheckedChange: (v) => set("allow_mixing", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "actief", children: "Actief" }), _jsx(Switch, { id: "actief", checked: form.is_active, onCheckedChange: (v) => set("is_active", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "standaard", children: "Standaard ladingdrager" }), _jsx(Switch, { id: "standaard", checked: form.is_default, onCheckedChange: (v) => set("is_default", v) })] }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Label, { htmlFor: "volgorde", children: "Volgorde" }), _jsx(Input, { id: "volgorde", type: "number", className: "w-24", value: form.sort_order, onChange: (e) => set("sort_order", Number(e.target.value)) })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: "Annuleren" }), _jsx(Button, { onClick: opslaan, disabled: saving || !form.code || !form.name, children: "Opslaan" })] })] }) })] }));
105
+ return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Container, { className: "h-6 w-6 text-primary" }), "Ladingdragers"] }), _jsx("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: "Hier staat hoe groot elke ladingdrager is. De Beladingindeling gebruikt deze maten om te bepalen hoeveel fusten er per laag en per drager passen. In de Rule Engine bepaal je per strategie welke ladingdragers gebruikt mogen worden." })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: reload, disabled: loading, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Vernieuwen"] }), _jsxs(Button, { size: "sm", onClick: openNieuw, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Ladingdrager"] }), _jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/logistiek-engine", children: "Terug" }) })] })] }), _jsx(LadingdragerVoorstellenCard, { onKlaar: reload }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Capaciteit per ladingdrager" }), _jsx(CardDescription, { children: "Lagen bepalen de hoogte: een product met vier lagen per drager neemt per laag 25% van de hoogte in." })] }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" })] })) : safeItems.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen ladingdragers ingesteld." })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Ladingdrager" }), _jsx(TableHead, { children: "Model" }), _jsx(TableHead, { className: "text-right", children: "Lagen" }), _jsx(TableHead, { className: "text-right", children: "Laagmaat" }), _jsx(TableHead, { className: "text-right", children: "Max dozen" }), _jsx(TableHead, { className: "text-right", children: "Max kg" }), _jsx(TableHead, { children: "Mengen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((row) => (_jsxs(TableRow, { className: row.is_active ? "" : "opacity-50", children: [_jsxs(TableCell, { children: [_jsx("div", { className: "font-medium", children: ladingdragerNaam(row.code, floricodeNamen, row.name) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: row.code }), row.is_default ? _jsx(Badge, { variant: "secondary", children: "Standaard" }) : null, !row.is_active ? _jsx(Badge, { variant: "outline", children: "Uit" }) : null] })] }), _jsx(TableCell, { className: "text-sm", children: CAPACITY_MODEL_LABELS[row.capacity_model] }), _jsx(TableCell, { className: "text-right", children: row.layers_per_carrier }), _jsxs(TableCell, { className: "text-right text-sm text-muted-foreground", children: [row.layer_length_cm, " \u00D7 ", row.layer_width_cm, " cm"] }), _jsx(TableCell, { className: "text-right", children: row.max_boxes ?? "—" }), _jsx(TableCell, { className: "text-right", children: row.max_weight_kg ?? "—" }), _jsx(TableCell, { children: _jsx(Badge, { variant: row.allow_mixing === false ? "outline" : "secondary", children: row.allow_mixing === false ? "Nooit mengen" : "Mengen mag" }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => openBewerk(row), children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => remove(row.id), children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, row.id))) })] })) })] }), _jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-lg", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: bewerkId ? "Ladingdrager bewerken" : "Nieuwe ladingdrager" }), _jsx(DialogDescription, { children: "Deze maten bepalen hoeveel er per laag en per drager past." })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "code", children: "Code" }), _jsx(Input, { id: "code", value: form.code, onChange: (e) => set("code", e.target.value), placeholder: "pallet", disabled: Boolean(bewerkId) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "name", children: "Naam" }), _jsx(Input, { id: "name", value: form.name, onChange: (e) => set("name", e.target.value) })] })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "Capaciteitsmodel" }), _jsxs(Select, { value: form.capacity_model, onValueChange: (v) => set("capacity_model", v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: Object.entries(CAPACITY_MODEL_LABELS).map(([value, label]) => (_jsx(SelectItem, { value: value, children: label }, value))) })] })] }), toonLagen ? (_jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lagen", children: "Lagen" }), _jsx(Input, { id: "lagen", type: "number", min: 1, value: form.layers_per_carrier, onChange: (e) => set("layers_per_carrier", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lengte", children: "Lengte (cm)" }), _jsx(Input, { id: "lengte", type: "number", min: 0, value: form.layer_length_cm, onChange: (e) => set("layer_length_cm", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "breedte", children: "Breedte (cm)" }), _jsx(Input, { id: "breedte", type: "number", min: 0, value: form.layer_width_cm, onChange: (e) => set("layer_width_cm", Number(e.target.value)) })] })] })) : null, _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxfust", children: "Max fusten per laag" }), _jsx(Input, { id: "maxfust", type: "number", min: 1, value: form.max_crates_per_layer, onChange: (e) => set("max_crates_per_layer", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxdozen", children: "Max dozen / fusten totaal" }), _jsx(Input, { id: "maxdozen", type: "number", min: 1, value: form.max_boxes, onChange: (e) => set("max_boxes", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxkg", children: "Max gewicht (kg)" }), _jsx(Input, { id: "maxkg", type: "number", min: 0, value: form.max_weight_kg, onChange: (e) => set("max_weight_kg", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxhoogte", children: "Max hoogte (cm)" }), _jsx(Input, { id: "maxhoogte", type: "number", min: 0, value: form.max_height_cm, onChange: (e) => set("max_height_cm", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxorders", children: "Max orders" }), _jsx(Input, { id: "maxorders", type: "number", min: 1, value: form.max_orders, onChange: (e) => set("max_orders", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxklanten", children: "Max klanten" }), _jsx(Input, { id: "maxklanten", type: "number", min: 1, value: form.max_customers, onChange: (e) => set("max_customers", e.target.value), placeholder: "Geen grens" })] })] }), _jsxs("div", { className: "space-y-3 rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "mengen", children: "Mengen van partijen toestaan" }), _jsx(Switch, { id: "mengen", checked: form.allow_mixing, onCheckedChange: (v) => set("allow_mixing", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "actief", children: "Actief" }), _jsx(Switch, { id: "actief", checked: form.is_active, onCheckedChange: (v) => set("is_active", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "standaard", children: "Standaard ladingdrager" }), _jsx(Switch, { id: "standaard", checked: form.is_default, onCheckedChange: (v) => set("is_default", v) })] }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Label, { htmlFor: "volgorde", children: "Volgorde" }), _jsx(Input, { id: "volgorde", type: "number", className: "w-24", value: form.sort_order, onChange: (e) => set("sort_order", Number(e.target.value)) })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: "Annuleren" }), _jsx(Button, { onClick: opslaan, disabled: saving || !form.code || !form.name, children: "Opslaan" })] })] }) })] }));
105
106
  }
@@ -0,0 +1,2 @@
1
+ export declare function StartlijstCard(): import("react").JSX.Element;
2
+ //# sourceMappingURL=StartlijstCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StartlijstCard.d.ts","sourceRoot":"","sources":["../../src/components/StartlijstCard.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,cAAc,gCAqG7B"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/StartlijstCard.tsx — 1.0.198 startlijst voor een nieuwe shell
4
+ // ============================================================================
5
+ // Drie stappen: ladingdragers → werkwijze → gereedheid per product. Met
6
+ // "Alles overnemen uit Floricode/Floriday": eerst een voorvertoning, pas na
7
+ // bevestiging worden alleen lege velden ingevuld en de bron vastgelegd.
8
+ // GEEN <Header /> hier — die levert de shell.
9
+ // ============================================================================
10
+ import { useCallback, useEffect, useState } from "react";
11
+ import { Link } from "@tanstack/react-router";
12
+ import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from "@flowselections/core";
13
+ import { CheckCircle2, Circle } from "lucide-react";
14
+ import { supabase } from "../integrations/supabase/moduleClient.js";
15
+ const VELD = {
16
+ plant_height_cm: "planthoogte inclusief pot",
17
+ fust_type_id: "fustsoort",
18
+ length_mm: "fustlengte",
19
+ width_mm: "fustbreedte",
20
+ height_mm: "fusthoogte",
21
+ };
22
+ export function StartlijstCard() {
23
+ const [s, setS] = useState(null);
24
+ const [fout, setFout] = useState(null);
25
+ const [voor, setVoor] = useState(null);
26
+ const [bezig, setBezig] = useState(false);
27
+ const laden = useCallback(async () => {
28
+ const { data, error } = await supabase.rpc("logistics_startlijst");
29
+ if (error)
30
+ setFout(error.message);
31
+ else
32
+ setS((data ?? {}));
33
+ }, []);
34
+ useEffect(() => {
35
+ void laden();
36
+ }, [laden]);
37
+ const overnemen = async (uitvoeren) => {
38
+ setBezig(true);
39
+ setFout(null);
40
+ const { data, error } = await supabase.rpc("logistics_data_overnemen", { p_uitvoeren: uitvoeren });
41
+ setBezig(false);
42
+ if (error)
43
+ return setFout(error.message);
44
+ const d = (data ?? {});
45
+ setVoor({ ...d, velden: Array.isArray(d.velden) ? d.velden : [], per_bron: d.per_bron ?? {} });
46
+ if (uitvoeren)
47
+ await laden();
48
+ };
49
+ const Stap = ({ klaar, titel, tekst, naar }) => (_jsxs("div", { className: "flex items-start gap-3", children: [klaar ? _jsx(CheckCircle2, { className: "mt-0.5 h-5 w-5 text-primary" }) : _jsx(Circle, { className: "mt-0.5 h-5 w-5 text-muted-foreground" }), _jsxs("div", { className: "text-sm", children: [_jsx("p", { className: "font-medium", children: titel }), _jsxs("p", { className: "text-muted-foreground", children: [tekst, naar && (_jsxs(_Fragment, { children: [" ", _jsx(Link, { to: naar, className: "underline", children: "Openen" })] }))] })] })] }));
50
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Startlijst" }), _jsx(CardDescription, { children: "Wat er nodig is om karren te kunnen indelen, in deze volgorde." })] }), _jsxs(CardContent, { className: "space-y-3", children: [fout && _jsx("p", { className: "text-sm text-destructive", children: fout }), _jsx(Stap, { klaar: s?.ladingdragers?.klaar, titel: "1. Ladingdragers", tekst: `${s?.ladingdragers?.aantal ?? 0} actief, ${s?.ladingdragers?.onvolledig ?? 0} zonder volledige maten.`, naar: "/logistiek-engine/ladingdragers" }), _jsx(Stap, { klaar: s?.werkwijze?.klaar, titel: "2. Werkwijze", tekst: s?.werkwijze?.klaar ? "Ingesteld." : "Nog niet ingesteld in de Rule Engine.", naar: "/logistiek-engine/rule-engine" }), _jsx(Stap, { klaar: s?.gereedheid?.klaar, titel: "3. Gereedheid per product", tekst: `${s?.gereedheid?.onvolledig ?? 0} van ${s?.gereedheid?.producten ?? 0} producten in open orders missen gegevens.` }), _jsxs("div", { className: "flex flex-wrap gap-2 border-t pt-3", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: bezig, onClick: () => void overnemen(false), children: "Alles overnemen uit Floricode/Floriday" }), voor && !voor.uitgevoerd && voor.aantal > 0 && (_jsxs(Button, { size: "sm", disabled: bezig, onClick: () => void overnemen(true), children: ["Bevestigen: ", voor.aantal, " veld(en) invullen"] }))] }), voor && (_jsxs("div", { className: "space-y-1 text-sm", children: [_jsxs("p", { children: [voor.uitgevoerd ? "Ingevuld" : "Voorvertoning", ": ", voor.aantal, " leeg veld(en)", Object.keys(voor.per_bron).length > 0 &&
51
+ ` (${Object.entries(voor.per_bron)
52
+ .map(([b, n]) => `${n} uit ${b}`)
53
+ .join(", ")})`, ". Bestaande waarden blijven staan."] }), voor.velden.slice(0, 30).map((v, i) => (_jsxs("p", { className: "text-xs text-muted-foreground", children: [v.naam, ": ", VELD[v.veld] ?? v.veld, " = ", String(v.waarde), " (", v.bron, ")"] }, i)))] }))] })] }));
54
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useGeblokkeerdeOrders.d.ts","sourceRoot":"","sources":["../../src/hooks/useGeblokkeerdeOrders.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkB9C,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,UAGzD;AAED,wBAAgB,qBAAqB;;;;;;;sBAqDhB,MAAM,EAAE;gCAwBT,MAAM;;;;;;;kCA8BN,MAAM;EA4BzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB;;;;;;iCAsCjB,MAAM,EAAE;EAmB5B"}
1
+ {"version":3,"file":"useGeblokkeerdeOrders.d.ts","sourceRoot":"","sources":["../../src/hooks/useGeblokkeerdeOrders.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAoB9C,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,UAGzD;AAED,wBAAgB,qBAAqB;;;;;;;sBAqDhB,MAAM,EAAE;gCAwBT,MAAM;;;;;;;kCA8BN,MAAM;EA4BzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB;;;;;;iCAsCjB,MAAM,EAAE;EAmB5B"}
@@ -6,6 +6,8 @@
6
6
  import { useCallback, useEffect, useState } from "react";
7
7
  import { supabase } from "../integrations/supabase/moduleClient.js";
8
8
  export const REDEN_LABEL = {
9
+ gewicht_onbekend: "Gewicht per fust onbekend",
10
+ ladingdrager_niet_in_beheer: "Ladingdrager niet in beheer",
9
11
  belading_onbekend: "Belading onbekend",
10
12
  belading_onvolledig: "Belading onvolledig",
11
13
  beladingsprofiel_ontbreekt: "Beladingsprofiel ontbreekt",
@@ -20,6 +20,9 @@ export { AfmetingenBronnenCard } from './components/AfmetingenBronnenCard.js';
20
20
  export { WerkwijzeHerindelingCard } from './components/WerkwijzeHerindelingCard.js';
21
21
  export { HerindelingMeldingCard } from './components/HerindelingMeldingCard.js';
22
22
  export { GeblokkeerdeStickersCard } from './components/GeblokkeerdeStickersCard.js';
23
+ export { DataGereedheidCard } from './components/DataGereedheidCard.js';
24
+ export { StartlijstCard } from './components/StartlijstCard.js';
25
+ export { LadingdragerVoorstellenCard } from './components/LadingdragerVoorstellenCard.js';
23
26
  export { EtiketInstellenMelding } from './components/EtiketInstellenMelding.js';
24
27
  export { VervoerderBewakingCard, leesVervoerderStand } from './components/VervoerderBewakingCard.js';
25
28
  export { WerktijdenCard } from './components/WerktijdenCard.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist-lib/index.js CHANGED
@@ -23,6 +23,9 @@ export { AfmetingenBronnenCard } from './components/AfmetingenBronnenCard.js';
23
23
  export { WerkwijzeHerindelingCard } from './components/WerkwijzeHerindelingCard.js';
24
24
  export { HerindelingMeldingCard } from './components/HerindelingMeldingCard.js';
25
25
  export { GeblokkeerdeStickersCard } from './components/GeblokkeerdeStickersCard.js';
26
+ export { DataGereedheidCard } from './components/DataGereedheidCard.js';
27
+ export { StartlijstCard } from './components/StartlijstCard.js';
28
+ export { LadingdragerVoorstellenCard } from './components/LadingdragerVoorstellenCard.js';
26
29
  export { EtiketInstellenMelding } from './components/EtiketInstellenMelding.js';
27
30
  export { VervoerderBewakingCard, leesVervoerderStand } from './components/VervoerderBewakingCard.js';
28
31
  export { WerktijdenCard } from './components/WerktijdenCard.js';