@flowselections/pick-schermen-kwekers 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +24 -24
  2. package/dist-lib/components/PickstationsPage.d.ts.map +1 -1
  3. package/dist-lib/components/PickstationsPage.js +2 -1
  4. package/dist-lib/components/pick/ReferentiedataBanner.d.ts +6 -0
  5. package/dist-lib/components/pick/ReferentiedataBanner.d.ts.map +1 -0
  6. package/dist-lib/components/pick/ReferentiedataBanner.js +17 -0
  7. package/dist-lib/components/settings/ReferentiedataPickdocumentenCard.d.ts +2 -0
  8. package/dist-lib/components/settings/ReferentiedataPickdocumentenCard.d.ts.map +1 -0
  9. package/dist-lib/components/settings/ReferentiedataPickdocumentenCard.js +84 -0
  10. package/dist-lib/hooks/usePickReferenceData.d.ts +4 -0
  11. package/dist-lib/hooks/usePickReferenceData.d.ts.map +1 -0
  12. package/dist-lib/hooks/usePickReferenceData.js +10 -0
  13. package/dist-lib/index.d.ts +5 -0
  14. package/dist-lib/index.d.ts.map +1 -1
  15. package/dist-lib/index.js +6 -5
  16. package/dist-lib/integrations/supabase/auth-middleware.d.ts +291 -1
  17. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  18. package/dist-lib/integrations/supabase/client.d.ts +291 -1
  19. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  20. package/dist-lib/integrations/supabase/client.server.d.ts +291 -1
  21. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  22. package/dist-lib/integrations/supabase/types.d.ts +297 -1
  23. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  24. package/dist-lib/lib/layoutMaker/pakbonHtml.js +49 -49
  25. package/dist-lib/lib/layoutRenderer.js +17 -17
  26. package/dist-lib/lib/pickReferenceApi.d.ts +37 -0
  27. package/dist-lib/lib/pickReferenceApi.d.ts.map +1 -0
  28. package/dist-lib/lib/pickReferenceApi.js +98 -0
  29. package/package.json +1 -1
  30. package/dist-lib/components/TemplateModulePage.d.ts +0 -2
  31. package/dist-lib/components/TemplateModulePage.d.ts.map +0 -1
  32. package/dist-lib/components/TemplateModulePage.js +0 -44
