@flowselections/floriday-afhandeling-module 1.0.31 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/components/afhandeling/AutoProcessStatus.js +1 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts +6 -6
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.js +73 -48
- package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControlePage.js +47 -14
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +48 -24
- package/dist-lib/components/afhandeling/VervoerdersPage.d.ts +8 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.js +17 -2
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +16 -5
- package/dist-lib/components/afhandeling/WerkplekWaarschuwing.d.ts +10 -0
- package/dist-lib/components/afhandeling/WerkplekWaarschuwing.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/WerkplekWaarschuwing.js +28 -0
- package/dist-lib/components/pickstation/PakbonTemplate.js +70 -70
- package/dist-lib/components/pickstation/printDocuments.d.ts +9 -2
- package/dist-lib/components/pickstation/printDocuments.d.ts.map +1 -1
- package/dist-lib/components/pickstation/printDocuments.js +8 -52
- package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/AfhandelingSettingsCard.js +12 -1
- package/dist-lib/hooks/useEngineTasks.js +1 -1
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +32 -14
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +695 -128
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +695 -128
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/{client.d.ts → moduleClient.d.ts} +697 -129
- package/dist-lib/integrations/supabase/moduleClient.d.ts.map +1 -0
- package/dist-lib/integrations/supabase/moduleClient.js +38 -0
- package/dist-lib/integrations/supabase/types.d.ts +727 -155
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +3 -0
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +1390 -256
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/carrierSignupMail.server.js +26 -26
- package/dist-lib/lib/carriers.functions.d.ts +3475 -640
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartAssignments.functions.d.ts +3475 -640
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +6950 -1280
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/deliveryNotePrint.d.ts +14 -6
- package/dist-lib/lib/deliveryNotePrint.d.ts.map +1 -1
- package/dist-lib/lib/deliveryNotePrint.js +61 -14
- package/dist-lib/lib/floriday.functions.d.ts +695 -128
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/floridayAutoProcess.js +1 -1
- package/dist-lib/lib/logisticsEngine/capacity.js +1 -1
- package/dist-lib/lib/logisticsEngine/emitQueue.d.ts +20 -0
- package/dist-lib/lib/logisticsEngine/emitQueue.d.ts.map +1 -0
- package/dist-lib/lib/logisticsEngine/emitQueue.js +88 -0
- package/dist-lib/lib/logisticsEngine/engine.js +1 -1
- package/dist-lib/lib/logisticsEngine/reschedule.js +1 -1
- package/dist-lib/lib/logisticsEngine/staffPlanning.js +1 -1
- package/dist-lib/lib/printing.d.ts +56 -0
- package/dist-lib/lib/printing.d.ts.map +1 -0
- package/dist-lib/lib/printing.js +209 -0
- package/package.json +3 -7
- package/dist-lib/integrations/supabase/auth-attacher.d.ts +0 -2
- package/dist-lib/integrations/supabase/auth-attacher.d.ts.map +0 -1
- package/dist-lib/integrations/supabase/auth-attacher.js +0 -12
- package/dist-lib/integrations/supabase/client.d.ts.map +0 -1
- package/dist-lib/integrations/supabase/client.js +0 -13
|
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
|
|
|
3
3
|
import { Badge, Button, toast } from "@flowselections/core";
|
|
4
4
|
import { CheckCircle2, Clock, Loader2, PlayCircle, RefreshCw, AlertTriangle } from "lucide-react";
|
|
5
5
|
import { autoProcessSalesOrder, fetchAutoProcessStatuses, } from "../../lib/floridayAutoProcess";
|
|
6
|
-
import { supabase } from "../../integrations/supabase/
|
|
6
|
+
import { supabase } from "../../integrations/supabase/moduleClient";
|
|
7
7
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { day: "2-digit", month: "short" });
|
|
8
8
|
function formatWaiting(date) {
|
|
9
9
|
const today = new Date();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ControlCart } from "../../lib/cartControl.functions";
|
|
2
2
|
import { type PickstationLang } from "../../lib/pickstationI18n";
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Rendert de controlelijst als losstaande HTML-pagina (A4 portrait).
|
|
5
|
+
* De HTML gaat naar de printwachtrij van de Layout maker; er wordt
|
|
6
|
+
* geen browser-printdialoog meer gebruikt.
|
|
7
|
+
*/
|
|
8
|
+
export declare function renderControleLijstHtml(carts: ControlCart[], lang?: PickstationLang): string;
|
|
9
9
|
//# sourceMappingURL=ControleLijstPrint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAuCnC;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,WAAW,EAAE,EACpB,IAAI,GAAE,eAAsB,GAC3B,MAAM,CAoGR"}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect } from "react";
|
|
3
|
-
import { createPortal } from "react-dom";
|
|
4
|
-
import { Button } from "@flowselections/core";
|
|
5
|
-
import { X, Printer } from "lucide-react";
|
|
6
1
|
import { countryCode } from "../../lib/countries";
|
|
7
2
|
import { getPrintDict, PICKSTATION_LOCALE, } from "../../lib/pickstationI18n";
|
|
8
3
|
const DAY_ABBR_BY_LANG = {
|
|
@@ -28,19 +23,20 @@ function computeKlaarzet(cart, lang) {
|
|
|
28
23
|
const time = `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
29
24
|
return { label: `${day} - ${time}`, sortKey: d.getTime() };
|
|
30
25
|
}
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
function esc(value) {
|
|
27
|
+
return String(value ?? "")
|
|
28
|
+
.replace(/&/g, "&")
|
|
29
|
+
.replace(/</g, "<")
|
|
30
|
+
.replace(/>/g, ">");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Rendert de controlelijst als losstaande HTML-pagina (A4 portrait).
|
|
34
|
+
* De HTML gaat naar de printwachtrij van de Layout maker; er wordt
|
|
35
|
+
* geen browser-printdialoog meer gebruikt.
|
|
36
|
+
*/
|
|
37
|
+
export function renderControleLijstHtml(carts, lang = "nl") {
|
|
33
38
|
const t = getPrintDict(lang);
|
|
34
39
|
const locale = PICKSTATION_LOCALE[lang] ?? "nl-NL";
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
const timer = setTimeout(() => window.print(), 300);
|
|
37
|
-
const handleAfterPrint = () => onClose();
|
|
38
|
-
window.addEventListener("afterprint", handleAfterPrint);
|
|
39
|
-
return () => {
|
|
40
|
-
clearTimeout(timer);
|
|
41
|
-
window.removeEventListener("afterprint", handleAfterPrint);
|
|
42
|
-
};
|
|
43
|
-
}, [onClose]);
|
|
44
40
|
const statusLabel = (status, printedCount) => {
|
|
45
41
|
switch (status) {
|
|
46
42
|
case "not_printed": return t.statusNotPrinted;
|
|
@@ -58,7 +54,7 @@ export function ControleLijstPrint({ carts, onClose, lang = "nl", }) {
|
|
|
58
54
|
month: "long",
|
|
59
55
|
year: "numeric",
|
|
60
56
|
});
|
|
61
|
-
const
|
|
57
|
+
const sorted = carts
|
|
62
58
|
.map((cart) => ({ cart, klaarzet: computeKlaarzet(cart, lang) }))
|
|
63
59
|
.sort((a, b) => {
|
|
64
60
|
if (a.klaarzet.sortKey !== b.klaarzet.sortKey) {
|
|
@@ -72,35 +68,64 @@ export function ControleLijstPrint({ carts, onClose, lang = "nl", }) {
|
|
|
72
68
|
const bn = b.cart.cartNumber ?? "\uFFFF";
|
|
73
69
|
return an.localeCompare(bn);
|
|
74
70
|
});
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
71
|
+
const rows = sorted.length
|
|
72
|
+
? sorted
|
|
73
|
+
.map(({ cart: c, klaarzet }) => `
|
|
74
|
+
<tr>
|
|
75
|
+
<td class="mono bold">${esc(c.cartNumber ?? "—")}</td>
|
|
76
|
+
<td class="right">${esc(c.cratesOnCart ?? "—")}</td>
|
|
77
|
+
<td class="bold">${esc(countryCode(c.country) ?? c.country ?? "—")}</td>
|
|
78
|
+
<td class="bold">${esc(klaarzet.label)}</td>
|
|
79
|
+
<td>${esc(statusLabel(c.status, c.printedCount))}</td>
|
|
80
|
+
</tr>`)
|
|
81
|
+
.join("")
|
|
82
|
+
: `<tr><td colspan="5" class="empty">${esc(t.noCartsToday)}</td></tr>`;
|
|
83
|
+
return `<!DOCTYPE html>
|
|
84
|
+
<html lang="${esc(lang)}">
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="utf-8" />
|
|
87
|
+
<title>${esc(t.checklistTitle)}</title>
|
|
88
|
+
<style>
|
|
89
|
+
@page { size: A4 portrait; margin: 12mm; }
|
|
90
|
+
body { font-family: Arial, Helvetica, sans-serif; color: #000; margin: 0; }
|
|
91
|
+
h1 { font-size: 20px; margin: 0; }
|
|
92
|
+
.head { display: flex; align-items: baseline; justify-content: space-between;
|
|
93
|
+
border-bottom: 1px solid #000; padding-bottom: 6px; margin-bottom: 12px; }
|
|
94
|
+
.total { font-size: 12px; margin-bottom: 10px; }
|
|
95
|
+
table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
|
96
|
+
th { text-align: left; border-bottom: 1px solid #000; padding: 3px 6px 3px 0; }
|
|
97
|
+
td { border-bottom: 1px solid #ccc; padding: 6px 6px 6px 0; white-space: nowrap; }
|
|
98
|
+
td.right, th.right { text-align: right; }
|
|
99
|
+
.mono { font-family: "Courier New", monospace; }
|
|
100
|
+
.bold { font-weight: 700; }
|
|
101
|
+
.empty { text-align: center; color: #666; padding: 24px 0; border: none; }
|
|
102
|
+
.sign { margin-top: 24px; font-size: 11px; }
|
|
103
|
+
.sign div { margin-top: 8px; }
|
|
104
|
+
.line { display: inline-block; border-bottom: 1px solid #000; width: 220px; }
|
|
105
|
+
tr { page-break-inside: avoid; }
|
|
106
|
+
thead { display: table-header-group; }
|
|
107
|
+
</style>
|
|
108
|
+
</head>
|
|
109
|
+
<body>
|
|
110
|
+
<div class="head"><h1>${esc(t.checklistTitle)}</h1><div>${esc(today)}</div></div>
|
|
111
|
+
<div class="total">${esc(t.totalCarts)}: <strong>${carts.length}</strong></div>
|
|
112
|
+
<table>
|
|
113
|
+
<thead>
|
|
114
|
+
<tr>
|
|
115
|
+
<th>${esc(t.colKarnr)}</th>
|
|
116
|
+
<th class="right">${esc(t.colFusten)}</th>
|
|
117
|
+
<th>${esc(t.colLand)}</th>
|
|
118
|
+
<th>${esc(t.colKlaarzetten)}</th>
|
|
119
|
+
<th>${esc(t.colStatus)}</th>
|
|
120
|
+
</tr>
|
|
121
|
+
</thead>
|
|
122
|
+
<tbody>${rows}</tbody>
|
|
123
|
+
</table>
|
|
124
|
+
<div class="sign">
|
|
125
|
+
<div>${esc(t.checkedBy)}: <span class="line"></span></div>
|
|
126
|
+
<div>${esc(t.dateTime)}: <span class="line"></span></div>
|
|
127
|
+
<div>${esc(t.signature)}: <span class="line"></span></div>
|
|
128
|
+
</div>
|
|
129
|
+
</body>
|
|
130
|
+
</html>`;
|
|
106
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ControlePage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControlePage.tsx"],"names":[],"mappings":"AAoHA,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CAAO,+BA2zBpE"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { supabase } from "../../integrations/supabase/
|
|
4
|
-
import { Button, Card, Checkbox, Dialog, DialogDescription, DialogTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Textarea, Badge, toast, } from "@flowselections/core";
|
|
5
|
-
import { Printer, CheckCircle2, AlertTriangle, History } from "lucide-react";
|
|
3
|
+
import { supabase } from "../../integrations/supabase/moduleClient";
|
|
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";
|
|
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
9
|
import { getTodaysControlCarts, getControlRescheduleProposals, submitControlSession, listControlHistory, getControlSessionDetail, getControlDraft, saveControlDraft, } from "../../lib/cartControl.functions";
|
|
10
|
-
import {
|
|
10
|
+
import { renderControleLijstHtml } from "./ControleLijstPrint";
|
|
11
|
+
import { printHtmlDocument, printFoutMelding } from "../../lib/printing";
|
|
12
|
+
import { WerkplekWaarschuwing, useWerkplek } from "./WerkplekWaarschuwing";
|
|
11
13
|
function fmtDate(iso) {
|
|
12
14
|
if (!iso)
|
|
13
15
|
return "—";
|
|
@@ -60,7 +62,8 @@ export function ControlePage({ onExit } = {}) {
|
|
|
60
62
|
const [notes, setNotes] = useState("");
|
|
61
63
|
const [checked, setChecked] = useState(new Set());
|
|
62
64
|
const [cartStates, setCartStates] = useState({});
|
|
63
|
-
const [
|
|
65
|
+
const [printBezig, setPrintBezig] = useState(false);
|
|
66
|
+
const werkplek = useWerkplek();
|
|
64
67
|
const [result, setResult] = useState(null);
|
|
65
68
|
const [pendingProposal, setPendingProposal] = useState(null);
|
|
66
69
|
const [confirmApproval, setConfirmApproval] = useState(null);
|
|
@@ -368,6 +371,16 @@ export function ControlePage({ onExit } = {}) {
|
|
|
368
371
|
const checkedCount = carts.filter((c) => checked.has(controlCartKey(c))).length;
|
|
369
372
|
return { total, printed, checked: checkedCount };
|
|
370
373
|
}, [carts, checked]);
|
|
374
|
+
// Paginering
|
|
375
|
+
const [pageSize, setPageSize] = useState(20);
|
|
376
|
+
const [page, setPage] = useState(1);
|
|
377
|
+
const pageCount = Math.max(1, Math.ceil(carts.length / pageSize));
|
|
378
|
+
const currentPage = Math.min(page, pageCount);
|
|
379
|
+
useEffect(() => {
|
|
380
|
+
if (page > pageCount)
|
|
381
|
+
setPage(pageCount);
|
|
382
|
+
}, [pageCount, page]);
|
|
383
|
+
const pagedCarts = useMemo(() => carts.slice((currentPage - 1) * pageSize, currentPage * pageSize), [carts, currentPage, pageSize]);
|
|
371
384
|
const pendingProposals = pendingProposal?.proposals ?? [];
|
|
372
385
|
const pendingBlocked = pendingProposal?.blocked ?? [];
|
|
373
386
|
const pendingNotReadyCount = pendingProposals.length + pendingBlocked.length;
|
|
@@ -403,20 +416,40 @@ export function ControlePage({ onExit } = {}) {
|
|
|
403
416
|
supabase.removeChannel(channel);
|
|
404
417
|
};
|
|
405
418
|
}, [qc]);
|
|
406
|
-
return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Controle karren" }), _jsxs("p", { className: "text-sm text-muted-foreground", children: ["Dagelijkse eindcontrole \u2014 vandaag ", new Date().toLocaleDateString("nl-NL")] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline",
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
419
|
+
return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsx(WerkplekWaarschuwing, { werkplek: werkplek }), _jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Controle karren" }), _jsxs("p", { className: "text-sm text-muted-foreground", children: ["Dagelijkse eindcontrole \u2014 vandaag ", new Date().toLocaleDateString("nl-NL")] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", disabled: !werkplek || printBezig || carts.length === 0, onClick: async () => {
|
|
420
|
+
setPrintBezig(true);
|
|
421
|
+
try {
|
|
422
|
+
await printHtmlDocument({
|
|
423
|
+
documenttype: "controlelijst",
|
|
424
|
+
documentnaam: `CTRL-${new Date().toISOString().slice(0, 10)}`,
|
|
425
|
+
html: renderControleLijstHtml(carts, "nl"),
|
|
426
|
+
papierformaat: "A4",
|
|
427
|
+
});
|
|
428
|
+
toast.success("Controlelijst naar de printer gestuurd.");
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
toast.error(printFoutMelding(err));
|
|
432
|
+
}
|
|
433
|
+
finally {
|
|
434
|
+
setPrintBezig(false);
|
|
435
|
+
}
|
|
436
|
+
}, 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)))
|
|
437
|
+
? true
|
|
438
|
+
: carts.some((c) => checked.has(controlCartKey(c)))
|
|
439
|
+
? "indeterminate"
|
|
440
|
+
: 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) => {
|
|
441
|
+
const k = controlCartKey(c);
|
|
442
|
+
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.printedCount ?? 0) > 0 ? (_jsx(Badge, { variant: "secondary", children: "Ja" })) : (_jsx(Badge, { variant: "outline", children: "Nee" })) })] }, k));
|
|
443
|
+
})] })] }), 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) => {
|
|
444
|
+
setPageSize(Number(v));
|
|
445
|
+
setPage(1);
|
|
446
|
+
}, children: [_jsx(SelectTrigger, { className: "h-8 w-[80px]", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: [10, 20, 50, 100].map((n) => (_jsx(SelectItem, { value: String(n), children: n }, n))) })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "outline", size: "icon", className: "h-8 w-8", "aria-label": "Vorige pagina", disabled: currentPage <= 1, onClick: () => setPage((p) => Math.max(1, p - 1)), children: _jsx(ChevronLeft, { className: "h-4 w-4" }) }), _jsxs("span", { className: "tabular-nums", children: [currentPage, " / ", pageCount] }), _jsx(Button, { variant: "outline", size: "icon", className: "h-8 w-8", "aria-label": "Volgende pagina", disabled: currentPage >= pageCount, onClick: () => setPage((p) => Math.min(pageCount, p + 1)), children: _jsx(ChevronRight, { className: "h-4 w-4" }) })] })] })] }))] }), _jsxs("div", { className: "max-w-xl", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { className: "text-sm font-medium", children: "Opmerkingen bij deze controle" }), _jsx("span", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: savingState === "saving"
|
|
414
447
|
? "Opslaan…"
|
|
415
448
|
: savingState === "saved"
|
|
416
449
|
? "Voortgang automatisch opgeslagen"
|
|
417
450
|
: lastSavedRef.current && notes === lastSavedRef.current
|
|
418
451
|
? "Concept bewaard"
|
|
419
|
-
: "" })] }), _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 ?? [] }),
|
|
452
|
+
: "" })] }), _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: () => {
|
|
420
453
|
setResult(null);
|
|
421
454
|
if (onExit)
|
|
422
455
|
onExit();
|
|
@@ -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;AAwCjE,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;
|
|
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;AAwCjE,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;AAWD,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,oBAAoB,sCAiF1F"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
@@ -7,8 +7,8 @@ import { CalendarClock, ChevronDown, ChevronRight, Printer, Users } from "lucide
|
|
|
7
7
|
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
8
8
|
import { isSameDay } from "../../lib/pickDate";
|
|
9
9
|
import { getOrderLines, } from "../../lib/cartAssignments.functions";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { printLayoutDocument, printFoutMelding } from "../../lib/printing";
|
|
11
|
+
import { WerkplekWaarschuwing, useWerkplek } from "./WerkplekWaarschuwing";
|
|
12
12
|
import { printDeliveryNotesMerged } from "../../lib/deliveryNotePrint";
|
|
13
13
|
import { AutoProcessStatus } from "./AutoProcessStatus";
|
|
14
14
|
import { CapacityWarning } from "./CapacityWarning";
|
|
@@ -18,6 +18,11 @@ import { VerzetOrderDialog } from "./VerzetOrderDialog";
|
|
|
18
18
|
import { setPickDay } from "../../lib/logisticsEngine/reschedule";
|
|
19
19
|
import { clearDayStaffPlan, computeCapacity, getDayStaffPlan, getEngineStaffDefaults, setDayStaffPlan, toDateKey, } from "../../lib/logisticsEngine/staffPlanning";
|
|
20
20
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { dateStyle: "full" });
|
|
21
|
+
/** Eén melding per dagdialoog zolang de werkplek niet is ingesteld. */
|
|
22
|
+
function DagWerkplekBanner() {
|
|
23
|
+
const werkplek = useWerkplek();
|
|
24
|
+
return _jsx(WerkplekWaarschuwing, { werkplek: werkplek });
|
|
25
|
+
}
|
|
21
26
|
export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
22
27
|
if (!date)
|
|
23
28
|
return null;
|
|
@@ -60,7 +65,7 @@ export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
|
60
65
|
runningIdx += a.cartCount;
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsxs(ResponsiveDialogBody, { children: [_jsx(DayCapacityWarning, { date: date }), _jsx(BezettingCard, { date: date, cartsToday: cartRows.length }), _jsxs(Tabs, { defaultValue: "bestellingen", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows }) })] })] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Sluiten" }) })] }) }));
|
|
68
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsxs(ResponsiveDialogBody, { children: [_jsx(DagWerkplekBanner, {}), _jsx(DayCapacityWarning, { date: date }), _jsx(BezettingCard, { date: date, cartsToday: cartRows.length }), _jsxs(Tabs, { defaultValue: "bestellingen", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows }) })] })] }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Sluiten" }) })] }) }));
|
|
64
69
|
}
|
|
65
70
|
function BezettingCard({ date, cartsToday }) {
|
|
66
71
|
const queryClient = useQueryClient();
|
|
@@ -147,6 +152,7 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
147
152
|
const [open, setOpen] = useState(false);
|
|
148
153
|
const [printing, setPrinting] = useState(false);
|
|
149
154
|
const [verzetOpen, setVerzetOpen] = useState(false);
|
|
155
|
+
const werkplek = useWerkplek();
|
|
150
156
|
const source = p.order.source;
|
|
151
157
|
const fetchLines = useServerFn(getOrderLines);
|
|
152
158
|
const linesQuery = useQuery({
|
|
@@ -180,22 +186,36 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
180
186
|
unit: null,
|
|
181
187
|
}));
|
|
182
188
|
let printed = 0;
|
|
189
|
+
let pakbonFailed = 0;
|
|
183
190
|
for (let idx = 0; idx < cartTotal; idx++) {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
191
|
+
const cartNumber = `${p.order.orderNumber}-${String(idx + 1).padStart(2, "0")}`;
|
|
192
|
+
try {
|
|
193
|
+
// Centrale pakbonlayout uit de Layout maker; de wachtrij kiest
|
|
194
|
+
// zelf de actieve layout en de bijbehorende printer.
|
|
195
|
+
await printLayoutDocument({
|
|
196
|
+
documenttype: "pakbon",
|
|
197
|
+
documentnaam: `PAK-${p.order.orderNumber}-${String(idx + 1).padStart(2, "0")}`,
|
|
198
|
+
payload: {
|
|
199
|
+
order: {
|
|
200
|
+
id: p.order.id,
|
|
201
|
+
orderNumber: p.order.orderNumber,
|
|
202
|
+
customerName: p.order.customerName,
|
|
203
|
+
country: p.order.country ?? null,
|
|
204
|
+
deliveryDate: p.order.deliveryDate,
|
|
205
|
+
pickDate: pickDateIso,
|
|
206
|
+
cartIndex: idx + 1,
|
|
207
|
+
cartTotal,
|
|
208
|
+
cartNumber,
|
|
209
|
+
lines: pakbonLines,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
printed++;
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
pakbonFailed++;
|
|
217
|
+
console.warn("[print-all] pakbon mislukt", cartNumber, err);
|
|
218
|
+
}
|
|
199
219
|
}
|
|
200
220
|
let deliveryOk = 0;
|
|
201
221
|
let deliveryFailed = 0;
|
|
@@ -219,14 +239,18 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
219
239
|
const parts = [`${printed} pakbon${printed === 1 ? "" : "nen"}`];
|
|
220
240
|
if (deliveryOk > 0)
|
|
221
241
|
parts.push(`${deliveryOk} afleverbrief`);
|
|
222
|
-
|
|
242
|
+
if (printed > 0 || deliveryOk > 0) {
|
|
243
|
+
toast.success(`Documenten geprint — ${parts.join(", ")}.`);
|
|
244
|
+
}
|
|
245
|
+
if (pakbonFailed > 0) {
|
|
246
|
+
toast.error(`${pakbonFailed} pakbon kon niet worden geprint.`);
|
|
247
|
+
}
|
|
223
248
|
if (deliveryFailed > 0) {
|
|
224
|
-
toast.error(`${deliveryFailed} afleverbrief kon niet worden
|
|
249
|
+
toast.error(`${deliveryFailed} afleverbrief kon niet worden geprint.`);
|
|
225
250
|
}
|
|
226
251
|
}
|
|
227
252
|
catch (err) {
|
|
228
|
-
|
|
229
|
-
toast.error(msg);
|
|
253
|
+
toast.error(printFoutMelding(err));
|
|
230
254
|
console.error("[print-all]", err);
|
|
231
255
|
}
|
|
232
256
|
finally {
|
|
@@ -243,7 +267,7 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
243
267
|
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
244
268
|
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
245
269
|
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId })) : null;
|
|
246
|
-
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing, title: "Alle pakbonnen en afleverbrieven van deze bestelling afdrukken", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), printing ? "Bezig…" : "Alle documenten afdrukken"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: (e) => {
|
|
270
|
+
})(), _jsxs(Button, { size: "sm", variant: "outline", onClick: handlePrintAll, disabled: printing || !werkplek, title: "Alle pakbonnen en afleverbrieven van deze bestelling afdrukken", children: [_jsx(Printer, { className: "mr-1 h-3.5 w-3.5" }), printing ? "Bezig…" : "Alle documenten afdrukken"] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: (e) => {
|
|
247
271
|
e.stopPropagation();
|
|
248
272
|
setVerzetOpen(true);
|
|
249
273
|
}, title: "Ophaaldag of ophaaltijd van deze order wijzigen", children: [_jsx(CalendarClock, { className: "mr-1 h-3.5 w-3.5" }), "Verzetten"] })] })] }), _jsx(VerzetOrderDialog, { open: verzetOpen, orderRef: p.order.orderNumber, carrierTarget: {
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Bewerken gebeurt via een searchparam (?id=<uuid>) i.p.v. een dynamisch
|
|
3
|
+
* URL-segment, zodat het ook werkt in hosts/shells die alleen statische
|
|
4
|
+
* module-routes registreren.
|
|
5
|
+
*/
|
|
6
|
+
export declare function VervoerdersPage({ carrierId }?: {
|
|
7
|
+
carrierId?: string | null;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
2
9
|
//# sourceMappingURL=VervoerdersPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,+BAShF"}
|
|
@@ -9,7 +9,22 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
9
9
|
import { toServerFnError } from "../../lib/serverFnError";
|
|
10
10
|
import { listCarriers, deleteCarrier, reorderCarriers } from "../../lib/carriers.functions";
|
|
11
11
|
import { carrierLeadDaysFromMoments } from "../../lib/carrierPlanning";
|
|
12
|
-
|
|
12
|
+
import { VervoerderForm } from "./VervoerderForm";
|
|
13
|
+
/**
|
|
14
|
+
* Bewerken gebeurt via een searchparam (?id=<uuid>) i.p.v. een dynamisch
|
|
15
|
+
* URL-segment, zodat het ook werkt in hosts/shells die alleen statische
|
|
16
|
+
* module-routes registreren.
|
|
17
|
+
*/
|
|
18
|
+
export function VervoerdersPage({ carrierId } = {}) {
|
|
19
|
+
const idFromUrl = carrierId ??
|
|
20
|
+
(typeof window !== "undefined"
|
|
21
|
+
? new URLSearchParams(window.location.search).get("id")
|
|
22
|
+
: null);
|
|
23
|
+
if (idFromUrl)
|
|
24
|
+
return _jsx(VervoerderForm, { carrierId: idFromUrl });
|
|
25
|
+
return _jsx(VervoerdersLijst, {});
|
|
26
|
+
}
|
|
27
|
+
function VervoerdersLijst() {
|
|
13
28
|
const queryClient = useQueryClient();
|
|
14
29
|
const fetchList = useServerFn(listCarriers);
|
|
15
30
|
const removeCarrier = useServerFn(deleteCarrier);
|
|
@@ -54,5 +69,5 @@ export function VervoerdersPage() {
|
|
|
54
69
|
[ids[index], ids[target]] = [ids[target], ids[index]];
|
|
55
70
|
reorderMutation.mutate(ids);
|
|
56
71
|
};
|
|
57
|
-
return (_jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Vervoerders" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Beheer vervoerders en hun verzendtarieven per land." })] }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] }), _jsx("div", { className: "border rounded-md bg-card", children: isLoading ? (_jsx("div", { className: "p-12 text-center text-muted-foreground", children: "Laden..." })) : error ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsxs("div", { className: "text-destructive", children: ["Fout bij laden: ", error.message] }), _jsx(Button, { variant: "outline", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : carriers.length === 0 ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsx(Truck, { className: "w-10 h-10 mx-auto text-muted-foreground" }), _jsx("div", { className: "font-medium", children: "Nog geen vervoerders" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Voeg een vervoerder toe om verzendtarieven in te stellen." }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-32", children: "Prioriteit" }), _jsx(TableHead, { children: "Bedrijfsnaam" }), _jsx(TableHead, { children: "Contactpersoon" }), _jsx(TableHead, { children: "E-mail" }), _jsx(TableHead, { children: "Telefoon" }), _jsx(TableHead, { children: "Levertijd" }), _jsx(TableHead, { children: "Landen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: carriers.map((c, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "w-6 text-sm font-medium tabular-nums text-muted-foreground", children: index + 1 }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, -1), disabled: index === 0 || reorderMutation.isPending, "aria-label": "Hoger", children: _jsx(ArrowUp, { className: "w-4 h-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, 1), disabled: index === carriers.length - 1 || reorderMutation.isPending, "aria-label": "Lager", children: _jsx(ArrowDown, { className: "w-4 h-4" }) })] }) }), _jsx(TableCell, { className: "font-medium", children: c.name }), _jsx(TableCell, { children: c.contact_person ?? "—" }), _jsx(TableCell, { children: c.email ?? "—" }), _jsx(TableCell, { children: c.phone ?? "—" }), _jsxs(TableCell, { children: [carrierLeadDaysFromMoments(c.pickup_moments), " werkdagen"] }), _jsx(TableCell, { children: c.rate_count }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/afhandeling/vervoerders
|
|
72
|
+
return (_jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Vervoerders" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Beheer vervoerders en hun verzendtarieven per land." })] }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] }), _jsx("div", { className: "border rounded-md bg-card", children: isLoading ? (_jsx("div", { className: "p-12 text-center text-muted-foreground", children: "Laden..." })) : error ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsxs("div", { className: "text-destructive", children: ["Fout bij laden: ", error.message] }), _jsx(Button, { variant: "outline", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : carriers.length === 0 ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsx(Truck, { className: "w-10 h-10 mx-auto text-muted-foreground" }), _jsx("div", { className: "font-medium", children: "Nog geen vervoerders" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Voeg een vervoerder toe om verzendtarieven in te stellen." }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-32", children: "Prioriteit" }), _jsx(TableHead, { children: "Bedrijfsnaam" }), _jsx(TableHead, { children: "Contactpersoon" }), _jsx(TableHead, { children: "E-mail" }), _jsx(TableHead, { children: "Telefoon" }), _jsx(TableHead, { children: "Levertijd" }), _jsx(TableHead, { children: "Landen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: carriers.map((c, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "w-6 text-sm font-medium tabular-nums text-muted-foreground", children: index + 1 }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, -1), disabled: index === 0 || reorderMutation.isPending, "aria-label": "Hoger", children: _jsx(ArrowUp, { className: "w-4 h-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, 1), disabled: index === carriers.length - 1 || reorderMutation.isPending, "aria-label": "Lager", children: _jsx(ArrowDown, { className: "w-4 h-4" }) })] }) }), _jsx(TableCell, { className: "font-medium", children: c.name }), _jsx(TableCell, { children: c.contact_person ?? "—" }), _jsx(TableCell, { children: c.email ?? "—" }), _jsx(TableCell, { children: c.phone ?? "—" }), _jsxs(TableCell, { children: [carrierLeadDaysFromMoments(c.pickup_moments), " werkdagen"] }), _jsx(TableCell, { children: c.rate_count }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/afhandeling/vervoerders", search: { id: c.id }, children: _jsx(Pencil, { className: "w-4 h-4" }) }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setDeletingId(c.id), className: "text-destructive hover:text-destructive", children: _jsx(Trash2, { className: "w-4 h-4" }) })] }) })] }, c.id))) })] })) }), _jsx(AlertDialog, { open: !!deletingId, onOpenChange: (o) => !o && setDeletingId(null), children: _jsxs(ResponsiveAlertDialogContent, { size: "sm", children: [_jsx(ResponsiveAlertDialogHeader, { children: _jsx(AlertDialogTitle, { children: "Vervoerder verwijderen?" }) }), _jsx(ResponsiveAlertDialogBody, { children: _jsx(AlertDialogDescription, { children: "Deze actie kan niet ongedaan gemaakt worden. Alle verzendtarieven worden ook verwijderd." }) }), _jsxs(ResponsiveAlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: () => deletingId && deleteMutation.mutate(deletingId), className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", children: "Verwijderen" })] })] }) })] }));
|
|
58
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAUjE,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,oBAAoB,GAAG,MAAM,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA+DD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,EACL,gBAAgB,EAChB,YAAY,EACZ,UAAU,GACX,EAAE,mBAAmB,+BA0JrB"}
|