@flowselections/floriday-afhandeling-module 1.0.41 → 1.0.43

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 (86) hide show
  1. package/dist-lib/components/afhandeling/AutoProcessStatus.d.ts +3 -1
  2. package/dist-lib/components/afhandeling/AutoProcessStatus.d.ts.map +1 -1
  3. package/dist-lib/components/afhandeling/AutoProcessStatus.js +36 -3
  4. package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -1
  5. package/dist-lib/components/afhandeling/ControlePage.js +53 -13
  6. package/dist-lib/components/afhandeling/DagDetailDialog.d.ts +1 -1
  7. package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
  8. package/dist-lib/components/afhandeling/DagDetailDialog.js +409 -120
  9. package/dist-lib/components/afhandeling/PickAgendaView.d.ts.map +1 -1
  10. package/dist-lib/components/afhandeling/PickAgendaView.js +4 -4
  11. package/dist-lib/components/afhandeling/PickingPage.d.ts.map +1 -1
  12. package/dist-lib/components/afhandeling/PickingPage.js +1 -1
  13. package/dist-lib/components/afhandeling/ScanControleView.d.ts +2 -0
  14. package/dist-lib/components/afhandeling/ScanControleView.d.ts.map +1 -0
  15. package/dist-lib/components/afhandeling/ScanControleView.js +158 -0
  16. package/dist-lib/components/afhandeling/WeekAgendaView.js +1 -1
  17. package/dist-lib/hooks/useCartIndex.d.ts.map +1 -1
  18. package/dist-lib/hooks/useCartIndex.js +6 -1
  19. package/dist-lib/hooks/useEngineTasks.js +1 -1
  20. package/dist-lib/hooks/useKnownOrders.d.ts +11 -0
  21. package/dist-lib/hooks/useKnownOrders.d.ts.map +1 -0
  22. package/dist-lib/hooks/useKnownOrders.js +54 -0
  23. package/dist-lib/hooks/useOrderBuffers.d.ts +17 -0
  24. package/dist-lib/hooks/useOrderBuffers.d.ts.map +1 -0
  25. package/dist-lib/hooks/useOrderBuffers.js +53 -0
  26. package/dist-lib/hooks/useOrderPickDates.d.ts +10 -0
  27. package/dist-lib/hooks/useOrderPickDates.d.ts.map +1 -0
  28. package/dist-lib/hooks/useOrderPickDates.js +62 -0
  29. package/dist-lib/hooks/useOrderPlanning.d.ts +1 -3
  30. package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
  31. package/dist-lib/hooks/useOrderPlanning.js +9 -13
  32. package/dist-lib/hooks/usePickAgenda.d.ts +1 -6
  33. package/dist-lib/hooks/usePickAgenda.d.ts.map +1 -1
  34. package/dist-lib/hooks/usePickAgenda.js +62 -9
  35. package/dist-lib/hooks/usePickMode.d.ts +10 -0
  36. package/dist-lib/hooks/usePickMode.d.ts.map +1 -0
  37. package/dist-lib/hooks/usePickMode.js +31 -0
  38. package/dist-lib/index.d.ts +2 -0
  39. package/dist-lib/index.d.ts.map +1 -1
  40. package/dist-lib/index.js +19 -6
  41. package/dist-lib/integrations/supabase/auth-middleware.d.ts +3598 -1225
  42. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  43. package/dist-lib/integrations/supabase/client.server.d.ts +3598 -1225
  44. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  45. package/dist-lib/integrations/supabase/moduleClient.d.ts +3598 -1225
  46. package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -1
  47. package/dist-lib/integrations/supabase/types.d.ts +3645 -1246
  48. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  49. package/dist-lib/integrations/supabase/types.js +1 -0
  50. package/dist-lib/lib/afhandelingSettings.functions.d.ts +6076 -1330
  51. package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
  52. package/dist-lib/lib/carriers.functions.d.ts +15052 -3187
  53. package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
  54. package/dist-lib/lib/cartAssignments.functions.d.ts +15052 -3187
  55. package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
  56. package/dist-lib/lib/cartControl.functions.d.ts +55913 -6313
  57. package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
  58. package/dist-lib/lib/cartControl.functions.js +134 -10
  59. package/dist-lib/lib/deliveryNote.functions.d.ts +25891 -0
  60. package/dist-lib/lib/deliveryNote.functions.d.ts.map +1 -0
  61. package/dist-lib/lib/deliveryNote.functions.js +32 -0
  62. package/dist-lib/lib/engineLayouts.functions.d.ts +25889 -0
  63. package/dist-lib/lib/engineLayouts.functions.d.ts.map +1 -0
  64. package/dist-lib/lib/engineLayouts.functions.js +42 -0
  65. package/dist-lib/lib/floriday.functions.d.ts +28979 -712
  66. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  67. package/dist-lib/lib/floriday.functions.js +118 -343
  68. package/dist-lib/lib/logisticsEngine/reschedule.d.ts +17 -0
  69. package/dist-lib/lib/logisticsEngine/reschedule.d.ts.map +1 -1
  70. package/dist-lib/lib/logisticsEngine/reschedule.js +63 -0
  71. package/dist-lib/lib/orderFulfilment.functions.d.ts +25891 -0
  72. package/dist-lib/lib/orderFulfilment.functions.d.ts.map +1 -0
  73. package/dist-lib/lib/orderFulfilment.functions.js +35 -0
  74. package/dist-lib/lib/orderStatus.d.ts +10 -0
  75. package/dist-lib/lib/orderStatus.d.ts.map +1 -0
  76. package/dist-lib/lib/orderStatus.js +81 -0
  77. package/dist-lib/lib/pickDates.functions.d.ts +25896 -0
  78. package/dist-lib/lib/pickDates.functions.d.ts.map +1 -0
  79. package/dist-lib/lib/pickDates.functions.js +56 -0
  80. package/dist-lib/lib/pickMode.d.ts +14 -0
  81. package/dist-lib/lib/pickMode.d.ts.map +1 -0
  82. package/dist-lib/lib/pickMode.js +103 -0
  83. package/dist-lib/lib/printing.d.ts +3 -1
  84. package/dist-lib/lib/printing.d.ts.map +1 -1
  85. package/dist-lib/lib/printing.js +1 -0
  86. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  interface Props {
2
2
  salesOrderId: string;
3
+ /** Ordernummer (order_ref) — nodig om opnieuw in te plannen via de Engine. */
4
+ orderRef?: string | null;
3
5
  /** Datum waarop de auto-verwerking mag starten (targetPickDate). */
4
6
  autoProcessDate?: Date | null;
5
7
  /** Toon knop "Nu verwerken" ook als datum nog niet bereikt. */
@@ -7,6 +9,6 @@ interface Props {
7
9
  /** Compact = alleen badge, geen knoppen. */
8
10
  compact?: boolean;
9
11
  }
10
- export declare function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger, compact, }: Props): import("react").JSX.Element;
12
+ export declare function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, allowManualTrigger, compact, }: Props): import("react").JSX.Element;
11
13
  export {};
