@flowselections/pick-schermen-kwekers 1.0.41 → 1.0.44

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 (41) hide show
  1. package/dist-lib/components/PickstationsPage.js +1 -1
  2. package/dist-lib/components/pick/PickScherm.d.ts.map +1 -1
  3. package/dist-lib/components/pick/PickScherm.js +174 -36
  4. package/dist-lib/components/pick/QueueTable.d.ts +6 -1
  5. package/dist-lib/components/pick/QueueTable.d.ts.map +1 -1
  6. package/dist-lib/components/pick/QueueTable.js +44 -11
  7. package/dist-lib/components/pick/ReferentiedataBanner.js +1 -1
  8. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -1
  9. package/dist-lib/integrations/supabase/previewAuthStorage.js +22 -4
  10. package/dist-lib/integrations/supabase/types.d.ts +368 -0
  11. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  12. package/dist-lib/lib/__tests__/pick142.test.d.ts +2 -0
  13. package/dist-lib/lib/__tests__/pick142.test.d.ts.map +1 -0
  14. package/dist-lib/lib/__tests__/pick142.test.js +80 -0
  15. package/dist-lib/lib/__tests__/pick143.test.d.ts +2 -0
  16. package/dist-lib/lib/__tests__/pick143.test.d.ts.map +1 -0
  17. package/dist-lib/lib/__tests__/pick143.test.js +61 -0
  18. package/dist-lib/lib/pick142.d.ts +58 -0
  19. package/dist-lib/lib/pick142.d.ts.map +1 -0
  20. package/dist-lib/lib/pick142.js +235 -0
  21. package/dist-lib/lib/pick143.d.ts +31 -0
  22. package/dist-lib/lib/pick143.d.ts.map +1 -0
  23. package/dist-lib/lib/pick143.js +93 -0
  24. package/dist-lib/lib/pickApi.d.ts +13 -0
  25. package/dist-lib/lib/pickApi.d.ts.map +1 -1
  26. package/dist-lib/lib/pickApi.js +28 -5
  27. package/dist-lib/lib/pickCartResults.d.ts +1 -1
  28. package/dist-lib/lib/pickCartResults.d.ts.map +1 -1
  29. package/dist-lib/lib/pickCartResults.js +2 -2
  30. package/dist-lib/lib/pickI18n.js +6 -6
  31. package/dist-lib/lib/pickPrintJobText.js +2 -2
  32. package/dist-lib/lib/pickRowState.d.ts +1 -1
  33. package/dist-lib/lib/pickRowState.d.ts.map +1 -1
  34. package/dist-lib/lib/pickRowState.js +6 -2
  35. package/dist-lib/lib/pickTypes.d.ts +29 -1
  36. package/dist-lib/lib/pickTypes.d.ts.map +1 -1
  37. package/dist-lib/lib/pickTypes.js +42 -8
  38. package/dist-lib/lib/pickUiText.d.ts.map +1 -1
  39. package/dist-lib/lib/pickUiText.js +10 -0
  40. package/dist-lib/lib/shippingNoteStatus.js +2 -2
  41. package/package.json +1 -1
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Badge, Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
3
3
  import { AlertTriangle, Check, Eye, Loader2, Lock, Printer, RefreshCw, RotateCcw } from "lucide-react";
4
- import { bufferOrdersOf, cartColumnInfo, comparePickQueue, dedupeByUnit, displayCartCount, displayPageCount, sinceLabel, unitTitleOf } from "../../lib/pickTypes";
4
+ import { cartColumnInfo, comparePickQueue, dedupeByUnit, displayCartCount, displayPageCount, sinceLabel, unitTitleOf } from "../../lib/pickTypes";
5
5
  import { duplicateNameTag } from "../../lib/pickRowState";
6
+ import { CART_PLAN_MISMATCH_MESSAGE, formatSiteTime, orderNumbersLabel } from "../../lib/pick142";
7
+ import { isRowPrintable, rowWaitMessage, rowWaitOf } from "../../lib/pick143";
6
8
  import { getPickTranslator } from "../../lib/pickI18n";
