@flowselections/pick-schermen-kwekers 1.0.11 → 1.0.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"PickstationsPage.d.ts","sourceRoot":"","sources":["../../src/components/PickstationsPage.tsx"],"names":[],"mappings":"AAmCA,wBAAgB,gBAAgB,gCAkL/B"}
1
+ {"version":3,"file":"PickstationsPage.d.ts","sourceRoot":"","sources":["../../src/components/PickstationsPage.tsx"],"names":[],"mappings":"AAwDA,wBAAgB,gBAAgB,gCA2O/B"}
@@ -1,41 +1,55 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { useMutation, useQueryClient } from "@tanstack/react-query";
4
- import { Button, Card, CardContent, Dialog, DialogContent, DialogHeader, DialogTitle, Input, Label, Switch, Textarea, toast, } from "@flowselections/core";
5
- import { Copy, ExternalLink, Loader2, Pencil, Plus, Trash2 } from "lucide-react";
4
+ import { Button, Card, CardContent, Dialog, DialogContent, DialogHeader, DialogTitle, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Switch, Textarea, toast, } from "@flowselections/core";
5
+ import { AlertTriangle, Copy, ExternalLink, Loader2, Pencil, Plus, Printer, Trash2, } from "lucide-react";
6
6
  import { pickApi } from "../lib/pickApi";
7
- import { usePickStations } from "../hooks/usePickConfig";
8
- const emptyDraft = { name: "", description: "", active: true };
7
+ import { usePickPrintPlekken, usePickStations, useStationPrintPlekken, } from "../hooks/usePickConfig";
8
+ const NO_PLEK = "__geen__";
9
+ const emptyDraft = { name: "", description: "", active: true, printPlekId: null };
9
10
  function publicUrl(slug) {
10
11
  const origin = typeof window !== "undefined" ? window.location.origin : "";
11
12
  return `${origin}/pickstation/${slug ?? ""}`;
12
13
  }