12
14
  //# sourceMappingURL=AutoProcessStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutoProcessStatus.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/AutoProcessStatus.tsx"],"names":[],"mappings":"AAUA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAeD,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,eAAe,EACf,kBAAyB,EACzB,OAAe,GAChB,EAAE,KAAK,+BAiJP"}
1
+ {"version":3,"file":"AutoProcessStatus.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/AutoProcessStatus.tsx"],"names":[],"mappings":"AAYA,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oEAAoE;IACpE,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAC9B,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAeD,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,kBAAyB,EACzB,OAAe,GAChB,EAAE,KAAK,+BAiLP"}
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useState } from "react";
3
+ import { useQueryClient } from "@tanstack/react-query";
3
4
  import { Badge, Button, toast } from "@flowselections/core";
4
5
  import { CheckCircle2, Clock, Loader2, PlayCircle, RefreshCw, AlertTriangle } from "lucide-react";
5
6
  import { autoProcessSalesOrder, fetchAutoProcessStatuses, } from "../../lib/floridayAutoProcess";
6
7
  import { supabase } from "../../integrations/supabase/moduleClient";
8
+ import { replanToNextDeliveryMoment } from "../../lib/logisticsEngine/reschedule";
7
9
  const NL_DATE = new Intl.DateTimeFormat("nl-NL", { day: "2-digit", month: "short" });
