@flowselections/floriday-afhandeling-module 1.0.12 → 1.0.13

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 (35) hide show
  1. package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts.map +1 -1
  2. package/dist-lib/components/afhandeling/ControleLijstPrint.js +63 -2
  3. package/dist-lib/components/pickstation/KioskControle.d.ts +2 -0
  4. package/dist-lib/components/pickstation/KioskControle.d.ts.map +1 -0
  5. package/dist-lib/components/pickstation/KioskControle.js +7 -0
  6. package/dist-lib/components/pickstation/PickstationPage.d.ts +2 -0
  7. package/dist-lib/components/pickstation/PickstationPage.d.ts.map +1 -0
  8. package/dist-lib/components/pickstation/PickstationPage.js +217 -0
  9. package/dist-lib/index.d.ts +2 -0
  10. package/dist-lib/index.d.ts.map +1 -1
  11. package/dist-lib/index.js +2 -0
  12. package/dist-lib/integrations/supabase/auth-middleware.d.ts +700 -1
  13. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  14. package/dist-lib/integrations/supabase/client.d.ts +700 -1
  15. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  16. package/dist-lib/integrations/supabase/client.server.d.ts +700 -1
  17. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  18. package/dist-lib/integrations/supabase/types.d.ts +720 -1
  19. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  20. package/dist-lib/lib/afhandelingSettings.functions.d.ts +1545 -147
  21. package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
  22. package/dist-lib/lib/carriers.functions.d.ts +3500 -5
  23. package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
  24. package/dist-lib/lib/cartAssignments.functions.d.ts +3500 -5
  25. package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
  26. package/dist-lib/lib/cartControl.functions.d.ts +7003 -10
  27. package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
  28. package/dist-lib/lib/cartControl.functions.js +3 -0
  29. package/dist-lib/lib/floriday.functions.d.ts +700 -1
  30. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  31. package/dist-lib/lib/pickstationOrders.server.d.ts.map +1 -1
  32. package/dist-lib/lib/pickstationOrders.server.js +1 -0
  33. package/dist-lib/lib/pickstationTypes.d.ts +2 -0
  34. package/dist-lib/lib/pickstationTypes.d.ts.map +1 -1
  35. package/package.json +15 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAanE,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,sCAkIA"}
1
+ {"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAqEnE,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,sCAgJA"}
@@ -3,7 +3,7 @@ import { useEffect } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { Button } from "@flowselections/core";
5
5
  import { X, Printer } from "lucide-react";
6
- function fmt(iso) {
6
+ function fmtDate(iso) {
7
7
  if (!iso)
8
8
  return "—";
9
9
  const d = new Date(iso);
@@ -15,6 +15,51 @@ function fmt(iso) {
15
15
  year: "numeric",
16
16
  });
17
17
  }
