@flowselections/layout-maker 1.24.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +139 -139
  2. package/dist-lib/components/AfdrukKnop.d.ts +19 -19
  3. package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
  4. package/dist-lib/components/PrintQueuePage.d.ts.map +1 -1
  5. package/dist-lib/components/PrintQueuePage.js +12 -1
  6. package/dist-lib/components/PrinterSetupWizard.js +3 -3
  7. package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
  8. package/dist-lib/components/PrintersRedirectPage.js +14 -14
  9. package/dist-lib/integrations/supabase/auth-middleware.d.ts +38 -0
  10. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  11. package/dist-lib/integrations/supabase/client.server.d.ts +38 -0
  12. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  13. package/dist-lib/integrations/supabase/types.d.ts +38 -0
  14. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  15. package/dist-lib/lib/aiLayout.functions.d.ts +38 -0
  16. package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
  17. package/dist-lib/lib/aiLayout.server.js +9 -9
  18. package/dist-lib/lib/browserPrint.js +1 -1
  19. package/dist-lib/lib/layoutPreview.js +7 -7
  20. package/dist-lib/lib/orderData.server.d.ts +25 -3
  21. package/dist-lib/lib/orderData.server.d.ts.map +1 -1
  22. package/dist-lib/lib/orderData.server.js +171 -55
  23. package/dist-lib/lib/pakbonBuilder.d.ts +2 -0
  24. package/dist-lib/lib/pakbonBuilder.d.ts.map +1 -1
  25. package/dist-lib/lib/pakbonBuilder.js +1 -1
  26. package/dist-lib/lib/pakbonHtml.d.ts.map +1 -1
  27. package/dist-lib/lib/pakbonHtml.js +53 -50
  28. package/dist-lib/lib/printQueue.server.d.ts +15 -3
  29. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  30. package/dist-lib/lib/printQueue.server.js +142 -13
  31. package/dist-lib/lib/printService.functions.d.ts +152 -0
  32. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  33. package/dist-lib/lib/printService.server.d.ts.map +1 -1
  34. package/dist-lib/lib/printService.server.js +3 -0
  35. package/dist-lib/lib/productiebonHtml.js +15 -15
  36. package/dist-lib/lib/profielHtml.js +18 -18
  37. package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
  38. package/dist-lib/lib/supabaseAdmin.server.js +43 -43
  39. package/dist-lib/lib/testpagina.js +3 -3
  40. package/dist-lib/lib/testprint.js +4 -4
  41. package/dist-lib/lib/useDocumentData.d.ts +4 -0
  42. package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
  43. package/package.json +139 -139