8
10
  function formatWaiting(date) {
9
11
  const today = new Date();
@@ -17,17 +19,20 @@ function formatWaiting(date) {
17
19
  return "Verwerkt morgen";
18
20
  return `Wacht tot ${NL_DATE.format(target)} (${diffDays} dagen)`;
19
21
  }
20
- export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger = true, compact = false, }) {
22
+ export function AutoProcessStatus({ salesOrderId, orderRef, autoProcessDate, allowManualTrigger = true, compact = false, }) {
21
23
  const [row, setRow] = useState(null);
22
24
  const [loading, setLoading] = useState(false);
25
+ const queryClient = useQueryClient();
23
26
  useEffect(() => {
24
27
  let cancelled = false;
25
28
  fetchAutoProcessStatuses([salesOrderId]).then((m) => {
26
29
  if (!cancelled)
27
30
  setRow(m.get(salesOrderId) ?? null);
28
31
  });
32
+ // Unieke kanaalnaam per instantie: dezelfde order kan meerdere keren in
33
+ // beeld staan en Supabase hergebruikt anders een al geabonneerd kanaal.
29
34
  const channel = supabase
30
- .channel(`auto-process-${salesOrderId}`)
35
+ .channel(`auto-process-${salesOrderId}-${Math.random().toString(36).slice(2)}`)
31
36
  .on("postgres_changes", {
32
37
  event: "*",
33
38
  schema: "public",
@@ -48,6 +53,34 @@ export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTr
48
53
  const handleProcess = async () => {
49
54
  setLoading(true);
50
55
  try {
56
+ if (orderRef) {
57
+ // Opnieuw inplannen op het eerstvolgende aflevermoment; de Engine
58
+ // bepaalt daarna zelf de pickdag en de bijbehorende taken.
59
+ const res = await replanToNextDeliveryMoment(orderRef);
60
+ if (!res.ok) {
61
+ toast.error(res.error ?? "Opnieuw inplannen mislukt");
62
+ }
63
+ else {
64
+ const d = res.moment
65
+ ? new Date(`${res.moment.date}T00:00:00`).toLocaleDateString("nl-NL")
66
+ : null;
67
+ toast.success(d
68
+ ? `Ingepland op ${d}${res.moment?.time ? ` om ${res.moment.time}` : ""}`
69
+ : "Order opnieuw ingepland");
70
+ // Direct verversen zodat de nieuwe leverdatum en de status meteen
71
+ // in beeld staan, precies zoals bij de andere bestellingen.
72
+ await Promise.all([
73
+ queryClient.invalidateQueries({ queryKey: ["logistics-pick-agenda"] }),
74
+ queryClient.invalidateQueries({ queryKey: ["engine", "tasks"] }),
75
+ queryClient.invalidateQueries({ queryKey: ["order-buffers"] }),
76
+ queryClient.invalidateQueries({ queryKey: ["floriday", "orders"] }),
77
+ queryClient.invalidateQueries({ queryKey: ["logistics-cart-index"] }),
78
+ queryClient.invalidateQueries({ queryKey: ["known-orders"] }),
79
+ ]);
80
+ await queryClient.refetchQueries({ queryKey: ["logistics-pick-agenda"], type: "active" });
81
+ }
82
+ return;
83
+ }
51
84
  const res = await autoProcessSalesOrder(salesOrderId);
52
85
  toast.success(res.status === "done"
53
86
  ? "Verwerkt — afleverbrief wordt aangemaakt"
@@ -99,5 +132,5 @@ export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTr
99
132
  return _jsx(_Fragment, { children: badge });
100
133
  const showRetry = status === "error";
101
134
  const showTrigger = allowManualTrigger && status !== "done" && status !== "acknowledging" && !loading;
102
- return (_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [badge, showTrigger ? (_jsx(Button, { size: "sm", variant: showRetry ? "outline" : "secondary", onClick: handleProcess, disabled: loading, children: showRetry ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-3 w-3 mr-1" }), " Opnieuw"] })) : (_jsxs(_Fragment, { children: [_jsx(PlayCircle, { className: "h-3 w-3 mr-1" }), " Nu verwerken"] })) })) : null] }));
135
+ return (_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [badge, showTrigger ? (_jsx(Button, { size: "sm", variant: showRetry ? "outline" : "secondary", onClick: handleProcess, disabled: loading, children: showRetry ? (_jsxs(_Fragment, { children: [_jsx(RefreshCw, { className: "h-3 w-3 mr-1" }), " Opnieuw"] })) : (_jsxs(_Fragment, { children: [_jsx(PlayCircle, { className: "h-3 w-3 mr-1" }), " ", orderRef ? "Nu inplannen" : "Nu verwerken"] })) })) : null] }));
103
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AA6HA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BAo1BpE"}
1
+ {"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AAkJA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BAu3BpE"}
@@ -2,25 +2,48 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useEffect, useMemo, useRef, useState } from "react";
3
3
  import { supabase } from "../../integrations/supabase/moduleClient";
4
4
  import { Button, Card, Checkbox, Dialog, DialogDescription, DialogTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Textarea, Badge, toast, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
5
- import { Printer, CheckCircle2, AlertTriangle, History, ChevronLeft, ChevronRight } from "lucide-react";
5
+ import { Printer, CheckCircle2, AlertTriangle, History, ChevronLeft, ChevronRight, ScanLine } from "lucide-react";
6
6
  import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
7
7
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
8
8
  import { useServerFn } from "@tanstack/react-start";
9
- import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, saveControlDraft, } from "../../lib/cartControl.functions";
9
+ import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, listDeliveredToday, saveControlDraft, } from "../../lib/cartControl.functions";
10
+ import { ScanControleView } from "./ScanControleView";
10
11
  import { renderControleLijstHtml } from "./ControleLijstPrint";
11
12
  import { printHtmlDocument, printFoutMelding } from "../../lib/printing";
13
+ function dayDiffFromToday(iso) {
14
+ const d = new Date(iso);
15
+ if (Number.isNaN(d.getTime()))
16
+ return null;
17
+ const today = new Date();
18
+ today.setHours(0, 0, 0, 0);
19
+ d.setHours(0, 0, 0, 0);
20
+ return Math.round((d.getTime() - today.getTime()) / 86400000);
21
+ }
22
+ /** "vandaag", "morgen", "over 3 dagen" of een korte datum. */
23
+ function relDayLabel(iso) {
24
+ const diff = dayDiffFromToday(iso);
25
+ const d = new Date(iso);
26
+ if (diff === null)
27
+ return iso;
28
+ if (diff === 0)
29
+ return "vandaag";
30
+ if (diff === 1)
31
+ return "morgen";
32
+ if (diff === -1)
33
+ return "gisteren";
34
+ if (diff > 1 && diff <= 7)
35
+ return `over ${diff} dagen`;
36
+ if (diff < -1)
37
+ return `${Math.abs(diff)} dagen geleden`;
38
+ return d.toLocaleDateString("nl-NL", { weekday: "short", day: "2-digit", month: "2-digit" });
39
+ }
12
40
  function fmtDate(iso) {
13
41
  if (!iso)
14
42
  return "—";
15
43
  const d = new Date(iso);
16
44
  if (Number.isNaN(d.getTime()))
17
45
  return iso;
18
- return d.toLocaleDateString("nl-NL", {
19
- weekday: "short",
20
- day: "2-digit",
21
- month: "2-digit",
22
- year: "numeric",
23
- });
46
+ return relDayLabel(iso);
24
47
  }
25
48
  function isTomorrowIso(iso) {
26
49
  if (!iso)
@@ -74,6 +97,7 @@ export function ControlePage({ onExit } = {}) {
74
97
  const fetchProposals = useServerFn(getControlRescheduleProposals);
75
98
  const submit = useServerFn(submitControlSession);
76
99
  const fetchDraft = useServerFn(getControlDraft);
100
+ const fetchDelivered = useServerFn(listDeliveredToday);
77
101
  const saveDraft = useServerFn(saveControlDraft);
78
102
  const cartsQ = useQuery({
79
103
  queryKey: ["control", "today"],
@@ -89,6 +113,13 @@ export function ControlePage({ onExit } = {}) {
89
113
  refetchOnMount: "always",
90
114
  refetchOnWindowFocus: true,
91
115
  });
116
+ const deliveredQ = useQuery({
117
+ queryKey: ["control", "delivered"],
118
+ queryFn: () => fetchDelivered(),
119
+ enabled: tab === "afgeleverd",
120
+ refetchOnMount: "always",
121
+ refetchOnWindowFocus: true,
122
+ });
92
123
  const draftQ = useQuery({
93
124
  queryKey: controlDraftQueryKey,
94
125
  queryFn: async () => (await fetchDraft()),
@@ -96,7 +127,9 @@ export function ControlePage({ onExit } = {}) {
96
127
  refetchOnMount: "always",
97
128
  refetchOnWindowFocus: true,
98
129
  });
99
- const carts = cartsQ.data?.carts ?? [];
130
+ // Karren die al zijn goedgekeurd (klaargezet/verzonden/geleverd) verdwijnen uit de controlelijst.
131
+ const APPROVED_CART_STATUSES = ["ready", "checked", "shipped", "delivered"];
132
+ const carts = (cartsQ.data?.carts ?? []).filter((c) => !APPROVED_CART_STATUSES.includes(String(c.status ?? "pending")));
100
133
  const currentDraftPayload = useMemo(() => {
101
134
  const nextStates = { ...cartStates };
102
135
  for (const cart of carts) {
@@ -408,6 +441,7 @@ export function ControlePage({ onExit } = {}) {
408
441
  setPage(pageCount);
409
442
  }, [pageCount, page]);
410
443
  const pagedCarts = useMemo(() => carts.slice((currentPage - 1) * pageSize, currentPage * pageSize), [carts, currentPage, pageSize]);
444
+ // Geen eigen hernummering meer: het karnummer komt uitsluitend uit de Engine.
411
445
  const pendingProposals = pendingProposal?.proposals ?? [];
412
446
  const pendingBlocked = pendingProposal?.blocked ?? [];
413
447
  const pendingNotReadyCount = pendingProposals.length + pendingBlocked.length;
@@ -465,13 +499,13 @@ export function ControlePage({ onExit } = {}) {
465
499
  finally {
466
500
  setPrintBezig(false);
467
501
  }
468
- }, children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), printBezig ? "Bezig met printen…" : "Controlelijst afdrukken"] }), _jsxs(Button, { onClick: runControl, disabled: submitM.isPending || proposalM.isPending || carts.length === 0 || tab !== "controle", children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), proposalM.isPending ? "Controleren…" : "Controle uitvoeren"] })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: tab === "controle" ? "default" : "outline", onClick: () => setTab("controle"), children: "Controle" }), _jsxs(Button, { variant: tab === "historie" ? "default" : "outline", onClick: () => setTab("historie"), children: [_jsx(History, { className: "h-4 w-4 mr-2" }), "Historie"] })] }), tab === "controle" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-3 items-center", children: [_jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Totaal karren vandaag" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.total })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Geprint" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.printed })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Aangevinkt" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.checked })] })] }), _jsxs(Card, { className: "p-0 overflow-hidden", children: [_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-12", children: _jsx(Checkbox, { checked: carts.length > 0 && carts.every((c) => checked.has(controlCartKey(c)))
502
+ }, children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), printBezig ? "Bezig met printen…" : "Controlelijst afdrukken"] }), _jsxs(Button, { onClick: runControl, disabled: submitM.isPending || proposalM.isPending || carts.length === 0 || tab !== "controle", children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), proposalM.isPending ? "Controleren…" : "Controle uitvoeren"] })] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: tab === "controle" ? "default" : "outline", onClick: () => setTab("controle"), children: "Controle" }), _jsxs(Button, { variant: tab === "scan" ? "default" : "outline", onClick: () => setTab("scan"), children: [_jsx(ScanLine, { className: "h-4 w-4 mr-2" }), "Scancontrole"] }), _jsxs(Button, { variant: tab === "afgeleverd" ? "default" : "outline", onClick: () => setTab("afgeleverd"), children: [_jsx(CheckCircle2, { className: "h-4 w-4 mr-2" }), "Afgeleverd"] }), _jsxs(Button, { variant: tab === "historie" ? "default" : "outline", onClick: () => setTab("historie"), children: [_jsx(History, { className: "h-4 w-4 mr-2" }), "Historie"] })] }), tab === "controle" && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-wrap gap-3 items-center", children: [_jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Totaal karren vandaag" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.total })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Geprint" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.printed })] }), _jsxs(Card, { className: "p-3", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Aangevinkt" }), _jsx("div", { className: "text-2xl font-semibold", children: stats.checked })] })] }), _jsxs(Card, { className: "p-0 overflow-hidden", children: [_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-12", children: _jsx(Checkbox, { checked: carts.length > 0 && carts.every((c) => checked.has(controlCartKey(c)))
469
503
  ? true
470
504
  : carts.some((c) => checked.has(controlCartKey(c)))
471
505
  ? "indeterminate"
472
- : false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Ophaaldatum" }), _jsx(TableHead, { children: "Uitgeprint" })] }) }), _jsxs(TableBody, { children: [cartsQ.isLoading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !cartsQ.isLoading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Geen karren om vandaag te controleren." }) })), pagedCarts.map((c) => {
506
+ : false, onCheckedChange: (v) => toggleAll(!!v) }) }), _jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Karnummer" }), _jsx(TableHead, { children: "Uitgeprint" })] }) }), _jsxs(TableBody, { children: [cartsQ.isLoading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !cartsQ.isLoading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 4, className: "text-center text-muted-foreground py-8", children: "Geen karren om vandaag te controleren." }) })), pagedCarts.map((c) => {
473
507
  const k = controlCartKey(c);
