@flowselections/logistiek-engine 1.0.1

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 (175) hide show
  1. package/README.md +24 -0
  2. package/dist-lib/_core-safelist.d.ts +2 -0
  3. package/dist-lib/_core-safelist.d.ts.map +1 -0
  4. package/dist-lib/_core-safelist.js +15 -0
  5. package/dist-lib/components/BeladingIndelingCard.d.ts +2 -0
  6. package/dist-lib/components/BeladingIndelingCard.d.ts.map +1 -0
  7. package/dist-lib/components/BeladingIndelingCard.js +77 -0
  8. package/dist-lib/components/BufferDebugCard.d.ts +19 -0
  9. package/dist-lib/components/BufferDebugCard.d.ts.map +1 -0
  10. package/dist-lib/components/BufferDebugCard.js +69 -0
  11. package/dist-lib/components/CapaciteitMeldingenCard.d.ts +2 -0
  12. package/dist-lib/components/CapaciteitMeldingenCard.d.ts.map +1 -0
  13. package/dist-lib/components/CapaciteitMeldingenCard.js +40 -0
  14. package/dist-lib/components/LadingdragersPage.d.ts +2 -0
  15. package/dist-lib/components/LadingdragersPage.d.ts.map +1 -0
  16. package/dist-lib/components/LadingdragersPage.js +102 -0
  17. package/dist-lib/components/LogistiekEngineLogo.d.ts +6 -0
  18. package/dist-lib/components/LogistiekEngineLogo.d.ts.map +1 -0
  19. package/dist-lib/components/LogistiekEngineLogo.js +4 -0
  20. package/dist-lib/components/LogistiekEnginePage.d.ts +2 -0
  21. package/dist-lib/components/LogistiekEnginePage.d.ts.map +1 -0
  22. package/dist-lib/components/LogistiekEnginePage.js +53 -0
  23. package/dist-lib/components/ModulePromptsPage.d.ts +2 -0
  24. package/dist-lib/components/ModulePromptsPage.d.ts.map +1 -0
  25. package/dist-lib/components/ModulePromptsPage.js +58 -0
  26. package/dist-lib/components/RegiePage.d.ts +2 -0
  27. package/dist-lib/components/RegiePage.d.ts.map +1 -0
  28. package/dist-lib/components/RegiePage.js +82 -0
  29. package/dist-lib/components/RuleEnginePage.d.ts +7 -0
  30. package/dist-lib/components/RuleEnginePage.d.ts.map +1 -0
  31. package/dist-lib/components/RuleEnginePage.js +114 -0
  32. package/dist-lib/components/StrategieDialog.d.ts +11 -0
  33. package/dist-lib/components/StrategieDialog.d.ts.map +1 -0
  34. package/dist-lib/components/StrategieDialog.js +38 -0
  35. package/dist-lib/components/VertragingMeldingenCard.d.ts +2 -0
  36. package/dist-lib/components/VertragingMeldingenCard.d.ts.map +1 -0
  37. package/dist-lib/components/VertragingMeldingenCard.js +32 -0
  38. package/dist-lib/components/VoorraadMeldingenCard.d.ts +2 -0
  39. package/dist-lib/components/VoorraadMeldingenCard.d.ts.map +1 -0
  40. package/dist-lib/components/VoorraadMeldingenCard.js +26 -0
  41. package/dist-lib/components/rule-engine/CollapsibleGroup.d.ts +12 -0
  42. package/dist-lib/components/rule-engine/CollapsibleGroup.d.ts.map +1 -0
  43. package/dist-lib/components/rule-engine/CollapsibleGroup.js +11 -0
  44. package/dist-lib/components/rule-engine/ConditionsEditor.d.ts +8 -0
  45. package/dist-lib/components/rule-engine/ConditionsEditor.d.ts.map +1 -0
  46. package/dist-lib/components/rule-engine/ConditionsEditor.js +31 -0
  47. package/dist-lib/components/rule-engine/FieldHelp.d.ts +14 -0
  48. package/dist-lib/components/rule-engine/FieldHelp.d.ts.map +1 -0
  49. package/dist-lib/components/rule-engine/FieldHelp.js +18 -0
  50. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts +2 -0
  51. package/dist-lib/components/rule-engine/FloridayConnectionBanner.d.ts.map +1 -0
  52. package/dist-lib/components/rule-engine/FloridayConnectionBanner.js +41 -0
  53. package/dist-lib/components/rule-engine/ImpactPanel.d.ts +5 -0
  54. package/dist-lib/components/rule-engine/ImpactPanel.d.ts.map +1 -0
  55. package/dist-lib/components/rule-engine/ImpactPanel.js +25 -0
  56. package/dist-lib/components/rule-engine/RuleFieldInput.d.ts +9 -0
  57. package/dist-lib/components/rule-engine/RuleFieldInput.d.ts.map +1 -0
  58. package/dist-lib/components/rule-engine/RuleFieldInput.js +80 -0
  59. package/dist-lib/components/rule-engine/VersionsPanel.d.ts +10 -0
  60. package/dist-lib/components/rule-engine/VersionsPanel.d.ts.map +1 -0
  61. package/dist-lib/components/rule-engine/VersionsPanel.js +16 -0
  62. package/dist-lib/components/settings/LogistiekEngineSettingsCard.d.ts +2 -0
  63. package/dist-lib/components/settings/LogistiekEngineSettingsCard.d.ts.map +1 -0
  64. package/dist-lib/components/settings/LogistiekEngineSettingsCard.js +22 -0
  65. package/dist-lib/hooks/useCapaciteitMeldingen.d.ts +20 -0
  66. package/dist-lib/hooks/useCapaciteitMeldingen.d.ts.map +1 -0
  67. package/dist-lib/hooks/useCapaciteitMeldingen.js +46 -0
  68. package/dist-lib/hooks/useDocumentLayouts.d.ts +13 -0
  69. package/dist-lib/hooks/useDocumentLayouts.d.ts.map +1 -0
  70. package/dist-lib/hooks/useDocumentLayouts.js +54 -0
  71. package/dist-lib/hooks/useLadingdragers.d.ts +16 -0
  72. package/dist-lib/hooks/useLadingdragers.d.ts.map +1 -0
  73. package/dist-lib/hooks/useLadingdragers.js +86 -0
  74. package/dist-lib/hooks/useLogistiekStrategieen.d.ts +29 -0
  75. package/dist-lib/hooks/useLogistiekStrategieen.d.ts.map +1 -0
  76. package/dist-lib/hooks/useLogistiekStrategieen.js +111 -0
  77. package/dist-lib/hooks/useLogistiekTaken.d.ts +89 -0
  78. package/dist-lib/hooks/useLogistiekTaken.d.ts.map +1 -0
  79. package/dist-lib/hooks/useLogistiekTaken.js +314 -0
  80. package/dist-lib/hooks/usePickstations.d.ts +10 -0
  81. package/dist-lib/hooks/usePickstations.d.ts.map +1 -0
  82. package/dist-lib/hooks/usePickstations.js +51 -0
  83. package/dist-lib/hooks/useRecalcJob.d.ts +24 -0
  84. package/dist-lib/hooks/useRecalcJob.d.ts.map +1 -0
  85. package/dist-lib/hooks/useRecalcJob.js +83 -0
  86. package/dist-lib/hooks/useRuleEngine.d.ts +48 -0
  87. package/dist-lib/hooks/useRuleEngine.d.ts.map +1 -0
  88. package/dist-lib/hooks/useRuleEngine.js +222 -0
  89. package/dist-lib/hooks/useVertragingMeldingen.d.ts +29 -0
  90. package/dist-lib/hooks/useVertragingMeldingen.d.ts.map +1 -0
  91. package/dist-lib/hooks/useVertragingMeldingen.js +68 -0
  92. package/dist-lib/hooks/useVoorraadMeldingen.d.ts +30 -0
  93. package/dist-lib/hooks/useVoorraadMeldingen.d.ts.map +1 -0
  94. package/dist-lib/hooks/useVoorraadMeldingen.js +70 -0
  95. package/dist-lib/index.d.ts +36 -0
  96. package/dist-lib/index.d.ts.map +1 -0
  97. package/dist-lib/index.js +52 -0
  98. package/dist-lib/integrations/supabase/auth-attacher.d.ts +2 -0
  99. package/dist-lib/integrations/supabase/auth-attacher.d.ts.map +1 -0
  100. package/dist-lib/integrations/supabase/auth-attacher.js +12 -0
  101. package/dist-lib/integrations/supabase/auth-middleware.d.ts +19781 -0
  102. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -0
  103. package/dist-lib/integrations/supabase/auth-middleware.js +52 -0
  104. package/dist-lib/integrations/supabase/client.d.ts +19777 -0
  105. package/dist-lib/integrations/supabase/client.d.ts.map +1 -0
  106. package/dist-lib/integrations/supabase/client.js +13 -0
  107. package/dist-lib/integrations/supabase/client.server.d.ts +19777 -0
  108. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -0
  109. package/dist-lib/integrations/supabase/client.server.js +30 -0
  110. package/dist-lib/integrations/supabase/types.d.ts +20355 -0
  111. package/dist-lib/integrations/supabase/types.d.ts.map +1 -0
  112. package/dist-lib/integrations/supabase/types.js +78 -0
  113. package/dist-lib/lib/bufferMatching.d.ts +26 -0
  114. package/dist-lib/lib/bufferMatching.d.ts.map +1 -0
  115. package/dist-lib/lib/bufferMatching.js +73 -0
  116. package/dist-lib/lib/bulkLoadCarrierPlanning.server.d.ts +23 -0
  117. package/dist-lib/lib/bulkLoadCarrierPlanning.server.d.ts.map +1 -0
  118. package/dist-lib/lib/bulkLoadCarrierPlanning.server.js +126 -0
  119. package/dist-lib/lib/floridayDocuments.functions.d.ts +59415 -0
  120. package/dist-lib/lib/floridayDocuments.functions.d.ts.map +1 -0
  121. package/dist-lib/lib/floridayDocuments.functions.js +68 -0
  122. package/dist-lib/lib/floridayDocuments.server.d.ts +51 -0
  123. package/dist-lib/lib/floridayDocuments.server.d.ts.map +1 -0
  124. package/dist-lib/lib/floridayDocuments.server.js +109 -0
  125. package/dist-lib/lib/loadCarrierPlanner.d.ts +71 -0
  126. package/dist-lib/lib/loadCarrierPlanner.d.ts.map +1 -0
  127. package/dist-lib/lib/loadCarrierPlanner.js +374 -0
  128. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts +98984 -0
  129. package/dist-lib/lib/loadCarrierPlanning.functions.d.ts.map +1 -0
  130. package/dist-lib/lib/loadCarrierPlanning.functions.js +106 -0
  131. package/dist-lib/lib/loadCarrierPlanning.server.d.ts +46 -0
  132. package/dist-lib/lib/loadCarrierPlanning.server.d.ts.map +1 -0
  133. package/dist-lib/lib/loadCarrierPlanning.server.js +515 -0
  134. package/dist-lib/lib/loadCarrierTaskSync.server.d.ts +3 -0
  135. package/dist-lib/lib/loadCarrierTaskSync.server.d.ts.map +1 -0
  136. package/dist-lib/lib/loadCarrierTaskSync.server.js +56 -0
  137. package/dist-lib/lib/loadCarrierTypes.d.ts +19 -0
  138. package/dist-lib/lib/loadCarrierTypes.d.ts.map +1 -0
  139. package/dist-lib/lib/loadCarrierTypes.js +41 -0
  140. package/dist-lib/lib/logisticsPlanner.d.ts +56 -0
  141. package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -0
  142. package/dist-lib/lib/logisticsPlanner.js +273 -0
  143. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts +39575 -0
  144. package/dist-lib/lib/logisticsRecalcJob.functions.d.ts.map +1 -0
  145. package/dist-lib/lib/logisticsRecalcJob.functions.js +30 -0
  146. package/dist-lib/lib/logisticsRecalcJob.server.d.ts +32 -0
  147. package/dist-lib/lib/logisticsRecalcJob.server.d.ts.map +1 -0
  148. package/dist-lib/lib/logisticsRecalcJob.server.js +116 -0
  149. package/dist-lib/lib/logisticsRecalculate.functions.d.ts +19792 -0
  150. package/dist-lib/lib/logisticsRecalculate.functions.d.ts.map +1 -0
  151. package/dist-lib/lib/logisticsRecalculate.functions.js +35 -0
  152. package/dist-lib/lib/logisticsTasks.d.ts +23 -0
  153. package/dist-lib/lib/logisticsTasks.d.ts.map +1 -0
  154. package/dist-lib/lib/logisticsTasks.js +92 -0
  155. package/dist-lib/lib/modulePrompts.d.ts +31 -0
  156. package/dist-lib/lib/modulePrompts.d.ts.map +1 -0
  157. package/dist-lib/lib/modulePrompts.js +1195 -0
  158. package/dist-lib/lib/ruleEngineImpact.d.ts +27 -0
  159. package/dist-lib/lib/ruleEngineImpact.d.ts.map +1 -0
  160. package/dist-lib/lib/ruleEngineImpact.js +257 -0
  161. package/dist-lib/lib/ruleEngineSchema.d.ts +69 -0
  162. package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -0
  163. package/dist-lib/lib/ruleEngineSchema.js +899 -0
  164. package/dist-lib/lib/ruleEngineWizard.d.ts +17 -0
  165. package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -0
  166. package/dist-lib/lib/ruleEngineWizard.js +204 -0
  167. package/dist-lib/lib/utils.d.ts +3 -0
  168. package/dist-lib/lib/utils.d.ts.map +1 -0
  169. package/dist-lib/lib/utils.js +5 -0
  170. package/dist-lib/lib/validationSchemas.d.ts +15 -0
  171. package/dist-lib/lib/validationSchemas.d.ts.map +1 -0
  172. package/dist-lib/lib/validationSchemas.js +25 -0
  173. package/dist-lib/styles.css +1 -0
  174. package/package.json +113 -0
  175. package/public/logo.png +0 -0
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # logistiek Engine
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/316ec9c5-0f01-408a-b7ec-3d4dccf9b65d).
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
+ ```
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=_core-safelist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_core-safelist.d.ts","sourceRoot":"","sources":["../src/_core-safelist.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ // Forceert Tailwind classes die uit @flowselections/core komen maar niet
2
+ // voorkomen in de eigen broncode van deze module.
3
+ // Zonder dit bestand worden deze classes weggeoptimaliseerd op de
4
+ // Lovable productie build.
5
+ const _safelist = [
6
+ // Layout — Sidebar en shell structuur
7
+ 'h-full', 'flex-col', 'flex-1', 'min-h-screen', 'ml-64', 'pt-16',
8
+ 'items-start', 'items-center', 'justify-between', 'border-t',
9
+ 'w-64', 'h-screen', 'h-20', 'overflow-y-auto',
10
+ // Grid — InstellingenPage
11
+ 'grid', 'lg:grid-cols-2', 'gap-6', 'p-6', 'space-y-6',
12
+ // Toggle/Switch — aan/uit zichtbaarheid
13
+ 'data-[state=checked]:bg-primary', 'data-[state=unchecked]:bg-input',
14
+ ];
15
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare function BeladingIndelingCard(): import("react").JSX.Element;
2
+ //# sourceMappingURL=BeladingIndelingCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BeladingIndelingCard.d.ts","sourceRoot":"","sources":["../../src/components/BeladingIndelingCard.tsx"],"names":[],"mappings":"AAmCA,wBAAgB,oBAAoB,gCA+InC"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/BeladingIndelingCard.tsx — voorbeeld van de beladingindeling
4
+ // ============================================================================
5
+ // Zoek een order op ordernummer en laat zien welke ladingdragers de Engine
6
+ // zou vormen, inclusief vulgraad, lagen en de partijen per drager.
7
+ // ============================================================================
8
+ import { useState } from "react";
9
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Label, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, supabase, toast, } from "@flowselections/core";
10
+ import { useServerFn } from "@tanstack/react-start";
11
+ import { Boxes, Search } from "lucide-react";
12
+ import { previewLoadCarrierPlan, replanOrderLoadCarriers } from "../lib/loadCarrierPlanning.functions";
13
+ import { carrierLabel } from "../lib/loadCarrierTypes";
14
+ const db = () => supabase;
15
+ export function BeladingIndelingCard() {
16
+ const preview = useServerFn(previewLoadCarrierPlan);
17
+ const replan = useServerFn(replanOrderLoadCarriers);
18
+ const [orderNummer, setOrderNummer] = useState("");
19
+ const [bezig, setBezig] = useState(false);
20
+ const [carts, setCarts] = useState([]);
21
+ const [warnings, setWarnings] = useState([]);
22
+ const [orderId, setOrderId] = useState(null);
23
+ const zoekOrderId = async () => {
24
+ const nummer = orderNummer.trim();
25
+ if (!nummer)
26
+ return null;
27
+ const { data } = await db()
28
+ .from("orders")
29
+ .select("id")
30
+ .eq("order_number", nummer)
31
+ .is("deleted_at", null)
32
+ .maybeSingle();
33
+ return data?.id ?? null;
34
+ };
35
+ const bereken = async () => {
36
+ setBezig(true);
37
+ try {
38
+ const id = await zoekOrderId();
39
+ if (!id) {
40
+ toast.error("Order niet gevonden");
41
+ return;
42
+ }
43
+ setOrderId(id);
44
+ const result = await preview({ data: { orderId: id } });
45
+ const list = Array.isArray(result?.carts) ? result.carts : [];
46
+ setCarts(list);
47
+ setWarnings(Array.isArray(result?.warnings) ? result.warnings : []);
48
+ if (result?.skipped === "locked")
49
+ toast.info("Deze buffer is vergrendeld en wordt niet herplaatst.");
50
+ else
51
+ toast.success(`${list.length} ladingdragers berekend`);
52
+ }
53
+ catch (e) {
54
+ toast.error(e?.message ?? "Berekenen mislukt");
55
+ }
56
+ finally {
57
+ setBezig(false);
58
+ }
59
+ };
60
+ const vastleggen = async () => {
61
+ if (!orderId)
62
+ return;
63
+ setBezig(true);
64
+ try {
65
+ const result = await replan({ data: { orderId } });
66
+ toast.success(`${result?.cartsCreated ?? 0} ladingdragers opgeslagen`);
67
+ }
68
+ catch (e) {
69
+ toast.error(e?.message ?? "Opslaan mislukt");
70
+ }
71
+ finally {
72
+ setBezig(false);
73
+ }
74
+ };
75
+ const safeCarts = Array.isArray(carts) ? carts : [];
76
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(Boxes, { className: "h-5 w-5 text-primary" }), "Beladingindeling"] }), _jsx(CardDescription, { children: "De Engine deelt de orderregels van de hele buffer in over ladingdragers. Bekijk eerst het resultaat en leg het daarna vast." }), _jsxs("div", { className: "flex flex-wrap items-end gap-2 pt-2", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "indeling-order", children: "Ordernummer" }), _jsx(Input, { id: "indeling-order", value: orderNummer, onChange: (e) => setOrderNummer(e.target.value), placeholder: "SO-12345", className: "w-56" })] }), _jsxs(Button, { onClick: () => void bereken(), disabled: bezig || !orderNummer.trim(), children: [_jsx(Search, { className: "mr-2 h-4 w-4" }), "Berekenen"] }), _jsx(Button, { variant: "outline", onClick: () => void vastleggen(), disabled: bezig || !orderId, children: "Vastleggen" })] })] }), _jsxs(CardContent, { className: "space-y-4", children: [warnings.length > 0 && (_jsx("ul", { className: "space-y-1 rounded-lg border border-dashed p-3 text-sm text-muted-foreground", children: warnings.map((w, i) => (_jsx("li", { children: w }, i))) })), safeCarts.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen indeling berekend." })) : (safeCarts.map((cart) => (_jsxs("div", { className: "space-y-2 rounded-lg border p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: "font-medium", children: ["Ladingdrager ", cart.cart_number] }), _jsx(Badge, { variant: "secondary", children: carrierLabel(cart.carrier_type) }), _jsxs(Badge, { variant: cart.is_complete ? "default" : "outline", children: [cart.occupancy_pct, "% vol"] }), _jsxs("span", { className: "text-xs text-muted-foreground", children: [cart.total_layers_used, " van ", cart.max_layers, " lagen", cart.weight_kg ? ` · ${cart.weight_kg} kg` : ""] })] }), _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Partij" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { className: "text-right", children: "Aandeel" })] }) }), _jsx(TableBody, { children: (Array.isArray(cart.items) ? cart.items : []).map((item, idx) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-medium", children: item.product_name }), _jsx(TableCell, { className: "text-right", children: item.crates }), _jsx(TableCell, { className: "text-right", children: item.plants }), _jsxs(TableCell, { className: "text-right", children: [Math.round(item.layer_share_pct * 10) / 10, "%"] })] }, `${item.order_item_id}-${idx}`))) })] })] }, cart.cart_number))))] })] }));
77
+ }
@@ -0,0 +1,19 @@
1
+ import type { BulkIndelingTotaal, LogistiekTaak } from "../hooks/useLogistiekTaken";
2
+ interface Props {
3
+ taken: LogistiekTaak[];
4
+ strategyId?: string | null;
5
+ simuleerBuffers: (orders: Array<Record<string, unknown>>, strategyId?: string | null) => Promise<{
6
+ orders: Array<Record<string, any>>;
7
+ groups: Array<Record<string, any>>;
8
+ } | null>;
9
+ herindelenBuffers: (strategyId?: string | null) => Promise<unknown>;
10
+ herindelenOrders: (dagen?: number) => Promise<{
11
+ checked?: number;
12
+ updated?: number;
13
+ durationMs?: number;
14
+ } | null>;
15
+ deelAllesIn?: (strategyId?: string | null, onVoortgang?: (tekst: string) => void) => Promise<BulkIndelingTotaal | null>;
16
+ }
17
+ export declare function BufferDebugCard({ taken, strategyId, simuleerBuffers, herindelenBuffers, herindelenOrders, deelAllesIn, }: Props): import("react").JSX.Element;
18
+ export {};
19
+ //# sourceMappingURL=BufferDebugCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BufferDebugCard.d.ts","sourceRoot":"","sources":["../../src/components/BufferDebugCard.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGpF,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,CACf,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,KACvB,OAAO,CAAC;QAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAChG,iBAAiB,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpE,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAClH,WAAW,CAAC,EAAE,CACZ,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,KAClC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACzC;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,GACZ,EAAE,KAAK,+BAsMP"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/BufferDebugCard.tsx — waarom is een order wel/niet gecombineerd
4
+ // ============================================================================
5
+ // Toont per openstaande order het bufferbesluit van de Engine, groepeert op
6
+ // bufferRef en legt regel voor regel uit welke criteria zijn gecontroleerd.
7
+ // ============================================================================
8
+ import { useMemo, useState } from "react";
9
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@flowselections/core";
10
+ import { Boxes, Layers, RefreshCw, Wand2, Zap } from "lucide-react";
11
+ import { bufferCriterionLabel, bufferReasonLabel } from "../lib/bufferMatching";
12
+ export function BufferDebugCard({ taken, strategyId, simuleerBuffers, herindelenBuffers, herindelenOrders, deelAllesIn, }) {
13
+ const [voortgang, setVoortgang] = useState(null);
14
+ const [indelingTotaal, setIndelingTotaal] = useState(null);
15
+ const [resultaat, setResultaat] = useState(null);
16
+ const [bezig, setBezig] = useState(false);
17
+ const [orderResultaat, setOrderResultaat] = useState(null);
18
+ // Eén representatieve payload per order, als invoer voor de simulatie.
19
+ const orders = useMemo(() => {
20
+ const veilig = Array.isArray(taken) ? taken : [];
21
+ const perOrder = new Map();
22
+ for (const taak of veilig) {
23
+ if (perOrder.has(taak.order_ref))
24
+ continue;
25
+ const payload = (taak.payload ?? {});
26
+ perOrder.set(taak.order_ref, { ...payload, orderRef: taak.order_ref });
27
+ }
28
+ return Array.from(perOrder.values());
29
+ }, [taken]);
30
+ const simuleer = async () => {
31
+ setBezig(true);
32
+ const data = await simuleerBuffers(orders, strategyId ?? null);
33
+ setResultaat(data);
34
+ setBezig(false);
35
+ };
36
+ const herindelen = async () => {
37
+ setBezig(true);
38
+ await herindelenBuffers(strategyId ?? null);
39
+ const data = await simuleerBuffers(orders, strategyId ?? null);
40
+ setResultaat(data);
41
+ setBezig(false);
42
+ };
43
+ const ordersHerindelen = async () => {
44
+ setBezig(true);
45
+ const res = await herindelenOrders(30);
46
+ setOrderResultaat(res);
47
+ setBezig(false);
48
+ };
49
+ const allesIndelen = async () => {
50
+ if (!deelAllesIn)
51
+ return;
52
+ setBezig(true);
53
+ setVoortgang("Bezig met indelen…");
54
+ const res = await deelAllesIn(strategyId ?? null, (tekst) => setVoortgang(tekst));
55
+ setIndelingTotaal(res);
56
+ setVoortgang(null);
57
+ setBezig(false);
58
+ };
59
+ const groepen = Array.isArray(resultaat?.groups) ? resultaat.groups : [];
60
+ const regels = Array.isArray(resultaat?.orders) ? resultaat.orders : [];
61
+ return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(Layers, { className: "h-4 w-4" }), " Buffersimulatie"] }), _jsx(CardDescription, { children: "Controleer per order welke combineerregels zijn gecontroleerd en waarom een order wel of niet in dezelfde orderbuffer terechtkomt." })] }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: () => void simuleer(), disabled: bezig || orders.length === 0, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), " Simuleren"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void herindelen(), disabled: bezig || orders.length === 0, children: [_jsx(Wand2, { className: "mr-2 h-4 w-4" }), " Taken opnieuw indelen"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void ordersHerindelen(), disabled: bezig, children: [_jsx(Zap, { className: "mr-2 h-4 w-4" }), " Orders nu opnieuw indelen"] }), deelAllesIn && (_jsxs(Button, { size: "sm", onClick: () => void allesIndelen(), disabled: bezig, children: [_jsx(Boxes, { className: "mr-2 h-4 w-4" }), " Alle orders indelen"] }))] })] }) }), _jsxs(CardContent, { className: "space-y-4", children: [voortgang && _jsx("p", { className: "text-sm font-medium", children: voortgang }), indelingTotaal && (_jsxs("div", { className: "rounded-lg border border-border p-3 text-sm", children: [_jsx("p", { className: "font-medium", children: "Laatste indeling" }), _jsxs("p", { className: "text-muted-foreground", children: [indelingTotaal.beladingen, " beladingen voor ", indelingTotaal.buffers, " buffers en", " ", indelingTotaal.orders, " losse orders \u00B7 ", indelingTotaal.takenBijgewerkt, " taken bijgewerkt", indelingTotaal.takenAangemaakt > 0
62
+ ? ` · ${indelingTotaal.takenAangemaakt} nieuwe takenketens`
63
+ : "", indelingTotaal.overgeslagen > 0
64
+ ? ` · ${indelingTotaal.overgeslagen} vergrendeld overgeslagen`
65
+ : "", indelingTotaal.mislukt > 0 ? ` · ${indelingTotaal.mislukt} mislukt` : ""] }), indelingTotaal.fouten.length > 0 && (_jsx("ul", { className: "text-destructive mt-1 list-disc pl-4 text-xs", children: indelingTotaal.fouten.map((f, i) => (_jsx("li", { children: f }, i))) }))] })), orderResultaat && (_jsxs("p", { className: "text-muted-foreground text-sm", children: ["Laatste herberekening: ", Number(orderResultaat.updated ?? 0), " van", " ", Number(orderResultaat.checked ?? 0), " orders verplaatst in", " ", Number(orderResultaat.durationMs ?? 0), " ms."] })), orders.length === 0 && (_jsx("p", { className: "text-muted-foreground text-sm", children: "Er zijn geen openstaande orders om te simuleren." })), resultaat === null && orders.length > 0 && (_jsxs("p", { className: "text-muted-foreground text-sm", children: ["Klik op \u201CSimuleren\u201D om ", orders.length, " openstaande order(s) door de combineerregels te halen."] })), groepen.length > 0 && (_jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Gevonden buffers" }), _jsx("ul", { className: "space-y-2", children: groepen.map((g) => (_jsxs("li", { className: "rounded-lg border border-border p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Badge, { variant: Number(g.count) > 1 ? "default" : "outline", children: [Number(g.count), " order", Number(g.count) === 1 ? "" : "s"] }), _jsx("span", { className: "text-sm", children: (Array.isArray(g.orderRefs) ? g.orderRefs : []).join(", ") })] }), _jsx("p", { className: "text-muted-foreground mt-1 font-mono text-xs break-all", children: String(g.bufferKey ?? "") })] }, String(g.bufferRef)))) })] })), regels.length > 0 && (_jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Uitleg per order" }), _jsx("ul", { className: "space-y-2", children: regels.map((r) => {
66
+ const trace = Array.isArray(r.trace) ? r.trace : [];
67
+ return (_jsxs("li", { className: "rounded-lg border border-border p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "text-sm font-medium", children: String(r.orderRef) }), _jsx(Badge, { variant: r.buffer ? "secondary" : "outline", children: bufferReasonLabel(r.reason) })] }), _jsx("ul", { className: "mt-2 space-y-1", children: trace.map((t, i) => (_jsxs("li", { className: "text-muted-foreground text-xs", children: [_jsx("span", { className: t.result ? "text-foreground" : "text-destructive", children: bufferCriterionLabel(String(t.rule)) }), t.value ? _jsxs("span", { children: [" = ", String(t.value)] }) : null, t.message ? _jsxs("span", { children: [" \u2014 ", String(t.message)] }) : null] }, i))) })] }, String(r.orderRef)));
68
+ }) })] }))] })] }));
69
+ }
@@ -0,0 +1,2 @@
1
+ export declare function CapaciteitMeldingenCard(): import("react").JSX.Element;
2
+ //# sourceMappingURL=CapaciteitMeldingenCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapaciteitMeldingenCard.d.ts","sourceRoot":"","sources":["../../src/components/CapaciteitMeldingenCard.tsx"],"names":[],"mappings":"AAwCA,wBAAgB,uBAAuB,gCA+DtC"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/CapaciteitMeldingenCard.tsx — waarschuwing bij te weinig capaciteit
4
+ // ============================================================================
5
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Skeleton, } from "@flowselections/core";
6
+ import { AlertTriangle, CheckCircle2, RefreshCw } from "lucide-react";
7
+ import { useCapaciteitMeldingen } from "../hooks/useCapaciteitMeldingen";
8
+ function datum(value) {
9
+ if (!value)
10
+ return "onbekend";
11
+ try {
12
+ return new Date(value).toLocaleDateString("nl-NL", { weekday: "long", day: "numeric", month: "long" });
13
+ }
14
+ catch {
15
+ return value;
16
+ }
17
+ }
18
+ /** Rekent het tekort in minuten om naar het aantal extra medewerkers dat nodig is. */
19
+ function personenTekort(shortageMinutes, availableMinutes, staff) {
20
+ const tekort = Number(shortageMinutes ?? 0);
21
+ const beschikbaar = Number(availableMinutes ?? 0);
22
+ if (!Number.isFinite(tekort) || tekort <= 0)
23
+ return 0;
24
+ const perPersoon = staff > 0 && beschikbaar > 0 ? beschikbaar / staff : 0;
25
+ if (perPersoon <= 0)
26
+ return 0;
27
+ return Math.ceil(tekort / perPersoon);
28
+ }
29
+ export function CapaciteitMeldingenCard() {
30
+ const { meldingen, staff, loading, reload, controleer } = useCapaciteitMeldingen();
31
+ const safe = Array.isArray(meldingen) ? meldingen : [];
32
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-row items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-amber-500" }), "Capaciteitswaarschuwingen"] }), _jsx(CardDescription, { children: "Per pickdag vergelijkt de Engine het werk met het aantal medewerkers dat je hebt ingepland." })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => void controleer(), children: "Nu berekenen" }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void reload(), children: [_jsx(RefreshCw, { className: "mr-1 h-4 w-4" }), "Vernieuwen"] })] })] }), _jsx(CardContent, { className: "space-y-3", children: loading ? (_jsx(Skeleton, { className: "h-20 w-full" })) : safe.length === 0 ? (_jsxs("p", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx(CheckCircle2, { className: "h-4 w-4 text-emerald-500" }), "Alle geplande dagen passen binnen de beschikbare capaciteit."] })) : (safe.map((m) => {
33
+ const extra = personenTekort(m.shortage_minutes, m.available_minutes, staff);
34
+ return (_jsxs("div", { className: "rounded-lg border border-amber-500/40 bg-amber-500/5 p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx("div", { className: "font-medium", children: datum(m.plan_date) }), _jsx(Badge, { variant: "destructive", children: extra > 0
35
+ ? `${extra} ${extra === 1 ? "persoon" : "personen"} tekort`
36
+ : "Te weinig capaciteit" })] }), _jsxs("p", { className: "mt-1 text-sm text-muted-foreground", children: [m.carts_total ?? 0, " karren op deze dag.", " ", staff > 0
37
+ ? `Met ${staff} ${staff === 1 ? "medewerker" : "medewerkers"} red je het niet: je hebt er ${extra > 0 ? extra : 1} extra nodig (samen ${staff + (extra > 0 ? extra : 1)}).`
38
+ : "Vul in stap 3 het gemiddeld aantal medewerkers in om het tekort in personen te tonen.", " ", "Circa ", m.carts_short ?? 0, " karren passen niet op deze dag."] })] }, m.id));
39
+ })) })] }));
40
+ }
@@ -0,0 +1,2 @@
1
+ export declare function LadingdragersPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=LadingdragersPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LadingdragersPage.d.ts","sourceRoot":"","sources":["../../src/components/LadingdragersPage.tsx"],"names":[],"mappings":"AA+HA,wBAAgB,iBAAiB,gCAwUhC"}
@@ -0,0 +1,102 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/LadingdragersPage.tsx — beheer van ladingdragertypen
4
+ // ============================================================================
5
+ // Per ladingdrager leg je vast hoe groot hij is. De Rule Engine bepaalt welke
6
+ // types een strategie mág gebruiken; hier staat hoeveel er in past.
7
+ // GEEN <Header /> hier — die levert de shell.
8
+ // ============================================================================
9
+ import { useState } from "react";
10
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
11
+ import { Container, Pencil, Plus, RefreshCw, Trash2 } from "lucide-react";
12
+ import { Link } from "@tanstack/react-router";
13
+ import { useLadingdragers } from "../hooks/useLadingdragers";
14
+ import { CAPACITY_MODEL_LABELS } from "../lib/loadCarrierTypes";
15
+ const LEEG = {
16
+ code: "",
17
+ name: "",
18
+ capacity_model: "layered",
19
+ layers_per_carrier: 5,
20
+ layer_length_cm: 135,
21
+ layer_width_cm: 56,
22
+ max_crates_per_layer: "",
23
+ max_boxes: "",
24
+ max_weight_kg: "",
25
+ max_height_cm: "",
26
+ max_orders: "",
27
+ max_customers: "",
28
+ allow_mixing: true,
29
+ is_active: true,
30
+ is_default: false,
31
+ sort_order: 100,
32
+ };
33
+ function toForm(row) {
34
+ const t = (v) => (v === null || v === undefined ? "" : String(v));
35
+ return {
36
+ code: row.code,
37
+ name: row.name,
38
+ capacity_model: row.capacity_model,
39
+ layers_per_carrier: row.layers_per_carrier,
40
+ layer_length_cm: row.layer_length_cm,
41
+ layer_width_cm: row.layer_width_cm,
42
+ max_crates_per_layer: t(row.max_crates_per_layer),
43
+ max_boxes: t(row.max_boxes),
44
+ max_weight_kg: t(row.max_weight_kg),
45
+ max_height_cm: t(row.max_height_cm),
46
+ max_orders: t(row.max_orders),
47
+ max_customers: t(row.max_customers),
48
+ allow_mixing: row.allow_mixing !== false,
49
+ is_active: row.is_active,
50
+ is_default: row.is_default,
51
+ sort_order: row.sort_order,
52
+ };
53
+ }
54
+ function toPayload(form) {
55
+ const n = (v) => (v.trim() === "" ? null : Number(v));
56
+ return {
57
+ code: form.code.trim(),
58
+ name: form.name.trim(),
59
+ capacity_model: form.capacity_model,
60
+ layers_per_carrier: Math.max(1, Number(form.layers_per_carrier) || 1),
61
+ layer_length_cm: Math.max(0, Number(form.layer_length_cm) || 0),
62
+ layer_width_cm: Math.max(0, Number(form.layer_width_cm) || 0),
63
+ max_crates_per_layer: n(form.max_crates_per_layer),
64
+ max_boxes: n(form.max_boxes),
65
+ max_weight_kg: n(form.max_weight_kg),
66
+ max_height_cm: n(form.max_height_cm),
67
+ max_orders: n(form.max_orders),
68
+ max_customers: n(form.max_customers),
69
+ allow_mixing: form.allow_mixing,
70
+ is_active: form.is_active,
71
+ is_default: form.is_default,
72
+ sort_order: Number(form.sort_order) || 0,
73
+ };
74
+ }
75
+ export function LadingdragersPage() {
76
+ const { items, loading, saving, reload, create, update, remove } = useLadingdragers();
77
+ const [open, setOpen] = useState(false);
78
+ const [bewerkId, setBewerkId] = useState(null);
79
+ const [form, setForm] = useState(LEEG);
80
+ const safeItems = Array.isArray(items) ? items : [];
81
+ const openNieuw = () => {
82
+ setBewerkId(null);
83
+ setForm(LEEG);
84
+ setOpen(true);
85
+ };
86
+ const openBewerk = (row) => {
87
+ setBewerkId(row.id);
88
+ setForm(toForm(row));
89
+ setOpen(true);
90
+ };
91
+ const opslaan = async () => {
92
+ const payload = toPayload(form);
93
+ if (!payload.code || !payload.name)
94
+ return;
95
+ const ok = bewerkId ? await update(bewerkId, payload) : await create(payload);
96
+ if (ok)
97
+ setOpen(false);
98
+ };
99
+ const set = (key, value) => setForm((prev) => ({ ...prev, [key]: value }));
100
+ const toonLagen = form.capacity_model === "layered" || form.capacity_model === "stacked";
101
+ return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Container, { className: "h-6 w-6 text-primary" }), "Ladingdragers"] }), _jsx("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: "Hier staat hoe groot elke ladingdrager is. De Beladingindeling gebruikt deze maten om te bepalen hoeveel fusten er per laag en per drager passen. In de Rule Engine bepaal je per strategie welke ladingdragers gebruikt mogen worden." })] }), _jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: reload, disabled: loading, children: [_jsx(RefreshCw, { className: "mr-2 h-4 w-4" }), "Vernieuwen"] }), _jsxs(Button, { size: "sm", onClick: openNieuw, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Ladingdrager"] }), _jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/logistiek-engine", children: "Terug" }) })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Capaciteit per ladingdrager" }), _jsx(CardDescription, { children: "Lagen bepalen de hoogte: een product met vier lagen per drager neemt per laag 25% van de hoogte in." })] }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" }), _jsx(Skeleton, { className: "h-10 w-full" })] })) : safeItems.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Nog geen ladingdragers ingesteld." })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Ladingdrager" }), _jsx(TableHead, { children: "Model" }), _jsx(TableHead, { className: "text-right", children: "Lagen" }), _jsx(TableHead, { className: "text-right", children: "Laagmaat" }), _jsx(TableHead, { className: "text-right", children: "Max dozen" }), _jsx(TableHead, { className: "text-right", children: "Max kg" }), _jsx(TableHead, { children: "Mengen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((row) => (_jsxs(TableRow, { className: row.is_active ? "" : "opacity-50", children: [_jsxs(TableCell, { children: [_jsx("div", { className: "font-medium", children: row.name }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: row.code }), row.is_default ? _jsx(Badge, { variant: "secondary", children: "Standaard" }) : null, !row.is_active ? _jsx(Badge, { variant: "outline", children: "Uit" }) : null] })] }), _jsx(TableCell, { className: "text-sm", children: CAPACITY_MODEL_LABELS[row.capacity_model] }), _jsx(TableCell, { className: "text-right", children: row.layers_per_carrier }), _jsxs(TableCell, { className: "text-right text-sm text-muted-foreground", children: [row.layer_length_cm, " \u00D7 ", row.layer_width_cm, " cm"] }), _jsx(TableCell, { className: "text-right", children: row.max_boxes ?? "—" }), _jsx(TableCell, { className: "text-right", children: row.max_weight_kg ?? "—" }), _jsx(TableCell, { children: _jsx(Badge, { variant: row.allow_mixing === false ? "outline" : "secondary", children: row.allow_mixing === false ? "Nooit mengen" : "Mengen mag" }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => openBewerk(row), children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => remove(row.id), children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, row.id))) })] })) })] }), _jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "max-h-[85vh] overflow-y-auto sm:max-w-lg", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: bewerkId ? "Ladingdrager bewerken" : "Nieuwe ladingdrager" }), _jsx(DialogDescription, { children: "Deze maten bepalen hoeveel er per laag en per drager past." })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "code", children: "Code" }), _jsx(Input, { id: "code", value: form.code, onChange: (e) => set("code", e.target.value), placeholder: "pallet", disabled: Boolean(bewerkId) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "name", children: "Naam" }), _jsx(Input, { id: "name", value: form.name, onChange: (e) => set("name", e.target.value) })] })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { children: "Capaciteitsmodel" }), _jsxs(Select, { value: form.capacity_model, onValueChange: (v) => set("capacity_model", v), children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: Object.entries(CAPACITY_MODEL_LABELS).map(([value, label]) => (_jsx(SelectItem, { value: value, children: label }, value))) })] })] }), toonLagen ? (_jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lagen", children: "Lagen" }), _jsx(Input, { id: "lagen", type: "number", min: 1, value: form.layers_per_carrier, onChange: (e) => set("layers_per_carrier", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "lengte", children: "Lengte (cm)" }), _jsx(Input, { id: "lengte", type: "number", min: 0, value: form.layer_length_cm, onChange: (e) => set("layer_length_cm", Number(e.target.value)) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "breedte", children: "Breedte (cm)" }), _jsx(Input, { id: "breedte", type: "number", min: 0, value: form.layer_width_cm, onChange: (e) => set("layer_width_cm", Number(e.target.value)) })] })] })) : null, _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxfust", children: "Max fusten per laag" }), _jsx(Input, { id: "maxfust", type: "number", min: 1, value: form.max_crates_per_layer, onChange: (e) => set("max_crates_per_layer", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxdozen", children: "Max dozen / fusten totaal" }), _jsx(Input, { id: "maxdozen", type: "number", min: 1, value: form.max_boxes, onChange: (e) => set("max_boxes", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxkg", children: "Max gewicht (kg)" }), _jsx(Input, { id: "maxkg", type: "number", min: 0, value: form.max_weight_kg, onChange: (e) => set("max_weight_kg", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxhoogte", children: "Max hoogte (cm)" }), _jsx(Input, { id: "maxhoogte", type: "number", min: 0, value: form.max_height_cm, onChange: (e) => set("max_height_cm", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxorders", children: "Max orders" }), _jsx(Input, { id: "maxorders", type: "number", min: 1, value: form.max_orders, onChange: (e) => set("max_orders", e.target.value), placeholder: "Geen grens" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "maxklanten", children: "Max klanten" }), _jsx(Input, { id: "maxklanten", type: "number", min: 1, value: form.max_customers, onChange: (e) => set("max_customers", e.target.value), placeholder: "Geen grens" })] })] }), _jsxs("div", { className: "space-y-3 rounded-lg border p-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "mengen", children: "Mengen van partijen toestaan" }), _jsx(Switch, { id: "mengen", checked: form.allow_mixing, onCheckedChange: (v) => set("allow_mixing", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "actief", children: "Actief" }), _jsx(Switch, { id: "actief", checked: form.is_active, onCheckedChange: (v) => set("is_active", v) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Label, { htmlFor: "standaard", children: "Standaard ladingdrager" }), _jsx(Switch, { id: "standaard", checked: form.is_default, onCheckedChange: (v) => set("is_default", v) })] }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Label, { htmlFor: "volgorde", children: "Volgorde" }), _jsx(Input, { id: "volgorde", type: "number", className: "w-24", value: form.sort_order, onChange: (e) => set("sort_order", Number(e.target.value)) })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(false), children: "Annuleren" }), _jsx(Button, { onClick: opslaan, disabled: saving || !form.code || !form.name, children: "Opslaan" })] })] }) })] }));
102
+ }
@@ -0,0 +1,6 @@
1
+ interface LogistiekEngineLogoProps {
2
+ className?: string;
3
+ }
4
+ export declare function LogistiekEngineLogo({ className }: LogistiekEngineLogoProps): import("react").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=LogistiekEngineLogo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogistiekEngineLogo.d.ts","sourceRoot":"","sources":["../../src/components/LogistiekEngineLogo.tsx"],"names":[],"mappings":"AAEA,UAAU,wBAAwB;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,SAAS,EAAE,EAAE,wBAAwB,+BAoB1E"}
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function LogistiekEngineLogo({ className }) {
3
+ return (_jsxs("svg", { viewBox: "0 0 40 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, "aria-hidden": "true", children: [_jsx("rect", { width: "40", height: "40", rx: "8", fill: "currentColor", opacity: "0.1" }), _jsx("path", { d: "M8 25h4a3 3 0 0 0 6 0h6a3 3 0 0 0 6 0h2v-6l-4-5h-4v-3H8v14Z", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }), _jsx("circle", { cx: "15", cy: "25", r: "2.5", fill: "currentColor" }), _jsx("circle", { cx: "27", cy: "25", r: "2.5", fill: "currentColor" })] }));
4
+ }
@@ -0,0 +1,2 @@
1
+ export declare function LogistiekEnginePage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=LogistiekEnginePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogistiekEnginePage.d.ts","sourceRoot":"","sources":["../../src/components/LogistiekEnginePage.tsx"],"names":[],"mappings":"AA8DA,wBAAgB,mBAAmB,gCAyLlC"}
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/LogistiekEnginePage.tsx
4
+ // ============================================================================
5
+ // Hoofdpagina van de Logistiek Engine module.
6
+ // GEEN <Header /> hier — die levert de shell via staticData.title.
7
+ // ============================================================================
8
+ import { useState } from "react";
9
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Badge, Switch, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Skeleton, } from "@flowselections/core";
10
+ import { Container, Pencil, Plus, SlidersHorizontal, Trash2, Workflow } from "lucide-react";
11
+ import { Link } from "@tanstack/react-router";
12
+ import { StrategieDialog } from "./StrategieDialog";
13
+ import { useLogistiekStrategieen, } from "../hooks/useLogistiekStrategieen";
14
+ const SNELKOPPELINGEN = [
15
+ {
16
+ to: "/logistiek-engine/rule-engine",
17
+ icon: SlidersHorizontal,
18
+ titel: "Werkwijze instellen",
19
+ uitleg: "Bepaal stap voor stap hoe orders worden verzameld, gepickt en klaargezet.",
20
+ },
21
+ {
22
+ to: "/logistiek-engine/regie",
23
+ icon: Workflow,
24
+ titel: "Overzicht & meldingen",
25
+ uitleg: "Zie wat er klaarstaat en waar aandacht voor nodig is.",
26
+ },
27
+ {
28
+ to: "/logistiek-engine/ladingdragers",
29
+ icon: Container,
30
+ titel: "Ladingdragers",
31
+ uitleg: "Beheer karren, dozen en andere ladingdragers.",
32
+ },
33
+ ];
34
+ export function LogistiekEnginePage() {
35
+ const { items, loading, saving, error, create, update, remove, toggleActive } = useLogistiekStrategieen();
36
+ const [dialogOpen, setDialogOpen] = useState(false);
37
+ const [editing, setEditing] = useState(null);
38
+ const [deleting, setDeleting] = useState(null);
39
+ const safeItems = Array.isArray(items) ? items : [];
40
+ const openNew = () => {
41
+ setEditing(null);
42
+ setDialogOpen(true);
43
+ };
44
+ const openEdit = (item) => {
45
+ setEditing(item);
46
+ setDialogOpen(true);
47
+ };
48
+ return (_jsxs("main", { className: "p-6 space-y-6", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Hier bepaal je hoe orders in je bedrijf logistiek worden afgehandeld." }), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: SNELKOPPELINGEN.map(({ to, icon: Icon, titel, uitleg }) => (_jsx(Link, { to: to, className: "group", children: _jsx(Card, { className: "h-full transition-colors group-hover:border-primary", children: _jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary", children: _jsx(Icon, { className: "h-5 w-5" }) }), _jsx(CardTitle, { className: "text-base", children: titel })] }), _jsx(CardDescription, { className: "pt-1", children: uitleg })] }) }) }, to))) }), _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx(CardTitle, { children: "Werkwijzen" }), _jsx(CardDescription, { children: "Alleen een werkwijze die aan staat wordt op je orders toegepast." })] }), _jsxs(Button, { size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Nieuwe werkwijze"] })] }) }), _jsx(CardContent, { children: loading ? (_jsxs("div", { className: "space-y-2", children: [_jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-8 w-full" })] })) : error ? (_jsx("p", { className: "text-sm text-destructive", children: "Kon de gegevens niet ophalen. Probeer het over een moment opnieuw." })) : safeItems.length === 0 ? (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Je hebt nog geen werkwijze ingesteld." }), _jsxs(Button, { variant: "outline", size: "sm", onClick: openNew, children: [_jsx(Plus, { className: "h-4 w-4" }), "Eerste werkwijze aanmaken"] })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Naam" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "w-48 text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: safeItems.map((item) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "h-3 w-3 shrink-0 rounded-full border border-border", style: { backgroundColor: item.color ?? "#3b82f6" } }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: item.name ?? "—" }), item.description && (_jsx("p", { className: "text-xs text-muted-foreground", children: item.description }))] })] }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { checked: !!item.is_active, onCheckedChange: () => toggleActive(item), "aria-label": "Aan of uit zetten" }), _jsx(Badge, { variant: item.is_active ? "default" : "secondary", children: item.is_active ? "Aan" : "Uit" })] }) }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsxs(Link, { to: "/logistiek-engine/rule-engine", search: { strategy: String(item.id), naam: item.name ?? "" }, children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Instellen"] }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => openEdit(item), "aria-label": "Bewerken", children: _jsx(Pencil, { className: "h-4 w-4" }) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: () => setDeleting(item), "aria-label": "Verwijderen", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }) })] }, String(item.id)))) })] })) })] }), _jsx(StrategieDialog, { open: dialogOpen, onOpenChange: setDialogOpen, strategie: editing, saving: saving, onSubmit: (input) => (editing ? update(editing.id, input) : create(input)) }), _jsx(AlertDialog, { open: !!deleting, onOpenChange: (open) => !open && setDeleting(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Werkwijze verwijderen?" }), _jsxs(AlertDialogDescription, { children: ["\"", deleting?.name, "\" wordt definitief verwijderd. Dit kan niet ongedaan worden gemaakt."] })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: async () => {
49
+ if (deleting)
50
+ await remove(deleting.id);
51
+ setDeleting(null);
52
+ }, children: "Verwijderen" })] })] }) })] }));
53
+ }
@@ -0,0 +1,2 @@
1
+ export declare function ModulePromptsPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=ModulePromptsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModulePromptsPage.d.ts","sourceRoot":"","sources":["../../src/components/ModulePromptsPage.tsx"],"names":[],"mappings":"AAkDA,wBAAgB,iBAAiB,gCAiJhC"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ============================================================================
3
+ // src/components/ModulePromptsPage.tsx — koppelprompts per module
4
+ // ============================================================================
5
+ // Bekijken, kopiëren en downloaden van de prompt per aangesloten module.
6
+ // GEEN <Header /> hier — die levert de shell.
7
+ // ============================================================================
8
+ import { useState } from "react";
9
+ import { Badge, Button, Card, CardContent, CardDescription, CardHeader, CardTitle, toast, } from "@flowselections/core";
10
+ import { Check, ChevronDown, ChevronUp, Copy, Download, Puzzle } from "lucide-react";
11
+ import { Link } from "@tanstack/react-router";
12
+ import { MODULE_PROMPTS, buildAllModulePrompts, buildRevisionPrompt, modulePromptFilename, } from "../lib/modulePrompts";
13
+ function downloadMarkdown(filename, content) {
14
+ const blob = new Blob([content], { type: "text/markdown;charset=utf-8" });
15
+ const url = URL.createObjectURL(blob);
16
+ const link = document.createElement("a");
17
+ link.href = url;
18
+ link.download = filename;
19
+ document.body.appendChild(link);
20
+ link.click();
21
+ document.body.removeChild(link);
22
+ URL.revokeObjectURL(url);
23
+ }
24
+ async function copyText(content) {
25
+ try {
26
+ await navigator.clipboard.writeText(content);
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ export function ModulePromptsPage() {
34
+ const [open, setOpen] = useState(null);
35
+ const [copied, setCopied] = useState(null);
36
+ const prompts = Array.isArray(MODULE_PROMPTS) ? MODULE_PROMPTS : [];
37
+ const handleCopy = async (key, content) => {
38
+ const ok = await copyText(content);
39
+ if (ok) {
40
+ setCopied(key);
41
+ toast.success("Prompt gekopieerd");
42
+ window.setTimeout(() => setCopied((c) => (c === key ? null : c)), 2000);
43
+ }
44
+ else {
45
+ toast.error("Kopiëren mislukt", { description: "Gebruik de downloadknop." });
46
+ }
47
+ };
48
+ return (_jsxs("div", { className: "space-y-6 p-6", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("h1", { className: "flex items-center gap-2 text-2xl font-semibold tracking-tight", children: [_jsx(Puzzle, { className: "h-6 w-6 text-primary" }), "Modules"] }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Koppelprompts voor de modules die op de Logistics Engine worden aangesloten. Kopieer of download de prompt en plak hem in het betreffende project." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "outline", asChild: true, children: _jsx(Link, { to: "/logistiek-engine", children: "Terug naar strategie\u00EBn" }) }), _jsxs(Button, { onClick: () => downloadMarkdown("logistics-engine-module-prompts.md", buildAllModulePrompts()), children: [_jsx(Download, { className: "mr-2 h-4 w-4" }), "Alles downloaden"] })] })] }), _jsx("p", { className: "text-muted-foreground text-sm", children: "Per module staan de prompts op volgorde. Nieuwe eisen komen er altijd als nieuwe prompt bij \u2014 eerdere prompts blijven geldig en worden niet herschreven. Stuur dus alleen de prompt(s) door die je nog niet hebt verstuurd." }), _jsx("div", { className: "space-y-4", children: prompts.map((prompt) => {
49
+ const key = prompt.moduleKey;
50
+ const revisions = Array.isArray(prompt.revisions) ? prompt.revisions : [];
51
+ return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs("div", { className: "space-y-1", children: [_jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsxs("span", { className: "text-muted-foreground", children: [prompt.order, "."] }), prompt.label, _jsx(Badge, { variant: "outline", className: "font-mono text-[10px]", children: key }), _jsxs(Badge, { variant: "secondary", className: "text-[10px]", children: [revisions.length, " prompt", revisions.length === 1 ? "" : "s"] })] }), _jsx(CardDescription, { children: prompt.summary })] }) }), _jsx(CardContent, { className: "space-y-3", children: revisions.map((rev) => {
52
+ const revKey = `${key}-${rev.number}`;
53
+ const full = buildRevisionPrompt(prompt, rev);
54
+ const isOpen = open === revKey;
55
+ return (_jsxs("div", { className: "rounded-lg border p-3", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm font-medium", children: [_jsxs(Badge, { variant: "outline", className: "text-[10px]", children: ["Prompt ", rev.number] }), rev.title, _jsx("span", { className: "text-muted-foreground text-xs font-normal", children: rev.date })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: rev.summary })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setOpen(isOpen ? null : revKey), children: [isOpen ? (_jsx(ChevronUp, { className: "mr-2 h-4 w-4" })) : (_jsx(ChevronDown, { className: "mr-2 h-4 w-4" })), isOpen ? "Verbergen" : "Bekijken"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void handleCopy(revKey, full), children: [copied === revKey ? (_jsx(Check, { className: "mr-2 h-4 w-4" })) : (_jsx(Copy, { className: "mr-2 h-4 w-4" })), "Kopi\u00EBren"] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => downloadMarkdown(modulePromptFilename(key, rev.number), full), children: [_jsx(Download, { className: "mr-2 h-4 w-4" }), "Download"] })] })] }), isOpen && (_jsx("pre", { className: "bg-muted text-foreground mt-3 max-h-96 overflow-auto rounded-md p-4 text-xs leading-relaxed whitespace-pre-wrap", children: full }))] }, revKey));
56
+ }) })] }, key));
57
+ }) })] }));
58
+ }
@@ -0,0 +1,2 @@
1
+ export declare function RegiePage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=RegiePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegiePage.d.ts","sourceRoot":"","sources":["../../src/components/RegiePage.tsx"],"names":[],"mappings":"AAoEA,wBAAgB,SAAS,gCA4WxB"}