@flowselections/layout-maker 1.22.2 → 1.23.2

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 (46) hide show
  1. package/README.md +139 -139
  2. package/dist-lib/components/AfdrukKnop.d.ts +19 -19
  3. package/dist-lib/components/AfdrukKnop.d.ts.map +1 -1
  4. package/dist-lib/components/NetwerkPrintersDialog.d.ts +7 -7
  5. package/dist-lib/components/NetwerkPrintersDialog.d.ts.map +1 -1
  6. package/dist-lib/components/PrinterSetupWizard.d.ts.map +1 -1
  7. package/dist-lib/components/PrinterSetupWizard.js +77 -30
  8. package/dist-lib/components/PrintersRedirectPage.d.ts +1 -1
  9. package/dist-lib/components/PrintersRedirectPage.js +14 -14
  10. package/dist-lib/index.d.ts +2 -5
  11. package/dist-lib/index.d.ts.map +1 -1
  12. package/dist-lib/index.js +1 -3
  13. package/dist-lib/integrations/supabase/auth-middleware.d.ts +233 -0
  14. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  15. package/dist-lib/integrations/supabase/client.server.d.ts +233 -0
  16. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  17. package/dist-lib/integrations/supabase/types.d.ts +236 -0
  18. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  19. package/dist-lib/lib/aiLayout.functions.d.ts +233 -0
  20. package/dist-lib/lib/aiLayout.functions.d.ts.map +1 -1
  21. package/dist-lib/lib/aiLayout.server.js +9 -9
  22. package/dist-lib/lib/browserPrint.d.ts +0 -23
  23. package/dist-lib/lib/browserPrint.d.ts.map +1 -1
  24. package/dist-lib/lib/browserPrint.js +4 -49
  25. package/dist-lib/lib/layoutPreview.js +7 -7
  26. package/dist-lib/lib/pakbonHtml.js +50 -50
  27. package/dist-lib/lib/papierFormaten.d.ts +30 -0
  28. package/dist-lib/lib/papierFormaten.d.ts.map +1 -0
  29. package/dist-lib/lib/papierFormaten.js +106 -0
  30. package/dist-lib/lib/printQueue.server.d.ts.map +1 -1
  31. package/dist-lib/lib/printQueue.server.js +44 -2
  32. package/dist-lib/lib/printService.functions.d.ts +932 -0
  33. package/dist-lib/lib/printService.functions.d.ts.map +1 -1
  34. package/dist-lib/lib/printService.server.d.ts +20 -0
  35. package/dist-lib/lib/printService.server.d.ts.map +1 -1
  36. package/dist-lib/lib/printService.server.js +24 -0
  37. package/dist-lib/lib/productiebonHtml.js +15 -15
  38. package/dist-lib/lib/profielHtml.js +18 -18
  39. package/dist-lib/lib/supabaseAdmin.server.d.ts +5 -5
  40. package/dist-lib/lib/supabaseAdmin.server.js +43 -43
  41. package/dist-lib/lib/testpagina.d.ts.map +1 -1
  42. package/dist-lib/lib/testpagina.js +27 -22
  43. package/dist-lib/lib/testprint.js +4 -4
  44. package/dist-lib/lib/useDocumentData.d.ts +1 -6
  45. package/dist-lib/lib/useDocumentData.d.ts.map +1 -1
  46. 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.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 +1 @@