474
- return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }), _jsx(TableCell, { className: "font-mono font-semibold", children: (c.orderNumbers?.length ?? 0) > 0 ? (_jsx("div", { className: "flex flex-col gap-0.5", children: c.orderNumbers.map((n) => (_jsx("span", { children: n }, n))) })) : (c.orderNumber || "—") }), _jsx(TableCell, { children: fmtDate(c.pickupDate) }), _jsx(TableCell, { children: (c.printedToday ?? (c.printedCount ?? 0) > 0) ? (_jsx(Badge, { variant: "secondary", children: "Ja" })) : (_jsx(Badge, { variant: "outline", children: "Nee" })) })] }, k));
508
+ return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx(Checkbox, { checked: checked.has(k), onCheckedChange: (v) => toggle(k, !!v) }) }), _jsxs(TableCell, { className: "font-mono font-semibold", children: [c.orderNumber || "—", _jsxs("span", { className: "ml-2 text-muted-foreground font-normal", children: ["[", c.cartSeq, " - ", c.cartTotal ?? c.cartSeq, "]"] })] }), _jsx(TableCell, { className: "font-mono font-semibold", children: c.cartNumber ?? "—" }), _jsx(TableCell, { children: (c.printedToday ?? (c.printedCount ?? 0) > 0) ? (_jsx(Badge, { variant: "secondary", children: "Ja" })) : (_jsx(Badge, { variant: "outline", children: "Nee" })) })] }, k));
475
509
  })] })] }), carts.length > 0 && (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 border-t bg-muted/20 px-4 py-3 text-sm", children: [_jsxs("span", { className: "text-muted-foreground", children: [carts.length, " resultaten"] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-muted-foreground", children: "Resultaten per pagina" }), _jsxs(Select, { value: String(pageSize), onValueChange: (v) => {
476
510
  setPageSize(Number(v));
477
511
  setPage(1);
@@ -481,7 +515,7 @@ export function ControlePage({ onExit } = {}) {
481
515
  ? "Voortgang automatisch opgeslagen"
482
516
  : lastSavedRef.current && notes === lastSavedRef.current
483
517
  ? "Concept bewaard"
484
- : "" })] }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Bijzonderheden, afwijkingen\u2026", rows: 3 }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Wordt automatisch bewaard tot de controle definitief is goedgekeurd." })] })] })), tab === "historie" && _jsx(HistorieView, { loading: histQ.isLoading, sessions: histQ.data?.sessions ?? [] }), _jsx(Dialog, { open: !!result, onOpenChange: (v) => !v && setResult(null), children: _jsxs(ResponsiveDialogContent, { size: "md", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsx(DialogTitle, { children: "Resultaat controle" }), _jsxs(DialogDescription, { children: [result?.checkedCount, " klaar \u00B7 ", result?.rescheduledCount, " doorgeschoven \u00B7", " ", result?.blockedCount, " geblokkeerd"] })] }), _jsxs(ResponsiveDialogBody, { className: "space-y-4", children: [result?.blocked && result.blocked.length > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2 text-destructive font-medium", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: "De volgende karren kunnen niet automatisch worden doorgeschoven omdat hierdoor de planning of levering in gevaar komt." })] }), _jsx(BlockedTable, { blocked: result.blocked })] })), result?.rescheduled && result.rescheduled.length > 0 && (_jsxs("div", { className: "border rounded-md p-3", children: [_jsx("div", { className: "font-medium mb-2", children: "Doorgeschoven karren" }), _jsx("ul", { className: "text-sm space-y-1", children: result.rescheduled.map((r, i) => (_jsxs("li", { children: [_jsx("span", { className: "font-mono", children: r.cartNumber ?? "—" }), " \u2014", " ", r.customerName, " \u2192 nieuwe pickdatum", " ", _jsx("strong", { children: fmtDate(r.newPickDate) })] }, i))) })] }))] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { onClick: () => {
518
+ : "" })] }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), placeholder: "Bijzonderheden, afwijkingen\u2026", rows: 3 }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Wordt automatisch bewaard tot de controle definitief is goedgekeurd." })] })] })), tab === "scan" && _jsx(ScanControleView, {}), tab === "afgeleverd" && (_jsx(AfgeleverdView, { loading: deliveredQ.isLoading, carts: deliveredQ.data?.carts ?? [] })), tab === "historie" && _jsx(HistorieView, { loading: histQ.isLoading, sessions: histQ.data?.sessions ?? [] }), _jsx(Dialog, { open: !!result, onOpenChange: (v) => !v && setResult(null), children: _jsxs(ResponsiveDialogContent, { size: "md", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsx(DialogTitle, { children: "Resultaat controle" }), _jsxs(DialogDescription, { children: [result?.checkedCount, " klaar \u00B7 ", result?.rescheduledCount, " doorgeschoven \u00B7", " ", result?.blockedCount, " geblokkeerd"] })] }), _jsxs(ResponsiveDialogBody, { className: "space-y-4", children: [result?.blocked && result.blocked.length > 0 && (_jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 p-3 space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2 text-destructive font-medium", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: "De volgende karren kunnen niet automatisch worden doorgeschoven omdat hierdoor de planning of levering in gevaar komt." })] }), _jsx(BlockedTable, { blocked: result.blocked })] })), result?.rescheduled && result.rescheduled.length > 0 && (_jsxs("div", { className: "border rounded-md p-3", children: [_jsx("div", { className: "font-medium mb-2", children: "Doorgeschoven karren" }), _jsx("ul", { className: "text-sm space-y-1", children: result.rescheduled.map((r, i) => (_jsxs("li", { children: [_jsx("span", { className: "font-mono", children: r.cartNumber ?? "—" }), " \u2014", " ", r.customerName, " \u2192 nieuwe pickdatum", " ", _jsx("strong", { children: fmtDate(r.newPickDate) })] }, i))) })] }))] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { onClick: () => {
485
519
  setResult(null);
486
520
  if (onExit)
487
521
  onExit();
@@ -528,3 +562,9 @@ function SummaryTile({ label, value, tone = "default", }) {
528
562
  }
529
563
  // Silence unused Input import (may be used later); keep tree-shakeable
530
564
  void Input;
565
+ function AfgeleverdView({ loading, carts }) {
566
+ return (_jsx(Card, { className: "p-0 overflow-hidden", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Ordernummer" }), _jsx(TableHead, { children: "Karnummer" }), _jsx(TableHead, { children: "Gecontroleerd om" })] }) }), _jsxs(TableBody, { children: [loading && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 3, className: "text-center text-muted-foreground py-8", children: "Laden\u2026" }) })), !loading && carts.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 3, className: "text-center text-muted-foreground py-8", children: "Vandaag zijn er nog geen karren afgeleverd." }) })), carts.map((c, i) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-mono font-semibold", children: c.orderNumber || "—" }), _jsx(TableCell, { className: "font-mono", children: c.cartNumberLabel || "—" }), _jsx(TableCell, { children: new Date(c.deliveredAt).toLocaleTimeString("nl-NL", {
567
+ hour: "2-digit",
568
+ minute: "2-digit",
569
+ }) })] }, `${c.orderNumber ?? "?"}-${c.cartNumberLabel ?? i}-${i}`)))] })] }) }));
570
+ }
@@ -5,5 +5,5 @@ export interface DagDetailDialogProps {
5
5
  planned: PlannedOrder[];
6
6
  onOpenChange: (open: boolean) => void;
7
7
  }
8
- export declare function DagDetailDialog({ open, date, planned, onOpenChange }: DagDetailDialogProps): import("react").JSX.Element | null;
8
+ export declare function DagDetailDialog(props: DagDetailDialogProps): import("react").JSX.Element | null;
9
9
  //# sourceMappingURL=DagDetailDialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAsCjE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAID,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,oBAAoB,sCAiF1F"}
1
+ {"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAyEjE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAQD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,sCAG1D"}