@flowselections/floriday-afhandeling-module 1.0.13 → 1.0.15
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.d.ts +12 -0
- package/dist-lib/components/afhandeling/AutoProcessStatus.d.ts.map +1 -0
- package/dist-lib/components/afhandeling/AutoProcessStatus.js +103 -0
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts +3 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/ControleLijstPrint.js +41 -63
- package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/DagDetailDialog.js +96 -4
- package/dist-lib/components/afhandeling/LeveringenPage.js +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/VervoerdersPage.js +2 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts +3 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
- package/dist-lib/components/afhandeling/WeekAgendaView.js +58 -17
- package/dist-lib/components/pickstation/PakbonTemplate.d.ts +2 -1
- package/dist-lib/components/pickstation/PakbonTemplate.d.ts.map +1 -1
- package/dist-lib/components/pickstation/PakbonTemplate.js +20 -17
- package/dist-lib/components/pickstation/PickstationPage.d.ts.map +1 -1
- package/dist-lib/components/pickstation/PickstationPage.js +57 -8
- package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
- package/dist-lib/components/settings/AfhandelingSettingsCard.js +14 -2
- package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
- package/dist-lib/hooks/useOrderPlanning.js +28 -11
- package/dist-lib/index.d.ts +3 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +3 -0
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +605 -4
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +605 -4
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +605 -4
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +613 -4
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.d.ts +1222 -8
- package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
- package/dist-lib/lib/afhandelingSettings.functions.js +28 -1
- package/dist-lib/lib/carrierPlanning.d.ts +25 -0
- package/dist-lib/lib/carrierPlanning.d.ts.map +1 -0
- package/dist-lib/lib/carrierPlanning.js +65 -0
- package/dist-lib/lib/carrierSignupMail.server.d.ts +0 -2
- package/dist-lib/lib/carrierSignupMail.server.d.ts.map +1 -1
- package/dist-lib/lib/carrierSignupMail.server.js +53 -216
- package/dist-lib/lib/carriers.functions.d.ts +3025 -20
- package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
- package/dist-lib/lib/carriers.functions.js +5 -0
- package/dist-lib/lib/cartAssignments.functions.d.ts +3025 -20
- package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.d.ts +6050 -40
- package/dist-lib/lib/cartControl.functions.d.ts.map +1 -1
- package/dist-lib/lib/cartControl.functions.js +1 -1
- package/dist-lib/lib/cartRescheduling.d.ts.map +1 -1
- package/dist-lib/lib/cartRescheduling.js +8 -6
- package/dist-lib/lib/countries.d.ts +2 -0
- package/dist-lib/lib/countries.d.ts.map +1 -1
- package/dist-lib/lib/countries.js +51 -0
- package/dist-lib/lib/deliveryNotePrint.d.ts +26 -0
- package/dist-lib/lib/deliveryNotePrint.d.ts.map +1 -0
- package/dist-lib/lib/deliveryNotePrint.js +172 -0
- package/dist-lib/lib/floriday.functions.d.ts +613 -4
- package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
- package/dist-lib/lib/floriday.functions.js +126 -8
- package/dist-lib/lib/floridayAutoProcess.d.ts +30 -0
- package/dist-lib/lib/floridayAutoProcess.d.ts.map +1 -0
- package/dist-lib/lib/floridayAutoProcess.js +70 -0
- package/dist-lib/lib/pickstationI18n.d.ts +46 -0
- package/dist-lib/lib/pickstationI18n.d.ts.map +1 -1
- package/dist-lib/lib/pickstationI18n.js +251 -0
- package/dist-lib/lib/pickstationOrders.server.d.ts.map +1 -1
- package/dist-lib/lib/pickstationOrders.server.js +55 -19
- package/dist-lib/lib/planning.d.ts +34 -0
- package/dist-lib/lib/planning.d.ts.map +1 -1
- package/dist-lib/lib/planning.js +84 -0
- package/package.json +2 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
salesOrderId: string;
|
|
3
|
+
/** Datum waarop de auto-verwerking mag starten (targetPickDate). */
|
|
4
|
+
autoProcessDate?: Date | null;
|
|
5
|
+
/** Toon knop "Nu verwerken" ook als datum nog niet bereikt. */
|
|
6
|
+
allowManualTrigger?: boolean;
|
|
7
|
+
/** Compact = alleen badge, geen knoppen. */
|
|
8
|
+
compact?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger, compact, }: Props): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=AutoProcessStatus.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Badge, Button, toast } from "@flowselections/core";
|
|
4
|
+
import { CheckCircle2, Clock, Loader2, PlayCircle, RefreshCw, AlertTriangle } from "lucide-react";
|
|
5
|
+
import { autoProcessSalesOrder, fetchAutoProcessStatuses, } from "../../lib/floridayAutoProcess";
|
|
6
|
+
import { supabase } from "../../integrations/supabase/client";
|
|
7
|
+
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { day: "2-digit", month: "short" });
|
|
8
|
+
function formatWaiting(date) {
|
|
9
|
+
const today = new Date();
|
|
10
|
+
today.setHours(0, 0, 0, 0);
|
|
11
|
+
const target = new Date(date);
|
|
12
|
+
target.setHours(0, 0, 0, 0);
|
|
13
|
+
const diffDays = Math.round((target.getTime() - today.getTime()) / 86400000);
|
|
14
|
+
if (diffDays <= 0)
|
|
15
|
+
return "Klaar om te verwerken";
|
|
16
|
+
if (diffDays === 1)
|
|
17
|
+
return "Verwerkt morgen";
|
|
18
|
+
return `Wacht tot ${NL_DATE.format(target)} (${diffDays} dagen)`;
|
|
19
|
+
}
|
|
20
|
+
export function AutoProcessStatus({ salesOrderId, autoProcessDate, allowManualTrigger = true, compact = false, }) {
|
|
21
|
+
const [row, setRow] = useState(null);
|
|
22
|
+
const [loading, setLoading] = useState(false);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
let cancelled = false;
|
|
25
|
+
fetchAutoProcessStatuses([salesOrderId]).then((m) => {
|
|
26
|
+
if (!cancelled)
|
|
27
|
+
setRow(m.get(salesOrderId) ?? null);
|
|
28
|
+
});
|
|
29
|
+
const channel = supabase
|
|
30
|
+
.channel(`auto-process-${salesOrderId}`)
|
|
31
|
+
.on("postgres_changes", {
|
|
32
|
+
event: "*",
|
|
33
|
+
schema: "public",
|
|
34
|
+
table: "floriday_auto_fulfillment_log",
|
|
35
|
+
filter: `sales_order_id=eq.${salesOrderId}`,
|
|
36
|
+
}, () => {
|
|
37
|
+
fetchAutoProcessStatuses([salesOrderId]).then((m) => {
|
|
38
|
+
if (!cancelled)
|
|
39
|
+
setRow(m.get(salesOrderId) ?? null);
|
|
40
|
+
});
|
|
41
|
+
})
|
|
42
|
+
.subscribe();
|
|
43
|
+
return () => {
|
|
44
|
+
cancelled = true;
|
|
45
|
+
supabase.removeChannel(channel);
|
|
46
|
+
};
|
|
47
|
+
}, [salesOrderId]);
|
|
48
|
+
const handleProcess = async () => {
|
|
49
|
+
setLoading(true);
|
|
50
|
+
try {
|
|
51
|
+
const res = await autoProcessSalesOrder(salesOrderId);
|
|
52
|
+
toast.success(res.status === "done"
|
|
53
|
+
? "Verwerkt — afleverbrief wordt aangemaakt"
|
|
54
|
+
: "Auto-verwerking gestart");
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
toast.error(e instanceof Error ? e.message : "Auto-verwerking mislukt");
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
setLoading(false);
|
|
61
|
+
fetchAutoProcessStatuses([salesOrderId]).then((m) => setRow(m.get(salesOrderId) ?? null));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const status = row?.status;
|
|
65
|
+
const now = new Date();
|
|
66
|
+
const reached = !autoProcessDate || now >= autoProcessDate;
|
|
67
|
+
let badge;
|
|
68
|
+
if (status === "done") {
|
|
69
|
+
badge = (_jsxs(Badge, { variant: "secondary", className: "gap-1 bg-green-100 text-green-800", children: [_jsx(CheckCircle2, { className: "h-3 w-3" }), " Afleverbrief klaar"] }));
|
|
70
|
+
}
|
|
71
|
+
else if (status === "error") {
|
|
72
|
+
badge = (_jsxs(Badge, { variant: "destructive", className: "gap-1", children: [_jsx(AlertTriangle, { className: "h-3 w-3" }), " Fout \u2014 ", row?.error?.slice(0, 40) ?? "onbekend"] }));
|
|
73
|
+
}
|
|
74
|
+
else if (status === "waiting_for_commit") {
|
|
75
|
+
const deadline = autoProcessDate
|
|
76
|
+
? new Intl.DateTimeFormat("nl-NL", { hour: "2-digit", minute: "2-digit" }).format(autoProcessDate)
|
|
77
|
+
: null;
|
|
78
|
+
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " Wacht op commit", deadline ? ` — deadline ${deadline}` : ""] }));
|
|
79
|
+
}
|
|
80
|
+
else if (status === "waiting_for_delivery_order") {
|
|
81
|
+
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " Wacht op Floriday delivery-order"] }));
|
|
82
|
+
}
|
|
83
|
+
else if (status === "ready_to_fulfill") {
|
|
84
|
+
badge = (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(PlayCircle, { className: "h-3 w-3" }), " Klaar voor fulfillment"] }));
|
|
85
|
+
}
|
|
86
|
+
else if (status === "acknowledging" ||
|
|
87
|
+
status === "creating_delivery_order" ||
|
|
88
|
+
status === "sending_fulfillment" ||
|
|
89
|
+
status === "generating_delivery_note") {
|
|
90
|
+
badge = (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), " In verwerking"] }));
|
|
91
|
+
}
|
|
92
|
+
else if (!reached && autoProcessDate) {
|
|
93
|
+
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " ", formatWaiting(autoProcessDate)] }));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
badge = (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(Clock, { className: "h-3 w-3" }), " Klaar om te verwerken"] }));
|
|
97
|
+
}
|
|
98
|
+
if (compact)
|
|
99
|
+
return _jsx(_Fragment, { children: badge });
|
|
100
|
+
const showRetry = status === "error";
|
|
101
|
+
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] }));
|
|
103
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ControlCart } from "../../lib/cartControl.functions";
|
|
2
|
+
import { type PickstationLang } from "../../lib/pickstationI18n";
|
|
2
3
|
/** Printbare controlelijst — één regel per kar met checkbox en opmerkingveld. */
|
|
3
|
-
export declare function ControleLijstPrint({ carts, onClose, }: {
|
|
4
|
+
export declare function ControleLijstPrint({ carts, onClose, lang, }: {
|
|
4
5
|
carts: ControlCart[];
|
|
5
6
|
onClose: () => void;
|
|
7
|
+
lang?: PickstationLang;
|
|
6
8
|
}): import("react").ReactPortal | null;
|
|
7
9
|
//# sourceMappingURL=ControleLijstPrint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"ControleLijstPrint.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/ControleLijstPrint.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAgCnC,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,OAAO,EACP,IAAW,GACZ,EAAE;IACD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB,sCAoJA"}
|
|
@@ -3,84 +3,63 @@ import { useEffect } from "react";
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { Button } from "@flowselections/core";
|
|
5
5
|
import { X, Printer } from "lucide-react";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function minusOneHour(hhmm) {
|
|
20
|
-
const [h, m] = hhmm.split(":").map((n) => parseInt(n, 10));
|
|
21
|
-
if (Number.isNaN(h) || Number.isNaN(m))
|
|
22
|
-
return hhmm;
|
|
23
|
-
const total = h * 60 + m - 60;
|
|
24
|
-
const norm = ((total % (24 * 60)) + 24 * 60) % (24 * 60);
|
|
25
|
-
const hh = String(Math.floor(norm / 60)).padStart(2, "0");
|
|
26
|
-
const mm = String(norm % 60).padStart(2, "0");
|
|
27
|
-
return `${hh}:${mm}`;
|
|
28
|
-
}
|
|
29
|
-
function todayIsoDay() {
|
|
30
|
-
const d = new Date();
|
|
31
|
-
const y = d.getFullYear();
|
|
32
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
33
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
34
|
-
return `${y}-${m}-${day}`;
|
|
35
|
-
}
|
|
36
|
-
function tomorrowIsoDay() {
|
|
37
|
-
const d = new Date();
|
|
38
|
-
d.setDate(d.getDate() + 1);
|
|
39
|
-
const y = d.getFullYear();
|
|
40
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
41
|
-
const day = String(d.getDate()).padStart(2, "0");
|
|
42
|
-
return `${y}-${m}-${day}`;
|
|
43
|
-
}
|
|
44
|
-
function computeKlaarzet(cart) {
|
|
45
|
-
const today = todayIsoDay();
|
|
46
|
-
const tomorrow = tomorrowIsoDay();
|
|
47
|
-
if (cart.pickupDate === today) {
|
|
48
|
-
const time = cart.pickupTime ? minusOneHour(cart.pickupTime) : null;
|
|
49
|
-
if (time) {
|
|
50
|
-
const [h, m] = time.split(":").map((n) => parseInt(n, 10));
|
|
51
|
-
return { label: time, sortKey: h * 60 + m };
|
|
52
|
-
}
|
|
53
|
-
// Ophaaldatum vandaag maar geen tijd bekend → einde van vandaag.
|
|
54
|
-
return { label: "vandaag", sortKey: 23 * 60 + 59 };
|
|
6
|
+
import { countryCode } from "../../lib/countries";
|
|
7
|
+
import { getPrintDict, PICKSTATION_LOCALE, } from "../../lib/pickstationI18n";
|
|
8
|
+
const DAY_ABBR_BY_LANG = {
|
|
9
|
+
nl: ["ZO", "MA", "DI", "WO", "DO", "VR", "ZA"],
|
|
10
|
+
en: ["SU", "MO", "TU", "WE", "TH", "FR", "SA"],
|
|
11
|
+
pl: ["ND", "PN", "WT", "ŚR", "CZ", "PT", "SB"],
|
|
12
|
+
ro: ["DU", "LU", "MA", "MI", "JO", "VI", "SÂ"],
|
|
13
|
+
bg: ["НД", "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ"],
|
|
14
|
+
uk: ["НД", "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ"],
|
|
15
|
+
};
|
|
16
|
+
function computeKlaarzet(cart, lang) {
|
|
17
|
+
if (!cart.pickupDate || !cart.pickupTime) {
|
|
18
|
+
return { label: "—", sortKey: Number.MAX_SAFE_INTEGER };
|
|
55
19
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
20
|
+
const [hh, mm] = cart.pickupTime.split(":").map((n) => parseInt(n, 10));
|
|
21
|
+
const d = new Date(cart.pickupDate);
|
|
22
|
+
if (Number.isNaN(d.getTime()) || Number.isNaN(hh) || Number.isNaN(mm)) {
|
|
23
|
+
return { label: "—", sortKey: Number.MAX_SAFE_INTEGER };
|
|
59
24
|
}
|
|
60
|
-
|
|
61
|
-
|
|
25
|
+
d.setHours(hh, mm, 0, 0);
|
|
26
|
+
d.setHours(d.getHours() - 1);
|
|
27
|
+
const day = (DAY_ABBR_BY_LANG[lang] ?? DAY_ABBR_BY_LANG.nl)[d.getDay()];
|
|
28
|
+
const time = `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
29
|
+
return { label: `${day} - ${time}`, sortKey: d.getTime() };
|
|
62
30
|
}
|
|
63
31
|
/** Printbare controlelijst — één regel per kar met checkbox en opmerkingveld. */
|
|
64
|
-
export function ControleLijstPrint({ carts, onClose, }) {
|
|
32
|
+
export function ControleLijstPrint({ carts, onClose, lang = "nl", }) {
|
|
33
|
+
const t = getPrintDict(lang);
|
|
34
|
+
const locale = PICKSTATION_LOCALE[lang] ?? "nl-NL";
|
|
65
35
|
useEffect(() => {
|
|
66
|
-
const
|
|
36
|
+
const timer = setTimeout(() => window.print(), 300);
|
|
67
37
|
const handleAfterPrint = () => onClose();
|
|
68
38
|
window.addEventListener("afterprint", handleAfterPrint);
|
|
69
39
|
return () => {
|
|
70
|
-
clearTimeout(
|
|
40
|
+
clearTimeout(timer);
|
|
71
41
|
window.removeEventListener("afterprint", handleAfterPrint);
|
|
72
42
|
};
|
|
73
43
|
}, [onClose]);
|
|
74
|
-
const
|
|
44
|
+
const statusLabel = (status, printedCount) => {
|
|
45
|
+
switch (status) {
|
|
46
|
+
case "not_printed": return t.statusNotPrinted;
|
|
47
|
+
case "printed": return t.statusPrinted(printedCount);
|
|
48
|
+
case "checked": return t.statusChecked;
|
|
49
|
+
case "ready": return t.statusReady;
|
|
50
|
+
case "shipped": return t.statusShipped;
|
|
51
|
+
case "delivered": return t.statusDelivered;
|
|
52
|
+
default: return String(status);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const today = new Date().toLocaleDateString(locale, {
|
|
75
56
|
weekday: "long",
|
|
76
57
|
day: "2-digit",
|
|
77
58
|
month: "long",
|
|
78
59
|
year: "numeric",
|
|
79
60
|
});
|
|
80
|
-
// Bereken klaarzet-moment per kar en sorteer op prioriteit
|
|
81
|
-
// (vroegste klaarzet bovenaan; daarna land, karnummer).
|
|
82
61
|
const sortedCarts = carts
|
|
83
|
-
.map((cart) => ({ cart, klaarzet: computeKlaarzet(cart) }))
|
|
62
|
+
.map((cart) => ({ cart, klaarzet: computeKlaarzet(cart, lang) }))
|
|
84
63
|
.sort((a, b) => {
|
|
85
64
|
if (a.klaarzet.sortKey !== b.klaarzet.sortKey) {
|
|
86
65
|
return a.klaarzet.sortKey - b.klaarzet.sortKey;
|
|
@@ -93,11 +72,10 @@ export function ControleLijstPrint({ carts, onClose, }) {
|
|
|
93
72
|
const bn = b.cart.cartNumber ?? "\uFFFF";
|
|
94
73
|
return an.localeCompare(bn);
|
|
95
74
|
});
|
|
96
|
-
const content = (_jsxs("div", { id: "controle-print-root", className: "fixed inset-0 z-[100] bg-white overflow-auto", children: [_jsxs("div", { className: "print:hidden sticky top-0 flex items-center justify-between p-3 border-b bg-white", children: [_jsx("div", { className: "font-semibold", children:
|
|
75
|
+
const content = (_jsxs("div", { id: "controle-print-root", className: "fixed inset-0 z-[100] bg-white overflow-auto", lang: lang, children: [_jsxs("div", { className: "print:hidden sticky top-0 flex items-center justify-between p-3 border-b bg-white", children: [_jsx("div", { className: "font-semibold", children: t.checklistPrintView }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { size: "sm", variant: "outline", onClick: () => window.print(), children: [_jsx(Printer, { className: "h-4 w-4 mr-2" }), t.reprint] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: onClose, children: [_jsx(X, { className: "h-4 w-4 mr-2" }), t.close] })] })] }), _jsxs("div", { className: "print-sheet p-8 print:p-0 max-w-[210mm] mx-auto text-black", children: [_jsxs("div", { className: "flex items-baseline justify-between border-b border-black pb-2 mb-4", children: [_jsx("h1", { className: "text-2xl font-bold", children: t.checklistTitle }), _jsx("div", { className: "text-sm", children: today })] }), _jsxs("div", { className: "text-sm mb-3", children: [t.totalCarts, ": ", _jsx("strong", { children: carts.length })] }), _jsxs("table", { className: "w-full text-[11px] border-collapse", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b border-black", children: [_jsx("th", { className: "text-left py-1 pr-2", children: t.colKarnr }), _jsx("th", { className: "text-right py-1 pr-2", children: t.colFusten }), _jsx("th", { className: "text-left py-1 pr-2", children: t.colLand }), _jsx("th", { className: "text-left py-1 pr-2", children: t.colKlaarzetten }), _jsx("th", { className: "text-left py-1 pr-2", children: t.colStatus })] }) }), _jsxs("tbody", { children: [sortedCarts.map(({ cart: c, klaarzet }) => (_jsxs("tr", { className: "border-b border-gray-300", children: [_jsx("td", { className: "py-2 pr-2 font-mono font-bold whitespace-nowrap", children: c.cartNumber ?? "—" }), _jsx("td", { className: "py-2 pr-2 text-right whitespace-nowrap", children: c.cratesOnCart ?? "—" }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap font-semibold", children: countryCode(c.country) ?? c.country ?? "—" }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap font-semibold", children: klaarzet.label }), _jsx("td", { className: "py-2 pr-2 whitespace-nowrap", children: statusLabel(c.status, c.printedCount) })] }, `${c.orderSource}#${c.orderId}#${c.cartIndex}`))), sortedCarts.length === 0 && (_jsx("tr", { children: _jsx("td", { colSpan: 5, className: "py-6 text-center text-gray-500", children: t.noCartsToday }) }))] })] }), _jsxs("div", { className: "mt-6 text-[11px]", children: [_jsxs("div", { children: [t.checkedBy, ": ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: [t.dateTime, ": ", _jsx("span", { className: "inline-block border-b border-black w-64" })] }), _jsxs("div", { className: "mt-2", children: [t.signature, ": ", _jsx("span", { className: "inline-block border-b border-black w-64" })] })] })] }), _jsx("style", { children: `
|
|
97
76
|
@media print {
|
|
98
77
|
@page { size: A4 portrait; margin: 12mm; }
|
|
99
78
|
html, body { background: #fff !important; margin: 0 !important; padding: 0 !important; }
|
|
100
|
-
/* Hide the entire app; show only the print root */
|
|
101
79
|
body > *:not(#controle-print-portal) { display: none !important; }
|
|
102
80
|
#controle-print-portal, #controle-print-root {
|
|
103
81
|
position: static !important;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"DagDetailDialog.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/DagDetailDialog.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AA6BjE,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,sCA2E1F"}
|
|
@@ -3,11 +3,15 @@ import { useState } from "react";
|
|
|
3
3
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
import { useServerFn } from "@tanstack/react-start";
|
|
5
5
|
import { Badge, Button, Dialog, DialogTitle, DialogDescription, Input, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
|
|
6
|
-
import { ChevronDown, ChevronRight, MoveRight, Truck } from "lucide-react";
|
|
6
|
+
import { ChevronDown, ChevronRight, MoveRight, Printer, Truck } from "lucide-react";
|
|
7
7
|
import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
|
|
8
8
|
import { isSameDay } from "../../lib/pickDate";
|
|
9
9
|
import { getOrderLines, moveCart as moveCartFn, } from "../../lib/cartAssignments.functions";
|
|
10
10
|
import { evaluateCartMove } from "../../lib/cartMoveImpact";
|
|
11
|
+
import { renderPakbonHtml } from "../pickstation/PakbonTemplate";
|
|
12
|
+
import { printHtml } from "../pickstation/printDocuments";
|
|
13
|
+
import { printDeliveryNotesMerged } from "../../lib/deliveryNotePrint";
|
|
14
|
+
import { AutoProcessStatus } from "./AutoProcessStatus";
|
|
11
15
|
const NL_DATE = new Intl.DateTimeFormat("nl-NL", { dateStyle: "full" });
|
|
12
16
|
export function DagDetailDialog({ open, date, planned, onOpenChange }) {
|
|
13
17
|
if (!date)
|
|
@@ -64,6 +68,7 @@ function BestellingenTab({ orders, date }) {
|
|
|
64
68
|
}
|
|
65
69
|
function OrderRow({ planned: p, cartsToday }) {
|
|
66
70
|
const [open, setOpen] = useState(false);
|
|
71
|
+
const [printing, setPrinting] = useState(false);
|
|
67
72
|
const source = p.order.source;
|
|
68
73
|
const fetchLines = useServerFn(getOrderLines);
|
|
69
74
|
const linesQuery = useQuery({
|
|
@@ -71,9 +76,96 @@ function OrderRow({ planned: p, cartsToday }) {
|
|
|
71
76
|
queryFn: () => fetchLines({ data: { orderId: p.order.id, orderSource: source } }),
|
|
72
77
|
enabled: open,
|
|
73
78
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
const handlePrintAll = async (e) => {
|
|
80
|
+
e.stopPropagation();
|
|
81
|
+
if (printing)
|
|
82
|
+
return;
|
|
83
|
+
setPrinting(true);
|
|
84
|
+
try {
|
|
85
|
+
// Zorg dat we regels hebben — anders eerst ophalen.
|
|
86
|
+
let lines = linesQuery.data?.lines ?? [];
|
|
87
|
+
if (lines.length === 0) {
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetchLines({ data: { orderId: p.order.id, orderSource: source } });
|
|
90
|
+
lines = res.lines;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
/* doorgaan met lege regels */
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const cartTotal = Math.max(1, p.order.cartCount ?? 1);
|
|
97
|
+
const pickDateIso = p.planning?.pickAssignments?.[0]?.date?.toISOString?.().slice(0, 10) ??
|
|
98
|
+
new Date().toISOString().slice(0, 10);
|
|
99
|
+
const pakbonLines = lines.map((l) => ({
|
|
100
|
+
description: l.article,
|
|
101
|
+
crates: l.crates,
|
|
102
|
+
unit: null,
|
|
103
|
+
}));
|
|
104
|
+
let printed = 0;
|
|
105
|
+
for (let idx = 0; idx < cartTotal; idx++) {
|
|
106
|
+
const html = renderPakbonHtml({
|
|
107
|
+
id: `${p.order.id}#${idx}`,
|
|
108
|
+
orderNumber: p.order.orderNumber,
|
|
109
|
+
customerName: p.order.customerName,
|
|
110
|
+
country: p.order.country ?? null,
|
|
111
|
+
deliveryDate: p.order.deliveryDate,
|
|
112
|
+
pickDate: pickDateIso,
|
|
113
|
+
cartIndex: idx + 1,
|
|
114
|
+
cartTotal,
|
|
115
|
+
cratesOnCart: null,
|
|
116
|
+
cartNumber: `${p.order.orderNumber}-${String(idx + 1).padStart(2, "0")}`,
|
|
117
|
+
lines: pakbonLines,
|
|
118
|
+
}, "nl");
|
|
119
|
+
await printHtml(html);
|
|
120
|
+
printed++;
|
|
121
|
+
}
|
|
122
|
+
let deliveryOk = 0;
|
|
123
|
+
let deliveryFailed = 0;
|
|
124
|
+
const salesOrderId = p.order.salesOrderId ?? (source === "floriday" ? p.order.id : null);
|
|
125
|
+
if (salesOrderId) {
|
|
126
|
+
try {
|
|
127
|
+
const res = await printDeliveryNotesMerged([
|
|
128
|
+
{ id: p.order.id, salesOrderId },
|
|
129
|
+
]);
|
|
130
|
+
deliveryOk = res.success;
|
|
131
|
+
deliveryFailed = res.failed.length;
|
|
132
|
+
if (res.failed.length > 0) {
|
|
133
|
+
console.warn("[print-all] afleverbrief mislukt", res.failed);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
deliveryFailed = 1;
|
|
138
|
+
console.warn("[print-all] afleverbrief-fout", err);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const parts = [`${printed} pakbon${printed === 1 ? "" : "nen"}`];
|
|
142
|
+
if (deliveryOk > 0)
|
|
143
|
+
parts.push(`${deliveryOk} afleverbrief`);
|
|
144
|
+
toast.success(`Documenten verstuurd naar printer — ${parts.join(", ")}.`);
|
|
145
|
+
if (deliveryFailed > 0) {
|
|
146
|
+
toast.error(`${deliveryFailed} afleverbrief kon niet worden opgehaald.`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
const msg = err instanceof Error ? err.message : "Printen mislukt";
|
|
151
|
+
toast.error(msg);
|
|
152
|
+
console.error("[print-all]", err);
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
setPrinting(false);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
return (_jsxs("div", { className: "rounded-lg border bg-card", children: [_jsxs("div", { className: "flex items-center gap-2 pr-3", children: [_jsxs("button", { type: "button", onClick: () => setOpen((o) => !o), className: "flex flex-1 items-center gap-3 px-4 py-3 text-left hover:bg-muted/50", children: [open ? _jsx(ChevronDown, { className: "h-4 w-4" }) : _jsx(ChevronRight, { className: "h-4 w-4" }), _jsxs("div", { className: "flex-1 grid grid-cols-2 md:grid-cols-4 gap-3 text-sm", children: [_jsxs("div", { children: [_jsx("div", { className: "font-medium", children: p.order.orderNumber }), _jsx("div", { className: "text-xs text-muted-foreground", children: p.order.customerName })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Type" }), _jsx("div", { children: p.order.deliveryType })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: "Leverdatum" }), _jsx("div", { children: p.order.deliveryDate
|
|
159
|
+
? new Date(p.order.deliveryDate).toLocaleDateString("nl-NL")
|
|
160
|
+
: "—" })] }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsxs(Badge, { variant: "secondary", children: [cartsToday, " karren vandaag"] }), _jsx(Badge, { variant: "outline", children: p.order.status }), (() => {
|
|
161
|
+
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
162
|
+
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
163
|
+
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId, compact: true, allowManualTrigger: false })) : null;
|
|
164
|
+
})()] })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [(() => {
|
|
165
|
+
const src = p.order.source === "floriday" ? "floriday" : "manual";
|
|
166
|
+
const soId = p.order.salesOrderId ?? (src === "floriday" ? p.order.id : null);
|
|
167
|
+
return soId ? (_jsx(AutoProcessStatus, { salesOrderId: soId })) : null;
|
|
168
|
+
})(), _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"] })] })] }), open && (_jsxs("div", { className: "border-t px-4 py-3 space-y-3", children: [_jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-3 text-sm", children: [_jsx(Field, { label: "Afleverlocatie", value: "\u2014" }), _jsx(Field, { label: "Ophaallocatie (tuin)", value: "\u2014" }), _jsx(Field, { label: "Vervoerder", value: "\u2014" })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Orderregels" }), linesQuery.isLoading && _jsx("p", { className: "text-xs", children: "Regels laden\u2026" }), linesQuery.data && _jsx(OrderLinesTable, { lines: linesQuery.data.lines }), linesQuery.error && _jsx("p", { className: "text-xs text-destructive", children: "Kon regels niet laden" })] })] }))] }));
|
|
77
169
|
}
|
|
78
170
|
function Field({ label, value }) {
|
|
79
171
|
return (_jsxs("div", { children: [_jsx("div", { className: "text-xs text-muted-foreground", children: label }), _jsx("div", { children: value })] }));
|
|
@@ -33,5 +33,5 @@ export function LeveringenPage() {
|
|
|
33
33
|
return true;
|
|
34
34
|
});
|
|
35
35
|
}, [planned, customer, deliveryType, dateFrom, dateTo]);
|
|
36
|
-
return (_jsx("main", { className: "p-6 space-y-6", children: _jsxs(Tabs, { defaultValue: "overzicht", className: "space-y-6", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "overzicht", children: "Overzicht" }), _jsx(TabsTrigger, { value: "veilbrieven", children: "Veilbrieven" })] }), _jsxs("div", { className: "flex flex-wrap items-end justify-between gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum vanaf" }), _jsx(Input, { type: "date", value: dateFrom, onChange: (e) => setDateFrom(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum t/m" }), _jsx(Input, { type: "date", value: dateTo, onChange: (e) => setDateTo(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Klant" }), _jsxs(Select, { value: customer, onValueChange: setCustomer, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle klanten" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle klanten" }), customers.map((c) => _jsx(SelectItem, { value: c, children: c }, c))] })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Type levering" }), _jsxs(Select, { value: deliveryType, onValueChange: setDeliveryType, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle types" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle types" }), deliveryTypes.map((t) => _jsx(SelectItem, { value: t, children: t }, t))] })] })] })] }), _jsx("div", { className: "flex items-end gap-2", children: _jsxs(Button, { variant: "outline", onClick: handleRecalc, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Herbereken planning"] }) })] }), _jsxs(TabsContent, { value: "overzicht", className: "space-y-3", children: [warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: filtered, mode: "delivery", isLoading: isLoading }))] }), _jsx(TabsContent, { value: "veilbrieven", children: _jsx("div", { className: "rounded-md border border-dashed p-10 text-center text-sm text-muted-foreground", children: "Veilbrieven volgen in een volgende iteratie." }) })] }) }));
|
|
36
|
+
return (_jsx("main", { className: "p-6 space-y-6", children: _jsxs(Tabs, { defaultValue: "overzicht", className: "space-y-6", children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "overzicht", children: "Overzicht" }), _jsx(TabsTrigger, { value: "veilbrieven", children: "Veilbrieven" })] }), _jsxs("div", { className: "flex flex-wrap items-end justify-between gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-end gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum vanaf" }), _jsx(Input, { type: "date", value: dateFrom, onChange: (e) => setDateFrom(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Datum t/m" }), _jsx(Input, { type: "date", value: dateTo, onChange: (e) => setDateTo(e.target.value), className: "w-40" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Klant" }), _jsxs(Select, { value: customer, onValueChange: setCustomer, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle klanten" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle klanten" }), customers.map((c) => _jsx(SelectItem, { value: c, children: c }, c))] })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Type levering" }), _jsxs(Select, { value: deliveryType, onValueChange: setDeliveryType, children: [_jsx(SelectTrigger, { className: "w-56", children: _jsx(SelectValue, { placeholder: "Alle types" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: ALL, children: "Alle types" }), deliveryTypes.map((t) => _jsx(SelectItem, { value: t, children: t }, t))] })] })] })] }), _jsx("div", { className: "flex items-end gap-2", children: _jsxs(Button, { variant: "outline", onClick: handleRecalc, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Herbereken planning"] }) })] }), _jsxs(TabsContent, { value: "overzicht", className: "space-y-3", children: [warning && !error && (_jsxs("div", { className: "rounded-md border border-amber-300 bg-amber-50 p-4 text-sm text-amber-900", children: [warning, " De beschikbare orders blijven zichtbaar."] })), error ? (_jsxs("div", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [error, _jsx(Button, { size: "sm", variant: "outline", className: "ml-3", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : (_jsx(WeekAgendaView, { planned: filtered, mode: "delivery", isLoading: isLoading, showPrintButtons: true }))] }), _jsx(TabsContent, { value: "veilbrieven", children: _jsx("div", { className: "rounded-md border border-dashed p-10 text-center text-sm text-muted-foreground", children: "Veilbrieven volgen in een volgende iteratie." }) })] }) }));
|
|
37
37
|
}
|
|
@@ -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":"AA6BA,wBAAgB,eAAe,gCA+L9B"}
|
|
@@ -7,6 +7,7 @@ import { Link } from "@tanstack/react-router";
|
|
|
7
7
|
import { useServerFn } from "@tanstack/react-start";
|
|
8
8
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
9
9
|
import { listCarriers, deleteCarrier, reorderCarriers } from "../../lib/carriers.functions";
|
|
10
|
+
import { carrierLeadDaysFromMoments } from "../../lib/carrierPlanning";
|
|
10
11
|
export function VervoerdersPage() {
|
|
11
12
|
const queryClient = useQueryClient();
|
|
12
13
|
const fetchList = useServerFn(listCarriers);
|
|
@@ -56,5 +57,5 @@ export function VervoerdersPage() {
|
|
|
56
57
|
[ids[index], ids[target]] = [ids[target], ids[index]];
|
|
57
58
|
reorderMutation.mutate(ids);
|
|
58
59
|
};
|
|
59
|
-
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 ?? "—" }),
|
|
60
|
+
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/$id/bewerken", params: { 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" })] })] }) })] }));
|
|
60
61
|
}
|
|
@@ -8,6 +8,8 @@ export interface WeekAgendaViewProps {
|
|
|
8
8
|
onOrderClick?: (order: FloridayOrder) => void;
|
|
9
9
|
onDayClick?: (date: Date) => void;
|
|
10
10
|
title?: string;
|
|
11
|
+
/** Toon "Afleverbrief" print-knoppen (per order + per dag). */
|
|
12
|
+
showPrintButtons?: boolean;
|
|
11
13
|
}
|
|
12
|
-
export declare function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title, }: WeekAgendaViewProps): import("react").JSX.Element;
|
|
14
|
+
export declare function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayClick, title, showPrintButtons, }: WeekAgendaViewProps): import("react").JSX.Element;
|
|
13
15
|
//# sourceMappingURL=WeekAgendaView.d.ts.map
|
|
@@ -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;AAElE,OAAO,KAAK,EAAE,YAAY,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;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,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;CAC5B;AA8DD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,EACL,gBAAgB,GACjB,EAAE,mBAAmB,+BAoIrB"}
|