18
+ /** Trek 1 uur af van "HH:MM" en geef terug als "HH:MM". */
19
+ function minusOneHour(hhmm) {
20
+ const [h, m] = hhmm.split(":").map((n) => parseInt(n, 10));
21
+ if (Number.isNaN(h) || Number.isNaN(m))
22
+ return hhmm;
23
+ const total = h * 60 + m - 60;
24
+ const norm = ((total % (24 * 60)) + 24 * 60) % (24 * 60);
25
+ const hh = String(Math.floor(norm / 60)).padStart(2, "0");
26
+ const mm = String(norm % 60).padStart(2, "0");
27
+ return `${hh}:${mm}`;
28
+ }
29
+ function todayIsoDay() {
30
+ const d = new Date();
31
+ const y = d.getFullYear();
32
+ const m = String(d.getMonth() + 1).padStart(2, "0");
33
+ const day = String(d.getDate()).padStart(2, "0");
34
+ return `${y}-${m}-${day}`;
35
+ }
36
+ function tomorrowIsoDay() {
37
+ const d = new Date();
38
+ d.setDate(d.getDate() + 1);
39
+ const y = d.getFullYear();
40
+ const m = String(d.getMonth() + 1).padStart(2, "0");
41
+ const day = String(d.getDate()).padStart(2, "0");
42
+ return `${y}-${m}-${day}`;
43
+ }
44
+ function computeKlaarzet(cart) {
45
+ const today = todayIsoDay();
46
+ const tomorrow = tomorrowIsoDay();
47
+ if (cart.pickupDate === today) {
48
+ const time = cart.pickupTime ? minusOneHour(cart.pickupTime) : null;
49
+ if (time) {
50
+ const [h, m] = time.split(":").map((n) => parseInt(n, 10));
51
+ return { label: time, sortKey: h * 60 + m };
52
+ }
53
+ // Ophaaldatum vandaag maar geen tijd bekend → einde van vandaag.
54
+ return { label: "vandaag", sortKey: 23 * 60 + 59 };
55
+ }
56
+ if (cart.pickupDate === tomorrow) {
57
+ // Moet uiterlijk vandaag klaar → toon datum vandaag.
58
+ return { label: fmtDate(today), sortKey: 23 * 60 + 58 };
59
+ }
60
+ // Overige gevallen: eind van de dag, met datum als label.
61
+ return { label: fmtDate(cart.pickupDate), sortKey: 24 * 60 + 999 };
62
+ }
18
63
  /** Printbare controlelijst — één regel per kar met checkbox en opmerkingveld. */
