@flowselections/pick-schermen-kwekers 1.0.58 → 1.0.62
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/PickPublicPage.d.ts.map +1 -1
- package/dist-lib/components/PickPublicPage.js +33 -2
- package/dist-lib/components/PickstationsPage.d.ts.map +1 -1
- package/dist-lib/components/PickstationsPage.js +2 -1
- package/dist-lib/components/pick/PickScherm.d.ts.map +1 -1
- package/dist-lib/components/pick/PickScherm.js +11 -4
- package/dist-lib/components/pick/ShippingNoteScan.d.ts.map +1 -1
- package/dist-lib/components/pick/ShippingNoteScan.js +52 -13
- package/dist-lib/components/pick/StationDevices.d.ts +6 -0
- package/dist-lib/components/pick/StationDevices.d.ts.map +1 -0
- package/dist-lib/components/pick/StationDevices.js +55 -0
- package/dist-lib/components/pick/StationPairing.d.ts +7 -0
- package/dist-lib/components/pick/StationPairing.d.ts.map +1 -0
- package/dist-lib/components/pick/StationPairing.js +25 -0
- package/dist-lib/components/pick/StickerState.d.ts +4 -0
- package/dist-lib/components/pick/StickerState.d.ts.map +1 -1
- package/dist-lib/components/pick/StickerState.js +30 -4
- package/dist-lib/hooks/usePickQueue.d.ts.map +1 -1
- package/dist-lib/hooks/usePickQueue.js +4 -0
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +3828 -90
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/__tests__/pick159.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/pick159.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/pick159.test.js +36 -0
- package/dist-lib/lib/__tests__/pick161.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/pick161.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/pick161.test.js +29 -0
- package/dist-lib/lib/__tests__/pickUitwijk.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/pickUitwijk.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/pickUitwijk.test.js +36 -0
- package/dist-lib/lib/pick150.d.ts.map +1 -1
- package/dist-lib/lib/pick150.js +2 -1
- package/dist-lib/lib/pick152.d.ts.map +1 -1
- package/dist-lib/lib/pick152.js +2 -1
- package/dist-lib/lib/pick156.d.ts.map +1 -1
- package/dist-lib/lib/pick156.js +2 -1
- package/dist-lib/lib/pick159.d.ts +56 -0
- package/dist-lib/lib/pick159.d.ts.map +1 -0
- package/dist-lib/lib/pick159.js +125 -0
- package/dist-lib/lib/pick161.d.ts +27 -0
- package/dist-lib/lib/pick161.d.ts.map +1 -0
- package/dist-lib/lib/pick161.js +86 -0
- package/dist-lib/lib/pickApi.d.ts.map +1 -1
- package/dist-lib/lib/pickApi.js +35 -81
- package/dist-lib/lib/pickPreview.d.ts.map +1 -1
- package/dist-lib/lib/pickPreview.js +5 -5
- package/dist-lib/lib/pickStickers.d.ts +5 -0
- package/dist-lib/lib/pickStickers.d.ts.map +1 -1
- package/dist-lib/lib/pickStickers.js +5 -1
- package/dist-lib/lib/pickUitwijk.d.ts +25 -0
- package/dist-lib/lib/pickUitwijk.d.ts.map +1 -0
- package/dist-lib/lib/pickUitwijk.js +93 -0
- package/dist-lib/lib/shippingNote.d.ts +2 -0
- package/dist-lib/lib/shippingNote.d.ts.map +1 -1
- package/dist-lib/lib/shippingNote.js +2 -1
- package/package.json +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PickPublicPage.d.ts","sourceRoot":"","sources":["../../src/components/PickPublicPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PickPublicPage.d.ts","sourceRoot":"","sources":["../../src/components/PickPublicPage.tsx"],"names":[],"mappings":"AAQA,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,+BAiE7C"}
|
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
2
3
|
import { useQuery } from "@tanstack/react-query";
|
|
3
4
|
import { Loader2 } from "lucide-react";
|
|
4
5
|
import { pickApi } from "../lib/pickApi.js";
|
|
6
|
+
import { fetchDeviceStatus, mustPair, readDeviceKey, setActiveDeviceKey } from "../lib/pick159.js";
|
|
5
7
|
import { PickScherm } from "./pick/PickScherm.js";
|
|
8
|
+
import { StationPairing } from "./pick/StationPairing.js";
|
|
6
9
|
/** Openbaar pickscherm, bereikbaar via /pickstation/<slug>. */
|
|
7
10
|
export function PickPublicPage({ slug }) {
|
|
11
|
+
const [deviceKey, setDeviceKey] = useState(null);
|
|
12
|
+
const [keyRead, setKeyRead] = useState(false);
|
|
13
|
+
const [qrCode, setQrCode] = useState(undefined);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
setActiveDeviceKey(deviceKey);
|
|
16
|
+
return () => setActiveDeviceKey(null);
|
|
17
|
+
}, [deviceKey]);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
setDeviceKey(readDeviceKey(slug));
|
|
20
|
+
const c = new URLSearchParams(window.location.search).get("koppelcode");
|
|
21
|
+
if (c)
|
|
22
|
+
setQrCode(c);
|
|
23
|
+
setKeyRead(true);
|
|
24
|
+
}, [slug]);
|
|
25
|
+
const { data: deviceStatus, isLoading: statusLoading, refetch } = useQuery({
|
|
26
|
+
queryKey: ["pick", "device-status", slug, deviceKey],
|
|
27
|
+
queryFn: () => fetchDeviceStatus(slug, deviceKey),
|
|
28
|
+
enabled: keyRead,
|
|
29
|
+
});
|
|
8
30
|
const { data: station, isLoading } = useQuery({
|
|
9
|
-
queryKey: ["pick", "station", slug],
|
|
31
|
+
queryKey: ["pick", "station", slug, deviceKey],
|
|
10
32
|
queryFn: () => pickApi.stationBySlug(slug),
|
|
33
|
+
enabled: keyRead,
|
|
11
34
|
});
|
|
12
|
-
if (isLoading) {
|
|
35
|
+
if (isLoading || !keyRead || statusLoading) {
|
|
13
36
|
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-background", children: _jsx(Loader2, { className: "h-8 w-8 animate-spin text-primary" }) }));
|
|
14
37
|
}
|
|
38
|
+
if (mustPair(deviceStatus ?? null) || (qrCode && !deviceStatus?.gekoppeld)) {
|
|
39
|
+
return (_jsx(StationPairing, { slug: slug, initialCode: qrCode, onPaired: () => {
|
|
40
|
+
setQrCode(undefined);
|
|
41
|
+
window.history.replaceState(null, "", window.location.pathname);
|
|
42
|
+
setDeviceKey(readDeviceKey(slug));
|
|
43
|
+
void refetch();
|
|
44
|
+
} }));
|
|
45
|
+
}
|
|
15
46
|
if (!station) {
|
|
16
47
|
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-background", children: _jsx("p", { className: "text-muted-foreground", children: "Pickstation niet gevonden of niet actief." }) }));
|
|
17
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PickstationsPage.d.ts","sourceRoot":"","sources":["../../src/components/PickstationsPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PickstationsPage.d.ts","sourceRoot":"","sources":["../../src/components/PickstationsPage.tsx"],"names":[],"mappings":"AAmGA,wBAAgB,gBAAgB,gCA6L/B"}
|
|
@@ -8,6 +8,7 @@ import { usePickStations } from "../hooks/usePickConfig.js";
|
|
|
8
8
|
import { useKoppelingVoorBron } from "../hooks/useKoppelingVoorBron.js";
|
|
9
9
|
import { ReferentiedataBanner } from "./pick/ReferentiedataBanner.js";
|
|
10
10
|
import { DOCUMENT_AUTO_TEXT } from "../lib/pick156.js";
|
|
11
|
+
import { StationDevices } from "./pick/StationDevices.js";
|
|
11
12
|
const emptyDraft = { name: "", description: "", active: true };
|
|
12
13
|
function publicUrl(slug) {
|
|
13
14
|
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
@@ -61,7 +62,7 @@ export function PickstationsPage() {
|
|
|
61
62
|
return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-bold text-foreground", children: "Pickstations" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Beheer je pickstations en de link die je met de medewerkers deelt." })] }), _jsxs(Button, { onClick: () => setDraft({ ...emptyDraft }), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Nieuw pickstation"] })] }), _jsx(ReferentiedataBanner, {}), isLoading ? (_jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Laden..."] })) : safeStations.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen pickstations." })) : (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3", children: safeStations.map((station) => (_jsx(Card, { className: "border-2", children: _jsxs(CardContent, { className: "space-y-4 p-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold text-foreground", children: station.name }), _jsx("p", { className: "text-sm text-muted-foreground", children: station.description })] }), _jsx("span", { className: "rounded-full px-2 py-1 text-xs font-medium " +
|
|
62
63
|
(station.active
|
|
63
64
|
? "bg-primary/10 text-primary"
|
|
64
|
-
: "bg-muted text-muted-foreground"), children: station.active ? "Actief" : "Inactief" })] }), _jsx("code", { className: "block truncate rounded bg-muted px-2 py-1 text-xs text-muted-foreground", children: publicUrl(station.slug) }), _jsx(StationPrintplek, { station: station }), _jsx("p", { className: "text-sm text-muted-foreground", children: DOCUMENT_AUTO_TEXT }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { className: "flex-1", asChild: true, children: _jsxs("a", { href: publicUrl(station.slug), target: "_blank", rel: "noreferrer", children: [_jsx(ExternalLink, { className: "mr-2 h-4 w-4" }), " Open pickstation"] }) }), _jsxs(Button, { variant: "outline", onClick: () => copyLink(station), children: [_jsx(Copy, { className: "mr-2 h-4 w-4" }), " Link kopi\u00EBren"] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setDraft({
|
|
65
|
+
: "bg-muted text-muted-foreground"), children: station.active ? "Actief" : "Inactief" })] }), _jsx("code", { className: "block truncate rounded bg-muted px-2 py-1 text-xs text-muted-foreground", children: publicUrl(station.slug) }), _jsx(StationPrintplek, { station: station }), _jsx("p", { className: "text-sm text-muted-foreground", children: DOCUMENT_AUTO_TEXT }), _jsx(StationDevices, { stationId: station.id, slug: station.slug ?? null }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { className: "flex-1", asChild: true, children: _jsxs("a", { href: publicUrl(station.slug), target: "_blank", rel: "noreferrer", children: [_jsx(ExternalLink, { className: "mr-2 h-4 w-4" }), " Open pickstation"] }) }), _jsxs(Button, { variant: "outline", onClick: () => copyLink(station), children: [_jsx(Copy, { className: "mr-2 h-4 w-4" }), " Link kopi\u00EBren"] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setDraft({
|
|
65
66
|
id: station.id,
|
|
66
67
|
name: station.name,
|
|
67
68
|
description: station.description ?? "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PickScherm.d.ts","sourceRoot":"","sources":["../../../src/components/pick/PickScherm.tsx"],"names":[],"mappings":"AA0DA,OAAO,EAaL,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AA2D7B,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAwBD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,+
|
|
1
|
+
{"version":3,"file":"PickScherm.d.ts","sourceRoot":"","sources":["../../../src/components/pick/PickScherm.tsx"],"names":[],"mappings":"AA0DA,OAAO,EAaL,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AA2D7B,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAwBD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,+BAyqEpD"}
|
|
@@ -26,7 +26,7 @@ import { usePrintBatch, usePrintJob } from "../../hooks/usePrintJob.js";
|
|
|
26
26
|
import { useShippingNoteStatus } from "../../hooks/useShippingNoteStatus.js";
|
|
27
27
|
import { firstVisibleTarget, isJobFinished, isRowGoneError, NO_ROW_IN_FILTER_MESSAGE, RELEASE_PENDING_MESSAGE, ROW_GONE_MESSAGE, stuckMessage, stuckMinutesOf, } from "../../lib/pickRowState.js";
|
|
28
28
|
import { CartItemRows, PlanWarnings } from "./CartItemRows.js";
|
|
29
|
-
import { CartStickerState, OrderStickerMeldingen, StickerFitMeldingen } from "./StickerState.js";
|
|
29
|
+
import { CartStickerState, OrderStickerMeldingen, StickerFitMeldingen, VroegeStickerWaarschuwing } from "./StickerState.js";
|
|
30
30
|
import { StickerReprintButton } from "./StickerReprintButton.js";
|
|
31
31
|
import { isJobFailed } from "../../lib/pick142.js";
|
|
32
32
|
import { isPrintBlocked } from "../../lib/pick156.js";
|
|
@@ -144,15 +144,22 @@ export function PickScherm({ station, onBack }) {
|
|
|
144
144
|
if (fetchingNotes)
|
|
145
145
|
return;
|
|
146
146
|
setFetchingNotes(true);
|
|
147
|
+
const id = toast.loading("Verzendbrieven ophalen…");
|
|
147
148
|
try {
|
|
148
149
|
const result = await refreshShippingNotesNow();
|
|
149
150
|
if (result.ok) {
|
|
150
|
-
toast.success(result.message ?? "Verzendbrieven worden opgehaald.");
|
|
151
|
+
toast.success(result.message ?? "Verzendbrieven worden opgehaald.", { id });
|
|
151
152
|
}
|
|
152
153
|
else {
|
|
153
|
-
toast.info("De verzendbrieven worden zo vanzelf opgehaald. Je hoeft niets te doen.");
|
|
154
|
+
toast.info("De verzendbrieven worden zo vanzelf opgehaald. Je hoeft niets te doen.", { id });
|
|
154
155
|
}
|
|
155
156
|
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
toast.error("Verzendbrieven ophalen lukte niet. Probeer het over een minuut opnieuw.", {
|
|
159
|
+
id,
|
|
160
|
+
description: e instanceof Error ? `Details voor beheer: ${e.message}` : undefined,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
156
163
|
finally {
|
|
157
164
|
setFetchingNotes(false);
|
|
158
165
|
}
|
|
@@ -1371,7 +1378,7 @@ export function PickScherm({ station, onBack }) {
|
|
|
1371
1378
|
const cart = plannedCart ?? { cartId: r.cartId, cartLabel: r.cartLabel ?? r.cartId };
|
|
1372
1379
|
setLastCartResults((prev) => prev.filter((x) => x.cartId !== r.cartId));
|
|
1373
1380
|
void reprintCart(lastPrinted, cart);
|
|
1374
|
-
}, children: "Opnieuw printen" })] }, r.cartId))) }) })), lastCartResults.length > 1 && (_jsxs("div", { className: "rounded-md border p-3 text-sm", "aria-label": "Resultaat per kar", children: [_jsx("p", { className: "mb-1 font-semibold text-foreground", children: "Resultaat per kar" }), _jsx("ul", { className: "space-y-0.5 text-muted-foreground", children: lastCartResults.map((r) => (_jsx("li", { className: r.outcome === "created" ? "text-foreground" : r.outcome === "error" ? "text-destructive" : "", children: cartResultLine(r) }, r.cartId))) })] })), _jsx(ShippingNoteScan, { stationId: station.id }), !pending && emptyNotice && (_jsx("p", { className: "text-sm text-muted-foreground", children: emptyNotice })), pending && (_jsxs(Card, { className: "border-2 border-primary", children: [_jsxs(CardContent, { className: "flex flex-col gap-4 p-4 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:p-5", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("confirmPrintTitle") }), _jsx("p", { className: "truncate text-xl font-bold text-foreground sm:text-2xl", children: pending.document_number ?? t("document") }), _jsx("p", { className: "truncate text-sm text-muted-foreground", children: [pending.order_number, pending.customer_name].filter(Boolean).join(" · ") })] }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [_jsx(Button, { variant: "outline", size: "lg", className: "h-12 w-full sm:w-auto", onClick: cancelPending, disabled: (busyId !== null || actionBusy), children: t("cancel") }), _jsxs(Button, { size: "lg", className: "h-14 w-full px-8 text-lg sm:w-auto", onClick: confirmPending, disabled: (busyId !== null || actionBusy) || fetchingData, variant: readiness.ready ? "default" : "secondary", children: [busyId === "confirm" || fetchingData ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : readiness.ready ? (_jsx(Printer, { className: "mr-2 h-5 w-5" })) : (_jsx(RefreshCw, { className: "mr-2 h-5 w-5" })), readiness.ready ? t("print") : "Pakbon ophalen"] })] })] }), !readiness.ready && (_jsx(CardContent, { className: "border-t p-4 sm:p-5", children: _jsxs("div", { className: "flex items-start gap-2 rounded-md border bg-muted/30 p-3 text-sm text-muted-foreground", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: fetchingData
|
|
1381
|
+
}, children: "Opnieuw printen" })] }, r.cartId))) }) })), lastCartResults.length > 1 && (_jsxs("div", { className: "rounded-md border p-3 text-sm", "aria-label": "Resultaat per kar", children: [_jsx("p", { className: "mb-1 font-semibold text-foreground", children: "Resultaat per kar" }), _jsx("ul", { className: "space-y-0.5 text-muted-foreground", children: lastCartResults.map((r) => (_jsx("li", { className: r.outcome === "created" ? "text-foreground" : r.outcome === "error" ? "text-destructive" : "", children: cartResultLine(r) }, r.cartId))) })] })), _jsx(VroegeStickerWaarschuwing, { stationId: station.id }), _jsx(ShippingNoteScan, { stationId: station.id }), !pending && emptyNotice && (_jsx("p", { className: "text-sm text-muted-foreground", children: emptyNotice })), pending && (_jsxs(Card, { className: "border-2 border-primary", children: [_jsxs(CardContent, { className: "flex flex-col gap-4 p-4 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between sm:p-5", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("confirmPrintTitle") }), _jsx("p", { className: "truncate text-xl font-bold text-foreground sm:text-2xl", children: pending.document_number ?? t("document") }), _jsx("p", { className: "truncate text-sm text-muted-foreground", children: [pending.order_number, pending.customer_name].filter(Boolean).join(" · ") })] }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [_jsx(Button, { variant: "outline", size: "lg", className: "h-12 w-full sm:w-auto", onClick: cancelPending, disabled: (busyId !== null || actionBusy), children: t("cancel") }), _jsxs(Button, { size: "lg", className: "h-14 w-full px-8 text-lg sm:w-auto", onClick: confirmPending, disabled: (busyId !== null || actionBusy) || fetchingData, variant: readiness.ready ? "default" : "secondary", children: [busyId === "confirm" || fetchingData ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : readiness.ready ? (_jsx(Printer, { className: "mr-2 h-5 w-5" })) : (_jsx(RefreshCw, { className: "mr-2 h-5 w-5" })), readiness.ready ? t("print") : "Pakbon ophalen"] })] })] }), !readiness.ready && (_jsx(CardContent, { className: "border-t p-4 sm:p-5", children: _jsxs("div", { className: "flex items-start gap-2 rounded-md border bg-muted/30 p-3 text-sm text-muted-foreground", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: fetchingData
|
|
1375
1382
|
? "De pakbon wordt opgevraagd. Zodra alles compleet is, verschijnt de printknop weer."
|
|
1376
1383
|
: planReason
|
|
1377
1384
|
? `${planReason} Klik op "Pakbon ophalen" om hem op te vragen.`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShippingNoteScan.d.ts","sourceRoot":"","sources":["../../../src/components/pick/ShippingNoteScan.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ShippingNoteScan.d.ts","sourceRoot":"","sources":["../../../src/components/pick/ShippingNoteScan.tsx"],"names":[],"mappings":"AAkBA,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,KAAK,+BA0NlE"}
|
|
@@ -3,6 +3,16 @@ import { useCallback, useState } from "react";
|
|
|
3
3
|
import { Badge, Button, Card, CardContent, Input, toast } from "@flowselections/core";
|
|
4
4
|
import { AlertTriangle, CheckCircle2, Loader2, ScanLine } from "lucide-react";
|
|
5
5
|
import { createShippingNote, lookupBarcode, } from "../../lib/shippingNote.js";
|
|
6
|
+
import { friendlyEngineMessage, isPakbonNumber, quantityText, SCAN_UNKNOWN, slipVariantText } from "../../lib/pick161.js";
|
|
7
|
+
import { pickDb } from "../../lib/pickApi.js";
|
|
8
|
+
async function toCartBarcode(code) {
|
|
9
|
+
if (!isPakbonNumber(code))
|
|
10
|
+
return code;
|
|
11
|
+
const { data, error } = await pickDb.rpc("pick_resolve_scan_code", { p_code: code });
|
|
12
|
+
if (error)
|
|
13
|
+
throw new Error(error.message);
|
|
14
|
+
return typeof data === "string" && data ? data : null;
|
|
15
|
+
}
|
|
6
16
|
/**
|
|
7
17
|
* Pakbon scannen -> verzendbrief. De module zoekt eerst op (leest alleen) en
|
|
8
18
|
* maakt pas na een expliciete bevestiging een verzendbrief aan via de Engine.
|
|
@@ -11,7 +21,19 @@ export function ShippingNoteScan({ stationId, onJobCreated }) {
|
|
|
11
21
|
const [code, setCode] = useState("");
|
|
12
22
|
const [busy, setBusy] = useState(false);
|
|
13
23
|
const [found, setFound] = useState(null);
|
|
14
|
-
const [notice,
|
|
24
|
+
const [notice, setNoticeRaw] = useState(null);
|
|
25
|
+
const [detail, setDetail] = useState(null);
|
|
26
|
+
const [status, setStatus] = useState(null);
|
|
27
|
+
const setNotice = useCallback((raw, fallback = SCAN_UNKNOWN) => {
|
|
28
|
+
if (raw == null) {
|
|
29
|
+
setNoticeRaw(null);
|
|
30
|
+
setDetail(null);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const f = friendlyEngineMessage(raw, fallback);
|
|
34
|
+
setNoticeRaw(f.message);
|
|
35
|
+
setDetail(f.detail);
|
|
36
|
+
}, []);
|
|
15
37
|
const [reprintNotice, setReprintNotice] = useState(null);
|
|
16
38
|
const [warning, setWarning] = useState(null);
|
|
17
39
|
const reset = useCallback(() => {
|
|
@@ -23,31 +45,43 @@ export function ShippingNoteScan({ stationId, onJobCreated }) {
|
|
|
23
45
|
const barcode = raw.trim();
|
|
24
46
|
if (!barcode)
|
|
25
47
|
return;
|
|
48
|
+
let found_barcode = barcode;
|
|
26
49
|
setBusy(true);
|
|
27
50
|
reset();
|
|
28
51
|
setNotice(null);
|
|
52
|
+
setStatus("Pakbon opzoeken…");
|
|
29
53
|
try {
|
|
30
|
-
const
|
|
54
|
+
const cartBarcode = await toCartBarcode(barcode);
|
|
55
|
+
if (!cartBarcode) {
|
|
56
|
+
setNotice(null);
|
|
57
|
+
setNoticeRaw(SCAN_UNKNOWN);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const lookup = await lookupBarcode(cartBarcode);
|
|
31
61
|
if (!lookup.ok) {
|
|
32
|
-
|
|
33
|
-
|
|
62
|
+
setNoticeRaw(SCAN_UNKNOWN);
|
|
63
|
+
setDetail(lookup.error);
|
|
34
64
|
return;
|
|
35
65
|
}
|
|
36
|
-
|
|
66
|
+
found_barcode = cartBarcode;
|
|
67
|
+
setFound({ barcode: found_barcode, lookup });
|
|
37
68
|
setCode("");
|
|
38
69
|
}
|
|
39
70
|
catch (e) {
|
|
40
|
-
|
|
71
|
+
setNoticeRaw("De pakbon kon niet worden opgezocht. Probeer het opnieuw.");
|
|
72
|
+
setDetail(e instanceof Error ? e.message : null);
|
|
41
73
|
}
|
|
42
74
|
finally {
|
|
43
75
|
setBusy(false);
|
|
76
|
+
setStatus(null);
|
|
44
77
|
}
|
|
45
|
-
}, [reset]);
|
|
78
|
+
}, [reset, setNotice]);
|
|
46
79
|
const handleConfirm = useCallback(async (allowReprint) => {
|
|
47
80
|
if (!found)
|
|
48
81
|
return;
|
|
49
82
|
setBusy(true);
|
|
50
83
|
setWarning(null);
|
|
84
|
+
setStatus("Verzendbrief klaarzetten…");
|
|
51
85
|
try {
|
|
52
86
|
const result = await createShippingNote({
|
|
53
87
|
barcode: found.barcode,
|
|
@@ -56,10 +90,12 @@ export function ShippingNoteScan({ stationId, onJobCreated }) {
|
|
|
56
90
|
});
|
|
57
91
|
if (!result.ok) {
|
|
58
92
|
if (result.errorCode === "al_geprint") {
|
|
59
|
-
setReprintNotice(
|
|
93
|
+
setReprintNotice("Er is al een verzendbrief voor deze kar gemaakt.");
|
|
60
94
|
return;
|
|
61
95
|
}
|
|
62
|
-
setNotice(result.error ?? "De verzendbrief kon niet worden klaargezet.");
|
|
96
|
+
setNotice(result.error ?? result.errorCode ?? null, "De verzendbrief kon niet worden klaargezet. Meld dit bij kantoor.");
|
|
97
|
+
if (!result.error && !result.errorCode)
|
|
98
|
+
setNoticeRaw("De verzendbrief kon niet worden klaargezet. Meld dit bij kantoor.");
|
|
63
99
|
reset();
|
|
64
100
|
return;
|
|
65
101
|
}
|
|
@@ -73,17 +109,20 @@ export function ShippingNoteScan({ stationId, onJobCreated }) {
|
|
|
73
109
|
setReprintNotice(null);
|
|
74
110
|
}
|
|
75
111
|
catch (e) {
|
|
76
|
-
setNotice(e instanceof Error ? e.message : "De verzendbrief kon niet worden klaargezet.");
|
|
112
|
+
setNotice(e instanceof Error ? e.message : null, "De verzendbrief kon niet worden klaargezet. Probeer het opnieuw.");
|
|
113
|
+
if (!(e instanceof Error))
|
|
114
|
+
setNoticeRaw("De verzendbrief kon niet worden klaargezet. Probeer het opnieuw.");
|
|
77
115
|
}
|
|
78
116
|
finally {
|
|
79
117
|
setBusy(false);
|
|
118
|
+
setStatus(null);
|
|
80
119
|
}
|
|
81
|
-
}, [found, stationId, onJobCreated, reset]);
|
|
120
|
+
}, [found, stationId, onJobCreated, reset, setNotice]);
|
|
82
121
|
const cart = found?.lookup.cart ?? null;
|
|
83
|
-
return (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-3 p-3 sm:p-4", children: [_jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [_jsx("p", { className: "text-sm font-semibold text-foreground", children: "Pakbon scannen" }), _jsxs("div", { className: "relative w-full min-w-0 sm:w-72", children: [_jsx(ScanLine, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { className: "h-12 pl-9 text-base", placeholder: "
|
|
122
|
+
return (_jsx(Card, { children: _jsxs(CardContent, { className: "space-y-3 p-3 sm:p-4", children: [_jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [_jsx("p", { className: "text-sm font-semibold text-foreground", children: "Pakbon scannen" }), _jsxs("div", { className: "relative w-full min-w-0 sm:w-72", children: [_jsx(ScanLine, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { className: "h-12 pl-9 text-base", placeholder: "Pakbonnummer of barcode onderaan de pakbon", value: code, disabled: busy, onChange: (e) => setCode(e.target.value), onKeyDown: (e) => {
|
|
84
123
|
if (e.key !== "Enter")
|
|
85
124
|
return;
|
|
86
125
|
e.preventDefault();
|
|
87
126
|
void handleLookup(code);
|
|
88
|
-
} })] })] }), notice && (_jsxs("div", { className: "flex items-start gap-2 rounded-md border-2 border-destructive/50 bg-destructive/5 p-3 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: notice })] })), warning && (_jsxs("div", { className: "flex items-start gap-2 rounded-md border p-3 text-sm text-muted-foreground", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: warning })] })), found && (_jsxs("div", { className: "rounded-md border-2 border-primary/40 bg-muted/20 p-3 sm:p-4", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-lg font-bold text-foreground", children: found.lookup.orderNumber ?? "Order" }), _jsx("p", { className: "truncate text-sm text-muted-foreground", children: [found.lookup.customerName, cart?.cartLabel].filter(Boolean).join(" · ") })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [cart?.slipVariant && _jsx(Badge, { variant: "outline", children: cart
|
|
127
|
+
} })] })] }), notice && (_jsxs("div", { className: "flex items-start gap-2 rounded-md border-2 border-destructive/50 bg-destructive/5 p-3 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: notice })] })), status && (_jsxs("p", { role: "status", className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " ", status] })), detail && notice && (_jsxs("details", { className: "text-xs text-muted-foreground", children: [_jsx("summary", { className: "cursor-pointer", children: "Details voor beheer" }), _jsx("p", { children: detail })] })), warning && (_jsxs("div", { className: "flex items-start gap-2 rounded-md border p-3 text-sm text-muted-foreground", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: warning })] })), found && (_jsxs("div", { className: "rounded-md border-2 border-primary/40 bg-muted/20 p-3 sm:p-4", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-lg font-bold text-foreground", children: found.lookup.orderNumber ?? "Order" }), _jsx("p", { className: "truncate text-sm text-muted-foreground", children: [found.lookup.customerName, cart?.cartLabel].filter(Boolean).join(" · ") })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [slipVariantText(cart?.slipVariant) && _jsx(Badge, { variant: "outline", children: slipVariantText(cart?.slipVariant) }), cart?.barcode && _jsx(Badge, { variant: "outline", children: cart.barcode }), found.lookup.alreadyPrinted && (_jsxs(Badge, { className: "bg-destructive text-destructive-foreground", children: ["Al geprint (", found.lookup.printCount, ")"] }))] })] }), _jsx("div", { className: "mt-3 divide-y rounded-md border bg-background", children: cart && cart.items.length > 0 ? (cart.items.map((item, index) => (_jsxs("div", { className: "flex items-center justify-between gap-3 p-3", children: [_jsx("span", { className: "min-w-0 truncate text-sm text-foreground", children: item.productName }), _jsx("span", { className: "shrink-0 text-sm font-semibold text-foreground", children: quantityText(item.quantity, item.crates) })] }, `${item.productName}-${index}`)))) : (_jsx("p", { className: "p-3 text-sm text-muted-foreground", children: "Geen regels bij deze kar." })) }), reprintNotice && (_jsxs("div", { className: "mt-3 flex items-start gap-2 rounded-md border-2 border-destructive/50 bg-destructive/5 p-3 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: reprintNotice })] })), _jsxs("div", { className: "mt-3 flex flex-col gap-2 sm:flex-row sm:justify-end", children: [_jsx(Button, { variant: "outline", size: "lg", className: "h-12 w-full sm:w-auto", onClick: reset, disabled: busy, children: "Annuleren" }), _jsxs(Button, { size: "lg", className: "h-12 w-full sm:w-auto", onClick: () => void handleConfirm(reprintNotice !== null), disabled: busy, children: [busy ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : (_jsx(CheckCircle2, { className: "mr-2 h-5 w-5" })), reprintNotice ? "Toch opnieuw printen" : "Verzendbrief klaarzetten"] })] })] }))] }) }));
|
|
89
128
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StationDevices.d.ts","sourceRoot":"","sources":["../../../src/components/pick/StationDevices.tsx"],"names":[],"mappings":"AAOA,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,+BAyE7F"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import QRCode from "qrcode";
|
|
4
|
+
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
|
+
import { Button, toast } from "@flowselections/core";
|
|
6
|
+
import { Loader2, Smartphone } from "lucide-react";
|
|
7
|
+
import { createPairCode, listDevices, revokeDevice } from "../../lib/pick159.js";
|
|
8
|
+
/** Beheer: apparaat koppelen (code + QR-link) en apparaten intrekken. */
|
|
9
|
+
export function StationDevices({ stationId, slug }) {
|
|
10
|
+
const qc = useQueryClient();
|
|
11
|
+
const [code, setCode] = useState(null);
|
|
12
|
+
const [bezig, setBezig] = useState(false);
|
|
13
|
+
const { data: devices = [], isLoading } = useQuery({
|
|
14
|
+
queryKey: ["pick", "devices", stationId],
|
|
15
|
+
queryFn: () => listDevices(stationId),
|
|
16
|
+
});
|
|
17
|
+
const actief = (Array.isArray(devices) ? devices : []).filter((d) => !d.ingetrokken_op);
|
|
18
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
19
|
+
const link = code && slug ? `${origin}/pickstation/${slug}?koppelcode=${code.code}` : null;
|
|
20
|
+
const [qr, setQr] = useState(null);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
// QR wordt in de browser zelf getekend; er gaat niets naar een dienst van buiten.
|
|
23
|
+
if (!link)
|
|
24
|
+
return setQr(null);
|
|
25
|
+
let actief = true;
|
|
26
|
+
QRCode.toDataURL(link, { margin: 1, width: 220 }).then((u) => actief && setQr(u)).catch(() => actief && setQr(null));
|
|
27
|
+
return () => {
|
|
28
|
+
actief = false;
|
|
29
|
+
};
|
|
30
|
+
}, [link]);
|
|
31
|
+
async function nieuweCode() {
|
|
32
|
+
setBezig(true);
|
|
33
|
+
try {
|
|
34
|
+
setCode(await createPairCode(stationId));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
toast.error("Er kon geen koppelcode worden gemaakt.");
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
setBezig(false);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function intrekken(id) {
|
|
44
|
+
if (!window.confirm("Dit apparaat intrekken? Het kan daarna niet meer printen."))
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
await revokeDevice(id);
|
|
48
|
+
void qc.invalidateQueries({ queryKey: ["pick", "devices", stationId] });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
toast.error("Intrekken lukte niet.");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("p", { className: "text-sm font-medium text-foreground", children: ["Apparaten ", isLoading ? "" : actief.length === 0 ? "– nog niet gekoppeld" : `– ${actief.length} gekoppeld`] }), actief.map((d) => (_jsxs("div", { className: "flex items-center justify-between gap-2 text-sm", children: [_jsxs("span", { className: "flex items-center gap-2 text-muted-foreground", children: [_jsx(Smartphone, { className: "h-4 w-4" }), d.naam ?? "Apparaat", d.laatst_gezien ? ` · laatst gezien ${new Date(d.laatst_gezien).toLocaleString("nl-NL")}` : ""] }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => void intrekken(d.id), children: "Intrekken" })] }, d.id))), _jsxs(Button, { size: "sm", variant: "secondary", disabled: bezig, onClick: () => void nieuweCode(), children: [bezig ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null, "Apparaat koppelen"] }), code ? (_jsxs("div", { className: "rounded-md border border-border p-3 text-sm", children: [_jsxs("p", { children: ["Koppelcode: ", _jsx("span", { className: "font-mono text-lg font-bold tracking-widest", children: code.code })] }), _jsx("p", { className: "text-muted-foreground", children: "10 minuten geldig, maximaal 5 pogingen." }), qr ? _jsx("img", { src: qr, alt: "QR-code om dit apparaat te koppelen", className: "mt-2 h-44 w-44 rounded bg-background" }) : null, link ? _jsxs("p", { className: "mt-2 break-all text-muted-foreground", children: ["Of open op het apparaat: ", link] }) : null] })) : null] }));
|
|
55
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Volledig scherm voor een apparaat zonder geldige sleutel. */
|
|
2
|
+
export declare function StationPairing({ slug, initialCode, onPaired }: {
|
|
3
|
+
slug: string;
|
|
4
|
+
initialCode?: string;
|
|
5
|
+
onPaired: () => void;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=StationPairing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StationPairing.d.ts","sourceRoot":"","sources":["../../../src/components/pick/StationPairing.tsx"],"names":[],"mappings":"AAKA,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAAE,+BAuC3H"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Button, Card, CardContent, Input, Label } from "@flowselections/core";
|
|
4
|
+
import { Loader2 } from "lucide-react";
|
|
5
|
+
import { NOT_PAIRED_TEXT, pairDevice, saveDeviceKey } from "../../lib/pick159.js";
|
|
6
|
+
/** Volledig scherm voor een apparaat zonder geldige sleutel. */
|
|
7
|
+
export function StationPairing({ slug, initialCode, onPaired }) {
|
|
8
|
+
const [code, setCode] = useState(initialCode ?? "");
|
|
9
|
+
const [naam, setNaam] = useState("");
|
|
10
|
+
const [bezig, setBezig] = useState(false);
|
|
11
|
+
const [fout, setFout] = useState(null);
|
|
12
|
+
async function koppel() {
|
|
13
|
+
setBezig(true);
|
|
14
|
+
setFout(null);
|
|
15
|
+
const r = await pairDevice(slug, code.trim().toUpperCase(), naam.trim() || null);
|
|
16
|
+
setBezig(false);
|
|
17
|
+
if (r.ok) {
|
|
18
|
+
saveDeviceKey(slug, r.key);
|
|
19
|
+
onPaired();
|
|
20
|
+
}
|
|
21
|
+
else
|
|
22
|
+
setFout(r.tekst);
|
|
23
|
+
}
|
|
24
|
+
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-4", children: _jsx(Card, { className: "w-full max-w-md", children: _jsxs(CardContent, { className: "space-y-4 p-6", children: [_jsx("p", { className: "text-lg font-semibold text-foreground", children: NOT_PAIRED_TEXT }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "pair-code", children: "Koppelcode" }), _jsx(Input, { id: "pair-code", value: code, maxLength: 6, autoComplete: "off", onChange: (e) => setCode(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "pair-naam", children: "Naam van dit apparaat (mag leeg)" }), _jsx(Input, { id: "pair-naam", value: naam, maxLength: 80, onChange: (e) => setNaam(e.target.value) })] }), fout ? _jsx("p", { className: "text-sm text-destructive", children: fout }) : null, _jsxs(Button, { className: "w-full", disabled: bezig || code.trim().length !== 6, onClick: () => void koppel(), children: [bezig ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null, "Koppelen"] })] }) }) }));
|
|
25
|
+
}
|
|
@@ -13,4 +13,8 @@ export declare function CartStickerState({ cartId, slug }: {
|
|
|
13
13
|
cartId: string;
|
|
14
14
|
slug: string | null;
|
|
15
15
|
}): import("react").JSX.Element | null;
|
|
16
|
+
/** Bovenaan het pickstation: stickers die vandaag/morgen via A4 of verkleind gaan. Niets als Layouts het nog niet levert. */
|
|
17
|
+
export declare function VroegeStickerWaarschuwing({ stationId }: {
|
|
18
|
+
stationId: string | null;
|
|
19
|
+
}): import("react").JSX.Element | null;
|
|
16
20
|
//# sourceMappingURL=StickerState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StickerState.d.ts","sourceRoot":"","sources":["../../../src/components/pick/StickerState.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StickerState.d.ts","sourceRoot":"","sources":["../../../src/components/pick/StickerState.tsx"],"names":[],"mappings":"AAcA,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,sCAuC5F;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,sCAoBvG;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,sCA8CzF;AAED,6HAA6H;AAC7H,wBAAgB,yBAAyB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,sCAiBpF"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useQuery } from "@tanstack/react-query";
|
|
3
|
-
import { fetchCartStickerState, fetchOrderStickerMeldingen, STICKER_UNKNOWN, stickerStatusLabel,
|
|
3
|
+
import { fetchCartStickerState, fetchOrderStickerMeldingen, STICKER_UNKNOWN, stickerStatusLabel, } from "../../lib/pickStickers.js";
|
|
4
|
+
import { stickerLine } from "../../lib/pick161.js";
|
|
5
|
+
import { fetchUitwijk, fetchVroegeWaarschuwing, vroegeWaarschuwingText } from "../../lib/pickUitwijk.js";
|
|
4
6
|
import { fetchStickerFit, STICKER_FIT_UNKNOWN, stickerFitTone } from "../../lib/pick150.js";
|
|
5
7
|
const POLL = 15000;
|
|
6
8
|
/** Controle vooraf of de klantstickers van de kar passen; vóór het printen. */
|
|
@@ -59,15 +61,39 @@ export function CartStickerState({ cartId, slug }) {
|
|
|
59
61
|
placeholderData: (prev) => prev,
|
|
60
62
|
retry: 1,
|
|
61
63
|
});
|
|
64
|
+
const jobIds = Array.isArray(q.data?.regels) ? q.data.regels.map((r) => r.printJobId).filter((x) => !!x).sort() : [];
|
|
65
|
+
const u = useQuery({
|
|
66
|
+
queryKey: ["pick", "uitwijk", jobIds.join(",")],
|
|
67
|
+
queryFn: () => fetchUitwijk(jobIds),
|
|
68
|
+
enabled: jobIds.length > 0,
|
|
69
|
+
refetchInterval: POLL,
|
|
70
|
+
placeholderData: (prev) => prev,
|
|
71
|
+
retry: 1,
|
|
72
|
+
});
|
|
62
73
|
if (q.isLoading)
|
|
63
74
|
return null;
|
|
64
75
|
if (q.isError || !q.data) {
|
|
65
76
|
return _jsx("p", { className: "mt-3 text-xs text-muted-foreground", children: STICKER_UNKNOWN });
|
|
66
77
|
}
|
|
67
78
|
const s = q.data;
|
|
79
|
+
const line = stickerLine(s, u.data);
|
|
68
80
|
const regels = Array.isArray(s.regels) ? s.regels : [];
|
|
69
|
-
const summary = stickerSummary(s);
|
|
70
81
|
if (s.totaal === 0)
|
|
71
|
-
return _jsx("p", { className: "mt-3 text-
|
|
72
|
-
return (_jsxs("details", { className: "mt-3 rounded-md border bg-background p-3 text-sm", children: [_jsxs("summary", { className: "cursor-pointer font-medium text-foreground", children: ["Stickers: ",
|
|
82
|
+
return _jsx("p", { className: "mt-3 text-sm text-muted-foreground", children: line });
|
|
83
|
+
return (_jsxs("details", { className: "mt-3 rounded-md border bg-background p-3 text-sm", children: [_jsxs("summary", { className: "cursor-pointer font-medium text-foreground", children: ["Stickers: ", line] }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "In de printwachtrij betekent nog niet fysiek geprint." }), _jsx("ul", { className: "mt-2 divide-y", children: regels.map((r, i) => (_jsxs("li", { className: "flex flex-wrap justify-between gap-2 py-1.5 text-xs", children: [_jsxs("span", { className: "text-foreground", children: [r.soort ?? "sticker", " \u00B7 ", r.kopieen ?? "—", "x", r.breedteMm && r.hoogteMm ? ` · ${r.breedteMm}x${r.hoogteMm} mm` : ""] }), _jsxs("span", { className: "text-muted-foreground", children: [stickerStatusLabel(r.status), r.reden ? ` — ${r.reden}` : ""] })] }, r.stickerId ?? i))) })] }));
|
|
84
|
+
}
|
|
85
|
+
/** Bovenaan het pickstation: stickers die vandaag/morgen via A4 of verkleind gaan. Niets als Layouts het nog niet levert. */
|
|
86
|
+
export function VroegeStickerWaarschuwing({ stationId }) {
|
|
87
|
+
const q = useQuery({
|
|
88
|
+
queryKey: ["pick", "vroege-sticker", stationId],
|
|
89
|
+
queryFn: () => fetchVroegeWaarschuwing(stationId),
|
|
90
|
+
refetchInterval: 5 * 60000,
|
|
91
|
+
placeholderData: (prev) => prev,
|
|
92
|
+
retry: 1,
|
|
93
|
+
});
|
|
94
|
+
const list = Array.isArray(q.data) ? q.data : [];
|
|
95
|
+
if (list.length === 0)
|
|
96
|
+
return null;
|
|
97
|
+
const today = new Date().toLocaleDateString("sv-SE");
|
|
98
|
+
return (_jsxs("div", { role: "status", className: "mb-3 space-y-1 rounded-md border-2 border-primary/40 bg-primary/5 p-3 text-sm text-foreground", children: [_jsx("p", { className: "font-medium", children: "Let op: stickers passen niet op het gewone etiket" }), list.map((w, i) => _jsx("p", { children: vroegeWaarschuwingText(w, today) }, i))] }));
|
|
73
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePickQueue.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickQueue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG9E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,EAAE,YAS5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"usePickQueue.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickQueue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG9E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,EAAE,YAS5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;;;;;;;;;;;IAoMG,gEAAgE;;IAEhE,6EAA6E;;;EAIhF;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM;;EAuBhG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,iFAOnF;AACD,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,OAAO,UAAO;;;YAQzC;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAEpF"}
|
|
@@ -164,6 +164,10 @@ export function usePickQueue(args) {
|
|
|
164
164
|
.channel(`pick-queue-${stationId ?? "all"}`)
|
|
165
165
|
.on("postgres_changes", queueFilter, invalidate)
|
|
166
166
|
.on("postgres_changes", lockFilter, invalidate)
|
|
167
|
+
// 1.0.59: alleen een seintje per station; de gegevens komen via functies met sleutel.
|
|
168
|
+
.on("postgres_changes", stationId
|
|
169
|
+
? { event: "UPDATE", schema: "public", table: "pick_station_signals", filter: `station_id=eq.${stationId}` }
|
|
170
|
+
: { event: "UPDATE", schema: "public", table: "pick_station_signals" }, invalidate)
|
|
167
171
|
.subscribe((status) => {
|
|
168
172
|
setRealtimeOk(status === "SUBSCRIBED");
|
|
169
173
|
});
|
package/dist-lib/index.d.ts
CHANGED
|
@@ -31,5 +31,6 @@ export * from "./lib/pick145.js";
|
|
|
31
31
|
export * from "./lib/pick150.js";
|
|
32
32
|
export * from "./lib/pick152.js";
|
|
33
33
|
export * from "./lib/pick156.js";
|
|
34
|
+
export * from "./lib/pick159.js";
|
|
34
35
|
export { DocumentChoiceMelding, useDocumentChoice } from "./components/pick/DocumentChoiceMelding.js";
|
|
35
36
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC9F,OAAO,EAAE,gCAAgC,EAAE,MAAM,wDAAwD,CAAC;AAC1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,eAAO,MAAM,kBAAkB,EAAE,UAYhC,CAAC;AAEF,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACzF,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC9F,OAAO,EAAE,gCAAgC,EAAE,MAAM,wDAAwD,CAAC;AAC1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,eAAO,MAAM,kBAAkB,EAAE,UAYhC,CAAC;AAEF,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACzF,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC"}
|
package/dist-lib/index.js
CHANGED
|
@@ -56,4 +56,5 @@ export * from "./lib/pick145.js";
|
|
|
56
56
|
export * from "./lib/pick150.js";
|
|
57
57
|
export * from "./lib/pick152.js";
|
|
58
58
|
export * from "./lib/pick156.js";
|
|
59
|
+
export * from "./lib/pick159.js";
|
|
59
60
|
export { DocumentChoiceMelding, useDocumentChoice } from "./components/pick/DocumentChoiceMelding.js";
|