1
- {"version":3,"file":"AfdrukKnop.d.ts","sourceRoot":"","sources":["../../src/components/AfdrukKnop.tsx"],"names":[],"mappings":"AASA,OAAO,EAAU,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG9D,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,GAAG,EACH,YAAY,EACZ,KAAmB,EACnB,QAAQ,EACR,OAAO,GACR,EAAE,eAAe,+BAwDjB"}
1
+ {"version":3,"file":"AfdrukKnop.d.ts","sourceRoot":"","sources":["../../src/components/AfdrukKnop.tsx"],"names":[],"mappings":"AASA,OAAO,EAAU,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG9D,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,GAAG,EACH,YAAY,EACZ,KAAmB,EACnB,QAAQ,EACR,OAAO,GACR,EAAE,eAAe,2CAwDjB"}
@@ -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.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":"NetwerkPrintersDialog.d.ts","sourceRoot":"","sources":["../../src/components/NetwerkPrintersDialog.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,+BAkHA"}
1
+ {"version":3,"file":"NetwerkPrintersDialog.d.ts","sourceRoot":"","sources":["../../src/components/NetwerkPrintersDialog.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,2CAkHA"}
@@ -1 +1 @@
1
- {"version":3,"file":"PrinterSetupWizard.d.ts","sourceRoot":"","sources":["../../src/components/PrinterSetupWizard.tsx"],"names":[],"mappings":"AA6CA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAoCD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,cAAc,EACd,iBAAsB,EACtB,eAAoB,EACpB,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC,+BAiXA"}
1
+ {"version":3,"file":"PrinterSetupWizard.d.ts","sourceRoot":"","sources":["../../src/components/PrinterSetupWizard.tsx"],"names":[],"mappings":"AAkDA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAwCD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,cAAc,EACd,iBAAsB,EACtB,eAAoB,EACpB,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CACjC,+BA0cA"}
@@ -7,14 +7,20 @@ import { useCallback, useEffect, useMemo, useState } from "react";
7
7
  import { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Input, Label, toast, } from "@flowselections/core";
8
8
  import { Check, CheckCircle2, FileText, Loader2, Printer, RefreshCw, Search, Tag, } from "lucide-react";
9
9
  import { supabase } from "../lib/supabaseClient.js";
10
- import { printDirect } from "../lib/directPrint.js";
10
+ import { printHtml, volgJobStatus } from "../lib/printApi.js";
11
11
  import { netwerkPrinters } from "../lib/printService.functions.js";
12
+ import { printerFormaatOpties } from "../lib/papierFormaten.js";
12
13
  import { PrintProgrammaUitleg, WerktHetNiet } from "./PrintProgrammaUitleg.js";
13
14
  const STAPPEN = ["Printer kiezen", "Naam en locatie", "Klaar"];
14
- function instellingenVoor(gebruik) {
15
- return gebruik === "etiket"
16
- ? { soort: "labelprinter", papierformaat: "label" }
17
- : { soort: "laserprinter", papierformaat: "A4" };
15
+ /**
16
+ * De instellingen die bij de printer worden bewaard. Kent de printer zijn eigen
17
+ * papierformaten, dan gebruiken we de gekozen echte formaatcode; anders vallen
18
+ * we terug op de eenvoudige keuze papier of etiket.
19
+ */
20
+ function instellingenVoor(gebruik, optie) {
21
+ if (optie)
22
+ return { papierformaat: optie.code };
23
+ return { papierformaat: gebruik === "etiket" ? "LABEL_100x62" : "A4" };
18
24
  }
19
25
  function Stappenbalk({ stap }) {
20
26
  return (_jsx("div", { className: "flex items-center gap-2", children: STAPPEN.map((s, i) => (_jsxs("div", { className: "flex flex-1 items-center gap-2", children: [_jsx("div", { className: `flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-xs font-medium ${i < stap
@@ -36,6 +42,9 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
36
42
  const [locatie, setLocatie] = useState("");
37
43
  const [gebruik, setGebruik] = useState("papier");
38
44
  const [printerId, setPrinterId] = useState(null);
45
+ const [formaten, setFormaten] = useState(null);
46
+ const [laden, setLaden] = useState([]);
47
+ const [formaatCode, setFormaatCode] = useState("");
39
48
  const zoeken = useCallback(async () => {
40
49
  setZoekt(true);
41
50
  setFout(null);
@@ -65,6 +74,9 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
65
74
  setLocatie("");
66
75
  setGebruik("papier");
67
76
  setPrinterId(null);
77
+ setFormaten(null);
78
+ setLaden([]);
79
+ setFormaatCode("");
68
80
  setZoekterm("");
69
81
  setUitlegOpen(false);
70
82
  return;
@@ -75,6 +87,17 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
75
87
  setNaam(bewerken.naam);
76
88
  setLocatie(bewerken.locatie ?? "");
77
89
  setGebruik(bewerken.papierformaat === "label" ? "etiket" : "papier");
90
+ setFormaatCode(bewerken.papierformaat && bewerken.papierformaat !== "label" ? bewerken.papierformaat : "");
91
+ void (async () => {
92
+ const { data } = await supabase
93
+ .from("printers")
94
+ .select("ondersteunde_formaten, ondersteunde_laden")
95
+ .eq("id", bewerken.id)
96
+ .maybeSingle();
97
+ const rij = data;
98
+ setFormaten(rij?.ondersteunde_formaten ?? null);
99
+ setLaden(Array.isArray(rij?.ondersteunde_laden) ? rij.ondersteunde_laden : []);
100
+ })();
78
101
  return;
79
102
  }
80
103
  void zoeken();
@@ -88,9 +111,16 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
88
111
  const kiesPrinter = (p) => {
89
112
  setGekozen(p);
90
113
  setNaam(p.naam);
91
- setLocatie(p.computer ?? "");
114
+ setLocatie("");
115
+ setFormaten(p.formaten ?? null);
116
+ setLaden(Array.isArray(p.laden) ? p.laden : []);
117
+ const opties = printerFormaatOpties(p.formaten ?? null);
118
+ const voorkeur = opties.find((o) => o.code === "A4") ?? opties[0];
119
+ setFormaatCode(voorkeur?.code ?? "");
92
120
  setStap(1);
93
121
  };
122
+ const formaatOpties = useMemo(() => printerFormaatOpties(formaten), [formaten]);
123
+ const gekozenFormaat = formaatOpties.find((o) => o.code === formaatCode) ?? null;
94
124
  const opslaan = async () => {
95
125
  const eindnaam = naam.trim() || gekozen?.naam || "";
96
126
  if (!eindnaam) {
@@ -105,7 +135,8 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
105
135
  .update({
106
136
  naam: eindnaam,
107
137
  locatie: locatie.trim() || null,
108
- ...instellingenVoor(gebruik),
138
+ ...instellingenVoor(gebruik, gekozenFormaat),
139
+ ...(formaten ? { ondersteunde_formaten: formaten, ondersteunde_laden: laden, formaten_bijgewerkt_op: new Date().toISOString() } : {}),
109
140
  })
110
141
  .eq("id", bewerken.id);
111
142
  if (error)
@@ -124,7 +155,8 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
124
155
  systeemnaam: gekozen?.naam ?? eindnaam,
125
156
  locatie: locatie.trim() || null,
126
157
  extern_printer_id: gekozen?.id ?? null,
127
- ...instellingenVoor(gebruik),
158
+ ...instellingenVoor(gebruik, gekozenFormaat),
159
+ ...(formaten ? { ondersteunde_formaten: formaten, ondersteunde_laden: laden, formaten_bijgewerkt_op: new Date().toISOString() } : {}),
128
160
  })
129
161
  .select("id")
130
162
  .single();
@@ -142,30 +174,44 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
142
174
  }
143
175
  };
144
176
  const [testStatus, setTestStatus] = useState("leeg");
177
+ const [testMelding, setTestMelding] = useState("");
145
178
  const testpagina = async () => {
179
+ if (!printerId) {
180
+ toast.error("De printer is nog niet opgeslagen");
181
+ return;
182
+ }
146
183
  setTestStatus("bezig");
147
- const html = `<div style="padding:20mm;font-size:14pt"><h1 style="font-size:20pt">Testpagina</h1>
148
- <p>Deze pagina hoort uit: <strong>${naam}</strong></p></div>`;
149
- const opdracht = {
150
- documenttype: "pakbon",
151
- formaatCode: gebruik === "etiket" ? "label" : "A4",
152
- orientatie: "portrait",
153
- documentnaam: "Testpagina",
154
- html,
155
- printerId: printerId ?? undefined,
156
- };
184
+ setTestMelding("");
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>
189
+ <p style="margin:0">Papier: ${maat} — ${new Date().toLocaleString("nl-NL")}</p></div>`;
157
190
  try {
158
- const direct = await printDirect(opdracht);
159
- if (direct.gelukt) {
160
- setTestStatus("gelukt");
161
- return;
162
- }
163
- if (direct.reden)
164
- toast.error(direct.reden);
165
- setTestStatus("fout");
191
+ const { jobId } = await printHtml({
192
+ documenttype: "vrij",
193
+ documentnaam: "Testpagina",
194
+ html,
195
+ printerId,
196
+ payload: { is_testpagina: true, test_id: `wizard-${Date.now()}` },
197
+ });
198
+ const stop = volgJobStatus(jobId, (st) => {
199
+ if (st.status === "voltooid") {
200
+ setTestStatus("gelukt");
201
+ setTestMelding(`Verstuurd naar ${naam}${gekozenFormaat ? ` op ${gekozenFormaat.label}` : ""}.`);
202
+ stop();
203
+ }
204
+ else if (st.status === "mislukt") {
205
+ setTestStatus("fout");
206
+ setTestMelding(st.foutmelding ?? "");
207
+ stop();
208
+ }
209
+ });
210
+ setTimeout(() => stop(), 60000);
166
211
  }
167
- catch {
212
+ catch (e) {
168
213
  setTestStatus("fout");
214
+ setTestMelding(e instanceof Error ? e.message : "");
169
215
  }
170
216
  };
171
217
  const opnieuw = () => {
@@ -178,12 +224,13 @@ export function PrinterSetupWizard({ open, onOpenChange, onKlaar, computerFilter
178
224
  void zoeken();
179
225
  };
180
226
  return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-xl", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: bewerken ? "Naam en locatie wijzigen" : "Printer toevoegen" }), _jsx(DialogDescription, { children: bewerken
181
- ? "Pas de naam, de locatie en het soort papier aan."
227
+ ? "Pas de naam, de omschrijving en het standaardformaat aan."
182
228
  : "Kies uw printer, geef hem een herkenbare naam en druk een testpagina af." })] }), !bewerken && _jsx(Stappenbalk, { stap: stap }), stap === 0 && (_jsxs("div", { className: "space-y-4", children: [lijst.length > 6 && (_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-2.5 left-3 h-4 w-4" }), _jsx(Input, { className: "pl-9", value: zoekterm, placeholder: "Zoek op printer of computer", onChange: (e) => setZoekterm(e.target.value) })] })), zoekt && (_jsxs("p", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Printers zoeken\u2026"] })), !zoekt && fout && _jsx("p", { className: "text-destructive text-sm", children: fout }), !zoekt && zichtbaar.length > 0 && (_jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: zichtbaar.map((p) => {
183
229
  const al = bekendeExterneIds.includes(p.id);
184
230
  return (_jsx("button", { type: "button", disabled: al, onClick: () => kiesPrinter(p), className: `rounded-xl border p-4 text-left transition ${al ? "opacity-60" : "hover:border-primary/50 hover:bg-accent/40"}`, children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Printer, { className: "text-muted-foreground mt-0.5 h-5 w-5 shrink-0" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-sm font-medium", children: p.naam }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: p.computer }), _jsxs("span", { className: "mt-2 flex items-center gap-1.5 text-xs", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${p.online ? "bg-primary" : "bg-muted-foreground/40"}` }), al ? "Al toegevoegd" : p.online ? "Beschikbaar" : "Niet aan"] })] })] }) }, p.id));
185
- }) })), !zoekt && zichtbaar.length === 0 && _jsx(PrintProgrammaUitleg, {}), !zoekt && zichtbaar.length > 0 && (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground text-sm underline", onClick: () => setUitlegOpen((v) => !v), children: "Ik zie mijn printer niet" }), uitlegOpen && _jsx(PrintProgrammaUitleg, { compact: true })] })), _jsx("div", { className: "flex justify-between", children: _jsxs(Button, { variant: "ghost", onClick: () => void zoeken(), disabled: zoekt, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), " Opnieuw zoeken"] }) })] })), stap === 1 && (_jsxs("div", { className: "grid gap-5 sm:grid-cols-[1fr_200px]", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Weergavenaam" }), _jsx(Input, { value: naam, placeholder: "Bijvoorbeeld: pakbonprinter voorin", onChange: (e) => setNaam(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Locatie" }), _jsx(Input, { value: locatie, placeholder: "Bijvoorbeeld: magazijn", onChange: (e) => setLocatie(e.target.value) }), bekendeLocaties.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 pt-1", children: bekendeLocaties.slice(0, 6).map((l) => (_jsx("button", { type: "button", onClick: () => setLocatie(l), className: "hover:bg-accent rounded-full border px-3 py-1 text-xs", children: l }, l))) }))] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Wat gaat deze printer afdrukken?" }), _jsx("div", { className: "grid grid-cols-2 gap-3", children: [
231
+ }) })), !zoekt && zichtbaar.length === 0 && _jsx(PrintProgrammaUitleg, {}), !zoekt && zichtbaar.length > 0 && (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { type: "button", className: "text-muted-foreground hover:text-foreground text-sm underline", onClick: () => setUitlegOpen((v) => !v), children: "Ik zie mijn printer niet" }), uitlegOpen && _jsx(PrintProgrammaUitleg, { compact: true })] })), _jsx("div", { className: "flex justify-between", children: _jsxs(Button, { variant: "ghost", onClick: () => void zoeken(), disabled: zoekt, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), " Opnieuw zoeken"] }) })] })), stap === 1 && (_jsxs("div", { className: "grid gap-5 sm:grid-cols-[1fr_200px]", children: [_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Weergavenaam" }), _jsx(Input, { value: naam, placeholder: "Bijvoorbeeld: pakbonprinter voorin", onChange: (e) => setNaam(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Omschrijving (optioneel)" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Waar staat deze printer? Bijvoorbeeld: magazijn achter." }), _jsx(Input, { value: locatie, placeholder: "Bijvoorbeeld: magazijn achter", onChange: (e) => setLocatie(e.target.value) }), bekendeLocaties.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 pt-1", children: bekendeLocaties.slice(0, 6).map((l) => (_jsx("button", { type: "button", onClick: () => setLocatie(l), className: "hover:bg-accent rounded-full border px-3 py-1 text-xs", children: l }, l))) }))] }), formaatOpties.length > 0 ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Standaardformaat van deze printer" }), _jsxs("p", { className: "text-muted-foreground text-xs", children: ["Deze printer kan: ", formaatOpties.map((o) => o.label.split(" (")[0]).join(", "), "."] }), formaatOpties.length === 1 ? (_jsx("p", { className: "text-sm", children: formaatOpties[0].label })) : (_jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: formaatOpties.map((o) => (_jsxs("button", { type: "button", onClick: () => setFormaatCode(o.code), className: `hover:bg-accent rounded-lg border p-3 text-left transition ${formaatCode === o.code ? "border-primary bg-accent" : ""}`, children: [o.breedte <= 120 && o.hoogte <= 220 ? (_jsx(Tag, { className: "text-muted-foreground mb-1 h-4 w-4" })) : (_jsx(FileText, { className: "text-muted-foreground mb-1 h-4 w-4" })), _jsx("p", { className: "text-sm font-medium", children: o.label.split(" (")[0] }), _jsxs("p", { className: "text-muted-foreground text-xs", children: [o.breedte, " \u00D7 ", o.hoogte, " mm"] })] }, o.code))) }))] })) : (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Wat gaat deze printer afdrukken?" }), _jsx("p", { className: "text-muted-foreground text-xs", children: "De formaten van deze printer konden niet worden opgehaald." }), _jsx("div", { className: "grid grid-cols-2 gap-3", children: [
186
232
  { code: "papier", label: "Papier (A4)", sub: "Gewone documenten", Icon: FileText },
187
233
  { code: "etiket", label: "Etiketten", sub: "Stickers en labels", Icon: Tag },
188
- ].map((o) => (_jsxs("button", { type: "button", onClick: () => setGebruik(o.code), className: `hover:bg-accent rounded-lg border p-4 text-left transition ${gebruik === o.code ? "border-primary bg-accent" : ""}`, children: [_jsx(o.Icon, { className: "text-muted-foreground mb-2 h-5 w-5" }), _jsx("p", { className: "text-sm font-medium", children: o.label }), _jsx("p", { className: "text-muted-foreground text-xs", children: o.sub })] }, o.code))) })] }), _jsxs("div", { className: "flex justify-between", children: [!bewerken ? (_jsx(Button, { variant: "ghost", onClick: () => setStap(0), children: "Terug" })) : (_jsx("span", {})), _jsx(Button, { disabled: bezig, onClick: () => void opslaan(), children: bewerken ? "Opslaan" : "Opslaan en verder" })] })] }), _jsxs("div", { className: "hidden sm:block", children: [_jsx("p", { className: "text-muted-foreground mb-2 text-xs", children: "Zo komt hij in de lijst:" }), _jsxs("div", { className: "bg-card rounded-xl border p-3", children: [_jsx(Printer, { className: "text-muted-foreground mb-2 h-4 w-4" }), _jsx("p", { className: "truncate text-sm font-medium", children: naam || "Naam van de printer" }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: locatie || "Geen locatie" })] })] })] })), stap === 2 && (_jsxs("div", { className: "space-y-4 text-center", children: [_jsx(CheckCircle2, { className: "text-primary mx-auto h-10 w-10" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "De printer is klaar voor gebruik" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [naam, " ", locatie ? `bij ${locatie}` : "", " drukt voortaan automatisch af."] })] }), testStatus !== "leeg" && (_jsxs("p", { className: "text-muted-foreground text-sm", children: [testStatus === "bezig" && "Onderweg naar de printer…", testStatus === "gelukt" && "De testpagina is verstuurd.", testStatus === "fout" && "De testpagina kon niet worden afgedrukt."] })), _jsxs("div", { className: "flex flex-wrap justify-center gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => void testpagina(), children: "Testpagina afdrukken" }), _jsx(Button, { variant: "ghost", onClick: opnieuw, children: "Nog een printer toevoegen" }), _jsx(Button, { onClick: () => onOpenChange(false), children: "Klaar" })] }), _jsx(WerktHetNiet, {})] }))] }) }));
234
+ ].map((o) => (_jsxs("button", { type: "button", onClick: () => setGebruik(o.code), className: `hover:bg-accent rounded-lg border p-4 text-left transition ${gebruik === o.code ? "border-primary bg-accent" : ""}`, children: [_jsx(o.Icon, { className: "text-muted-foreground mb-2 h-5 w-5" }), _jsx("p", { className: "text-sm font-medium", children: o.label }), _jsx("p", { className: "text-muted-foreground text-xs", children: o.sub })] }, o.code))) })] })), _jsxs("div", { className: "flex justify-between", children: [!bewerken ? (_jsx(Button, { variant: "ghost", onClick: () => setStap(0), children: "Terug" })) : (_jsx("span", {})), _jsx(Button, { disabled: bezig, onClick: () => void opslaan(), children: bewerken ? "Opslaan" : "Opslaan en verder" })] })] }), _jsxs("div", { className: "hidden sm:block", children: [_jsx("p", { className: "text-muted-foreground mb-2 text-xs", children: "Zo komt hij in de lijst:" }), _jsxs("div", { className: "bg-card rounded-xl border p-3", children: [_jsx(Printer, { className: "text-muted-foreground mb-2 h-4 w-4" }), _jsx("p", { className: "truncate text-sm font-medium", children: naam || "Naam van de printer" }), _jsx("p", { className: "text-muted-foreground truncate text-xs", children: locatie || gekozen?.computer || "Geen omschrijving" })] })] })] })), stap === 2 && (_jsxs("div", { className: "space-y-4 text-center", children: [_jsx(CheckCircle2, { className: "text-primary mx-auto h-10 w-10" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: "De printer is klaar voor gebruik" }), _jsxs("p", { className: "text-muted-foreground text-sm", children: [naam, " ", locatie ? `bij ${locatie}` : "", " drukt voortaan automatisch af."] })] }), testStatus !== "leeg" && (_jsxs("p", { className: "text-muted-foreground text-sm", children: [testStatus === "bezig" && "Onderweg naar de printer…", testStatus === "gelukt" && (testMelding || "De testpagina is afgedrukt."), testStatus === "fout" &&
235
+ `De testpagina kon niet worden afgedrukt.${testMelding ? ` ${testMelding}` : ""}`] })), _jsxs("div", { className: "flex flex-wrap justify-center gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => void testpagina(), children: "Testpagina afdrukken" }), _jsx(Button, { variant: "ghost", onClick: opnieuw, children: "Nog een printer toevoegen" }), _jsx(Button, { onClick: () => onOpenChange(false), children: "Klaar" })] }), _jsx(WerktHetNiet, {})] }))] }) }));
189
236
  }
@@ -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
+ }
@@ -14,6 +14,8 @@ export { drukTestpaginaAf } from './lib/testpagina.js';
14
14
  export { TestprintDialog } from './components/TestprintDialog.js';
15
15
  export { bepaalTestOverzicht, verstuurTestprint } from './lib/testprint.js';
16
16
  export type { TestprintContext, TestprintRegel, TestprintResultaat } from './lib/testprint.js';
17
+ export { bedoeldePrinter, formaatDef, paginaCss } from './lib/browserPrint.js';
18
+ export type { Orientatie, PrinterKeuze } from './lib/browserPrint.js';
17
19
  export { PrintQueuePage } from './components/PrintQueuePage.js';
18
20
  export { AiLayoutImportDialog } from './components/AiLayoutImportDialog.js';
19
21
  export { LogosPage, LogoThumbnail } from './components/LogosPage.js';
@@ -58,15 +60,10 @@ export type { PlekNamen } from './lib/printQueue.js';
58
60
  export type { PrintJobModel, PrinterModel } from './lib/useDocumentData.js';
59
61
  export { beschikbareLayouts, beschikbarePrinters, printDocument, printPdf, printHtml, printerVoorWerkplek, printerVoorDocumenttype, volgJobStatus, DubbeleAanvraagFout, } from './lib/printApi.js';
60
62
  export type { PrintDocumentInput, PrintDocumentResult, PrintPdfInput, PrintHtmlInput, JobStatus, } from './lib/printApi.js';
61
- export { bedoeldePrinter, drukAf, formaatDef, paginaCss } from './lib/browserPrint.js';
62
- export type { AfdrukOpdracht, AfdrukResultaat, Orientatie, PrinterKeuze } from './lib/browserPrint.js';
63
63
  export { printDirect } from './lib/directPrint.js';
64
64
  export type { DirectPrintOpdracht, DirectPrintResultaat } from './lib/directPrint.js';
65
65
  export { htmlNaarPdfBase64 } from './lib/documentPdf.js';
66
66
  export type { PdfOpdracht } from './lib/documentPdf.js';
67
- export { NetwerkPrintersDialog } from './components/NetwerkPrintersDialog.js';
68
- export { AfdrukKnop } from './components/AfdrukKnop.js';
69
- export type { AfdrukKnopProps } from './components/AfdrukKnop.js';
70
67
  export { supabase } from './lib/supabaseClient.js';
71
68
  export { useLayoutIdParam } from './lib/useLayoutIdParam.js';
72
69
  export { PaginaDocument } from './components/PaginaDocument.js';