19
64
  export function ControleLijstPrint({ carts, onClose, }) {
20
65
  useEffect(() => {
@@ -32,7 +77,23 @@ export function ControleLijstPrint({ carts, onClose, }) {
32
77
  month: "long",
33
78
  year: "numeric",
34
79
  });
35
- const content = (_jsxs("div", { id: "controle-print-root", className: "fixed inset-0 z-[100] bg-white overflow-auto", children: [_jsxs("div", { className: "print:hidden sticky top-0 flex items-center justify-between p-3 border-b bg-white", children: [_jsx("div", { className: "font-semibold", children: "Controlelijst \u2014 printweergave" }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: () => window.print(), children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), "Opnieuw printen"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: onClose, children: [_jsx(X, { className: "h-4 w-4 mr-2" }), "Sluiten"] })] })] }), _jsxs("div", { className: "print-sheet p-8 print:p-0 max-w-[210mm] mx-auto text-black", children: [_jsxs("div", { className: "flex items-baseline justify-between border-b border-black pb-2 mb-4", children: [_jsx("h1", { className: "text-2xl font-bold", children: "Controlelijst karren" }), _jsx("div", { className: "text-sm", children: today })] }), _jsxs("div", { className: "text-sm mb-3", children: ["Totaal karren: ", _jsx("strong", { children: carts.length })] }), _jsxs("table", { className: "w-full text-[11px] border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-black", children: [_jsx("th", { className: "text-left py-1 pr-2", children: "Karnr" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Klant" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Vervoerder" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Lever" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Ophaal" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Print" }), _jsx("th", { className: "text-center py-1 px-2", children: "Klaar" }), _jsx("th", { className: "text-left py-1 pr-2", children: "Opmerkingen" })] }) }), _jsxs("tbody", { children: [carts.map((c) => (_jsxs("tr", { className: "border-b border-gray-300", children: [_jsx("td", { className: "py-2 pr-2 font-mono font-bold whitespace-nowrap", children: c.cartNumber ?? "—" }), _jsx("td", { className: "py-2 pr-2", children: c.customerName }), _jsx("td", { className: "py-2 pr-2", children: c.carrierName ?? "—" }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap", children: fmt(c.deliveryDate) }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap", children: fmt(c.pickupDate) }), _jsx("td", { className: "py-2 pr-2 text-center", children: c.printedCount > 0 ? "✓" : "" }), _jsx("td", { className: "py-2 px-2 text-center", children: _jsx("span", { className: "inline-block w-4 h-4 border border-black" }) }), _jsx("td", { className: "py-2 pr-2 w-[30%]", children: _jsx("span", { className: "inline-block w-full border-b border-gray-400 h-4" }) })] }, `${c.orderSource}#${c.orderId}#${c.cartIndex}`))), carts.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: 8, className: "py-6 text-center text-gray-500", children: "Geen karren om vandaag te controleren." }) }))] })] }), _jsxs("div", { className: "mt-6 text-[11px]", children: [_jsxs("div", { children: ["Gecontroleerd door: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: ["Datum / tijd: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: ["Handtekening: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] })] })] }), _jsx("style", { children: `
80
+ // Bereken klaarzet-moment per kar en sorteer op prioriteit
81
+ // (vroegste klaarzet bovenaan; daarna land, karnummer).
82
+ const sortedCarts = carts
83
+ .map((cart) => ({ cart, klaarzet: computeKlaarzet(cart) }))
84
+ .sort((a, b) => {
85
+ if (a.klaarzet.sortKey !== b.klaarzet.sortKey) {
86
+ return a.klaarzet.sortKey - b.klaarzet.sortKey;
87
+ }
88
+ const ac = a.cart.country ?? "\uFFFF";
89
+ const bc = b.cart.country ?? "\uFFFF";
90
+ if (ac !== bc)
91
+ return ac.localeCompare(bc);
92
+ const an = a.cart.cartNumber ?? "\uFFFF";
93
+ const bn = b.cart.cartNumber ?? "\uFFFF";
94
+ return an.localeCompare(bn);
95
+ });
96
+ const content = (_jsxs("div", { id: "controle-print-root", className: "fixed inset-0 z-[100] bg-white overflow-auto", children: [_jsxs("div", { className: "print:hidden sticky top-0 flex items-center justify-between p-3 border-b bg-white", children: [_jsx("div", { className: "font-semibold", children: "Controlelijst \u2014 printweergave" }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: () => window.print(), children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), "Opnieuw printen"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: onClose, children: [_jsx(X, { className: "h-4 w-4 mr-2" }), "Sluiten"] })] })] }), _jsxs("div", { className: "print-sheet p-8 print:p-0 max-w-[210mm] mx-auto text-black", children: [_jsxs("div", { className: "flex items-baseline justify-between border-b border-black pb-2 mb-4", children: [_jsx("h1", { className: "text-2xl font-bold", children: "Controlelijst karren" }), _jsx("div", { className: "text-sm", children: today })] }), _jsxs("div", { className: "text-sm mb-3", children: ["Totaal karren: ", _jsx("strong", { children: carts.length })] }), _jsxs("table", { className: "w-full text-[11px] border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-black", children: [_jsx("th", { className: "text-left py-1 pr-2", children: "KARNR" }), _jsx("th", { className: "text-right py-1 pr-2", children: "FUSTEN" }), _jsx("th", { className: "text-left py-1 pr-2", children: "LAND" }), _jsx("th", { className: "text-left py-1 pr-2", children: "KLAARZETTEN" }), _jsx("th", { className: "text-center py-1 px-2", children: "KLAAR" }), _jsx("th", { className: "text-left py-1 pr-2", children: "OPMERKINGEN" })] }) }), _jsxs("tbody", { children: [sortedCarts.map(({ cart: c, klaarzet }) => (_jsxs("tr", { className: "border-b border-gray-300", children: [_jsx("td", { className: "py-2 pr-2 font-mono font-bold whitespace-nowrap", children: c.cartNumber ?? "—" }), _jsx("td", { className: "py-2 pr-2 text-right whitespace-nowrap", children: c.cratesOnCart ?? "—" }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap", children: c.country ?? "—" }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap font-semibold", children: klaarzet.label }), _jsx("td", { className: "py-2 px-2 text-center", children: _jsx("span", { className: "inline-block w-4 h-4 border border-black" }) }), _jsx("td", { className: "py-2 pr-2 w-[35%]", children: _jsx("span", { className: "inline-block w-full border-b border-gray-400 h-4" }) })] }, `${c.orderSource}#${c.orderId}#${c.cartIndex}`))), sortedCarts.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: 6, className: "py-6 text-center text-gray-500", children: "Geen karren om vandaag te controleren." }) }))] })] }), _jsxs("div", { className: "mt-6 text-[11px]", children: [_jsxs("div", { children: ["Gecontroleerd door: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: ["Datum / tijd: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: ["Handtekening: ", _jsx("span", { className: "inline-block border-b border-black w-64" })] })] })] }), _jsx("style", { children: `
36
97
  @media print {
37
98
  @page { size: A4 portrait; margin: 12mm; }
38
99
  html, body { background: #fff !important; margin: 0 !important; padding: 0 !important; }
@@ -0,0 +1,2 @@
1
+ export declare function KioskControle(): import("react").JSX.Element;
2
+ //# sourceMappingURL=KioskControle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KioskControle.d.ts","sourceRoot":"","sources":["../../../src/components/pickstation/KioskControle.tsx"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,gCAoB5B"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useNavigate } from "@tanstack/react-router";
3
+ import { ControlePage } from "../afhandeling/ControlePage";
4
+ export function KioskControle() {
5
+ const navigate = useNavigate();
6
+ return (_jsxs("div", { className: "min-h-screen bg-slate-50 text-slate-900 flex flex-col", children: [_jsx("header", { className: "bg-white border-b sticky top-0 z-20", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4 py-3 flex items-center gap-3", children: [_jsx("button", { onClick: () => navigate({ to: "/pickstation" }), className: "h-12 px-4 rounded-xl bg-white border-2 border-slate-300 hover:bg-slate-100 font-semibold", children: "\u2190 Terug naar Picking" }), _jsx("h1", { className: "text-xl font-semibold", children: "Picking-modus" })] }) }), _jsx("main", { className: "flex-1", children: _jsx(ControlePage, { onExit: () => navigate({ to: "/pickstation" }) }) })] }));
7
+ }
@@ -0,0 +1,2 @@
1
+ export declare function PickstationPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=PickstationPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickstationPage.d.ts","sourceRoot":"","sources":["../../../src/components/pickstation/PickstationPage.tsx"],"names":[],"mappings":"AA6CA,wBAAgB,eAAe,gCA8W9B"}
@@ -0,0 +1,217 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from "react";
3
+ import { useNavigate } from "@tanstack/react-router";
4
+ import { useQuery } from "@tanstack/react-query";
5
+ import { LanguagePicker } from "./LanguagePicker";
6
+ import { renderPakbonHtml } from "./PakbonTemplate";
7
+ import { printHtml, printPdfBase64 } from "./printDocuments";
8
+ import { ControleLijstPrint } from "../afhandeling/ControleLijstPrint";
9
+ import { PICKSTATION_DICT, PICKSTATION_LANGUAGES, } from "../../lib/pickstationI18n";
10
+ const LANG_KEY = "pickstation.lang";
11
+ const LAST_GOOD_ORDERS_KEY = "pickstation.lastGoodOrders";
12
+ function statusBadge(status, t, printedCount) {
13
+ switch (status) {
14
+ case "not_printed":
15
+ return { label: t.notPrinted, className: "bg-slate-200 text-slate-700" };
16
+ case "printed":
17
+ return {
18
+ label: `✓ ${t.printed(printedCount || 1)}`,
19
+ className: "bg-emerald-100 text-emerald-800",
20
+ };
21
+ case "checked":
22
+ return { label: `✓ ${t.statusChecked}`, className: "bg-sky-100 text-sky-800" };
23
+ case "ready":
24
+ return { label: t.statusReady, className: "bg-indigo-100 text-indigo-800" };
25
+ case "shipped":
26
+ return { label: t.statusShipped, className: "bg-amber-100 text-amber-900" };
27
+ case "delivered":
28
+ return { label: `✓ ${t.statusDelivered}`, className: "bg-emerald-600 text-white" };
29
+ }
30
+ }
31
+ export function PickstationPage() {
32
+ const navigate = useNavigate();
33
+ const [lang, setLang] = useState(null);
34
+ const [printingId, setPrintingId] = useState(null);
35
+ const [pickerOpen, setPickerOpen] = useState(false);
36
+ const [lastGoodOrders, setLastGoodOrders] = useState([]);
37
+ const [pendingConfirm, setPendingConfirm] = useState(null);
38
+ const [confirming, setConfirming] = useState(false);
39
+ const [printWarning, setPrintWarning] = useState(null);
40
+ const [showChecklist, setShowChecklist] = useState(false);
41
+ useEffect(() => {
42
+ const stored = (typeof localStorage !== "undefined"
43
+ ? localStorage.getItem(LANG_KEY)
44
+ : null);
45
+ const storedOrders = typeof localStorage !== "undefined"
46
+ ? localStorage.getItem(LAST_GOOD_ORDERS_KEY)
47
+ : null;
48
+ if (storedOrders) {
49
+ try {
50
+ const parsed = JSON.parse(storedOrders);
51
+ if (Array.isArray(parsed))
52
+ setLastGoodOrders(parsed);
53
+ }
54
+ catch {
55
+ localStorage.removeItem(LAST_GOOD_ORDERS_KEY);
56
+ }
57
+ }
58
+ if (stored && PICKSTATION_LANGUAGES.some((l) => l.code === stored)) {
59
+ setLang(stored);
60
+ }
61
+ else {
62
+ setPickerOpen(true);
63
+ }
64
+ }, []);
65
+ const pickLang = useCallback((l) => {
66
+ setLang(l);
67
+ setPickerOpen(false);
68
+ try {
69
+ localStorage.setItem(LANG_KEY, l);
70
+ }
71
+ catch {
72
+ /* ignore */
73
+ }
74
+ }, []);
75
+ const ordersQuery = useQuery({
76
+ queryKey: ["pickstation", "orders"],
77
+ queryFn: async () => {
78
+ const res = await fetch("/api/public/pickstation/orders", { cache: "no-store" });
79
+ if (!res.ok)
80
+ throw new Error(`HTTP ${res.status}`);
81
+ return res.json();
82
+ },
83
+ refetchInterval: 30000,
84
+ refetchOnWindowFocus: true,
85
+ enabled: lang !== null,
86
+ });
87
+ const t = useMemo(() => PICKSTATION_DICT[lang ?? "nl"], [lang]);
88
+ useEffect(() => {
89
+ if (ordersQuery.data && !ordersQuery.data.error) {
90
+ const next = ordersQuery.data.orders ?? [];
91
+ setLastGoodOrders(next);
92
+ try {
93
+ localStorage.setItem(LAST_GOOD_ORDERS_KEY, JSON.stringify(next));
94
+ }
95
+ catch {
96
+ /* ignore */
97
+ }
98
+ }
99
+ }, [ordersQuery.data]);
100
+ const queryError = ordersQuery.data?.error ??
101
+ (ordersQuery.error instanceof Error ? ordersQuery.error.message : undefined);
102
+ const freshOrders = ordersQuery.data?.orders ?? [];
103
+ const orders = queryError ? lastGoodOrders : freshOrders;
104
+ const printedCount = orders.filter((o) => o.printedCount > 0).length;
105
+ const handlePrint = useCallback(async (order) => {
106
+ if (printingId || pendingConfirm)
107
+ return;
108
+ setPrintingId(order.id);
109
+ setPrintWarning(null);
110
+ try {
111
+ let auctionLetter = null;
112
+ try {
113
+ const res = await fetch("/api/public/pickstation/print", {
114
+ method: "POST",
115
+ headers: { "Content-Type": "application/json" },
116
+ body: JSON.stringify({
117
+ orderId: order.id,
118
+ sourceOrderId: order.orderId,
119
+ orderNumber: `${order.orderNumber} (kar ${order.cartIndex}/${order.cartTotal})`,
120
+ customerName: order.customerName,
121
+ documents: ["packing-slip", "auction-letter"],
122
+ confirmed: false,
123
+ }),
124
+ });
125
+ if (res.ok) {
126
+ const body = (await res.json());
127
+ auctionLetter = body.auctionLetter ?? null;
128
+ }
129
+ }
130
+ catch {
131
+ /* network error – continue with pakbon only */
132
+ }
133
+ const html = renderPakbonHtml(order);
134
+ await printHtml(html);
135
+ if (auctionLetter) {
136
+ await printPdfBase64(auctionLetter.base64, auctionLetter.mime);
137
+ }
138
+ setPendingConfirm(order);
139
+ }
140
+ finally {
141
+ setPrintingId(null);
142
+ }
143
+ }, [printingId, pendingConfirm]);
144
+ const confirmPrinted = useCallback(async (yes) => {
145
+ const order = pendingConfirm;
146
+ if (!order)
147
+ return;
148
+ if (!yes) {
149
+ setPendingConfirm(null);
150
+ return;
151
+ }
152
+ setConfirming(true);
153
+ setPrintWarning(null);
154
+ try {
155
+ const res = await fetch("/api/public/pickstation/print", {
156
+ method: "POST",
157
+ headers: { "Content-Type": "application/json" },
158
+ body: JSON.stringify({
159
+ orderId: order.id,
160
+ sourceOrderId: order.orderId,
161
+ orderNumber: `${order.orderNumber} (kar ${order.cartIndex}/${order.cartTotal})`,
162
+ customerName: order.customerName,
163
+ documents: ["packing-slip", "auction-letter"],
164
+ confirmed: true,
165
+ }),
166
+ });
167
+ if (res.ok) {
168
+ const body = (await res.json());
169
+ if (body.warning)
170
+ setPrintWarning(body.warning);
171
+ }
172
+ else {
173
+ setPrintWarning(`Bevestigen mislukt (HTTP ${res.status}).`);
174
+ }
175
+ }
176
+ catch (e) {
177
+ setPrintWarning(e instanceof Error ? e.message : "Bevestigen mislukt.");
178
+ }
179
+ finally {
180
+ setConfirming(false);
181
+ setPendingConfirm(null);
182
+ void ordersQuery.refetch();
183
+ }
184
+ }, [pendingConfirm, ordersQuery]);
185
+ const printNext = useCallback(() => {
186
+ const next = orders[0];
187
+ if (next)
188
+ void handlePrint(next);
189
+ }, [orders, handlePrint]);
190
+ if (!lang || pickerOpen) {
191
+ return _jsx(LanguagePicker, { onPick: pickLang });
192
+ }
193
+ return (_jsxs("div", { className: "min-h-screen bg-slate-50 text-slate-900", children: [_jsx("header", { className: "bg-white border-b sticky top-0 z-10", children: _jsxs("div", { className: "max-w-6xl mx-auto px-4 py-4 flex items-center gap-3 flex-wrap", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h1", { className: "text-2xl font-semibold leading-tight", children: t.title }), _jsxs("p", { className: "text-sm text-slate-500", children: [t.subtitle, " \u00B7 ", t.ofTotal(printedCount, orders.length)] })] }), _jsxs("button", { onClick: () => setPickerOpen(true), className: "h-14 px-5 rounded-xl bg-white border-2 border-slate-300 hover:bg-slate-100 font-semibold text-lg", children: ["\uD83C\uDF10 ", t.changeLang] }), _jsxs("button", { onClick: () => setShowChecklist(true), className: "h-14 px-5 rounded-xl bg-white border-2 border-slate-300 hover:bg-slate-100 font-semibold text-lg", children: ["\uD83D\uDCCB ", t.printChecklist] }), _jsxs("button", { onClick: () => navigate({ to: "/controle" }), className: "h-14 px-5 rounded-xl bg-sky-600 hover:bg-sky-700 text-white font-semibold text-lg shadow", children: ["\u2713 ", t.runControl] }), _jsxs("button", { onClick: printNext, disabled: printingId !== null || orders.length === 0, className: "h-14 px-6 rounded-xl bg-emerald-600 hover:bg-emerald-700 disabled:bg-slate-300 text-white font-bold text-lg shadow", children: ["\uD83D\uDDA8 ", t.printNext] })] }) }), _jsxs("main", { className: "max-w-6xl mx-auto px-4 py-6", children: [ordersQuery.isLoading && _jsx("p", { className: "text-xl text-center py-12", children: t.loading }), queryError && orders.length > 0 && (_jsxs("div", { className: "bg-amber-50 border-2 border-amber-300 text-amber-900 rounded-xl p-4 mb-4", children: [_jsx("strong", { children: "Let op:" }), " verversen is niet gelukt, daarom blijven de laatst bekende pakbonnen zichtbaar. ", queryError] })), printWarning && (_jsxs("div", { className: "bg-amber-50 border-2 border-amber-300 text-amber-900 rounded-xl p-4 mb-4", children: [_jsx("strong", { children: "Let op:" }), " ", printWarning] })), queryError && orders.length === 0 && (_jsxs("div", { className: "bg-rose-50 border-2 border-rose-300 text-rose-900 rounded-xl p-4 mb-4", children: [_jsx("strong", { children: "Picklijst niet bijgewerkt:" }), " ", queryError, " De orders zijn hierdoor niet verwijderd; controleer de Pickagenda of probeer opnieuw."] })), !ordersQuery.isLoading && orders.length === 0 && !queryError && (_jsx("p", { className: "text-2xl text-center py-16 text-slate-500", children: t.empty })), orders.length > 0 && (_jsx("div", { className: "bg-white rounded-2xl border border-slate-200 overflow-hidden shadow-sm", children: _jsxs("table", { className: "w-full text-lg", children: [_jsx("thead", { className: "bg-slate-100 text-slate-600 text-sm uppercase tracking-wide", children: _jsxs("tr", { children: [_jsx("th", { className: "text-left px-5 py-3", children: "Karnr" }), _jsx("th", { className: "text-left px-5 py-3", children: t.orderNumber }), _jsx("th", { className: "text-left px-5 py-3", children: "Kar" }), _jsx("th", { className: "text-left px-5 py-3", children: "Fusten" }), _jsx("th", { className: "text-left px-5 py-3", children: t.customer }), _jsx("th", { className: "text-left px-5 py-3", children: t.country }), _jsx("th", { className: "text-left px-5 py-3", children: t.deliveryDate }), _jsx("th", { className: "text-left px-5 py-3", children: t.status })] }) }), _jsx("tbody", { children: orders.map((o) => {
194
+ const isPrinting = printingId === o.id;
195
+ const badge = statusBadge(o.status, t, o.printedCount);
196
+ return (_jsxs("tr", { className: `border-t border-slate-100 transition select-none ${isPrinting ? "bg-emerald-50" : "hover:bg-slate-50"}`, style: { minHeight: 64 }, children: [_jsx("td", { className: "px-5 py-4 whitespace-nowrap cursor-pointer", onClick: () => void handlePrint(o), children: _jsx("span", { className: "inline-block px-3 py-1.5 rounded-md bg-black text-white font-black text-xl tracking-widest font-mono whitespace-nowrap", children: o.cartNumber ?? "—" }) }), _jsx("td", { className: "px-5 py-4 font-bold text-xl cursor-pointer", onClick: () => void handlePrint(o), children: o.orderNumber }), _jsxs("td", { className: "px-5 py-4 font-semibold", children: [o.cartIndex, "/", o.cartTotal] }), _jsx("td", { className: "px-5 py-4 font-semibold", children: o.cratesOnCart != null ? o.cratesOnCart : "—" }), _jsx("td", { className: "px-5 py-4", children: o.customerName }), _jsx("td", { className: "px-5 py-4", children: o.country ?? "—" }), _jsx("td", { className: "px-5 py-4", children: o.deliveryDate
197
+ ? new Date(o.deliveryDate).toLocaleDateString(lang === "en" ? "en-GB" : lang)
198
+ : "—" }), _jsx("td", { className: "px-5 py-4", children: isPrinting ? (_jsx("span", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full bg-emerald-600 text-white font-semibold", children: t.printingNow })) : (_jsx("span", { className: `inline-flex items-center gap-2 px-3 py-1 rounded-full font-semibold ${badge.className}`, children: badge.label })) })] }, o.id));
199
+ }) })] }) })), _jsx("p", { className: "text-xs text-slate-400 mt-6 text-center", children: t.printDialogHint })] }), pendingConfirm && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: _jsxs("div", { className: "bg-white rounded-2xl shadow-2xl max-w-md w-full p-6", children: [_jsx("h2", { className: "text-2xl font-bold mb-2", children: t.confirmPrintedTitle }), _jsx("p", { className: "text-slate-600 mb-2", children: t.confirmPrintedBody }), _jsx("div", { className: "mb-4 inline-block px-4 py-2 rounded-md bg-black text-white font-black text-3xl tracking-widest font-mono", children: pendingConfirm.cartNumber ?? "—" }), _jsxs("p", { className: "text-slate-800 font-semibold mb-6", children: [pendingConfirm.orderNumber, " \u00B7 kar ", pendingConfirm.cartIndex, "/", pendingConfirm.cartTotal] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("button", { onClick: () => void confirmPrinted(true), disabled: confirming, className: "h-14 rounded-xl bg-emerald-600 hover:bg-emerald-700 disabled:bg-slate-300 text-white font-bold text-lg shadow", children: ["\u2713 ", t.confirmYes] }), _jsxs("button", { onClick: () => void confirmPrinted(false), disabled: confirming, className: "h-14 rounded-xl bg-white border-2 border-slate-300 hover:bg-slate-100 disabled:opacity-60 font-semibold text-lg", children: ["\u2715 ", t.confirmNo] })] })] }) })), showChecklist && (_jsx(ControleLijstPrint, { carts: orders.map((o) => ({
200
+ cartNumberId: null,
201
+ cartNumber: o.cartNumber,
202
+ orderId: o.orderId,
203
+ orderSource: o.orderSource,
204
+ cartIndex: o.cartIndex - 1,
205
+ orderNumber: o.orderNumber,
206
+ customerName: o.customerName,
207
+ carrierName: o.carrierName,
208
+ deliveryDate: o.deliveryDate,
209
+ pickupDate: o.pickupDate,
210
+ pickupTime: o.pickupTime,
211
+ country: o.country,
212
+ cratesOnCart: o.cratesOnCart,
213
+ pickDate: o.deliveryDate ?? "",
214
+ printedCount: o.printedCount,
215
+ status: o.status,
216
+ })), onClose: () => setShowChecklist(false) }))] }));
217
+ }
@@ -9,5 +9,7 @@ export { PlanningAgendaPage } from "./components/afhandeling/PlanningAgendaPage"
9
9
  export { ControlePage } from "./components/afhandeling/ControlePage";
10
10
  export { AfhandelingSettingsCard } from "./components/settings/AfhandelingSettingsCard";
11
11
  export { VervoerdersSettingsCard } from "./components/settings/VervoerdersSettingsCard";
12
+ export { PickstationPage } from "./components/pickstation/PickstationPage";
13
+ export { KioskControle } from "./components/pickstation/KioskControle";
12
14
  export declare const floridayAfhandelingModule: FlowModule;
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAKxF,eAAO,MAAM,yBAAyB,EAAE,UAkBvC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAKvE,eAAO,MAAM,yBAAyB,EAAE,UAkBvC,CAAC"}
package/dist-lib/index.js CHANGED
@@ -9,6 +9,8 @@ export { PlanningAgendaPage } from "./components/afhandeling/PlanningAgendaPage"
9
9
  export { ControlePage } from "./components/afhandeling/ControlePage";
10
10
  export { AfhandelingSettingsCard } from "./components/settings/AfhandelingSettingsCard";
11
11
  export { VervoerdersSettingsCard } from "./components/settings/VervoerdersSettingsCard";
12
+ export { PickstationPage } from "./components/pickstation/PickstationPage";
13
+ export { KioskControle } from "./components/pickstation/KioskControle";
12
14
  import { AfhandelingSettingsCard } from "./components/settings/AfhandelingSettingsCard";
13
15
  import { VervoerdersSettingsCard } from "./components/settings/VervoerdersSettingsCard";
14
16
  export const floridayAfhandelingModule = {