@flowselections/pick-schermen-kwekers 1.0.84 → 1.0.89

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 (85) hide show
  1. package/dist-lib/components/PickPublicPage.d.ts.map +1 -1
  2. package/dist-lib/components/PickPublicPage.js +12 -0
  3. package/dist-lib/components/pick/DocumentChoiceMelding.d.ts +1 -1
  4. package/dist-lib/components/pick/DocumentChoiceMelding.d.ts.map +1 -1
  5. package/dist-lib/components/pick/PickScherm.d.ts.map +1 -1
  6. package/dist-lib/components/pick/PickScherm.js +377 -159
  7. package/dist-lib/components/pick/werkvloer/Werkvloer.d.ts +52 -0
  8. package/dist-lib/components/pick/werkvloer/Werkvloer.d.ts.map +1 -0
  9. package/dist-lib/components/pick/werkvloer/Werkvloer.js +33 -0
  10. package/dist-lib/hooks/useCartStickerStates.d.ts +1 -1
  11. package/dist-lib/hooks/useCartStickerStates.d.ts.map +1 -1
  12. package/dist-lib/hooks/usePickConfig.d.ts +11 -11
  13. package/dist-lib/hooks/usePickConfig.d.ts.map +1 -1
  14. package/dist-lib/hooks/usePickPrintStatus.d.ts +3 -3
  15. package/dist-lib/hooks/usePickPrintStatus.d.ts.map +1 -1
  16. package/dist-lib/hooks/usePickPrintStatus.js +4 -4
  17. package/dist-lib/hooks/usePickQueue.d.ts +3 -3
  18. package/dist-lib/hooks/usePickQueue.d.ts.map +1 -1
  19. package/dist-lib/hooks/usePickReferenceData.d.ts +1 -1
  20. package/dist-lib/hooks/usePickReferenceData.d.ts.map +1 -1
  21. package/dist-lib/hooks/useShippingNoteStatus.d.ts +1 -1
  22. package/dist-lib/hooks/useShippingNoteStatus.d.ts.map +1 -1
  23. package/dist-lib/hooks/useShippingNoteStatus.js +11 -9
  24. package/dist-lib/hooks/useWerkvloer.d.ts +20 -0
  25. package/dist-lib/hooks/useWerkvloer.d.ts.map +1 -0
  26. package/dist-lib/hooks/useWerkvloer.js +98 -0
  27. package/dist-lib/integrations/supabase/client.js +1 -1
  28. package/dist-lib/integrations/supabase/client.server.js +1 -1
  29. package/dist-lib/integrations/supabase/types.d.ts +1331 -91
  30. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  31. package/dist-lib/lib/__tests__/pickPublicStatus.test.d.ts +2 -0
  32. package/dist-lib/lib/__tests__/pickPublicStatus.test.d.ts.map +1 -0
  33. package/dist-lib/lib/__tests__/pickPublicStatus.test.js +48 -0
  34. package/dist-lib/lib/labels.d.ts +2 -0
  35. package/dist-lib/lib/labels.d.ts.map +1 -1
  36. package/dist-lib/lib/labels.js +41 -0
  37. package/dist-lib/lib/pick142.d.ts.map +1 -1
  38. package/dist-lib/lib/pick142.js +7 -10
  39. package/dist-lib/lib/pick156.d.ts.map +1 -1
  40. package/dist-lib/lib/pick156.js +6 -20
  41. package/dist-lib/lib/pick159.js +1 -1
  42. package/dist-lib/lib/pickApi.d.ts +20 -0
  43. package/dist-lib/lib/pickApi.d.ts.map +1 -1
  44. package/dist-lib/lib/pickApi.js +27 -0
  45. package/dist-lib/lib/shippingNoteStatus.d.ts +1 -1
  46. package/dist-lib/lib/shippingNoteStatus.d.ts.map +1 -1
  47. package/dist-lib/lib/shippingNoteStatus.js +5 -2
  48. package/dist-lib/lib/werkvloer.d.ts +40 -0
  49. package/dist-lib/lib/werkvloer.d.ts.map +1 -0
  50. package/dist-lib/lib/werkvloer.js +121 -0
  51. package/dist-lib/lib/werkvloer.test.d.ts +2 -0
  52. package/dist-lib/lib/werkvloer.test.d.ts.map +1 -0
  53. package/dist-lib/lib/werkvloer.test.js +49 -0
  54. package/package.json +1 -1
  55. package/schema/pickschermen.sql +176 -0
  56. package/dist-lib/lib/layoutApi.d.ts +0 -23
  57. package/dist-lib/lib/layoutApi.d.ts.map +0 -1
  58. package/dist-lib/lib/layoutApi.js +0 -94
  59. package/dist-lib/lib/layoutMaker/documentProfiles.d.ts +0 -50
  60. package/dist-lib/lib/layoutMaker/documentProfiles.d.ts.map +0 -1
  61. package/dist-lib/lib/layoutMaker/documentProfiles.js +0 -458
  62. package/dist-lib/lib/layoutMaker/documentTypes.d.ts +0 -123
  63. package/dist-lib/lib/layoutMaker/documentTypes.d.ts.map +0 -1
  64. package/dist-lib/lib/layoutMaker/documentTypes.js +0 -74
  65. package/dist-lib/lib/layoutMaker/logoLibrary.d.ts +0 -13
  66. package/dist-lib/lib/layoutMaker/logoLibrary.d.ts.map +0 -1
  67. package/dist-lib/lib/layoutMaker/logoLibrary.js +0 -54
  68. package/dist-lib/lib/layoutMaker/pakbonBuilder.d.ts +0 -196
  69. package/dist-lib/lib/layoutMaker/pakbonBuilder.d.ts.map +0 -1
  70. package/dist-lib/lib/layoutMaker/pakbonBuilder.js +0 -813
  71. package/dist-lib/lib/layoutMaker/pakbonHtml.d.ts +0 -48
  72. package/dist-lib/lib/layoutMaker/pakbonHtml.d.ts.map +0 -1
  73. package/dist-lib/lib/layoutMaker/pakbonHtml.js +0 -703
  74. package/dist-lib/lib/layoutRenderer.d.ts +0 -7
  75. package/dist-lib/lib/layoutRenderer.d.ts.map +0 -1
  76. package/dist-lib/lib/layoutRenderer.js +0 -233
  77. package/dist-lib/lib/layoutTypes.d.ts +0 -84
  78. package/dist-lib/lib/layoutTypes.d.ts.map +0 -1
  79. package/dist-lib/lib/layoutTypes.js +0 -25
  80. package/dist-lib/lib/orderContext.d.ts +0 -50
  81. package/dist-lib/lib/orderContext.d.ts.map +0 -1
  82. package/dist-lib/lib/orderContext.js +0 -162
  83. package/dist-lib/lib/pakbonOrderInput.d.ts +0 -8
  84. package/dist-lib/lib/pakbonOrderInput.d.ts.map +0 -1
  85. package/dist-lib/lib/pakbonOrderInput.js +0 -150