package/README.md CHANGED
@@ -1,139 +1,139 @@
1
- # Layout maker (pakbonnen, verzendbrieven, ectra)
2
-
3
- blank project start
4
-
5
- This project was built with [Lovable](https://lovable.dev).
6
-
7
- ## Build with Lovable
8
-
9
- Continue developing this project in the [Lovable editor](https://lovable.dev/projects/4735fccb-b385-4b48-b4f8-ef135f63f4f7).
10
-
11
- - **Ship faster**: describe what you want to build and Lovable handles the code.
12
- - **Stay in sync**: every change made in Lovable is committed straight to this repository.
13
- - **Full ownership**: this code is yours. Push to `main` on GitHub and your changes sync back into Lovable, ready for your next prompt.
14
-
15
- ## Development
16
-
17
- Prefer working locally? You need Node.js and npm — [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating).
18
-
19
- ```sh
20
- git clone <this-repository-url>
21
- cd <repository-name>
22
- npm i
23
- npm run dev
24
- ```
25
-
26
- ## Installeren in een andere shell
27
-
28
- 1. Draai `sql/print-schema.sql` één keer in de Supabase-database van die shell
29
- (SQL editor). Het script is idempotent en zet tabellen, rechten, RLS,
30
- functies, de geplande taken én de opslagmap `layout-logos` voor de Logo
31
- Bibliotheek klaar. Zorg dat de extensies `pg_cron` en `pg_net` aan staan.
32
-
33
- 2. Zet in de omgeving van de shell:
34
- - `SUPABASE_URL` en `SERVICE_ROLE_KEY` — nodig voor achtergrondprinten
35
- - `CENTRAL_AUTH_URL` en `CENTRAL_AUTH_SECRET` — nodig voor de printdienst
36
- 3. Zorg dat de shell het tick-eindpunt host. De setup-CLI doet dit automatisch
37
- op basis van `flowselections.serverRoutes` in `package.json`. Handmatig
38
- opgezette shells maken zelf dit bestand aan:
39
-
40
- ```ts
41
- // src/routes/api/public/print/queue-tick.ts
42
- import { createFileRoute } from "@tanstack/react-router";
43
- import { behandelQueueTick } from "@flowselections/layout-maker/print";
44
-
45
- export const Route = createFileRoute("/api/public/print/queue-tick")({
46
- server: {
47
- handlers: {
48
- POST: async ({ request }) => {
49
- // De shell levert de databaseverbinding; de module maakt er nooit zelf een.
50
- const { supabaseAdmin } = await import(
51
- "../../../../integrations/supabase/client.server"
52
- );
53
- return behandelQueueTick(request, supabaseAdmin);
54
- },
55
- },
56
- },
57
- });
58
- ```
59
-
60
- Het eindpunt accepteert drie toegangsbewijzen: een runner-sleutel uit
61
- `print_queue_runners.tick_sleutel`, `SUPABASE_PUBLISHABLE_KEY` (de cron) of
62
- het sessietoken van een ingelogde gebruiker (de knop in de Printwachtrij).
63
-
64
-
65
- 4. Klaar. Zodra de module in de shell draait meldt hij zichzelf aan als
66
- verwerker van de printwachtrij. Een nieuwe printopdracht wordt meteen
67
- opgepakt; daarnaast verwerkt de geplande taak `print-queue-tick` elke minuut
68
- de wachtende opdrachten. Reageert een shell een uur lang niet, dan wordt hij
69
- automatisch op inactief gezet. De taak `print-queue-cleanup` ruimt dagelijks
70
- oude opdrachten en bestanden op.
71
-
72
- ## Printen vanuit een andere module
73
-
74
- Andere modules in dezelfde shell gebruiken uitsluitend de print-API van deze
75
- module; zij hoeven de printtabellen niet te kennen en mogen er ook niet zelf in
76
- schrijven (dan blijft de opdracht wachten tot de volgende cronronde).
77
-
78
- ```ts
79
- import {
80
- printDocument, printPdf, printHtml,
81
- printerVoorWerkplek, printerVoorDocumenttype, volgJobStatus,
82
- } from "@flowselections/layout-maker";
83
-
84
- // 1. Document dat via een ontwerp uit deze module wordt opgemaakt
85
- const { jobId } = await printDocument({
86
- documenttype: "pakbon", // moet een bestaande documentsoort zijn
87
- documentnaam: "PB-2601284",
88
- payload: { order, order_id: order.id }, // order_id: verplicht kenmerk
89
- });
90
-
91
- // 2. Kant-en-klare PDF (Floriday-document, klantsticker, externe factuur)
92
- // Zonder printerId wordt de printer bepaald via de gekoppelde layout van
93
- // de documentsoort (of de koppeling op papierformaat).
94
- await printPdf({
95
- documenttype: "factuur",
96
- documentnaam: "F-2026-00123",
97
- pdfBase64, // met of zonder data:-voorvoegsel
98
- payload: { order_id: factuur.id },
99
- });
100
-
101
- // Geef in payload altijd een order-kenmerk mee: queue_item_id, order_id of
102
- // ordernummer. De wachtrij gebruikt dat om dubbele aanvragen te herkennen;
103
- // zonder kenmerk kunnen twee orders met dezelfde documentnaam binnen tien
104
- // minuten als dubbel worden gezien.
105
-
106
-
107
- // Of expliciet per werkplek:
108
- const printerId = await printerVoorWerkplek("PICKSTATION-1", "A4");
109
- await printPdf({
110
- documenttype: "afleverbrief",
111
- documentnaam: "AFL-12345",
112
- pdfBase64,
113
- printerId: printerId!,
114
- });
115
-
116
-
117
- // 3. Eigen opmaak afdrukken (geen layout, anders wint de layout)
118
- await printHtml({
119
- documenttype: "controlelijst",
120
- documentnaam: "Controlelijst kar 12",
121
- html,
122
- printerId: printerId!,
123
- });
124
-
125
- // Status live volgen (realtime staat aan op print_jobs)
126
- const stop = volgJobStatus(jobId, (s) => console.log(s.status, s.foutmelding));
127
- ```
128
-
129
- Belangrijk:
130
-
131
- - **Documentsoorten** liggen vast in de database: pakbon, factuur, offerte,
132
- orderbevestiging, etiket, verzendlabel, productlabel, barcode_label,
133
- magazijnlijst, controlelijst, transportdocument, sticker, productiebon,
134
- veilingbon, afleverbrief, veilingbrief en vrij.
135
- - **Beslisvolgorde bij het afdrukken**: kant-en-klare PDF > gekoppelde layout >
136
- meegestuurde opmaak > actieve layout van de documentsoort.
137
- - **Dubbelbeveiliging**: een identieke aanvraag binnen 10 minuten wordt
138
- genegeerd; de aanroep werpt dan `DubbeleAanvraagFout`. Geef bij bulkprints per
139
- document een eigen `documentnaam` zodat elke opdracht uniek is.
1
+ # Layout maker (pakbonnen, verzendbrieven, ectra)
2
+
3
+ blank project start
4
+
5
+ This project was built with [Lovable](https://lovable.dev).
6
+
7
+ ## Build with Lovable
8
+
9
+ Continue developing this project in the [Lovable editor](https://lovable.dev/projects/4735fccb-b385-4b48-b4f8-ef135f63f4f7).
10
+
11
+ - **Ship faster**: describe what you want to build and Lovable handles the code.
12
+ - **Stay in sync**: every change made in Lovable is committed straight to this repository.
13
+ - **Full ownership**: this code is yours. Push to `main` on GitHub and your changes sync back into Lovable, ready for your next prompt.
14
+
15
+ ## Development
16
+
17
+ Prefer working locally? You need Node.js and npm — [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating).
18
+
19
+ ```sh
20
+ git clone <this-repository-url>
21
+ cd <repository-name>
22
+ npm i
23
+ npm run dev
24
+ ```
25
+
26
+ ## Installeren in een andere shell
27
+
28
+ 1. Draai `sql/print-schema.sql` één keer in de Supabase-database van die shell
29
+ (SQL editor). Het script is idempotent en zet tabellen, rechten, RLS,
30
+ functies, de geplande taken én de opslagmap `layout-logos` voor de Logo
31
+ Bibliotheek klaar. Zorg dat de extensies `pg_cron` en `pg_net` aan staan.
32
+
33
+ 2. Zet in de omgeving van de shell:
34
+ - `SUPABASE_URL` en `SERVICE_ROLE_KEY` — nodig voor achtergrondprinten
35
+ - `CENTRAL_AUTH_URL` en `CENTRAL_AUTH_SECRET` — nodig voor de printdienst
36
+ 3. Zorg dat de shell het tick-eindpunt host. De setup-CLI doet dit automatisch
37
+ op basis van `flowselections.serverRoutes` in `package.json`. Handmatig
38
+ opgezette shells maken zelf dit bestand aan:
39
+
40
+ ```ts
41
+ // src/routes/api/public/print/queue-tick.ts
42
+ import { createFileRoute } from "@tanstack/react-router";
43
+ import { behandelQueueTick } from "@flowselections/layout-maker/print";
44
+
45
+ export const Route = createFileRoute("/api/public/print/queue-tick")({
46
+ server: {
47
+ handlers: {
48
+ POST: async ({ request }) => {
49
+ // De shell levert de databaseverbinding; de module maakt er nooit zelf een.
50
+ const { supabaseAdmin } = await import(
51
+ "../../../../integrations/supabase/client.server"
52
+ );
53
+ return behandelQueueTick(request, supabaseAdmin);
54
+ },
55
+ },
56
+ },
57
+ });
58
+ ```
59
+
60
+ Het eindpunt accepteert drie toegangsbewijzen: een runner-sleutel uit
61
+ `print_queue_runners.tick_sleutel`, `SUPABASE_PUBLISHABLE_KEY` (de cron) of
62
+ het sessietoken van een ingelogde gebruiker (de knop in de Printwachtrij).
63
+
64
+
65
+ 4. Klaar. Zodra de module in de shell draait meldt hij zichzelf aan als
66
+ verwerker van de printwachtrij. Een nieuwe printopdracht wordt meteen
67
+ opgepakt; daarnaast verwerkt de geplande taak `print-queue-tick` elke minuut
68
+ de wachtende opdrachten. Reageert een shell een uur lang niet, dan wordt hij
69
+ automatisch op inactief gezet. De taak `print-queue-cleanup` ruimt dagelijks
70
+ oude opdrachten en bestanden op.
71
+
72
+ ## Printen vanuit een andere module
73
+
74
+ Andere modules in dezelfde shell gebruiken uitsluitend de print-API van deze
75
+ module; zij hoeven de printtabellen niet te kennen en mogen er ook niet zelf in
76
+ schrijven (dan blijft de opdracht wachten tot de volgende cronronde).
77
+
78
+ ```ts
79
+ import {
80
+ printDocument, printPdf, printHtml,
81
+ printerVoorWerkplek, printerVoorDocumenttype, volgJobStatus,
82
+ } from "@flowselections/layout-maker";
83
+
84
+ // 1. Document dat via een ontwerp uit deze module wordt opgemaakt
85
+ const { jobId } = await printDocument({
86
+ documenttype: "pakbon", // moet een bestaande documentsoort zijn
87
+ documentnaam: "PB-2601284",
88
+ payload: { order, order_id: order.id }, // order_id: verplicht kenmerk
89
+ });
90
+
91
+ // 2. Kant-en-klare PDF (Floriday-document, klantsticker, externe factuur)
92
+ // Zonder printerId wordt de printer bepaald via de gekoppelde layout van
93
+ // de documentsoort (of de koppeling op papierformaat).
94
+ await printPdf({
95
+ documenttype: "factuur",
96
+ documentnaam: "F-2026-00123",
97
+ pdfBase64, // met of zonder data:-voorvoegsel
98
+ payload: { order_id: factuur.id },
99
+ });
100
+
101
+ // Geef in payload altijd een order-kenmerk mee: queue_item_id, order_id of
102
+ // ordernummer. De wachtrij gebruikt dat om dubbele aanvragen te herkennen;
103
+ // zonder kenmerk kunnen twee orders met dezelfde documentnaam binnen tien
104
+ // minuten als dubbel worden gezien.
105
+
106
+
107
+ // Of expliciet per werkplek:
108
+ const printerId = await printerVoorWerkplek("PICKSTATION-1", "A4");
109
+ await printPdf({
110
+ documenttype: "afleverbrief",
111
+ documentnaam: "AFL-12345",
112
+ pdfBase64,
113
+ printerId: printerId!,
114
+ });
115
+
116
+
117
+ // 3. Eigen opmaak afdrukken (geen layout, anders wint de layout)
118
+ await printHtml({
119
+ documenttype: "controlelijst",
120
+ documentnaam: "Controlelijst kar 12",
121
+ html,
122
+ printerId: printerId!,
123
+ });
124
+
125
+ // Status live volgen (realtime staat aan op print_jobs)
126
+ const stop = volgJobStatus(jobId, (s) => console.log(s.status, s.foutmelding));
127
+ ```
128
+
129
+ Belangrijk:
130
+
131
+ - **Documentsoorten** liggen vast in de database: pakbon, factuur, offerte,
132
+ orderbevestiging, etiket, verzendlabel, productlabel, barcode_label,
133
+ magazijnlijst, controlelijst, transportdocument, sticker, productiebon,
134
+ veilingbon, afleverbrief, veilingbrief en vrij.
135
+ - **Beslisvolgorde bij het afdrukken**: kant-en-klare PDF > gekoppelde layout >
136
+ meegestuurde opmaak > actieve layout van de documentsoort.
137
+ - **Dubbelbeveiliging**: een identieke aanvraag binnen 10 minuten wordt
138
+ genegeerd; de aanroep werpt dan `DubbeleAanvraagFout`. Geef bij bulkprints per
139
+ document een eigen `documentnaam` zodat elke opdracht uniek is.
@@ -1,20 +1,20 @@
1
- import { type Orientatie } from "../lib/browserPrint.js";
2
- export interface AfdrukKnopProps {
3
- documenttype: string;
4
- formaatCode: string | null;
5
- orientatie: Orientatie;
6
- /** Levert de HTML van het document aan op het moment van afdrukken. */
7
- getHtml: () => string;
8
- css?: string;
9
- documentnaam?: string;
10
- label?: string;
11
- layoutId?: string | null;
12
- kopieen?: number;
13
- }
14
- /**
15
- * @deprecated Verouderd — deze knop gebruikt het browser-printvenster als
16
- * terugval. Gebruik `printHtml()` / `printPdf()` uit `printApi` zodat alles
17
- * via PrintNode loopt.
18
- */
19
- export declare function AfdrukKnop({ documenttype, formaatCode, orientatie, getHtml, css, documentnaam, label, layoutId, kopieen, }: AfdrukKnopProps): import("react/jsx-runtime").JSX.Element;
1
+ import { type Orientatie } from "../lib/browserPrint.js";
2
+ export interface AfdrukKnopProps {
3
+ documenttype: string;
4
+ formaatCode: string | null;
5
+ orientatie: Orientatie;
6
+ /** Levert de HTML van het document aan op het moment van afdrukken. */
7
+ getHtml: () => string;
8
+ css?: string;
9
+ documentnaam?: string;
10
+ label?: string;
11
+ layoutId?: string | null;
12
+ kopieen?: number;
13
+ }
14
+ /**
15
+ * @deprecated Verouderd — deze knop gebruikt het browser-printvenster als
16
+ * terugval. Gebruik `printHtml()` / `printPdf()` uit `printApi` zodat alles
17
+ * via PrintNode loopt.
18
+ */
19
+ export declare function AfdrukKnop({ documenttype, formaatCode, orientatie, getHtml, css, documentnaam, label, layoutId, kopieen, }: AfdrukKnopProps): import("react/jsx-runtime").JSX.Element;
20
20
  //# sourceMappingURL=AfdrukKnop.d.ts.map
@@ -1,8 +1,8 @@
1
- export declare function NetwerkPrintersDialog({ open, onOpenChange, huidigePrinterId, huidigePrinterNaam, onKlaar, }: {
2
- open: boolean;
3
- onOpenChange: (v: boolean) => void;
4
- huidigePrinterId?: string | null;
5
- huidigePrinterNaam?: string | null;
6
- onKlaar?: () => void;
7
- }): import("react/jsx-runtime").JSX.Element;
1
+ export declare function NetwerkPrintersDialog({ open, onOpenChange, huidigePrinterId, huidigePrinterNaam, onKlaar, }: {
2
+ open: boolean;
3
+ onOpenChange: (v: boolean) => void;
4
+ huidigePrinterId?: string | null;
5
+ huidigePrinterNaam?: string | null;
6
+ onKlaar?: () => void;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
8
  //# sourceMappingURL=NetwerkPrintersDialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PrintQueuePage.d.ts","sourceRoot":"","sources":["../../src/components/PrintQueuePage.tsx"],"names":[],"mappings":"AA+DA,wBAAgB,cAAc,gCAsP7B"}
1
+ {"version":3,"file":"PrintQueuePage.d.ts","sourceRoot":"","sources":["../../src/components/PrintQueuePage.tsx"],"names":[],"mappings":"AAuEA,wBAAgB,cAAc,gCAuQ7B"}
@@ -16,6 +16,13 @@ const STATUS_VARIANT = {
16
16
  mislukt: "destructive",
17
17
  geannuleerd: "outline",
18
18
  };
19
+ /** Leesbare naam van de bron waaruit het document is opgemaakt. */
20
+ const BRON_LABEL = {
21
+ extern_pdf: "aangeleverde PDF",
22
+ eigen_layout: "eigen ontwerp",
23
+ render_html: "meegestuurde opmaak",
24
+ klantlayout: "klantlayout",
25
+ };
19
26
  /**
20
27
  * Heeft deze opdracht een kenmerk waarmee hij van andere orders te
21
28
  * onderscheiden is? Zo niet, dan valt de dubbelbescherming terug op het
@@ -96,7 +103,11 @@ export function PrintQueuePage() {
96
103
  await reload(true);
97
104
  };
98
105
  const bijgewerkt = useAutoRefresh(ronde, lopende ? 5000 : 20000);
99
- return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: "Printwachtrij" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Volg printopdrachten, herstart mislukte prints en print documenten opnieuw." })] }), _jsx("span", { className: "text-muted-foreground text-xs", children: bijgewerktTekst(bijgewerkt) })] }), _jsx(PrintStatusBanner, { fout: tickFout }), _jsx("div", { className: "grid gap-4 md:grid-cols-4", children: ["wachtend", "bezig", "voltooid", "mislukt"].map((s) => (_jsx(Card, { children: _jsxs(CardHeader, { className: "pb-2", children: [_jsx(CardDescription, { className: "capitalize", children: s }), _jsx(CardTitle, { className: "text-2xl", children: tellingen[s] ?? 0 })] }) }, s))) }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsx(CardTitle, { className: "text-base", children: "Opdrachten" }), _jsx(CardDescription, { children: loading ? "Laden…" : `${gefilterd.length} opdrachten` })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-3 md:grid-cols-4", children: [_jsxs("div", { className: "relative md:col-span-2", children: [_jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { className: "pl-9", placeholder: "Zoek op document of gebruiker", value: zoek, onChange: (e) => setZoek(e.target.value) })] }), _jsxs(Select, { value: status, onValueChange: setStatus, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Alle statussen" }), ["wachtend", "bezig", "voltooid", "mislukt", "geannuleerd"].map((s) => (_jsx(SelectItem, { value: s, children: s }, s)))] })] }), _jsxs(Select, { value: plekFilter, onValueChange: setPlekFilter, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Alle printplekken" }), plekOpties.map((p) => (_jsx(SelectItem, { value: p, children: p }, p))), _jsx(SelectItem, { value: "\u2014", children: "Zonder printplek" })] })] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Document" }), _jsx(TableHead, { children: "Printplek" }), _jsx(TableHead, { children: "Layout" }), _jsx(TableHead, { children: "Printer" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { children: "Tijdstip" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsxs(TableBody, { children: [gefilterd.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 7, className: "py-10 text-center text-sm text-muted-foreground", children: "Geen printopdrachten." }) })), gefilterd.map((j) => (_jsxs(TableRow, { children: [_jsxs(TableCell, { children: [_jsx("span", { className: "font-medium", children: j.documentnaam ?? documentTypeLabel(j.documenttype) }), j.is_herprint && (_jsx(Badge, { variant: "outline", className: "ml-2", children: "herprint" })), !heeftOrderKenmerk(j) && (_jsx(Badge, { variant: "outline", className: "ml-2 text-amber-600", children: "geen orderkenmerk" })), j.foutmelding && (_jsx("span", { className: "block text-xs text-destructive", children: j.foutmelding }))] }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: plekPerJob.get(j.id) || "—" }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: j.layout_id ? layoutNaam.get(j.layout_id) ?? "—" : "—" }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: j.printer_id ? printerNaam.get(j.printer_id) ?? "—" : "—" }), _jsx(TableCell, { children: _jsx(Badge, { variant: STATUS_VARIANT[j.status] ?? "outline", children: j.status }) }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: new Date(j.created_at).toLocaleString("nl-NL") }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: async () => {
106
+ return (_jsxs("main", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-end justify-between gap-4", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold", children: "Printwachtrij" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Volg printopdrachten, herstart mislukte prints en print documenten opnieuw." })] }), _jsx("span", { className: "text-muted-foreground text-xs", children: bijgewerktTekst(bijgewerkt) })] }), _jsx(PrintStatusBanner, { fout: tickFout }), _jsx("div", { className: "grid gap-4 md:grid-cols-4", children: ["wachtend", "bezig", "voltooid", "mislukt"].map((s) => (_jsx(Card, { children: _jsxs(CardHeader, { className: "pb-2", children: [_jsx(CardDescription, { className: "capitalize", children: s }), _jsx(CardTitle, { className: "text-2xl", children: tellingen[s] ?? 0 })] }) }, s))) }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsx(CardTitle, { className: "text-base", children: "Opdrachten" }), _jsx(CardDescription, { children: loading ? "Laden…" : `${gefilterd.length} opdrachten` })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-3 md:grid-cols-4", children: [_jsxs("div", { className: "relative md:col-span-2", children: [_jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { className: "pl-9", placeholder: "Zoek op document of gebruiker", value: zoek, onChange: (e) => setZoek(e.target.value) })] }), _jsxs(Select, { value: status, onValueChange: setStatus, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Alle statussen" }), ["wachtend", "bezig", "voltooid", "mislukt", "geannuleerd"].map((s) => (_jsx(SelectItem, { value: s, children: s }, s)))] })] }), _jsxs(Select, { value: plekFilter, onValueChange: setPlekFilter, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "alle", children: "Alle printplekken" }), plekOpties.map((p) => (_jsx(SelectItem, { value: p, children: p }, p))), _jsx(SelectItem, { value: "\u2014", children: "Zonder printplek" })] })] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Document" }), _jsx(TableHead, { children: "Printplek" }), _jsx(TableHead, { children: "Layout (aangeleverd \u2192 gebruikt)" }), _jsx(TableHead, { children: "Printer" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { children: "Tijdstip" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsxs(TableBody, { children: [gefilterd.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 7, className: "py-10 text-center text-sm text-muted-foreground", children: "Geen printopdrachten." }) })), gefilterd.map((j) => (_jsxs(TableRow, { children: [_jsxs(TableCell, { children: [_jsx("span", { className: "font-medium", children: j.documentnaam ?? documentTypeLabel(j.documenttype) }), j.is_herprint && (_jsx(Badge, { variant: "outline", className: "ml-2", children: "herprint" })), !heeftOrderKenmerk(j) && (_jsx(Badge, { variant: "outline", className: "ml-2 text-amber-600", children: "geen orderkenmerk" })), j.foutmelding && (_jsx("span", { className: "block text-xs text-destructive", children: j.foutmelding }))] }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: plekPerJob.get(j.id) || "—" }), _jsxs(TableCell, { className: "text-sm text-muted-foreground", children: [_jsx("span", { title: "Aangeleverd door de module", children: j.layout_id ? layoutNaam.get(j.layout_id) ?? "Onbekende layout" : "geen" }), _jsxs("span", { className: "block text-xs", children: ["\u2192", " ", _jsx("span", { title: "Layout die de wachtrij gebruikte", children: j.gebruikte_layout_id
107
+ ? layoutNaam.get(j.gebruikte_layout_id) ?? "Onbekende layout"
108
+ : j.gebruikte_bron
109
+ ? "geen layout"
110
+ : "nog niet verwerkt" }), j.gebruikte_bron && (_jsx(Badge, { variant: "outline", className: "ml-2", children: BRON_LABEL[j.gebruikte_bron] ?? j.gebruikte_bron }))] })] }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: j.printer_id ? printerNaam.get(j.printer_id) ?? "—" : "—" }), _jsx(TableCell, { children: _jsx(Badge, { variant: STATUS_VARIANT[j.status] ?? "outline", children: j.status }) }), _jsx(TableCell, { className: "text-sm text-muted-foreground", children: new Date(j.created_at).toLocaleString("nl-NL") }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: async () => {
100
111
  if (!j.layout_id)
101
112
  return;
102
113
  try {
@@ -183,9 +183,9 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
183
183
  setTestStatus("bezig");
184
184
  setTestMelding("");
185
185
  const maat = gekozenFormaat ? `${gekozenFormaat.breedte} × ${gekozenFormaat.hoogte} mm` : "standaardformaat";
186
- const html = `<div style="padding:15mm;font-family:Arial,Helvetica,sans-serif;font-size:12pt">
187
- <h1 style="font-size:20pt;margin:0 0 6mm">Testpagina</h1>
188
- <p style="margin:0 0 3mm">Deze pagina hoort uit: <strong>${naam}</strong></p>
186
+ const html = `<div style="padding:15mm;font-family:Arial,Helvetica,sans-serif;font-size:12pt">
187
+ <h1 style="font-size:20pt;margin:0 0 6mm">Testpagina</h1>
188
+ <p style="margin:0 0 3mm">Deze pagina hoort uit: <strong>${naam}</strong></p>
189
189
  <p style="margin:0">Papier: ${maat} — ${new Date().toLocaleString("nl-NL")}</p></div>`;
190
190
  try {
191
191
  const { jobId } = await printHtml({
@@ -1,2 +1,2 @@
1
- export declare function PrintersRedirectPage(): import("react").JSX.Element;
1
+ export declare function PrintersRedirectPage(): import("react").JSX.Element;
2
2
  //# sourceMappingURL=PrintersRedirectPage.d.ts.map
@@ -1,14 +1,14 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- // ============================================================================
3
- // src/components/PrintersRedirectPage.tsx — oude URL /layouts-printers/printers
4
- // stuurt door naar de samengevoegde pagina Printplekken.
5
- // ============================================================================
6
- import { useEffect } from "react";
7
- import { useNavigate } from "@tanstack/react-router";
8
- export function PrintersRedirectPage() {
9
- const navigate = useNavigate();
10
- useEffect(() => {
11
- void navigate({ to: "/layouts-printers/printplekken", replace: true });
12
- }, [navigate]);
13
- return _jsx("p", { className: "text-muted-foreground p-6 text-sm", children: "Doorsturen naar Printplekken\u2026" });
14
- }
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/PrintersRedirectPage.tsx — oude URL /layouts-printers/printers
4
+ // stuurt door naar de samengevoegde pagina Printplekken.
5
+ // ============================================================================
6
+ import { useEffect } from "react";
7
+ import { useNavigate } from "@tanstack/react-router";
8
+ export function PrintersRedirectPage() {
9
+ const navigate = useNavigate();
10
+ useEffect(() => {
11
+ void navigate({ to: "/layouts-printers/printplekken", replace: true });
12
+ }, [navigate]);
13
+ return _jsx("p", { className: "text-muted-foreground p-6 text-sm", children: "Doorsturen naar Printplekken\u2026" });
14
+ }
@@ -10736,6 +10736,24 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
10736
10736
  };
10737
10737
  Relationships: [];
10738
10738
  };
10739
+ maps_job_lease: {
10740
+ Row: {
10741
+ job: string;
10742
+ locked_until: string;
10743
+ updated_at: string;
10744
+ };
10745
+ Insert: {
10746
+ job: string;
10747
+ locked_until?: string;
10748
+ updated_at?: string;
10749
+ };
10750
+ Update: {
10751
+ job?: string;
10752
+ locked_until?: string;
10753
+ updated_at?: string;
10754
+ };
10755
+ Relationships: [];
10756
+ };
10739
10757
  maps_request_queue: {
10740
10758
  Row: {
10741
10759
  attempts: number;
@@ -13597,6 +13615,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
13597
13615
  foutmelding: string | null;
13598
13616
  gebruiker_id: string | null;
13599
13617
  gebruiker_naam: string;
13618
+ gebruikte_bron: string | null;
13619
+ gebruikte_layout_id: string | null;
13600
13620
  gestart_op: string | null;
13601
13621
  herkomst: string | null;
13602
13622
  id: string;
@@ -13627,6 +13647,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
13627
13647
  foutmelding?: string | null;
13628
13648
  gebruiker_id?: string | null;
13629
13649
  gebruiker_naam?: string;
13650
+ gebruikte_bron?: string | null;
13651
+ gebruikte_layout_id?: string | null;
13630
13652
  gestart_op?: string | null;
13631
13653
  herkomst?: string | null;
13632
13654
  id?: string;
@@ -13657,6 +13679,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
13657
13679
  foutmelding?: string | null;
13658
13680
  gebruiker_id?: string | null;
13659
13681
  gebruiker_naam?: string;
13682
+ gebruikte_bron?: string | null;
13683
+ gebruikte_layout_id?: string | null;
13660
13684
  gestart_op?: string | null;
13661
13685
  herkomst?: string | null;
13662
13686
  id?: string;
@@ -20326,6 +20350,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
20326
20350
  foutmelding: string | null;
20327
20351
  gebruiker_id: string | null;
20328
20352
  gebruiker_naam: string;
20353
+ gebruikte_bron: string | null;
20354
+ gebruikte_layout_id: string | null;
20329
20355
  gestart_op: string | null;
20330
20356
  herkomst: string | null;
20331
20357
  id: string;
@@ -20447,6 +20473,8 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
20447
20473
  foutmelding: string | null;
20448
20474
  gebruiker_id: string | null;
20449
20475
  gebruiker_naam: string;
20476
+ gebruikte_bron: string | null;
20477
+ gebruikte_layout_id: string | null;
20450
20478
  gestart_op: string | null;
20451
20479
  herkomst: string | null;
20452
20480
  id: string;
@@ -21503,6 +21531,12 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21503
21531
  };
21504
21532
  Returns: string;
21505
21533
  };
21534
+ logistics_document_type_map: {
21535
+ Args: {
21536
+ _document_code: string;
21537
+ };
21538
+ Returns: Database["public"]["Enums"]["doc_layout_type"][];
21539
+ };
21506
21540
  logistics_emit_event: {
21507
21541
  Args: {
21508
21542
  p_event_type: string;
@@ -21966,6 +22000,10 @@ export declare const requireSupabaseAuth: import("@tanstack/start-client-core").
21966
22000
  };
21967
22001
  Returns: string;
21968
22002
  };
22003
+ maps_kick_queue: {
22004
+ Args: never;
22005
+ Returns: undefined;
22006
+ };
21969
22007
  mark_offer_clicked: {
21970
22008
  Args: {
21971
22009
  p_code: string;