@@ -590,55 +590,55 @@ export function renderPakbonDocument(config, order, opties = {}) {
590
590
  const font = opties.lettertype ?? 'Arial, Helvetica, "Segoe UI", sans-serif';
591
591
  const grootte = opties.lettergrootte ?? 8.5;
592
592
  const body = renderPakbonBody(config, order, opties);
593
- return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
594
- <title>${esc(opties.titel ?? "Pakbon")}</title>
595
- <style>
596
- @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
597
- * { box-sizing: border-box; }
598
- html, body { margin: 0; padding: 0; }
599
- body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
600
- .blok { margin-bottom: 2mm; }
601
- .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
602
- .vet { font-weight: 600; }
603
- .kv { display: flex; justify-content: space-between; gap: 3mm; }
604
- .kv .k { color: #6b7280; }
605
- .kv .v { font-weight: 500; }
606
- .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
607
- .kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
608
- table.regels { width: 100%; border-collapse: collapse; table-layout: fixed; }
609
- table.regels th, table.regels td { overflow-wrap: anywhere; }
610
- table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
611
- table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
612
- .rand { border: 0.2mm solid #d1d5db; }
613
- .onder { border-bottom: 0.2mm solid #d1d5db; }
614
- table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
615
- tr.zebra td { background: #f3f4f6; }
616
- .plijst { margin: 0; padding-left: 4mm; }
617
- .groep { margin-bottom: 1.5mm; }
618
- .regelrij { display: flex; gap: 2mm; }
619
- .tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
620
- .karblok { margin-bottom: 2mm; }
621
- .karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
622
- .karkop { display: flex; justify-content: space-between; align-items: center; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; }
623
- .bundel { display: inline-block; border: 0.3mm dashed #6b7280; border-radius: 1mm; padding: 0.4mm 1.5mm; margin-bottom: 1mm; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2mm; font-size: 90%; }
624
- .laag { margin-bottom: 1.5mm; }
625
- .laagkop { display: flex; justify-content: space-between; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; }
626
- .laagkop.compact { border-bottom: none; }
627
- .meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
628
- .totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
629
- .paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; }
630
- .handtekening { margin-top: 3mm; }
631
- .lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
632
- .lijnveld.hoog { padding-bottom: 10mm; }
633
- .lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
634
- .balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
635
- .qr { border: 0.25mm dashed #9ca3af; }
636
- .streepjes { width: 45mm; background: repeating-linear-gradient(to right, #111827 0 2px, transparent 2px 5px); }
637
- .klein { font-size: 85%; color: #6b7280; }
638
- .breekvoor { break-before: page; page-break-before: always; }
639
- .heelhouden { break-inside: avoid; page-break-inside: avoid; }
640
- img { max-width: 100%; }
641
- </style></head>
593
+ return `<!doctype html><html lang="nl"><head><meta charset="utf-8" />
594
+ <title>${esc(opties.titel ?? "Pakbon")}</title>
595
+ <style>
596
+ @page { size: ${b}mm ${h}mm; margin: ${marge}mm; }
597
+ * { box-sizing: border-box; }
598
+ html, body { margin: 0; padding: 0; }
599
+ body { font-family: ${font}; font-size: ${grootte}pt; color: #111827; line-height: 1.35; }
600
+ .blok { margin-bottom: 2mm; }
601
+ .sectitel { font-size: 90%; font-weight: 600; text-transform: uppercase; color: #6b7280; margin-bottom: 0.6mm; }
602
+ .vet { font-weight: 600; }
603
+ .kv { display: flex; justify-content: space-between; gap: 3mm; }
604
+ .kv .k { color: #6b7280; }
605
+ .kv .v { font-weight: 500; }
606
+ .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6mm; }
607
+ .kader { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
608
+ table.regels { width: 100%; border-collapse: collapse; table-layout: fixed; }
609
+ table.regels th, table.regels td { overflow-wrap: anywhere; }
610
+ table.regels th, table.regels td { padding: 0.7mm 1mm; vertical-align: top; }
611
+ table.regels th { font-size: 90%; text-transform: uppercase; color: #6b7280; font-weight: 600; text-align: left; }
612
+ .rand { border: 0.2mm solid #d1d5db; }
613
+ .onder { border-bottom: 0.2mm solid #d1d5db; }
614
+ table.regels.compact th, table.regels.compact td { padding: 0.3mm 0.8mm; }
615
+ tr.zebra td { background: #f3f4f6; }
616
+ .plijst { margin: 0; padding-left: 4mm; }
617
+ .groep { margin-bottom: 1.5mm; }
618
+ .regelrij { display: flex; gap: 2mm; }
619
+ .tweekolom { display: grid; grid-template-columns: 1fr 1fr; gap: 3mm; }
620
+ .karblok { margin-bottom: 2mm; }
621
+ .karblok.omkaderd { border: 0.25mm solid #d1d5db; border-radius: 1mm; padding: 1.5mm; }
622
+ .karkop { display: flex; justify-content: space-between; align-items: center; padding: 0.8mm 1.5mm; border-radius: 1mm; margin-bottom: 1mm; }
623
+ .bundel { display: inline-block; border: 0.3mm dashed #6b7280; border-radius: 1mm; padding: 0.4mm 1.5mm; margin-bottom: 1mm; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2mm; font-size: 90%; }
624
+ .laag { margin-bottom: 1.5mm; }
625
+ .laagkop { display: flex; justify-content: space-between; font-weight: 500; border-bottom: 0.2mm solid #d1d5db; padding-bottom: 0.4mm; margin-bottom: 0.6mm; }
626
+ .laagkop.compact { border-bottom: none; }
627
+ .meta { display: flex; gap: 3mm; font-size: 88%; font-weight: 400; color: #4b5563; }
628
+ .totalen { display: flex; flex-wrap: wrap; gap: 5mm; border-top: 0.25mm solid #d1d5db; padding-top: 1.2mm; font-weight: 500; }
629
+ .paginavoet { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; }
630
+ .handtekening { margin-top: 3mm; }
631
+ .lijnveld { margin-top: 4mm; border-bottom: 0.25mm solid #6b7280; padding-bottom: 3mm; }
632
+ .lijnveld.hoog { padding-bottom: 10mm; }
633
+ .lijn { border-top: 0.25mm solid #d1d5db; margin: 1.5mm 0; }
634
+ .balk { height: 1mm; background: #374151; margin: 1.5mm 0; }
635
+ .qr { border: 0.25mm dashed #9ca3af; }
636
+ .streepjes { width: 45mm; background: repeating-linear-gradient(to right, #111827 0 2px, transparent 2px 5px); }
637
+ .klein { font-size: 85%; color: #6b7280; }
638
+ .breekvoor { break-before: page; page-break-before: always; }
639
+ .heelhouden { break-inside: avoid; page-break-inside: avoid; }
640
+ img { max-width: 100%; }
641
+ </style></head>
642
642
  <body>${body}</body></html>`;
643
643
  }
644
644
  /** Handig voor testen: het document met de voorbeeldgegevens. */
@@ -212,22 +212,22 @@ export function renderLayoutHtml(resolved, data, locale = "nl-NL") {
212
212
  const body = resolved.elements
213
213
  .map((el) => renderElement(el, resolved, data, locale))
214
214
  .join("\n");
215
- return `<!DOCTYPE html>
216
- <html lang="nl"><head><meta charset="utf-8" />
217
- <title>${esc(layout.naam)}</title>
218
- <style>
219
- @page { size: ${w}mm ${h}mm; margin: 0; }
220
- * { box-sizing: border-box; }
221
- html, body { margin: 0; padding: 0; }
222
- body { font-family: ${baseFont}; font-size: ${baseSize}pt; color: #000; }
223
- .page { position: relative; width: ${w}mm; height: ${h}mm; overflow: hidden; }
224
- .content { position: absolute; left: ${ml}mm; top: ${mt}mm; right: ${mr}mm; bottom: ${mb}mm; }
225
- .el { position: absolute; white-space: pre-wrap; }
226
- .lbl { font-weight: 600; }
227
- .lay-table { width: 100%; border-collapse: collapse; font-size: inherit; }
228
- .lay-table th, .lay-table td { padding: 1mm 1.5mm; border-bottom: 0.2mm solid #999; vertical-align: top; }
229
- .barcode { font-family: "Libre Barcode 39", monospace; font-size: 30pt; letter-spacing: 4px; line-height: 1; }
230
- .barcode-text { font-size: 8pt; letter-spacing: 2px; }
231
- </style></head>
215
+ return `<!DOCTYPE html>
216
+ <html lang="nl"><head><meta charset="utf-8" />
217
+ <title>${esc(layout.naam)}</title>
218
+ <style>
219
+ @page { size: ${w}mm ${h}mm; margin: 0; }
220
+ * { box-sizing: border-box; }
221
+ html, body { margin: 0; padding: 0; }
222
+ body { font-family: ${baseFont}; font-size: ${baseSize}pt; color: #000; }
223
+ .page { position: relative; width: ${w}mm; height: ${h}mm; overflow: hidden; }
224
+ .content { position: absolute; left: ${ml}mm; top: ${mt}mm; right: ${mr}mm; bottom: ${mb}mm; }
225
+ .el { position: absolute; white-space: pre-wrap; }
226
+ .lbl { font-weight: 600; }
227
+ .lay-table { width: 100%; border-collapse: collapse; font-size: inherit; }
228
+ .lay-table th, .lay-table td { padding: 1mm 1.5mm; border-bottom: 0.2mm solid #999; vertical-align: top; }
229
+ .barcode { font-family: "Libre Barcode 39", monospace; font-size: 30pt; letter-spacing: 4px; line-height: 1; }
230
+ .barcode-text { font-size: 8pt; letter-spacing: 2px; }
231
+ </style></head>
232
232
  <body><div class="page"><div class="content">${body}</div></div></body></html>`;
233
233
  }
@@ -0,0 +1,37 @@
1
+ import type { PickDocumentType, PickStatus } from "./pickTypes";
2
+ /** Codes waar SQL-functies en TypeScript hardcoded op zoeken. */
3
+ export declare const VERPLICHTE_TYPE_CODES: readonly ["pakbon"];
4
+ export declare const VERPLICHTE_STATUS_CODES: readonly ["queued", "reserved", "printing", "printed", "cancelled"];
5
+ export interface PickReferenceStatus {
6
+ verplichte_types: string[];
7
+ verplichte_statussen: string[];
8
+ types_aantal: number;
9
+ statussen_aantal: number;
10
+ types_ontbreken: string[];
11
+ types_inactief: string[];
12
+ statussen_ontbreken: string[];
13
+ statussen_inactief: string[];
14
+ types: PickDocumentType[];
15
+ statussen: PickStatus[];
16
+ }
17
+ export declare const pickReferenceApi: {
18
+ /** Eén bron voor kaart en banner: aantallen, ontbrekende codes en de rijen zelf. */
19
+ status(): Promise<PickReferenceStatus>;
20
+ seed(): Promise<{
21
+ statuses_toegevoegd: number;
22
+ types_toegevoegd: number;
23
+ }>;
24
+ updateType(id: string, patch: Partial<PickDocumentType>): Promise<void>;
25
+ updateStatus(id: string, patch: Partial<PickStatus>): Promise<void>;
26
+ insertType(row: {
27
+ code: string;
28
+ name: string;
29
+ }): Promise<void>;
30
+ insertStatus(row: {
31
+ code: string;
32
+ name: string;
33
+ }): Promise<void>;
34
+ };
35
+ /** Alle verplichte codes die ontbreken of uitgezet zijn, als leesbare regels. */
36
+ export declare function referentieProblemen(s: PickReferenceStatus | undefined | null): string[];
37
+ //# sourceMappingURL=pickReferenceApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pickReferenceApi.d.ts","sourceRoot":"","sources":["../../src/lib/pickReferenceApi.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEhE,iEAAiE;AACjE,eAAO,MAAM,qBAAqB,qBAAsB,CAAC;AACzD,eAAO,MAAM,uBAAuB,qEAM1B,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB;AAoBD,eAAO,MAAM,gBAAgB;IAC3B,oFAAoF;cACpE,OAAO,CAAC,mBAAmB,CAAC;YAmB9B,OAAO,CAAC;QAAE,mBAAmB,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;mBAU3D,MAAM,SAAS,OAAO,CAAC,gBAAgB,CAAC;qBAKtC,MAAM,SAAS,OAAO,CAAC,UAAU,CAAC;oBAKnC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;sBAK5B;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAIvD,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,mBAAmB,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAgBvF"}
@@ -0,0 +1,98 @@
1
+ import { pickDb } from "./pickApi";
2
+ import { safeArray } from "./pickTypes";
3
+ /** Codes waar SQL-functies en TypeScript hardcoded op zoeken. */
4
+ export const VERPLICHTE_TYPE_CODES = ["pakbon"];
5
+ export const VERPLICHTE_STATUS_CODES = [
6
+ "queued",
7
+ "reserved",
8
+ "printing",
9
+ "printed",
10
+ "cancelled",
11
+ ];
12
+ const leeg = {
13
+ verplichte_types: [...VERPLICHTE_TYPE_CODES],
14
+ verplichte_statussen: [...VERPLICHTE_STATUS_CODES],
15
+ types_aantal: 0,
16
+ statussen_aantal: 0,
17
+ types_ontbreken: [],
18
+ types_inactief: [],
19
+ statussen_ontbreken: [],
20
+ statussen_inactief: [],
21
+ types: [],
22
+ statussen: [],
23
+ };
24
+ function num(v) {
25
+ const n = Number(v);
26
+ return Number.isFinite(n) ? n : 0;
27
+ }
28
+ export const pickReferenceApi = {
29
+ /** Eén bron voor kaart en banner: aantallen, ontbrekende codes en de rijen zelf. */
30
+ async status() {
31
+ const { data, error } = await pickDb.rpc("pick_reference_data_status");
32
+ if (error)
33
+ throw new Error(error.message);
34
+ const row = (data ?? {});
35
+ return {
36
+ ...leeg,
37
+ verplichte_types: safeArray(row.verplichte_types),
38
+ verplichte_statussen: safeArray(row.verplichte_statussen),
39
+ types_aantal: num(row.types_aantal),
40
+ statussen_aantal: num(row.statussen_aantal),
41
+ types_ontbreken: safeArray(row.types_ontbreken),
42
+ types_inactief: safeArray(row.types_inactief),
43
+ statussen_ontbreken: safeArray(row.statussen_ontbreken),
44
+ statussen_inactief: safeArray(row.statussen_inactief),
45
+ types: safeArray(row.types),
46
+ statussen: safeArray(row.statussen),
47
+ };
48
+ },
49
+ async seed() {
50
+ const { data, error } = await pickDb.rpc("pick_seed_reference_data");
51
+ if (error)
52
+ throw new Error(error.message);
53
+ const row = (data ?? {});
54
+ return {
55
+ statuses_toegevoegd: num(row["statuses_toegevoegd"]),
56
+ types_toegevoegd: num(row["types_toegevoegd"]),
57
+ };
58
+ },
59
+ async updateType(id, patch) {
60
+ const res = await pickDb.from("pick_document_types").update(patch).eq("id", id);
61
+ if (res.error)
62
+ throw new Error(res.error.message);
63
+ },
64
+ async updateStatus(id, patch) {
65
+ const res = await pickDb.from("pick_document_statuses").update(patch).eq("id", id);
66
+ if (res.error)
67
+ throw new Error(res.error.message);
68
+ },
69
+ async insertType(row) {
70
+ const res = await pickDb.from("pick_document_types").insert(row);
71
+ if (res.error)
72
+ throw new Error(res.error.message);
73
+ },
74
+ async insertStatus(row) {
75
+ const res = await pickDb.from("pick_document_statuses").insert(row);
76
+ if (res.error)
77
+ throw new Error(res.error.message);
78
+ },
79
+ };
80
+ /** Alle verplichte codes die ontbreken of uitgezet zijn, als leesbare regels. */
81
+ export function referentieProblemen(s) {
82
+ if (!s)
83
+ return [];
84
+ const regels = [];
85
+ for (const code of safeArray(s.types_ontbreken)) {
86
+ regels.push(`Documenttype '${code}' ontbreekt.`);
87
+ }
88
+ for (const code of safeArray(s.types_inactief)) {
89
+ regels.push(`Documenttype '${code}' staat op inactief.`);
90
+ }
91
+ for (const code of safeArray(s.statussen_ontbreken)) {
92
+ regels.push(`Documentstatus '${code}' ontbreekt.`);
93
+ }
94
+ for (const code of safeArray(s.statussen_inactief)) {
95
+ regels.push(`Documentstatus '${code}' staat op inactief.`);
96
+ }
97
+ return regels;
98
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/pick-schermen-kwekers",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "flowselections": {
5
5
  "moduleId": "pick-schermen",
6
6
  "pages": [
@@ -1,2 +0,0 @@
1
- export declare function TemplateModulePage(): import("react").JSX.Element;
2
- //# sourceMappingURL=TemplateModulePage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TemplateModulePage.d.ts","sourceRoot":"","sources":["../../src/components/TemplateModulePage.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,kBAAkB,gCAmFjC"}
@@ -1,44 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- // ============================================================================
3
- // src/components/TemplateModulePage.tsx — EXAMPLE PAGE COMPONENT
4
- // ============================================================================
5
- // Pagina-componenten horen in src/components/, NIET alleen in src/routes/.
6
- // src/routes/ wordt NIET naar npm gepubliceerd (zie tsconfig.build.json exclude).
7
- //
8
- // GEEN <Header /> hier — die zit in _authenticated.tsx via staticData.title
9
- // ============================================================================
10
- import { useState, useEffect } from "react";
11
- import { useAuth, supabase, Button, Card, CardContent, CardHeader, CardTitle, toast, } from "@flowselections/core";
12
- import { TemplateModuleLogo } from './TemplateModuleLogo';
13
- export function TemplateModulePage() {
14
- // Auth is guaranteed — this user is already logged in
15
- const { user, isAdmin } = useAuth();
16
- // Example state — replace with your own
17
- const [items, setItems] = useState([]);
18
- const [loading, setLoading] = useState(true);
19
- useEffect(() => {
20
- loadData();
21
- }, []);
22
- const loadData = async () => {
23
- setLoading(true);
24
- try {
25
- // Example query — replace "products" with your table
26
- const { data, error } = await supabase
27
- .from("products")
28
- .select("*")
29
- .limit(10);
30
- if (error)
31
- throw error;
32
- // ✅ Altijd Array.isArray bewaken op server-function data
33
- // const safeItems = Array.isArray(data?.items) ? data.items : [];
34
- setItems(Array.isArray(data) ? data : []);
35
- }
36
- catch {
37
- toast.error("Fout bij het laden van gegevens");
38
- }
39
- finally {
40
- setLoading(false);
41
- }
42
- };
43
- return (_jsxs("main", { className: "p-6 space-y-6", children: [isAdmin && (_jsxs("div", { className: "text-sm text-muted-foreground", children: ["Ingelogd als admin: ", user?.email] })), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: "Overzicht" }) }), _jsxs(CardContent, { children: [loading ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Laden..." })) : items.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Geen gegevens gevonden." })) : (_jsxs("p", { className: "text-sm", children: [items.length, " items geladen."] })), _jsx(Button, { onClick: loadData, className: "mt-4", disabled: loading, children: "Vernieuwen" })] })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(TemplateModuleLogo, { className: "w-6 h-6 text-primary" }), _jsx("span", { children: "SVG-component (voorkeur voor vector-logo's)" })] })] }));
44
- }