@@ -0,0 +1,52 @@
1
+ import { type WerkvloerCard } from "../../../lib/werkvloer.js";
2
+ /** Inhoud van de vaste meldingsplek. */
3
+ export type Slot = {
4
+ kind: "none";
5
+ } | {
6
+ kind: "offline";
7
+ } | {
8
+ kind: "busy";
9
+ lines: string[];
10
+ } | {
11
+ kind: "success";
12
+ text: string;
13
+ } | {
14
+ kind: "error";
15
+ text: string;
16
+ } | {
17
+ kind: "info";
18
+ text: string;
19
+ };
20
+ /**
21
+ * Vaste meldingsplek: altijd even hoog, zodat de lijst eronder nooit
22
+ * verspringt als er een melding verschijnt of verdwijnt.
23
+ */
24
+ export declare function MeldingsPlek({ slot, onDismiss }: {
25
+ slot: Slot;
26
+ onDismiss: () => void;
27
+ }): import("react").JSX.Element;
28
+ export interface CardState {
29
+ /** Uitgeschakeld met deze tekst op de knop (bijv. "Wordt geprint"). */
30
+ disabledLabel: string | null;
31
+ /** Nog niet printklaar: reden + knop "Pakbon ophalen". */
32
+ notReadyReason: string | null;
33
+ /** Korte statusregel uit de Engine (printstatus, sticker, uitwijk). */
34
+ statusLine: string | null;
35
+ }
36
+ interface KaartProps {
37
+ card: WerkvloerCard;
38
+ state: CardState;
39
+ tz: string | null;
40
+ mode: "todo" | "printed";
41
+ leaving: boolean;
42
+ disabled: boolean;
43
+ showLead: boolean;
44
+ onPrint: (card: WerkvloerCard) => void;
45
+ onFetch: (card: WerkvloerCard) => void;
46
+ onPreview: (card: WerkvloerCard) => void;
47
+ onMarkPrinted: (card: WerkvloerCard) => void;
48
+ }
49
+ /** Eén order of gezamenlijke levering. Alleen opnieuw getekend als iets echt verandert. */
50
+ export declare const WerkvloerKaart: import("react").NamedExoticComponent<KaartProps>;
51
+ export {};
52
+ //# sourceMappingURL=Werkvloer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Werkvloer.d.ts","sourceRoot":"","sources":["../../../../src/components/pick/werkvloer/Werkvloer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE9F,wCAAwC;AACxC,MAAM,MAAM,IAAI,GACZ;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,IAAI,CAAA;CAAE,+BA6CtF;AAED,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uEAAuE;IACvE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC9C;AAED,2FAA2F;AAC3F,eAAO,MAAM,cAAc,kDA2DzB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { AlertTriangle, CheckCircle2, Loader2, MoreVertical, Printer, WifiOff, Zap } from "lucide-react";
4
+ import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@flowselections/core";
5
+ import { wv } from "../../../lib/labels.js";
6
+ import { cartsText, sinceLabel, timeLabel } from "../../../lib/werkvloer.js";
7
+ /**
8
+ * Vaste meldingsplek: altijd even hoog, zodat de lijst eronder nooit
9
+ * verspringt als er een melding verschijnt of verdwijnt.
10
+ */
11
+ export function MeldingsPlek({ slot, onDismiss }) {
12
+ const base = "flex min-h-[88px] w-full items-center gap-4 rounded-lg px-5 py-3 text-xl font-semibold transition-opacity duration-300";
13
+ if (slot.kind === "none")
14
+ return _jsx("div", { "aria-hidden": true, className: `${base} opacity-0` });
15
+ if (slot.kind === "offline")
16
+ return (_jsxs("div", { role: "alert", className: `${base} bg-destructive text-destructive-foreground`, children: [_jsx(WifiOff, { className: "h-8 w-8 shrink-0" }), _jsx("span", { children: wv("offline") })] }));
17
+ if (slot.kind === "busy")
18
+ return (_jsxs("div", { role: "status", "aria-live": "polite", className: `${base} border-2 border-primary bg-muted text-foreground`, children: [_jsx(Loader2, { className: "h-8 w-8 shrink-0 animate-spin" }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { children: wv("busy") }), slot.lines.length > 0 && (_jsx("ul", { className: "mt-1 space-y-0.5 text-lg font-normal", children: slot.lines.map((l) => (_jsx("li", { className: "truncate", children: l }, l))) }))] })] }));
19
+ const tone = slot.kind === "success"
20
+ ? "bg-primary text-primary-foreground"
21
+ : slot.kind === "error"
22
+ ? "bg-destructive text-destructive-foreground"
23
+ : "border-2 border-border bg-muted text-foreground";
24
+ const Icon = slot.kind === "success" ? CheckCircle2 : AlertTriangle;
25
+ return (_jsxs("button", { type: "button", role: slot.kind === "error" ? "alert" : "status", "aria-live": "polite", onClick: onDismiss, className: `${base} ${tone} text-left`, children: [_jsx(Icon, { className: "h-8 w-8 shrink-0" }), _jsx("span", { children: slot.text })] }));
26
+ }
27
+ /** Eén order of gezamenlijke levering. Alleen opnieuw getekend als iets echt verandert. */
28
+ export const WerkvloerKaart = memo(function WerkvloerKaart({ card, state, tz, mode, leaving, disabled, showLead, onPrint, onFetch, onPreview, onMarkPrinted, }) {
29
+ const when = mode === "printed" ? (timeLabel(card.printedAt, tz) ? `geprint ${timeLabel(card.printedAt, tz)}` : null) : sinceLabel(card.since, tz);
30
+ const carts = cartsText(card.carts);
31
+ const buttonLabel = state.disabledLabel ?? (state.notReadyReason ? wv("fetchData") : mode === "printed" ? wv("reprint") : wv("print"));
32
+ return (_jsxs("li", { className: `flex flex-col gap-3 rounded-xl border-2 bg-card p-4 text-card-foreground transition-opacity duration-300 animate-in fade-in sm:flex-row sm:items-center sm:gap-4 ${card.urgent && mode === "todo" ? "border-destructive" : "border-border"} ${leaving ? "pointer-events-none opacity-0" : "opacity-100"}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1", children: [_jsx("span", { className: "text-2xl font-bold tabular-nums text-foreground sm:text-3xl", children: card.orderNumbers.join(" + ") || "—" }), carts && _jsx("span", { className: "text-2xl font-bold tabular-nums text-foreground", children: carts }), card.urgent && mode === "todo" && (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-md bg-destructive px-2 py-1 text-lg font-bold uppercase text-destructive-foreground", children: [_jsx(Zap, { className: "h-5 w-5" }), " ", wv("urgentBadge")] }))] }), _jsx("p", { className: "mt-1 truncate text-lg text-muted-foreground", children: [card.customer, when].filter(Boolean).join(" · ") }), (state.notReadyReason || state.statusLine) && (_jsx("p", { className: "mt-1 text-lg text-foreground", children: state.notReadyReason ?? state.statusLine }))] }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [showLead && mode === "todo" && (_jsx(Button, { variant: "outline", className: "h-16 px-4 text-lg", disabled: disabled, onClick: () => onMarkPrinted(card), children: wv("markPrinted") })), _jsxs(Button, { className: "h-16 min-w-[9rem] flex-1 px-6 text-xl sm:flex-none [&_svg]:!size-6", variant: state.notReadyReason ? "secondary" : mode === "printed" ? "outline" : "default", disabled: disabled || state.disabledLabel !== null, onClick: () => (state.notReadyReason ? onFetch(card) : onPrint(card)), children: [_jsx(Printer, { className: "mr-2 h-6 w-6" }), buttonLabel] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", className: "h-16 w-14 [&_svg]:!size-6", "aria-label": `${wv("more")} ${card.orderNumbers.join(" + ")}`, children: _jsx(MoreVertical, { className: "h-6 w-6" }) }) }), _jsx(DropdownMenuContent, { align: "end", children: _jsx(DropdownMenuItem, { className: "min-h-14 text-lg", onSelect: () => onPreview(card), children: wv("preview") }) })] })] })] }));
33
+ });
@@ -4,5 +4,5 @@ export declare const STICKER_POLL = 15000;
4
4
  * karren van de order in één aanroep. Vult de cache van de losse onderdelen,
5
5
  * die met een slug zelf niet meer opvragen.
6
6
  */
7
- export declare function useCartStickerStates(cartIds: string[], slug: string | null): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../lib/pickStickerBundle.js").CartStickerBundleItem[]>, Error>;
7
+ export declare function useCartStickerStates(cartIds: string[], slug: string | null): import("@tanstack/react-query").UseQueryResult<import("../lib/pickStickerBundle.js").CartStickerBundleItem[], Error>;
8
8
  //# sourceMappingURL=useCartStickerStates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useCartStickerStates.d.ts","sourceRoot":"","sources":["../../src/hooks/useCartStickerStates.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,8HA2B1E"}
1
+ {"version":3,"file":"useCartStickerStates.d.ts","sourceRoot":"","sources":["../../src/hooks/useCartStickerStates.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,qHA2B1E"}
@@ -1,15 +1,15 @@
1
- export declare function usePickCountries(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickCountry[]>, Error>;
2
- export declare function usePickStatuses(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickStatus[]>, Error>;
3
- export declare function usePickPrinters(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickPrinter[]>, Error>;
4
- export declare function usePickDocumentTypes(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickDocumentType[]>, Error>;
5
- export declare function usePickStationTypes(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickStationType[]>, Error>;
6
- export declare function usePickTasks(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickTask[]>, Error>;
7
- export declare function usePickStations(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickStation[]>, Error>;
1
+ export declare function usePickCountries(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickCountry[], Error>;
2
+ export declare function usePickStatuses(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickStatus[], Error>;
3
+ export declare function usePickPrinters(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickPrinter[], Error>;
4
+ export declare function usePickDocumentTypes(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickDocumentType[], Error>;
5
+ export declare function usePickStationTypes(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickStationType[], Error>;
6
+ export declare function usePickTasks(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickTask[], Error>;
7
+ export declare function usePickStations(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickStation[], Error>;
8
8
  /** Actieve printplekken uit de Layout maker. */
9
- export declare function usePickPrintPlekken(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickPrintPlek[]>, Error>;
9
+ export declare function usePickPrintPlekken(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickPrintPlek[], Error>;
10
10
  /** Koppelingen pickstation → printplek (beheerpagina). */
11
- export declare function useStationPrintPlekken(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickStationPrintPlekRow[]>, Error>;
11
+ export declare function useStationPrintPlekken(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickStationPrintPlekRow[], Error>;
12
12
  /** De printplek van één pickstation (ook in openbare pickschermen). */
13
- export declare function useStationPrintPlek(stationId?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickStationPrintPlek | null>, Error>;
14
- export declare function usePickScreens(stationId?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickScreen[]>, Error>;
13
+ export declare function useStationPrintPlek(stationId?: string): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickStationPrintPlek | null, Error>;
14
+ export declare function usePickScreens(stationId?: string): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickScreen[], Error>;
15
15
  //# sourceMappingURL=usePickConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePickConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,+FAE/B;AACD,wBAAgB,eAAe,8FAE9B;AACD,wBAAgB,eAAe,+FAE9B;AACD,wBAAgB,oBAAoB,oGAEnC;AACD,wBAAgB,mBAAmB,mGAElC;AACD,wBAAgB,YAAY,4FAE3B;AACD,wBAAgB,eAAe,+FAE9B;AACD,gDAAgD;AAChD,wBAAgB,mBAAmB,iGAElC;AACD,0DAA0D;AAC1D,wBAAgB,sBAAsB,2GAKrC;AACD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,4GAMrD;AAED,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,6FAKhD"}
1
+ {"version":3,"file":"usePickConfig.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickConfig.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,sFAE/B;AACD,wBAAgB,eAAe,qFAE9B;AACD,wBAAgB,eAAe,sFAE9B;AACD,wBAAgB,oBAAoB,2FAEnC;AACD,wBAAgB,mBAAmB,0FAElC;AACD,wBAAgB,YAAY,mFAE3B;AACD,wBAAgB,eAAe,sFAE9B;AACD,gDAAgD;AAChD,wBAAgB,mBAAmB,wFAElC;AACD,0DAA0D;AAC1D,wBAAgB,sBAAsB,kGAKrC;AACD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,mGAMrD;AAED,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,oFAKhD"}
@@ -1,14 +1,14 @@
1
1
  import { type PrintStatusResult } from "../lib/pickPrintStatus.js";
2
2
  /**
3
3
  * Eén aanroep voor alle zichtbare regels. Openbaar station (slug):
4
- * pickstation_print_status; ingelogd scherm: logistics_print_status direct.
4
+ * altijd pickstation_print_status, ook zonder gekoppeld apparaat.
5
5
  * Fout: "niet beschikbaar" met reden, nooit terugvallen op printed_at.
6
6
  */
7
7
  export declare function fetchPrintStatus(ids: string[], slug: string | null): Promise<PrintStatusResult>;
8
8
  export declare function usePickPrintStatus(ids: string[], slug: string | null, enabled?: boolean): {
9
- result: NoInfer<PrintStatusResult> | null;
9
+ result: PrintStatusResult | null;
10
10
  loading: boolean;
11
11
  inPrint: Set<string>;
12
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<PrintStatusResult>, Error>>;
12
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<PrintStatusResult, Error>>;
13
13
  };
14
14
  //# sourceMappingURL=usePickPrintStatus.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePickPrintStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickPrintStatus.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQ9F;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgBrG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,UAAO;;;;;EAkBpF"}
1
+ {"version":3,"file":"usePickPrintStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickPrintStatus.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAQ9F;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAerG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,UAAO;;;;;EAkBpF"}
@@ -8,14 +8,14 @@ const db = keyedRpc(supabase);
8
8
  const MAX_IDS = 500;
9
9
  /**
10
10
  * Eén aanroep voor alle zichtbare regels. Openbaar station (slug):
11
- * pickstation_print_status; ingelogd scherm: logistics_print_status direct.
11
+ * altijd pickstation_print_status, ook zonder gekoppeld apparaat.
12
12
  * Fout: "niet beschikbaar" met reden, nooit terugvallen op printed_at.
13
13
  */
14
14
  export async function fetchPrintStatus(ids, slug) {
15
15
  const list = ids.slice(0, MAX_IDS);
16
- const { data, error } = await pickMeasure("printstatus", () => slug
17
- ? db.rpc("pickstation_print_status", { p_slug: slug, p_queue_item_ids: list })
18
- : db.rpc("logistics_print_status", { p_queue_item_ids: list }));
16
+ if (!slug?.trim())
17
+ return { beschikbaar: false, reden: "Het pickstation ontbreekt; open het scherm opnieuw.", byId: new Map() };
18
+ const { data, error } = await pickMeasure("printstatus", () => db.rpc("pickstation_print_status", { p_slug: slug, p_queue_item_ids: list }));
19
19
  if (error) {
20
20
  const missing = /could not find|does not exist|PGRST202/i.test(error.message);
21
21
  return {
@@ -50,12 +50,12 @@ export declare function usePickHeartbeat(stationId?: string, screenId?: string |
50
50
  export declare function usePickCountryCounts(args: {
51
51
  stationId?: string;
52
52
  screenId?: string;
53
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<Record<string, number>>, Error>;
53
+ }): import("@tanstack/react-query").UseQueryResult<Record<string, number>, Error>;
54
54
  /** Pickdagen waarop nog orders klaarstaan (vandaag en later). */
55
- export declare function usePickDays(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<{
55
+ export declare function usePickDays(enabled?: boolean): import("@tanstack/react-query").UseQueryResult<{
56
56
  day: string;
57
57
  orders: number;
58
- }[]>, Error>;
58
+ }[], Error>;
59
59
  /** Zelfde station, scherm en pickdag (positie 2-4 van de wachtrij-sleutel). */
60
60
  export declare function sameQueueScope(a: readonly unknown[], b: readonly unknown[]): boolean;
61
61
  //# sourceMappingURL=usePickQueue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePickQueue.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickQueue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAM9E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,EAAE,YAS5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;;;;;;;IAuNG,sDAAsD;;;;;;IAMtD,gEAAgE;;IAEhE,4EAA4E;;IAE5E,6EAA6E;;;EAIhF;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM;;EAuBhG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,0FAOnF;AACD,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,OAAO,UAAO;;;aAQzC;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAEpF"}
1
+ {"version":3,"file":"usePickQueue.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickQueue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAM9E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,EAAE,YAS5B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;;;;;;;IAuNG,sDAAsD;;;;;;IAMtD,gEAAgE;;IAEhE,4EAA4E;;IAE5E,6EAA6E;;;EAIhF;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM;;EAuBhG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,iFAOnF;AACD,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,OAAO,UAAO;;;YAQzC;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAEpF"}
@@ -1,4 +1,4 @@
1
1
  export declare const PICK_REFERENCE_QUERY_KEY: readonly ["pick", "referenceData"];
2
2
  /** Eén bron voor de instellingenkaart en de waarschuwingsbanner. */
3
- export declare function usePickReferenceData(): import("@tanstack/react-query").UseQueryResult<NoInfer<import("../index.js").PickReferenceStatus>, Error>;
3
+ export declare function usePickReferenceData(): import("@tanstack/react-query").UseQueryResult<import("../index.js").PickReferenceStatus, Error>;
4
4
  //# sourceMappingURL=usePickReferenceData.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePickReferenceData.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickReferenceData.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,oCAAqC,CAAC;AAE3E,oEAAoE;AACpE,wBAAgB,oBAAoB,qGAKnC"}
1
+ {"version":3,"file":"usePickReferenceData.d.ts","sourceRoot":"","sources":["../../src/hooks/usePickReferenceData.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,oCAAqC,CAAC;AAE3E,oEAAoE;AACpE,wBAAgB,oBAAoB,4FAKnC"}
@@ -11,7 +11,7 @@ export interface WatchedShippingNote {
11
11
  * wacht, geprint is of is mislukt. Uitsluitend lezen: er wordt nooit een nieuwe
12
12
  * aanvraag of printopdracht gemaakt.
13
13
  */
14
- export declare function useShippingNoteStatus(): {
14
+ export declare function useShippingNoteStatus(slug: string | null): {
15
15
  shippingNotes: WatchedShippingNote[];
16
16
  watchShippingNotes: (entries: {
17
17
  jobId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"useShippingNoteStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useShippingNoteStatus.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB;;kCAYvB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE;;mCA4C5B,OAAO,CAAC;QAC5D,EAAE,EAAE,OAAO,CAAC;QACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;EAuFH"}
1
+ {"version":3,"file":"useShippingNoteStatus.d.ts","sourceRoot":"","sources":["../../src/hooks/useShippingNoteStatus.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;;kCAY3C;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE;;mCA4C5B,OAAO,CAAC;QAC5D,EAAE,EAAE,OAAO,CAAC;QACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,CAAC;EAyFH"}
@@ -8,7 +8,7 @@ const MAX_MS = 15 * 60 * 1000;
8
8
  * wacht, geprint is of is mislukt. Uitsluitend lezen: er wordt nooit een nieuwe
9
9
  * aanvraag of printopdracht gemaakt.
10
10
  */
11
- export function useShippingNoteStatus() {
11
+ export function useShippingNoteStatus(slug) {
12
12
  const [notes, setNotes] = useState([]);
13
13
  const notesRef = useRef([]);
14
14
  const startedAt = useRef({});
@@ -63,9 +63,10 @@ export function useShippingNoteStatus() {
63
63
  if (current.length > 0) {
64
64
  const results = await Promise.all(current.map(async (note) => {
65
65
  try {
66
- return { jobId: note.jobId, state: await readShippingNoteStatus(note.jobId, note.cartId) };
66
+ return { jobId: note.jobId, state: await readShippingNoteStatus(note.jobId, note.cartId, slug) };
67
67
  }
68
- catch {
68
+ catch (error) {
69
+ console.error("Pickstation: verzendbriefstatus kon niet worden gelezen", error);
69
70
  return null;
70
71
  }
71
72
  }));
@@ -73,11 +74,11 @@ export function useShippingNoteStatus() {
73
74
  .filter((r) => r !== null)
74
75
  .map((r) => [r.jobId, r.state]));
75
76
  if (byJob.size > 0) {
76
- apply(notesRef.current.map((note) => byJob.has(note.jobId) ? { ...note, state: byJob.get(note.jobId) } : note));
77
+ apply(notesRef.current.map((note) => byJob.get(note.jobId) ? { ...note, state: byJob.get(note.jobId) ?? note.state } : note));
77
78
  }
78
79
  }
79
80
  return result;
80
- }, [apply]);
81
+ }, [apply, slug]);
81
82
  const key = notes.map((note) => note.jobId).join(",");
82
83
  useEffect(() => {
83
84
  if (!key)
@@ -104,9 +105,10 @@ export function useShippingNoteStatus() {
104
105
  }
105
106
  const results = await Promise.all(pending.map(async (note) => {
106
107
  try {
107
- return { jobId: note.jobId, state: await readShippingNoteStatus(note.jobId, note.cartId) };
108
+ return { jobId: note.jobId, state: await readShippingNoteStatus(note.jobId, note.cartId, slug) };
108
109
  }
109
- catch {
110
+ catch (error) {
111
+ console.error("Pickstation: verzendbriefstatus kon niet worden gelezen", error);
110
112
  // Status tijdelijk niet leesbaar; volgende ronde volgt.
111
113
  return null;
112
114
  }
@@ -117,7 +119,7 @@ export function useShippingNoteStatus() {
117
119
  .map((r) => [r.jobId, r.state]));
118
120
  if (byJob.size === 0)
119
121
  return;
120
- const updated = notesRef.current.map((note) => byJob.has(note.jobId) ? { ...note, state: byJob.get(note.jobId) } : note);
122
+ const updated = notesRef.current.map((note) => byJob.get(note.jobId) ? { ...note, state: byJob.get(note.jobId) ?? note.state } : note);
121
123
  notesRef.current = updated;
122
124
  setNotes(updated);
123
125
  };
@@ -127,6 +129,6 @@ export function useShippingNoteStatus() {
127
129
  stopped = true;
128
130
  stop();
129
131
  };
130
- }, [key]);
132
+ }, [key, slug]);
131
133
  return { shippingNotes: notes, watchShippingNotes, clearShippingNotes, refreshShippingNotesNow };
132
134
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Houdt de getoonde lijst vast terwijl iemand het scherm aanraakt en tot 2 s
3
+ * daarna. Verdwenen kaarten blijven 300 ms staan (fade-out) op hun plek.
4
+ */
5
+ export declare function useStableList<T>(items: T[], keyOf: (item: T) => string, holdMs?: number): {
6
+ shown: {
7
+ item: T;
8
+ leaving: boolean;
9
+ }[];
10
+ handlers: {
11
+ onPointerDown: () => void;
12
+ onPointerUp: () => void;
13
+ onPointerCancel: () => void;
14
+ };
15
+ };
16
+ /** Na `ms` zonder aanraking of toets: onIdle. */
17
+ export declare function useIdle(ms: number, onIdle: () => void): void;
18
+ /** Browser meldt verbinding (navigator.onLine + online/offline-events). */
19
+ export declare function useBrowserOnline(): boolean;
20
+ //# sourceMappingURL=useWerkvloer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWerkvloer.d.ts","sourceRoot":"","sources":["../../src/hooks/useWerkvloer.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EAAE,MAAM,SAAO;;cACzC,CAAC;iBAAW,OAAO;;;;;;;EAuD/D;AAED,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,QAgBrD;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,YAc/B"}
@@ -0,0 +1,98 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ /**
3
+ * Houdt de getoonde lijst vast terwijl iemand het scherm aanraakt en tot 2 s
4
+ * daarna. Verdwenen kaarten blijven 300 ms staan (fade-out) op hun plek.
5
+ */
6
+ export function useStableList(items, keyOf, holdMs = 2000) {
7
+ const [shown, setShown] = useState(() => items.map((item) => ({ item, leaving: false })));
8
+ const touching = useRef(false);
9
+ const releaseTimer = useRef(null);
10
+ const latest = useRef(items);
11
+ latest.current = items;
12
+ const [tick, setTick] = useState(0);
13
+ const apply = useCallback(() => {
14
+ const next = latest.current;
15
+ setShown((prev) => {
16
+ const nextKeys = new Set(next.map(keyOf));
17
+ const out = next.map((item) => ({ item, leaving: false }));
18
+ // Verdwenen kaarten op hun oude plek laten uitfaden.
19
+ prev.forEach((entry, index) => {
20
+ const k = keyOf(entry.item);
21
+ if (!nextKeys.has(k) && !entry.leaving)
22
+ out.splice(Math.min(index, out.length), 0, { item: entry.item, leaving: true });
23
+ });
24
+ // Niets veranderd: zelfde lijst teruggeven, zodat React niets opnieuw tekent.
25
+ if (out.length === prev.length && out.every((e, i) => e.item === prev[i].item && e.leaving === prev[i].leaving))
26
+ return prev;
27
+ return out;
28
+ });
29
+ }, [keyOf]);
30
+ useEffect(() => {
31
+ if (!touching.current && releaseTimer.current === null)
32
+ apply();
33
+ }, [items, apply, tick]);
34
+ // Uitgefade kaarten na 300 ms echt weghalen.
35
+ useEffect(() => {
36
+ if (!shown.some((e) => e.leaving))
37
+ return;
38
+ const t = window.setTimeout(() => setShown((prev) => prev.filter((e) => !e.leaving)), 300);
39
+ return () => window.clearTimeout(t);
40
+ }, [shown]);
41
+ const onPointerDown = useCallback(() => {
42
+ touching.current = true;
43
+ if (releaseTimer.current !== null) {
44
+ window.clearTimeout(releaseTimer.current);
45
+ releaseTimer.current = null;
46
+ }
47
+ }, []);
48
+ const onPointerUp = useCallback(() => {
49
+ touching.current = false;
50
+ if (releaseTimer.current !== null)
51
+ window.clearTimeout(releaseTimer.current);
52
+ releaseTimer.current = window.setTimeout(() => {
53
+ releaseTimer.current = null;
54
+ setTick((n) => n + 1);
55
+ }, holdMs);
56
+ }, [holdMs]);
57
+ useEffect(() => () => {
58
+ if (releaseTimer.current !== null)
59
+ window.clearTimeout(releaseTimer.current);
60
+ }, []);
61
+ return { shown, handlers: { onPointerDown, onPointerUp, onPointerCancel: onPointerUp } };
62
+ }
63
+ /** Na `ms` zonder aanraking of toets: onIdle. */
64
+ export function useIdle(ms, onIdle) {
65
+ const cb = useRef(onIdle);
66
+ cb.current = onIdle;
67
+ useEffect(() => {
68
+ let timer = window.setTimeout(() => cb.current(), ms);
69
+ const reset = () => {
70
+ window.clearTimeout(timer);
71
+ timer = window.setTimeout(() => cb.current(), ms);
72
+ };
73
+ const events = ["pointerdown", "keydown", "wheel", "touchstart"];
74
+ for (const e of events)
75
+ window.addEventListener(e, reset, { passive: true });
76
+ return () => {
77
+ window.clearTimeout(timer);
78
+ for (const e of events)
79
+ window.removeEventListener(e, reset);
80
+ };
81
+ }, [ms]);
82
+ }
83
+ /** Browser meldt verbinding (navigator.onLine + online/offline-events). */
84
+ export function useBrowserOnline() {
85
+ const [online, setOnline] = useState(true);
86
+ useEffect(() => {
87
+ setOnline(navigator.onLine);
88
+ const on = () => setOnline(true);
89
+ const off = () => setOnline(false);
90
+ window.addEventListener("online", on);
91
+ window.addEventListener("offline", off);
92
+ return () => {
93
+ window.removeEventListener("online", on);
94
+ window.removeEventListener("offline", off);
95
+ };
96
+ }, []);
97
+ return online;
98
+ }
@@ -1,5 +1,5 @@
1
1
  // Geen project-URL of sleutel in module-code: de client komt van @flowselections/core (env-gebaseerd, dezelfde sessie als de shell).
2
2
  import { supabase as coreSupabase } from "@flowselections/core";
3
3
  // Import the supabase client like this:
4
- // import { supabase } from "../../integrations/supabase/client.js";
4
+ // import { supabase } from "./client.js";
5
5
  export const supabase = coreSupabase;
@@ -20,7 +20,7 @@ function createSupabaseAdminClient() {
20
20
  let _supabaseAdmin;
21
21
  // Server-side Supabase client with service role - bypasses RLS
22
22
  // SECURITY: Only use this for trusted server-side operations, never expose to client code
23
- // Import like: import { supabaseAdmin } from "../../integrations/supabase/client.server.js";
23
+ // Import like: import { supabaseAdmin } from "./client.server.js";
24
24
  export const supabaseAdmin = new Proxy({}, {
25
25
  get(_, prop, receiver) {
26
26
  if (!_supabaseAdmin)