7
9
  import { parseSentElsewhere } from "../../lib/pickApi";
8
10
  import { sentElsewhereMessage } from "../../lib/pickCartResults";
@@ -30,6 +32,28 @@ function printedSlipCount(item) {
30
32
  return printed;
31
33
  return displayCartCount(item.cart_count) ?? 1;
32
34
  }
35
+ /** Kar die nu niet geprint mag worden: karindeling klopt niet, of deelkar wacht. */
36
+ function blockedMessage(r, timeZone, item) {
37
+ if (r?.mismatch)
38
+ return CART_PLAN_MISMATCH_MESSAGE;
39
+ const wait = item ? rowWaitOf(item.payload) : null;
40
+ if (wait && !wait.printable)
41
+ return rowWaitMessage(wait, timeZone);
42
+ if (r?.notPrintable || r?.waitUntil)
43
+ return rowWaitMessage({ printable: false, until: r.waitUntil ?? null, reason: null }, timeZone);
44
+ return null;
45
+ }
46
+ /** Vier stappen per kar; alleen wat echt bekend is, wordt als gedaan getoond. */
47
+ function CartSteps({ printed, waiting }) {
48
+ const steps = [
49
+ { label: "Printen", done: printed },
50
+ { label: "Bij printer", done: printed && !waiting },
51
+ { label: "Gescand", done: false },
52
+ { label: "Gemeld bij Floriday", done: false },
53
+ ];
54
+ return (_jsx("ol", { className: "mt-3 flex flex-wrap items-center gap-1 text-xs", children: steps.map((step, i) => (_jsxs("li", { className: "flex items-center gap-1", children: [_jsx("span", { className: "rounded-full px-2 py-0.5 font-medium " +
55
+ (step.done ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"), children: step.label }), i < steps.length - 1 && _jsx("span", { className: "text-muted-foreground", children: "\u2192" })] }, step.label))) }));
56
+ }
33
57
  function priorityTone(priority, urgent) {
34
58
  if (urgent)
35
59
  return "bg-destructive text-destructive-foreground";
@@ -39,7 +63,7 @@ function priorityTone(priority, urgent) {
39
63
  return "bg-secondary text-secondary-foreground";
40
64
  return "bg-muted text-muted-foreground";
41
65
  }
42
- export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId, readinessById, waitingIds, onPick, onReprint, onPrintAll, onSelectPrinted, onMarkPrinted, onPreview, readOnly, t: translator, }) {
66
+ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId, readinessById, waitingIds, onPick, onReprint, onPrintAll, onSelectPrinted, onMarkPrinted, onPreview, readOnly, t: translator, siteTimeZone = null, }) {
43
67
  const t = translator ?? getPickTranslator("nl");
44
68
  // Volgorde identiek aan de keuze van "volgende uitprinten" (zie
45
69
  // comparePickQueue): niet-geprinte regels bovenaan, en bij gelijke stand op
@@ -50,7 +74,7 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
50
74
  .slice()
51
75
  .sort(comparePickQueue);
52
76
  const docById = new Map((Array.isArray(documentTypes) ? documentTypes : []).map((d) => [d.id, d]));
53
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden overflow-x-auto rounded-lg border md:block", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t("document") }), _jsx(TableHead, { children: t("order") }), _jsx(TableHead, { children: t("customer") }), _jsx(TableHead, { className: "text-right", children: t("lines") }), _jsx(TableHead, { className: "text-right", children: "Karren" }), _jsx(TableHead, { className: "text-right", children: "Pakbonnen" }), _jsx(TableHead, { className: "text-right", children: t("page") }), _jsx(TableHead, { children: t("status") }), _jsx(TableHead, { children: t("priority") }), _jsx(TableHead, { children: t("announced") }), _jsx(TableHead, { children: t("waiting") }), _jsx(TableHead, { className: "text-right", children: t("action") })] }) }), _jsxs(TableBody, { children: [safeItems.map((item) => {
77
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden overflow-x-auto rounded-lg border min-[1100px]:block", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t("document") }), _jsx(TableHead, { children: t("order") }), _jsx(TableHead, { children: t("customer") }), _jsx(TableHead, { className: "text-right", children: t("lines") }), _jsx(TableHead, { className: "text-right", children: "Karren" }), _jsx(TableHead, { className: "text-right", children: "Pakbonnen" }), _jsx(TableHead, { className: "text-right", children: t("page") }), _jsx(TableHead, { children: t("status") }), _jsx(TableHead, { children: t("priority") }), _jsx(TableHead, { children: t("announced") }), _jsx(TableHead, { children: t("waiting") }), _jsx(TableHead, { className: "sticky right-0 z-10 bg-background text-right shadow-[-8px_0_8px_-8px_hsl(var(--border))]", children: t("action") })] }) }), _jsxs(TableBody, { children: [safeItems.map((item) => {
54
78
  const printed = !!item.printed_at;
55
79
  const readiness = readinessById[item.id];
56
80
  const checking = !readiness || readiness.checking;
@@ -62,7 +86,7 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
62
86
  const doc = item.document_type_id ? docById.get(item.document_type_id) : undefined;
63
87
  const warnings = Array.isArray(item.warnings) ? item.warnings : [];
64
88
  const selectable = !!onSelectPrinted && !readOnly && !locked;
65
- return (_jsxs(TableRow, { tabIndex: selectable ? 0 : undefined, role: selectable ? "button" : undefined, "aria-label": selectable ? `Selecteer ${item.document_number}` : undefined, className: (locked || printed ? "opacity-60 " : "") + (selectable ? "cursor-pointer hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : ""), onClick: () => {
89
+ return (_jsxs(TableRow, { tabIndex: selectable ? 0 : undefined, role: selectable ? "button" : undefined, "aria-label": selectable ? `Selecteer ${item.document_number}` : undefined, className: (locked || printed || !isRowPrintable(item) ? "opacity-60 " : "") + (selectable ? "cursor-pointer hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : ""), onClick: () => {
66
90
  if (selectable)
67
91
  onSelectPrinted?.(item);
68
92
  }, onKeyDown: (event) => {
@@ -70,7 +94,7 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
70
94
  event.preventDefault();
71
95
  onSelectPrinted?.(item);
72
96
  }
73
- }, children: [_jsxs(TableCell, { className: "font-medium", children: [_jsxs("div", { className: "flex items-center gap-2", children: [unitTitleOf(item), dupTag && _jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: ["(", dupTag, ")"] }), replaced && (_jsx("span", { className: "rounded bg-destructive/10 px-1.5 py-0.5 text-xs font-semibold text-destructive", title: readiness?.reason ?? undefined, children: "Vervangen" })), replaced && readiness?.reason && (_jsx("span", { className: "text-xs font-normal text-destructive", children: readiness.reason })), waiting && (_jsx("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs font-semibold text-muted-foreground", children: "Wacht op printer" })), sentElsewhereLines(item).map((line) => (_jsx("span", { className: "text-xs font-normal text-muted-foreground", children: line }, line))), warnings.length > 0 && (_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive", "aria-label": t("warning") }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: doc?.name ?? "-" })] }), _jsx(TableCell, { children: bufferOrdersOf(item).length > 0 ? "" : item.order_number }), _jsx(TableCell, { children: item.customer_name }), _jsx(TableCell, { className: "text-right", children: item.line_count }), _jsx(TableCell, { className: "text-right", children: (() => {
97
+ }, children: [_jsxs(TableCell, { className: "font-medium", children: [_jsxs("div", { className: "flex items-center gap-2", children: [unitTitleOf(item), dupTag && _jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: ["(", dupTag, ")"] }), replaced && (_jsx("span", { className: "rounded bg-destructive/10 px-1.5 py-0.5 text-xs font-semibold text-destructive", title: readiness?.reason ?? undefined, children: "Vervangen" })), replaced && readiness?.reason && (_jsx("span", { className: "text-xs font-normal text-destructive", children: readiness.reason })), waiting && (_jsx("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs font-semibold text-muted-foreground", children: "Wacht op printer" })), sentElsewhereLines(item).map((line) => (_jsx("span", { className: "text-xs font-normal text-muted-foreground", children: line }, line))), warnings.length > 0 && (_jsx(AlertTriangle, { className: "h-4 w-4 text-destructive", "aria-label": t("warning") }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: doc?.name ?? "-" })] }), _jsx(TableCell, { children: orderNumbersLabel(item) }), _jsx(TableCell, { children: item.customer_name }), _jsx(TableCell, { className: "text-right", children: item.line_count }), _jsx(TableCell, { className: "text-right", children: (() => {
74
98
  const info = cartColumnInfo(item);
75
99
  return (_jsxs("div", { className: "flex flex-col items-end", children: [_jsx("span", { children: info.carts }), info.cartLabel && (_jsx("span", { className: "text-xs text-muted-foreground", children: info.cartLabel })), info.reason && (_jsx("span", { className: "text-xs text-muted-foreground", children: info.reason }))] }));
76
100
  })() }), _jsx(TableCell, { className: "text-right", children: printedSlipCount(item) ?? "—" }), _jsx(TableCell, { className: "text-right", children: displayPageCount(item.line_count) }), _jsxs(TableCell, { children: [_jsx(Badge, { variant: printed ? "secondary" : "default", children: printed ? t("statusPrinted") : t("statusToPrint") }), printed && (_jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: new Date(item.printed_at).toLocaleTimeString([], {
@@ -80,20 +104,20 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
80
104
  priorityTone(item.priority, item.is_urgent), children: item.is_urgent ? t("urgent") : item.priority }) }), _jsx(TableCell, { className: "whitespace-nowrap text-sm", children: new Date(item.announced_at).toLocaleTimeString(t.locale, {
81
105
  hour: "2-digit",
82
106
  minute: "2-digit",
83
- }) }), _jsx(TableCell, { className: "whitespace-nowrap text-sm", children: sinceLabel(item.announced_at) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [onPreview && (_jsx("button", { type: "button", "aria-label": "Voorbeeld " + item.document_number, title: "Voorbeeld " + item.document_number, className: "inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground", onClick: (e) => {
107
+ }) }), _jsx(TableCell, { className: "whitespace-nowrap text-sm", children: sinceLabel(item.announced_at) }), _jsx(TableCell, { className: "sticky right-0 z-10 bg-background text-right shadow-[-8px_0_8px_-8px_hsl(var(--border))]", children: _jsxs("div", { className: "flex items-center justify-end gap-1", children: [onPreview && (_jsx("button", { type: "button", "aria-label": "Voorbeeld " + item.document_number, title: "Voorbeeld " + item.document_number, className: "inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground", onClick: (e) => {
84
108
  e.stopPropagation();
85
109
  onPreview(item);
86
110
  }, children: _jsx(Eye, { className: "h-5 w-5" }) })), !printed && onMarkPrinted && (_jsx("button", { type: "button", "aria-label": "Markeer " + item.document_number + " als geprint", title: "Markeer als geprint (zonder opnieuw printen)", disabled: readOnly || busyId === item.id, className: "inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50", onClick: (e) => {
87
111
  e.stopPropagation();
88
112
  onMarkPrinted(item);
89
- }, children: _jsx(Check, { className: "h-5 w-5" }) })), printed ? (_jsxs(Button, { size: "sm", variant: "ghost", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
113
+ }, children: _jsx(Check, { className: "h-5 w-5" }) })), blockedMessage(readinessById[item.id], siteTimeZone, item) && !printed ? (_jsx("span", { className: "max-w-56 text-right text-xs font-medium text-destructive", children: blockedMessage(readinessById[item.id], siteTimeZone, item) })) : printed ? (_jsxs(Button, { size: "sm", variant: "ghost", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
90
114
  e.stopPropagation();
91
115
  (onPrintAll ?? onReprint ?? onPick)(item);
92
116
  }, children: [checking ? (_jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" })) : ready ? (_jsx(RotateCcw, { className: "mr-1 h-4 w-4" })) : (_jsx(RefreshCw, { className: "mr-1 h-4 w-4" })), replaced ? "Vervangen" : checking ? "Pakbon controleren" : ready ? t("print") : "Pakbon ophalen"] })) : locked ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Lock, { className: "h-3.5 w-3.5" }), " ", t("inProgress")] })) : (_jsxs(Button, { size: "sm", variant: "outline", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
93
117
  e.stopPropagation();
94
118
  (onPrintAll ?? onPick)(item);
95
119
  }, children: [checking ? (_jsx(Loader2, { className: "mr-1 h-4 w-4 animate-spin" })) : !ready ? (_jsx(RefreshCw, { className: "mr-1 h-4 w-4" })) : (_jsx(Printer, { className: "mr-1 h-4 w-4" })), replaced ? "Vervangen" : checking ? "Pakbon controleren" : ready ? t("print") : "Pakbon ophalen"] }))] }) })] }, item.id));
96
- }), safeItems.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 11, className: "py-10 text-center text-muted-foreground", children: t("emptyQueue") }) }))] })] }) }), _jsxs("div", { className: "space-y-3 md:hidden", children: [safeItems.map((item) => {
120
+ }), safeItems.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 11, className: "py-10 text-center text-muted-foreground", children: t("emptyQueue") }) }))] })] }) }), _jsxs("div", { className: "space-y-3 min-[1100px]:hidden", children: [safeItems.map((item) => {
97
121
  const printed = !!item.printed_at;
98
122
  const readiness = readinessById[item.id];
99
123
  const checking = !readiness || readiness.checking;
@@ -105,7 +129,7 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
105
129
  const doc = item.document_type_id ? docById.get(item.document_type_id) : undefined;
106
130
  const warnings = Array.isArray(item.warnings) ? item.warnings : [];
107
131
  const selectable = !!onSelectPrinted && !readOnly && !locked;
108
- return (_jsxs("div", { tabIndex: selectable ? 0 : undefined, role: selectable ? "button" : undefined, "aria-label": selectable ? `Selecteer ${item.document_number}` : undefined, className: "rounded-lg border bg-card p-4 " + (locked || printed ? "opacity-60 " : "") + (selectable ? "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : ""), onClick: () => {
132
+ return (_jsxs("div", { tabIndex: selectable ? 0 : undefined, role: selectable ? "button" : undefined, "aria-label": selectable ? `Selecteer ${item.document_number}` : undefined, className: "rounded-lg border bg-card p-4 " + (locked || printed || !isRowPrintable(item) ? "opacity-60 " : "") + (selectable ? "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" : ""), onClick: () => {
109
133
  if (selectable)
110
134
  onSelectPrinted?.(item);
111
135
  }, onKeyDown: (event) => {
@@ -120,13 +144,22 @@ export function QueueTable({ items, lockedIds, statuses, documentTypes, busyId,
120
144
  hour: "2-digit",
121
145
  minute: "2-digit",
122
146
  }) })), _jsx("span", { className: "rounded px-2 py-0.5 text-xs font-semibold " +
123
- priorityTone(item.priority, item.is_urgent), children: item.is_urgent ? t("urgent") : item.priority })] })] })] }), _jsxs("div", { className: "mt-2 min-w-0 space-y-0.5 text-sm", children: [bufferOrdersOf(item).length > 0 ? null : (_jsx("p", { className: "truncate text-foreground", children: item.order_number })), _jsx("p", { className: "truncate text-muted-foreground", children: item.customer_name })] }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [_jsxs("span", { children: [t("lines"), ": ", item.line_count] }), (() => {
147
+ priorityTone(item.priority, item.is_urgent), children: item.is_urgent ? t("urgent") : item.priority })] })] })] }), _jsxs("div", { className: "mt-2 min-w-0 space-y-0.5 text-sm", children: [orderNumbersLabel(item) && (_jsx("p", { className: "truncate text-foreground", children: orderNumbersLabel(item) })), _jsx("p", { className: "truncate text-muted-foreground", children: item.customer_name })] }), _jsxs("div", { className: "mt-2 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [_jsxs("span", { children: [t("lines"), ": ", item.line_count] }), (() => {
124
148
  const info = cartColumnInfo(item);
125
149
  return (_jsxs("span", { children: ["Karren: ", info.carts, info.cartLabel ? ` · ${info.cartLabel}` : "", info.reason ? ` · ${info.reason}` : ""] }));
126
150
  })(), _jsxs("span", { children: ["Pakbonnen: ", printedSlipCount(item) ?? "—"] }), _jsxs("span", { children: [t("page"), ": ", displayPageCount(item.line_count)] }), _jsxs("span", { children: [t("announced"), ":", " ", new Date(item.announced_at).toLocaleTimeString(t.locale, {
127
151
  hour: "2-digit",
128
152
  minute: "2-digit",
129
- })] }), _jsxs("span", { children: [t("waiting"), ": ", sinceLabel(item.announced_at)] })] }), _jsxs("div", { className: "mt-3", children: [printed ? (_jsxs(Button, { size: "lg", variant: "outline", className: "h-12 w-full", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
153
+ })] }), _jsxs("span", { children: [t("waiting"), ": ", sinceLabel(item.announced_at)] })] }), (() => {
154
+ const info = cartColumnInfo(item);
155
+ const payload = (item.payload && typeof item.payload === "object" ? item.payload : {});
156
+ const cartType = typeof payload["cartTypeName"] === "string" ? payload["cartTypeName"] : null;
157
+ const crates = Number(payload["crates"]);
158
+ return (_jsxs("div", { className: "mt-2 space-y-0.5", children: [info.cartLabel && (_jsx("p", { className: "text-xl font-bold text-foreground", children: [info.cartLabel, cartType].filter(Boolean).join(" · ") })), _jsx("p", { className: "text-sm text-muted-foreground", children: [
159
+ Number.isFinite(crates) && crates > 0 ? `${crates} fust` : null,
160
+ item.due_at ? `Vertrek ${formatSiteTime(item.due_at, siteTimeZone)}` : null,
161
+ ].filter(Boolean).join(" · ") })] }));
162
+ })(), _jsx(CartSteps, { printed: printed, waiting: waiting }), _jsxs("div", { className: "mt-3", children: [blockedMessage(readiness, siteTimeZone, item) && !printed ? (_jsx("p", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm font-medium text-destructive", children: blockedMessage(readiness, siteTimeZone, item) })) : printed ? (_jsxs(Button, { size: "lg", variant: "outline", className: "h-12 w-full", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
130
163
  e.stopPropagation();
131
164
  (onPrintAll ?? onReprint ?? onPick)(item);
132
165
  }, children: [checking ? (_jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" })) : ready ? (_jsx(RotateCcw, { className: "mr-2 h-4 w-4" })) : (_jsx(RefreshCw, { className: "mr-2 h-4 w-4" })), replaced ? "Vervangen" : checking ? "Pakbon controleren" : ready ? t("print") : "Pakbon ophalen"] })) : locked ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Lock, { className: "h-3.5 w-3.5" }), " ", t("inProgress")] })) : (_jsxs(Button, { size: "lg", className: "h-12 w-full", disabled: readOnly || busyId === item.id || checking || replaced, onClick: (e) => {
@@ -13,5 +13,5 @@ export function ReferentiedataBanner() {
13
13
  const problemen = referentieProblemen(data);
14
14
  if (problemen.length === 0)
15
15
  return null;
16
- return (_jsxs("div", { className: "space-y-3 rounded-lg border border-destructive/50 bg-destructive/5 p-4", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-destructive" }), _jsxs("div", { className: "space-y-1", children: [_jsx("h2", { className: "font-semibold text-destructive", children: "Referentiedata ontbreekt \u2014 er komt niets in de pickwachtrij" }), _jsx("ul", { className: "list-inside list-disc text-sm text-destructive", children: problemen.map((p) => (_jsx("li", { children: p }, p))) }), _jsx("p", { className: "text-sm text-muted-foreground", children: "De synchronisatie stopt hierop en pickstations blijven leeg." })] })] }), _jsx(Button, { variant: "outline", size: "sm", asChild: true, children: _jsx(Link, { to: "/instellingen", children: "Naar referentiedata-instellingen" }) })] }));
16
+ return (_jsxs("div", { className: "space-y-3 rounded-lg border border-destructive/50 bg-destructive/5 p-4", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-destructive" }), _jsxs("div", { className: "space-y-1", children: [_jsx("h2", { className: "font-semibold text-destructive", children: "Instellingen voor pickdocumenten ontbreken; er komen geen orders op het pickstation. Vraag kantoor dit te herstellen." }), _jsxs("details", { className: "text-sm text-muted-foreground", children: [_jsx("summary", { children: "Details voor beheer" }), _jsx("ul", { className: "list-inside list-disc", children: problemen.map((p) => (_jsx("li", { children: p }, p))) })] })] })] }), _jsx(Button, { variant: "outline", size: "sm", asChild: true, children: _jsx(Link, { to: "/instellingen", children: "Naar instellingen" }) })] }));
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"previewAuthStorage.d.ts","sourceRoot":"","sources":["../../../src/integrations/supabase/previewAuthStorage.ts"],"names":[],"mappings":"AAIA,wBAAgB,sBAAsB;mBA2Db,MAAM;mBAeZ,MAAM,SAAS,MAAM;sBASlB,MAAM;cAK3B"}
1
+ {"version":3,"file":"previewAuthStorage.d.ts","sourceRoot":"","sources":["../../../src/integrations/supabase/previewAuthStorage.ts"],"names":[],"mappings":"AAIA,wBAAgB,sBAAsB;mBA6Db,MAAM;mBAwBZ,MAAM,SAAS,MAAM;sBASlB,MAAM;cAM3B"}
@@ -61,21 +61,38 @@ export function brokeredPreviewStorage() {
61
61
  // The editor may not be listening yet at the first getItem, so retry once.
62
62
  let firstGet = true;
63
63
  const RETRY_DELAY = 250;
64
+ // Blocked third-party storage throws here; seeding must not break broker reads.
65
+ const readLocal = (key) => { try {
66
+ return localStorage.getItem(key);
67
+ }
68
+ catch {
69
+ return undefined;
70
+ } };
64
71
  return {
65
72
  getItem: async (key) => {
66
- let res = await request('lovable-preview-auth:get', key);
73
+ // Sent with GET and REMOVE so an editor that never cached this session can check or revoke it.
74
+ const local = readLocal(key);
75
+ let res = await request('lovable-preview-auth:get', key, local ?? undefined);
67
76
  if (!res && firstGet) {
68
77
  await new Promise((r) => setTimeout(r, RETRY_DELAY));
69
- res = await request('lovable-preview-auth:get', key);
78
+ res = await request('lovable-preview-auth:get', key, local ?? undefined);
70
79
  }
71
80
  firstGet = false;
72
81
  // '' is the logout tombstone: clear the local copy too so it can't resurrect if
73
82
  // the broker later goes silent. A null reply means never-synced -> keep local.
74
83
  if (res && res.ok && typeof res.value === 'string') {
75
84
  if (res.value === '') {
76
- localStorage.removeItem(key);
85
+ if (local !== undefined && readLocal(key) === local)
86
+ localStorage.removeItem(key);
77
87
  return null;
78
88
  }
89
+ // Seed this origin so a new tab, whose editor holds no session, stays signed in.
90
+ if (local === null && readLocal(key) === null) {
91
+ try {
92
+ localStorage.setItem(key, res.value);
93
+ }
94
+ catch { /* storage full: still return the editor's session */ }
95
+ }
79
96
  return res.value;
80
97
  }
81
98
  return localStorage.getItem(key);
@@ -92,8 +109,9 @@ export function brokeredPreviewStorage() {
92
109
  });
93
110
  },
94
111
  removeItem: (key) => {
112
+ const local = readLocal(key);
95
113
  localStorage.removeItem(key);
96
- return request('lovable-preview-auth:remove', key).then(() => undefined);
114
+ return request('lovable-preview-auth:remove', key, local ?? undefined).then(() => undefined);
97
115
  },
98
116
  };
99
117
  }