13
14
  export function PickstationsPage() {
14
15
  const { data: stations, isLoading } = usePickStations();
16
+ const { data: printPlekken } = usePickPrintPlekken();
17
+ const { data: koppelingen } = useStationPrintPlekken();
15
18
  const queryClient = useQueryClient();
16
19
  const [draft, setDraft] = useState(null);
17
20
  const safeStations = Array.isArray(stations) ? stations : [];
21
+ const safePlekken = Array.isArray(printPlekken) ? printPlekken : [];
22
+ const safeKoppelingen = Array.isArray(koppelingen) ? koppelingen : [];
23
+ const plekOf = (stationId) => safeKoppelingen.find((k) => k.station_id === stationId) ?? null;
18
24
  const save = useMutation({
19
25
  mutationFn: async (d) => {
20
- await pickApi.upsert("pick_stations", {
26
+ const row = await pickApi.upsert("pick_stations", {
21
27
  ...(d.id ? { id: d.id } : {}),
22
28
  name: d.name.trim(),
23
29
  description: d.description.trim() || null,
24
30
  active: d.active,
25
31
  });
32
+ const stationId = d.id ?? row?.["id"] ?? null;
33
+ if (stationId)
34
+ await pickApi.setStationPrintPlek(stationId, d.printPlekId);
26
35
  },
27
36
  onSuccess: () => {
28
37
  toast.success("Pickstation opgeslagen.");
29
38
  setDraft(null);
30
39
  queryClient.invalidateQueries({ queryKey: ["pick", "stations"] });
40
+ queryClient.invalidateQueries({ queryKey: ["pick", "stationPrintPlekken"] });
31
41
  },
32
42
  onError: (e) => toast.error(e instanceof Error ? e.message : "Opslaan mislukt."),
33
43
  });
34
44
  const remove = useMutation({
35
- mutationFn: (id) => pickApi.remove("pick_stations", id),
45
+ mutationFn: async (id) => {
46
+ await pickApi.setStationPrintPlek(id, null);
47
+ await pickApi.remove("pick_stations", id);
48
+ },
36
49
  onSuccess: () => {
37
50
  toast.success("Pickstation verwijderd.");
38
51
  queryClient.invalidateQueries({ queryKey: ["pick", "stations"] });
52
+ queryClient.invalidateQueries({ queryKey: ["pick", "stationPrintPlekken"] });
39
53
  },
40
54
  onError: (e) => toast.error(e instanceof Error ? e.message : "Verwijderen mislukt."),
41
55
  });
@@ -52,10 +66,11 @@ export function PickstationsPage() {
52
66
  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 hun openbare link. Alle logica komt uit de Logistiek Engine." })] }), _jsxs(Button, { onClick: () => setDraft({ ...emptyDraft }), children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), " Nieuw pickstation"] })] }), 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 " +
53
67
  (station.active
54
68
  ? "bg-primary/10 text-primary"
55
- : "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) }), _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({
69
+ : "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) }), plekOf(station.id) ? (_jsxs("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(Printer, { className: "h-4 w-4 shrink-0" }), _jsxs("span", { className: "truncate", children: ["Printplek: ", plekOf(station.id)?.naam] })] })) : (_jsxs("p", { className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-2 py-1.5 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), "Nog geen printplek gekoppeld \u2014 de opdracht blijft in de wachtrij staan."] })), _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({
56
70
  id: station.id,
57
71
  name: station.name,
58
72
  description: station.description ?? "",
59
73
  active: station.active,
60
- }), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), " Wijzigen"] }), _jsxs(Button, { variant: "ghost", size: "sm", className: "text-destructive", onClick: () => remove.mutate(station.id), children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), " Verwijderen"] })] })] }) }, station.id))) })), _jsx(Dialog, { open: draft !== null, onOpenChange: (open) => !open && setDraft(null), children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: draft?.id ? "Pickstation wijzigen" : "Nieuw pickstation" }) }), draft && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "station-name", children: "Naam" }), _jsx(Input, { id: "station-name", value: draft.name, onChange: (e) => setDraft({ ...draft, name: e.target.value }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "station-desc", children: "Omschrijving (optioneel)" }), _jsx(Textarea, { id: "station-desc", value: draft.description, onChange: (e) => setDraft({ ...draft, description: e.target.value }) })] }), _jsxs("div", { className: "flex items-center justify-between rounded-md border px-3 py-2", children: [_jsx(Label, { htmlFor: "station-active", children: "Actief" }), _jsx(Switch, { id: "station-active", checked: draft.active, onCheckedChange: (v) => setDraft({ ...draft, active: v }) })] }), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => setDraft(null), children: "Annuleren" }), _jsxs(Button, { disabled: !draft.name.trim() || save.isPending, onClick: () => save.mutate(draft), children: [save.isPending && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), " Opslaan"] })] })] }))] }) })] }));
74
+ printPlekId: plekOf(station.id)?.print_plek_id ?? null,
75
+ }), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), " Wijzigen"] }), _jsxs(Button, { variant: "ghost", size: "sm", className: "text-destructive", onClick: () => remove.mutate(station.id), children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), " Verwijderen"] })] })] }) }, station.id))) })), _jsx(Dialog, { open: draft !== null, onOpenChange: (open) => !open && setDraft(null), children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: draft?.id ? "Pickstation wijzigen" : "Nieuw pickstation" }) }), draft && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "station-name", children: "Naam" }), _jsx(Input, { id: "station-name", value: draft.name, onChange: (e) => setDraft({ ...draft, name: e.target.value }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "station-desc", children: "Omschrijving (optioneel)" }), _jsx(Textarea, { id: "station-desc", value: draft.description, onChange: (e) => setDraft({ ...draft, description: e.target.value }) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "station-plek", children: "Printplek" }), _jsxs(Select, { value: draft.printPlekId ?? NO_PLEK, onValueChange: (v) => setDraft({ ...draft, printPlekId: v === NO_PLEK ? null : v }), children: [_jsx(SelectTrigger, { id: "station-plek", children: _jsx(SelectValue, { placeholder: "Kies een printplek" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: NO_PLEK, children: "Geen printplek" }), safePlekken.map((plek) => (_jsxs(SelectItem, { value: plek.id, children: [plek.naam, plek.omschrijving ? ` — ${plek.omschrijving}` : ""] }, plek.id)))] })] }), !draft.printPlekId && (_jsx("p", { className: "text-sm text-destructive", children: "Nog geen printplek gekoppeld \u2014 de opdracht blijft in de wachtrij staan." }))] }), _jsxs("div", { className: "flex items-center justify-between rounded-md border px-3 py-2", children: [_jsx(Label, { htmlFor: "station-active", children: "Actief" }), _jsx(Switch, { id: "station-active", checked: draft.active, onCheckedChange: (v) => setDraft({ ...draft, active: v }) })] }), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => setDraft(null), children: "Annuleren" }), _jsxs(Button, { disabled: !draft.name.trim() || save.isPending, onClick: () => save.mutate(draft), children: [save.isPending && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), " Opslaan"] })] })] }))] }) })] }));
61
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PickScherm.d.ts","sourceRoot":"","sources":["../../../src/components/pick/PickScherm.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAatE,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,+BAslBpD"}
1
+ {"version":3,"file":"PickScherm.d.ts","sourceRoot":"","sources":["../../../src/components/pick/PickScherm.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAkBtE,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,+BAgmBpD"}
@@ -10,7 +10,7 @@ import { getPickTranslator } from "../../lib/pickI18n";
10
10
  import { friendlyPickError, getPickUiTexts } from "../../lib/pickUiText";
11
11
  import { getPrintJobTexts, printJobStatusLabel } from "../../lib/pickPrintJobText";
12
12
  import { defaultFilters, usePickHeartbeat, usePickQueue, } from "../../hooks/usePickQueue";
13
- import { usePickDocumentTypes, usePickStatuses } from "../../hooks/usePickConfig";
13
+ import { usePickDocumentTypes, usePickStatuses, useStationPrintPlek, } from "../../hooks/usePickConfig";
14
14
  import { usePrintJob } from "../../hooks/usePrintJob";
15
15
  const LANG_STORAGE_KEY = "pick.language";
16
16
  /**
@@ -33,6 +33,7 @@ export function PickScherm({ station, onBack }) {
33
33
  const { data: statuses } = usePickStatuses();
34
34
  const { data: documentTypes } = usePickDocumentTypes();
35
35
  const { online } = usePickHeartbeat(station.id, null, sessionId);
36
+ const { data: printPlek, isLoading: plekLoading } = useStationPrintPlek(station.id);
36
37
  const { tracked, track, clear: clearJob } = usePrintJob();
37
38
  const t = useMemo(() => getPickTranslator(lang ?? "nl"), [lang]);
38
39
  const jobTexts = useMemo(() => getPrintJobTexts(t.lang), [t]);
@@ -295,7 +296,7 @@ export function PickScherm({ station, onBack }) {
295
296
  const totalPages = Math.max(1, Math.ceil(total / filters.pageSize));
296
297
  const jobStatus = tracked?.job?.status ?? null;
297
298
  const jobFailed = jobStatus === "mislukt" || jobStatus === "geannuleerd";
298
- return (_jsxs("div", { className: "space-y-4 pb-24 md:pb-0", children: [_jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:flex-wrap md:items-center md:justify-between", children: [_jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: [_jsxs(Button, { variant: "outline", size: "lg", className: "h-12 shrink-0 px-3 sm:px-4", onClick: () => setLang(null), "aria-label": t("changeLanguage"), children: [_jsx(Globe, { className: "h-5 w-5 sm:mr-2" }), _jsx("span", { className: "hidden sm:inline", children: t("changeLanguage") })] }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "truncate text-lg font-bold text-foreground sm:text-xl", children: station.name }), _jsxs("p", { className: "truncate text-sm text-muted-foreground", children: [pendingCount, " ", t("statusToPrint"), " \u00B7 ", printedCount, " ", t("statusPrinted")] })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [!online && (_jsxs(Badge, { className: "bg-destructive text-destructive-foreground", children: [_jsx(WifiOff, { className: "mr-1 h-3.5 w-3.5" }), " ", t("offline")] })), _jsx(Button, { variant: "outline", size: "icon", className: "h-12 w-12 shrink-0", onClick: refresh, "aria-label": t("refresh"), children: _jsx(RefreshCw, { className: "h-4 w-4" }) }), _jsxs(Button, { size: "lg", className: "hidden h-14 px-8 text-lg md:inline-flex", onClick: () => (pending ? confirmPending() : fetchNext()), disabled: busyId !== null, children: [busyId !== null ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : (_jsx(Printer, { className: "mr-2 h-5 w-5" })), t("printNext"), pending?.document_number ? ` · ${pending.document_number}` : ""] })] })] }), !pending && emptyNotice && (_jsx("p", { className: "text-sm text-muted-foreground", children: emptyNotice })), pending && (_jsx(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, children: t("cancel") }), _jsxs(Button, { size: "lg", className: "h-14 w-full px-8 text-lg sm:w-auto", onClick: confirmPending, disabled: busyId !== null, children: [busyId === "confirm" ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : (_jsx(Printer, { className: "mr-2 h-5 w-5" })), t("print")] })] })] }) })), tracked && (_jsx(Card, { className: jobFailed ? "border-2 border-destructive" : "border-2 border-primary/40", children: _jsxs(CardContent, { className: "flex flex-col gap-4 p-4 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [jobFailed ? (_jsx(AlertTriangle, { className: "h-6 w-6 shrink-0 text-destructive" })) : jobStatus === "voltooid" ? (_jsx(CheckCircle2, { className: "h-6 w-6 shrink-0 text-primary" })) : (_jsx(Loader2, { className: "h-6 w-6 shrink-0 animate-spin text-muted-foreground" })), _jsxs("div", { className: "min-w-0", children: [_jsxs("p", { className: "truncate text-sm font-medium text-muted-foreground", children: [jobTexts.jobTitle, " ", tracked.documentNumber ? `· ${tracked.documentNumber}` : ""] }), _jsx("p", { className: "text-lg font-semibold text-foreground", children: printJobStatusLabel(jobStatus, t.lang) }), tracked.job?.printer_naam && (_jsxs("p", { className: "truncate text-sm text-muted-foreground", children: [jobTexts.printerLabel, ": ", tracked.job.printer_naam] })), jobFailed && (_jsxs("p", { className: "text-sm text-destructive", children: [tracked.job?.foutmelding ?? jobTexts.unknown, " \u00B7 ", jobTexts.requeued] }))] })] }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [jobFailed && lastPrinted && (_jsxs(Button, { size: "lg", className: "h-12 w-full sm:w-auto", onClick: () => {
299
+ return (_jsxs("div", { className: "space-y-4 pb-24 md:pb-0", children: [_jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:flex-wrap md:items-center md:justify-between", children: [_jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: [_jsxs(Button, { variant: "outline", size: "lg", className: "h-12 shrink-0 px-3 sm:px-4", onClick: () => setLang(null), "aria-label": t("changeLanguage"), children: [_jsx(Globe, { className: "h-5 w-5 sm:mr-2" }), _jsx("span", { className: "hidden sm:inline", children: t("changeLanguage") })] }), _jsxs("div", { className: "min-w-0", children: [_jsx("h2", { className: "truncate text-lg font-bold text-foreground sm:text-xl", children: station.name }), _jsxs("p", { className: "truncate text-sm text-muted-foreground", children: [pendingCount, " ", t("statusToPrint"), " \u00B7 ", printedCount, " ", t("statusPrinted")] })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [!online && (_jsxs(Badge, { className: "bg-destructive text-destructive-foreground", children: [_jsx(WifiOff, { className: "mr-1 h-3.5 w-3.5" }), " ", t("offline")] })), _jsx(Button, { variant: "outline", size: "icon", className: "h-12 w-12 shrink-0", onClick: refresh, "aria-label": t("refresh"), children: _jsx(RefreshCw, { className: "h-4 w-4" }) }), _jsxs(Button, { size: "lg", className: "hidden h-14 px-8 text-lg md:inline-flex", onClick: () => (pending ? confirmPending() : fetchNext()), disabled: busyId !== null, children: [busyId !== null ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : (_jsx(Printer, { className: "mr-2 h-5 w-5" })), t("printNext"), pending?.document_number ? ` · ${pending.document_number}` : ""] })] })] }), !plekLoading && !printPlek && (_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: "Nog geen printplek gekoppeld \u2014 de opdracht blijft in de wachtrij staan." })] })), !pending && emptyNotice && (_jsx("p", { className: "text-sm text-muted-foreground", children: emptyNotice })), pending && (_jsx(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, children: t("cancel") }), _jsxs(Button, { size: "lg", className: "h-14 w-full px-8 text-lg sm:w-auto", onClick: confirmPending, disabled: busyId !== null, children: [busyId === "confirm" ? (_jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" })) : (_jsx(Printer, { className: "mr-2 h-5 w-5" })), t("print")] })] })] }) })), tracked && (_jsx(Card, { className: jobFailed ? "border-2 border-destructive" : "border-2 border-primary/40", children: _jsxs(CardContent, { className: "flex flex-col gap-4 p-4 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between", children: [_jsxs("div", { className: "flex min-w-0 items-start gap-3", children: [jobFailed ? (_jsx(AlertTriangle, { className: "h-6 w-6 shrink-0 text-destructive" })) : jobStatus === "voltooid" ? (_jsx(CheckCircle2, { className: "h-6 w-6 shrink-0 text-primary" })) : (_jsx(Loader2, { className: "h-6 w-6 shrink-0 animate-spin text-muted-foreground" })), _jsxs("div", { className: "min-w-0", children: [_jsxs("p", { className: "truncate text-sm font-medium text-muted-foreground", children: [jobTexts.jobTitle, " ", tracked.documentNumber ? `· ${tracked.documentNumber}` : ""] }), _jsx("p", { className: "text-lg font-semibold text-foreground", children: printJobStatusLabel(jobStatus, t.lang) }), tracked.job?.printer_naam && (_jsxs("p", { className: "truncate text-sm text-muted-foreground", children: [jobTexts.printerLabel, ": ", tracked.job.printer_naam] })), jobFailed && (_jsxs("p", { className: "text-sm text-destructive", children: [tracked.job?.foutmelding ?? jobTexts.unknown, " \u00B7 ", jobTexts.requeued] }))] })] }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [jobFailed && lastPrinted && (_jsxs(Button, { size: "lg", className: "h-12 w-full sm:w-auto", onClick: () => {
299
300
  clearJob();
300
301
  void handlePick(lastPrinted);
301
302
  }, disabled: busyId !== null, children: [_jsx(Printer, { className: "mr-2 h-5 w-5" }), " ", jobTexts.retry] })), _jsx(Button, { variant: "outline", size: "lg", className: "h-12 w-full sm:w-auto", onClick: clearJob, children: jobTexts.close })] })] }) })), _jsx(Card, { children: _jsxs(CardContent, { className: "flex flex-wrap items-center gap-3 p-3 sm:p-4", children: [_jsxs("div", { className: "relative w-full min-w-0 flex-1 sm:min-w-64", children: [_jsx(Search, { 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: t("search"), value: searchInput, onChange: (e) => setSearchInput(e.target.value) })] }), _jsxs("div", { className: "relative w-full min-w-0 sm:w-56", 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: ui.scanPlaceholder, value: scanInput, onChange: (e) => setScanInput(e.target.value), onKeyDown: (e) => {
@@ -5,5 +5,11 @@ export declare function usePickDocumentTypes(): import("@tanstack/react-query").
5
5
  export declare function usePickStationTypes(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickStationType[]>, Error>;
6
6
  export declare function usePickTasks(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickTask[]>, Error>;
7
7
  export declare function usePickStations(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickStation[]>, Error>;
8
+ /** Actieve printplekken uit de Layout maker. */
9
+ export declare function usePickPrintPlekken(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickPrintPlek[]>, Error>;
10
+ /** Koppelingen pickstation → printplek (beheerpagina). */
11
+ export declare function useStationPrintPlekken(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickStationPrintPlekRow[]>, Error>;
12
+ /** De printplek van één pickstation (ook in openbare pickschermen). */
13
+ export declare function useStationPrintPlek(stationId?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickStationPrintPlek | null>, Error>;
8
14
  export declare function usePickScreens(stationId?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<import("..").PickScreen[]>, Error>;
9
15
  //# sourceMappingURL=usePickConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePickConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,+FAE/B;AACD,wBAAgB,eAAe,8FAE9B;AACD,wBAAgB,eAAe,+FAE9B;AACD,wBAAgB,oBAAoB,oGAEnC;AACD,wBAAgB,mBAAmB,mGAElC;AACD,wBAAgB,YAAY,4FAE3B;AACD,wBAAgB,eAAe,+FAE9B;AACD,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,6FAKhD"}
1
+ {"version":3,"file":"usePickConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,+FAE/B;AACD,wBAAgB,eAAe,8FAE9B;AACD,wBAAgB,eAAe,+FAE9B;AACD,wBAAgB,oBAAoB,oGAEnC;AACD,wBAAgB,mBAAmB,mGAElC;AACD,wBAAgB,YAAY,4FAE3B;AACD,wBAAgB,eAAe,+FAE9B;AACD,gDAAgD;AAChD,wBAAgB,mBAAmB,iGAElC;AACD,0DAA0D;AAC1D,wBAAgB,sBAAsB,2GAKrC;AACD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,4GAMrD;AAED,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,6FAKhD"}
@@ -21,6 +21,25 @@ export function usePickTasks() {
21
21
  export function usePickStations() {
22
22
  return useQuery({ queryKey: ["pick", "stations"], queryFn: pickApi.stations });
23
23
  }
24
+ /** Actieve printplekken uit de Layout maker. */
25
+ export function usePickPrintPlekken() {
26
+ return useQuery({ queryKey: ["pick", "printPlekken"], queryFn: pickApi.printPlekken });
27
+ }
28
+ /** Koppelingen pickstation → printplek (beheerpagina). */
29
+ export function useStationPrintPlekken() {
30
+ return useQuery({
31
+ queryKey: ["pick", "stationPrintPlekken"],
32
+ queryFn: pickApi.stationPrintPlekken,
33
+ });
34
+ }
35
+ /** De printplek van één pickstation (ook in openbare pickschermen). */
36
+ export function useStationPrintPlek(stationId) {
37
+ return useQuery({
38
+ queryKey: ["pick", "stationPrintPlek", stationId ?? "none"],
39
+ queryFn: () => (stationId ? pickApi.stationPrintPlek(stationId) : null),
40
+ enabled: Boolean(stationId),
41
+ });
42
+ }
24
43
  export function usePickScreens(stationId) {
25
44
  return useQuery({
26
45
  queryKey: ["pick", "screens", stationId ?? "all"],
@@ -674,6 +674,99 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
674
674
  };
675
675
  Relationships: [];
676
676
  };
677
+ artikelen_cache: {
678
+ Row: {
679
+ artikelcode: string;
680
+ bron: string;
681
+ bruto_prijs_cent: number | null;
682
+ created_at: string;
683
+ eenheid: string;
684
+ fabrikant: string | null;
685
+ fetched_at: string;
686
+ gtin: string | null;
687
+ id: string;
688
+ naam: string;
689
+ netto_prijs_cent: number | null;
690
+ omschrijving: string | null;
691
+ raw: import("./types").Json;
692
+ updated_at: string;
693
+ valuta: string;
694
+ };
695
+ Insert: {
696
+ artikelcode: string;
697
+ bron?: string;
698
+ bruto_prijs_cent?: number | null;
699
+ created_at?: string;
700
+ eenheid?: string;
701
+ fabrikant?: string | null;
702
+ fetched_at?: string;
703
+ gtin?: string | null;
704
+ id?: string;
705
+ naam: string;
706
+ netto_prijs_cent?: number | null;
707
+ omschrijving?: string | null;
708
+ raw?: import("./types").Json;
709
+ updated_at?: string;
710
+ valuta?: string;
711
+ };
712
+ Update: {
713
+ artikelcode?: string;
714
+ bron?: string;
715
+ bruto_prijs_cent?: number | null;
716
+ created_at?: string;
717
+ eenheid?: string;
718
+ fabrikant?: string | null;
719
+ fetched_at?: string;
720
+ gtin?: string | null;
721
+ id?: string;
722
+ naam?: string;
723
+ netto_prijs_cent?: number | null;
724
+ omschrijving?: string | null;
725
+ raw?: import("./types").Json;
726
+ updated_at?: string;
727
+ valuta?: string;
728
+ };
729
+ Relationships: [];
730
+ };
731
+ artikelen_veldconfig: {
732
+ Row: {
733
+ bron_pad: string;
734
+ created_at: string;
735
+ id: string;
736
+ label: string;
737
+ sort_order: number;
738
+ type: string;
739
+ updated_at: string;
740
+ veld_key: string;
741
+ zichtbaar_in_detail: boolean;
742
+ zichtbaar_in_lijst: boolean;
743
+ };
744
+ Insert: {
745
+ bron_pad: string;
746
+ created_at?: string;
747
+ id?: string;
748
+ label: string;
749
+ sort_order?: number;
750
+ type?: string;
751
+ updated_at?: string;
752
+ veld_key: string;
753
+ zichtbaar_in_detail?: boolean;
754
+ zichtbaar_in_lijst?: boolean;
755
+ };
756
+ Update: {
757
+ bron_pad?: string;
758
+ created_at?: string;
759
+ id?: string;
760
+ label?: string;
761
+ sort_order?: number;
762
+ type?: string;
763
+ updated_at?: string;
764
+ veld_key?: string;
765
+ zichtbaar_in_detail?: boolean;
766
+ zichtbaar_in_lijst?: boolean;
767
+ };
768
+ Relationships: [];
769
+ };
677
770
  booking_items: {
678
771
  Row: {
679
772
  booking_id: string;
@@ -3146,6 +3239,48 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
3146
3239
  };
3147
3240
  Relationships: [];
3148
3241
  };
3242
+ document_printplek_printers: {
3243
+ Row: {
3244
+ created_at: string;
3245
+ documenttype: string;
3246
+ id: string;
3247
+ papierformaat: string | null;
3248
+ print_plek_id: string;
3249
+ printer_id: string | null;
3250
+ updated_at: string;
3251
+ };
3252
+ Insert: {
3253
+ created_at?: string;
3254
+ documenttype: string;
3255
+ id?: string;
3256
+ papierformaat?: string | null;
3257
+ print_plek_id: string;
3258
+ printer_id?: string | null;
3259
+ updated_at?: string;
3260
+ };
3261
+ Update: {
3262
+ created_at?: string;
3263
+ documenttype?: string;
3264
+ id?: string;
3265
+ papierformaat?: string | null;
3266
+ print_plek_id?: string;
3267
+ printer_id?: string | null;
3268
+ updated_at?: string;
3269
+ };
3270
+ Relationships: [{
3271
+ foreignKeyName: "document_printplek_printers_print_plek_id_fkey";
3272
+ columns: ["print_plek_id"];
3273
+ isOneToOne: false;
3274
+ referencedRelation: "print_plekken";
3275
+ referencedColumns: ["id"];
3276
+ }, {
3277
+ foreignKeyName: "document_printplek_printers_printer_id_fkey";
3278
+ columns: ["printer_id"];
3279
+ isOneToOne: false;
3280
+ referencedRelation: "printers";
3281
+ referencedColumns: ["id"];
3282
+ }];
3283
+ };
3149
3284
  document_werkplek_printers: {
3150
3285
  Row: {
3151
3286
  created_at: string;
@@ -9125,6 +9260,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
9125
9260
  id: string;
9126
9261
  last_error: string | null;
9127
9262
  last_error_at: string | null;
9263
+ last_error_code: string | null;
9264
+ last_gateway_status: number | null;
9265
+ last_response: import("./types").Json | null;
9128
9266
  last_sent_hash: string | null;
9129
9267
  locked_by: string | null;
9130
9268
  locked_until: string | null;
@@ -9145,6 +9283,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
9145
9283
  id?: string;
9146
9284
  last_error?: string | null;
9147
9285
  last_error_at?: string | null;
9286
+ last_error_code?: string | null;
9287
+ last_gateway_status?: number | null;
9288
+ last_response?: import("./types").Json | null;
9148
9289
  last_sent_hash?: string | null;
9149
9290
  locked_by?: string | null;
9150
9291
  locked_until?: string | null;
@@ -9165,6 +9306,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
9165
9306
  id?: string;
9166
9307
  last_error?: string | null;
9167
9308
  last_error_at?: string | null;
9309
+ last_error_code?: string | null;
9310
+ last_gateway_status?: number | null;
9311
+ last_response?: import("./types").Json | null;
9168
9312
  last_sent_hash?: string | null;
9169
9313
  locked_by?: string | null;
9170
9314
  locked_until?: string | null;
@@ -13334,6 +13478,99 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
13334
13478
  referencedColumns: ["id"];
13335
13479
  }];
13336
13480
  };
13481
+ print_plek_computers: {
13482
+ Row: {
13483
+ computer_naam: string;
13484
+ created_at: string;
13485
+ id: string;
13486
+ print_plek_id: string;
13487
+ updated_at: string;
13488
+ };
13489
+ Insert: {
13490
+ computer_naam: string;
13491
+ created_at?: string;
13492
+ id?: string;
13493
+ print_plek_id: string;
13494
+ updated_at?: string;
13495
+ };
13496
+ Update: {
13497
+ computer_naam?: string;
13498
+ created_at?: string;
13499
+ id?: string;
13500
+ print_plek_id?: string;
13501
+ updated_at?: string;
13502
+ };
13503
+ Relationships: [{
13504
+ foreignKeyName: "print_plek_computers_print_plek_id_fkey";
13505
+ columns: ["print_plek_id"];
13506
+ isOneToOne: false;
13507
+ referencedRelation: "print_plekken";
13508
+ referencedColumns: ["id"];
13509
+ }];
13510
+ };
13511
+ print_plek_koppelingen: {
13512
+ Row: {
13513
+ bron: string;
13514
+ bron_id: string;
13515
+ created_at: string;
13516
+ id: string;
13517
+ label: string | null;
13518
+ print_plek_id: string;
13519
+ updated_at: string;
13520
+ };
13521
+ Insert: {
13522
+ bron: string;
13523
+ bron_id: string;
13524
+ created_at?: string;
13525
+ id?: string;
13526
+ label?: string | null;
13527
+ print_plek_id: string;
13528
+ updated_at?: string;
13529
+ };
13530
+ Update: {
13531
+ bron?: string;
13532
+ bron_id?: string;
13533
+ created_at?: string;
13534
+ id?: string;
13535
+ label?: string | null;
13536
+ print_plek_id?: string;
13537
+ updated_at?: string;
13538
+ };
13539
+ Relationships: [{
13540
+ foreignKeyName: "print_plek_koppelingen_print_plek_id_fkey";
13541
+ columns: ["print_plek_id"];
13542
+ isOneToOne: false;
13543
+ referencedRelation: "print_plekken";
13544
+ referencedColumns: ["id"];
13545
+ }];
13546
+ };
13547
+ print_plekken: {
13548
+ Row: {
13549
+ actief: boolean;
13550
+ created_at: string;
13551
+ id: string;
13552
+ naam: string;
13553
+ omschrijving: string | null;
13554
+ updated_at: string;
13555
+ };
13556
+ Insert: {
13557
+ actief?: boolean;
13558
+ created_at?: string;
13559
+ id?: string;
13560
+ naam: string;
13561
+ omschrijving?: string | null;
13562
+ updated_at?: string;
13563
+ };
13564
+ Update: {
13565
+ actief?: boolean;
13566
+ created_at?: string;
13567
+ id?: string;
13568
+ naam?: string;
13569
+ omschrijving?: string | null;
13570
+ updated_at?: string;
13571
+ };
13572
+ Relationships: [];
13573
+ };
13337
13574
  print_queue_runners: {
13338
13575
  Row: {
13339
13576
  actief: boolean;
@@ -18592,6 +18829,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
18592
18829
  scheduled_end_time: string | null;
18593
18830
  scheduled_start_time: string | null;
18594
18831
  sequence_number: number;
18832
+ signature_accepted_at: string | null;
18833
+ signature_by_user_id: string | null;
18834
+ signature_name: string | null;
18595
18835
  source_email_meta: import("./types").Json | null;
18596
18836
  source_mailbox_message_id: string | null;
18597
18837
  source_pdf_path: string | null;
@@ -18627,6 +18867,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
18627
18867
  scheduled_end_time?: string | null;
18628
18868
  scheduled_start_time?: string | null;
18629
18869
  sequence_number: number;
18870
+ signature_accepted_at?: string | null;
18871
+ signature_by_user_id?: string | null;
18872
+ signature_name?: string | null;
18630
18873
  source_email_meta?: import("./types").Json | null;
18631
18874
  source_mailbox_message_id?: string | null;
18632
18875
  source_pdf_path?: string | null;
@@ -18662,6 +18905,9 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
18662
18905
  scheduled_end_time?: string | null;
18663
18906
  scheduled_start_time?: string | null;
18664
18907
  sequence_number?: number;
18908
+ signature_accepted_at?: string | null;
18909
+ signature_by_user_id?: string | null;
18910
+ signature_name?: string | null;
18665
18911
  source_email_meta?: import("./types").Json | null;
18666
18912
  source_mailbox_message_id?: string | null;
18667
18913
  source_pdf_path?: string | null;
@@ -21056,6 +21302,23 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21056
21302
  };
21057
21303
  Returns: string;
21058
21304
  };
21305
+ logistics_floriday_finish_push_v2: {
21306
+ Args: {
21307
+ _error?: string;
21308
+ _error_code?: string;
21309
+ _fulfillment_order_id?: string;
21310
+ _gateway_status?: number;
21311
+ _id: string;
21312
+ _max_age_hours?: number;
21313
+ _max_attempts?: number;
21314
+ _ok: boolean;
21315
+ _permanent?: boolean;
21316
+ _response?: import("./types").Json;
21317
+ _revision: number;
21318
+ _sent_hash?: string;
21319
+ };
21320
+ Returns: string;
21321
+ };
21059
21322
  logistics_floriday_prune_pushes: {
21060
21323
  Args: {
21061
21324
  _days?: number;
@@ -21691,6 +21954,14 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21691
21954
  };
21692
21955
  Returns: import("./types").Json;
21693
21956
  };
21957
+ pick_print_plekken: {
21958
+ Args: never;
21959
+ Returns: {
21960
+ id: string;
21961
+ naam: string;
21962
+ omschrijving: string;
21963
+ }[];
21964
+ };
21694
21965
  pick_release_expired_locks: {
21695
21966
  Args: never;
21696
21967
  Returns: number;
@@ -21755,6 +22026,13 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21755
22026
  isSetofReturn: false;
21756
22027
  };
21757
22028
  };
22029
+ pick_set_station_print_plek: {
22030
+ Args: {
22031
+ _print_plek_id: string;
22032
+ _station_id: string;
22033
+ };
22034
+ Returns: string;
22035
+ };
21758
22036
  pick_station_dashboard: {
21759
22037
  Args: never;
21760
22038
  Returns: {
@@ -21767,6 +22045,25 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21767
22045
  waiting: number;
21768
22046
  }[];
21769
22047
  };
22048
+ pick_station_print_plek: {
22049
+ Args: {
22050
+ _station_id: string;
22051
+ };
22052
+ Returns: {
22053
+ naam: string;
22054
+ omschrijving: string;
22055
+ print_plek_id: string;
22056
+ }[];
22057
+ };
22058
+ pick_station_print_plekken: {
22059
+ Args: never;
22060
+ Returns: {
22061
+ naam: string;
22062
+ omschrijving: string;
22063
+ print_plek_id: string;
22064
+ station_id: string;
22065
+ }[];
22066
+ };
21770
22067
  pick_station_slugify: {
21771
22068
  Args: {
21772
22069
  _id: string;