@flowselections/floriday-afhandeling-module 1.0.10 → 1.0.11

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 (69) hide show
  1. package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts +7 -0
  2. package/dist-lib/components/afhandeling/ControleLijstPrint.d.ts.map +1 -0
  3. package/dist-lib/components/afhandeling/ControleLijstPrint.js +67 -0
  4. package/dist-lib/components/afhandeling/ControlePage.d.ts +2 -0
  5. package/dist-lib/components/afhandeling/ControlePage.d.ts.map +1 -0
  6. package/dist-lib/components/afhandeling/ControlePage.js +456 -0
  7. package/dist-lib/components/afhandeling/DagDetailDialog.d.ts.map +1 -1
  8. package/dist-lib/components/afhandeling/DagDetailDialog.js +9 -5
  9. package/dist-lib/components/afhandeling/VervoerderForm.d.ts.map +1 -1
  10. package/dist-lib/components/afhandeling/VervoerderForm.js +10 -1
  11. package/dist-lib/components/afhandeling/VervoerdersPage.d.ts.map +1 -1
  12. package/dist-lib/components/afhandeling/VervoerdersPage.js +3 -2
  13. package/dist-lib/components/afhandeling/WeekAgendaView.d.ts.map +1 -1
  14. package/dist-lib/components/afhandeling/WeekAgendaView.js +15 -5
  15. package/dist-lib/components/afhandeling/WeekdayPicker.d.ts +12 -0
  16. package/dist-lib/components/afhandeling/WeekdayPicker.d.ts.map +1 -0
  17. package/dist-lib/components/afhandeling/WeekdayPicker.js +30 -0
  18. package/dist-lib/components/pickstation/PakbonTemplate.d.ts +1 -0
  19. package/dist-lib/components/pickstation/PakbonTemplate.d.ts.map +1 -1
  20. package/dist-lib/components/pickstation/PakbonTemplate.js +31 -8
  21. package/dist-lib/components/settings/AfhandelingSettingsCard.d.ts.map +1 -1
  22. package/dist-lib/components/settings/AfhandelingSettingsCard.js +9 -2
  23. package/dist-lib/components/ui/responsive-dialog.d.ts +20 -0
  24. package/dist-lib/components/ui/responsive-dialog.d.ts.map +1 -0
  25. package/dist-lib/components/ui/responsive-dialog.js +44 -0
  26. package/dist-lib/hooks/useOrderPlanning.d.ts.map +1 -1
  27. package/dist-lib/hooks/useOrderPlanning.js +17 -6
  28. package/dist-lib/index.d.ts +1 -0
  29. package/dist-lib/index.d.ts.map +1 -1
  30. package/dist-lib/index.js +4 -2
  31. package/dist-lib/integrations/supabase/auth-middleware.d.ts +629 -3
  32. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  33. package/dist-lib/integrations/supabase/client.d.ts +629 -3
  34. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  35. package/dist-lib/integrations/supabase/client.server.d.ts +629 -3
  36. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  37. package/dist-lib/integrations/supabase/types.d.ts +639 -3
  38. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  39. package/dist-lib/lib/afhandelingSettings.functions.d.ts +1318 -62
  40. package/dist-lib/lib/afhandelingSettings.functions.d.ts.map +1 -1
  41. package/dist-lib/lib/afhandelingSettings.functions.js +16 -1
  42. package/dist-lib/lib/carrierMatch.server.d.ts +27 -0
  43. package/dist-lib/lib/carrierMatch.server.d.ts.map +1 -0
  44. package/dist-lib/lib/carrierMatch.server.js +75 -0
  45. package/dist-lib/lib/carriers.functions.d.ts +3151 -15
  46. package/dist-lib/lib/carriers.functions.d.ts.map +1 -1
  47. package/dist-lib/lib/carriers.functions.js +17 -2
  48. package/dist-lib/lib/cartAssignments.functions.d.ts +3145 -15
  49. package/dist-lib/lib/cartAssignments.functions.d.ts.map +1 -1
  50. package/dist-lib/lib/cartControl.functions.d.ts +99259 -0
  51. package/dist-lib/lib/cartControl.functions.d.ts.map +1 -0
  52. package/dist-lib/lib/cartControl.functions.js +489 -0
  53. package/dist-lib/lib/cartRescheduling.d.ts +30 -0
  54. package/dist-lib/lib/cartRescheduling.d.ts.map +1 -0
  55. package/dist-lib/lib/cartRescheduling.js +71 -0
  56. package/dist-lib/lib/floriday.functions.d.ts +629 -3
  57. package/dist-lib/lib/floriday.functions.d.ts.map +1 -1
  58. package/dist-lib/lib/pickstationI18n.d.ts +8 -0
  59. package/dist-lib/lib/pickstationI18n.d.ts.map +1 -1
  60. package/dist-lib/lib/pickstationI18n.js +48 -0
  61. package/dist-lib/lib/pickstationOrders.server.d.ts +1 -0
  62. package/dist-lib/lib/pickstationOrders.server.d.ts.map +1 -1
  63. package/dist-lib/lib/pickstationOrders.server.js +94 -7
  64. package/dist-lib/lib/pickstationTypes.d.ts +12 -0
  65. package/dist-lib/lib/pickstationTypes.d.ts.map +1 -1
  66. package/dist-lib/lib/planning.d.ts +23 -0
  67. package/dist-lib/lib/planning.d.ts.map +1 -1
  68. package/dist-lib/lib/planning.js +66 -6
  69. package/package.json +1 -1
@@ -2,8 +2,9 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useState } from "react";
3
3
  import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
4
4
  import { useServerFn } from "@tanstack/react-start";
5
- import { Badge, Button, Dialog, DialogContent, DialogHeader, DialogTitle, Input, Tabs, TabsContent, TabsList, TabsTrigger, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, toast, } from "@flowselections/core";
5
+ import { Badge, Button, Dialog, DialogTitle, DialogDescription, Input, Tabs, TabsContent, TabsList, TabsTrigger, toast, } from "@flowselections/core";
6
6
  import { ChevronDown, ChevronRight, MoveRight, Truck } from "lucide-react";
7
+ import { ResponsiveDialogBody, ResponsiveDialogContent, ResponsiveDialogFooter, ResponsiveDialogHeader, } from "../../components/ui/responsive-dialog";
7
8
  import { isSameDay } from "../../lib/pickDate";
8
9
  import { getOrderLines, moveCart as moveCartFn, } from "../../lib/cartAssignments.functions";
9
10
  import { evaluateCartMove } from "../../lib/cartMoveImpact";
@@ -50,7 +51,7 @@ export function DagDetailDialog({ open, date, planned, onOpenChange }) {
50
51
  runningIdx += a.cartCount;
51
52
  }
52
53
  }
53
- return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-5xl max-h-[90vh] overflow-y-auto", children: [_jsx(DialogHeader, { children: _jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }) }), _jsxs("div", { className: "flex flex-wrap gap-3 text-sm text-muted-foreground", children: [_jsxs("span", { children: [ordersOnDay.length, " bestellingen"] }), _jsx("span", { children: "\u00B7" }), _jsxs("span", { children: [cartRows.length, " karren"] })] }), _jsxs(Tabs, { defaultValue: "bestellingen", className: "mt-4", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows, currentDate: date }) })] })] }) }));
54
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(ResponsiveDialogContent, { size: "xl", children: [_jsxs(ResponsiveDialogHeader, { children: [_jsxs(DialogTitle, { children: ["Dagdetails \u2014 ", NL_DATE.format(date)] }), _jsxs(DialogDescription, { children: [ordersOnDay.length, " bestellingen \u00B7 ", cartRows.length, " karren"] })] }), _jsx(ResponsiveDialogBody, { children: _jsxs(Tabs, { defaultValue: "bestellingen", children: [_jsxs(TabsList, { children: [_jsxs(TabsTrigger, { value: "bestellingen", children: ["Bestellingen (", ordersOnDay.length, ")"] }), _jsxs(TabsTrigger, { value: "karren", children: ["Karren (", cartRows.length, ")"] })] }), _jsx(TabsContent, { value: "bestellingen", className: "mt-4", children: _jsx(BestellingenTab, { orders: ordersOnDay, date: date }) }), _jsx(TabsContent, { value: "karren", className: "mt-4", children: _jsx(KarrenTab, { carts: cartRows, currentDate: date }) })] }) }), _jsx(ResponsiveDialogFooter, { children: _jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Sluiten" }) })] }) }));
54
55
  }
55
56
  function BestellingenTab({ orders, date }) {
56
57
  if (orders.length === 0) {
@@ -81,14 +82,17 @@ function OrderLinesTable({ lines }) {
81
82
  if (lines.length === 0) {
82
83
  return _jsx("p", { className: "text-xs text-muted-foreground", children: "Geen orderregels gevonden." });
83
84
  }
84
- return (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Artikel" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { className: "text-right", children: "Fusten" }), _jsx(TableHead, { className: "text-right", children: "Overig" })] }) }), _jsx(TableBody, { children: lines.map((l) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: l.article }), _jsx(TableCell, { className: "text-right", children: l.plants }), _jsx(TableCell, { className: "text-right", children: l.crates ?? "—" }), _jsx(TableCell, { className: "text-right", children: l.otherUnits ?? "—" })] }, l.id))) })] }));
85
+ return (_jsx("div", { className: "grid gap-2", children: lines.map((l) => (_jsxs("div", { className: "grid gap-2 rounded-md border p-2 text-sm md:grid-cols-[minmax(0,1fr)_auto_auto_auto] md:items-center", children: [_jsx("div", { className: "min-w-0 truncate font-medium", title: l.article, children: l.article }), _jsx(Metric, { label: "Planten", value: l.plants }), _jsx(Metric, { label: "Fusten", value: l.crates ?? "—" }), _jsx(Metric, { label: "Overig", value: l.otherUnits ?? "—" })] }, l.id))) }));
85
86
  }
86
87
  function KarrenTab({ carts, currentDate }) {
87
88
  const [moveCartRow, setMoveCartRow] = useState(null);
88
89
  if (carts.length === 0) {
89
90
  return _jsx("p", { className: "text-sm text-muted-foreground", children: "Geen karren ingepland op deze dag." });
90
91
  }
91
- return (_jsxs(_Fragment, { children: [_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: "Karnummer" }), _jsx(TableHead, { children: "Klant" }), _jsx(TableHead, { children: "Bestelling" }), _jsx(TableHead, { children: "Tuin" }), _jsx(TableHead, { children: "Vervoerder" }), _jsx(TableHead, { className: "text-right", children: "Bezetting" }), _jsx(TableHead, { className: "text-right", children: "Lagen" }), _jsx(TableHead, { className: "text-right", children: "Planten" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "text-right", children: "Actie" })] }) }), _jsx(TableBody, { children: carts.map((c) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: "font-medium", children: c.cartNumber }), _jsx(TableCell, { children: c.order.order.customerName }), _jsx(TableCell, { children: c.order.order.orderNumber }), _jsx(TableCell, { children: "\u2014" }), _jsx(TableCell, { children: "\u2014" }), _jsxs(TableCell, { className: "text-right", children: [c.occupancy, "%"] }), _jsx(TableCell, { className: "text-right", children: c.layers }), _jsx(TableCell, { className: "text-right", children: c.plants }), _jsx(TableCell, { children: _jsx(Badge, { variant: "secondary", children: "Nog te picken" }) }), _jsx(TableCell, { className: "text-right", children: _jsxs(Button, { size: "sm", variant: "outline", onClick: () => setMoveCartRow(c), children: [_jsx(MoveRight, { className: "mr-1 h-3.5 w-3.5" }), " Verplaatsen"] }) })] }, c.key))) })] }), _jsx(VerplaatsKarDialog, { cart: moveCartRow, currentDate: currentDate, onClose: () => setMoveCartRow(null) })] }));
92
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "grid gap-3", children: carts.map((c) => (_jsx("div", { className: "rounded-md border p-3", children: _jsxs("div", { className: "grid gap-3 lg:grid-cols-[1fr_1.4fr_1fr_auto_auto] lg:items-center", children: [_jsx(Field, { label: "Karnummer", value: c.cartNumber }), _jsx(Field, { label: "Klant", value: c.order.order.customerName }), _jsx(Field, { label: "Bestelling", value: c.order.order.orderNumber }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Badge, { variant: "secondary", children: "Nog te picken" }), _jsxs(Badge, { variant: "outline", children: [c.occupancy, "%"] }), _jsxs(Badge, { variant: "outline", children: [c.layers, " lagen"] }), _jsxs(Badge, { variant: "outline", children: [c.plants, " planten"] })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: () => setMoveCartRow(c), children: [_jsx(MoveRight, { className: "mr-1 h-3.5 w-3.5" }), " Verplaatsen"] })] }) }, c.key))) }), _jsx(VerplaatsKarDialog, { cart: moveCartRow, currentDate: currentDate, onClose: () => setMoveCartRow(null) })] }));
93
+ }
94
+ function Metric({ label, value }) {
95
+ return (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2 md:block md:text-right", children: [_jsx("span", { className: "text-xs text-muted-foreground md:block", children: label }), _jsx("span", { className: "font-medium", children: value })] }));
92
96
  }
93
97
  function VerplaatsKarDialog({ cart, currentDate, onClose, }) {
94
98
  const [newDate, setNewDate] = useState("");
@@ -141,5 +145,5 @@ function VerplaatsKarDialog({ cart, currentDate, onClose, }) {
141
145
  return null;
142
146
  const parsed = newDate ? new Date(newDate) : null;
143
147
  const impact = parsed ? evaluateCartMove(parsed, currentDate, cart.order.planning) : null;
144
- return (_jsx(Dialog, { open: !!cart, onOpenChange: (o) => !o && onClose(), children: _jsxs(DialogContent, { className: "max-w-md", children: [_jsx(DialogHeader, { children: _jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(Truck, { className: "h-4 w-4" }), " Kar verplaatsen"] }) }), _jsxs("div", { className: "space-y-3 text-sm", children: [_jsxs("div", { className: "rounded-md border bg-muted/40 p-3", children: [_jsx("div", { className: "font-medium", children: cart.cartNumber }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [cart.order.order.customerName, " \u00B7 ", cart.order.order.orderNumber] })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Nieuwe pickdatum" }), _jsx(Input, { type: "date", value: newDate, onChange: (e) => setNewDate(e.target.value) })] }), impact && (_jsxs("div", { className: "space-y-1", children: [impact.blockers.map((b, i) => (_jsxs("p", { className: "text-xs text-destructive", children: ["\u26A0 ", b] }, `b${i}`))), impact.warnings.map((w, i) => (_jsxs("p", { className: "text-xs text-amber-600", children: ["! ", w] }, `w${i}`))), impact.ok && impact.warnings.length === 0 && (_jsx("p", { className: "text-xs text-green-600", children: "\u2713 Verplaatsing is logistiek haalbaar." }))] })), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "ghost", onClick: onClose, children: "Annuleren" }), _jsx(Button, { onClick: () => mutation.mutate(), disabled: !newDate || (impact ? !impact.ok : false) || mutation.isPending, children: mutation.isPending ? "Bezig…" : "Bevestig verplaatsing" })] })] })] }) }));
148
+ return (_jsx(Dialog, { open: !!cart, onOpenChange: (o) => !o && onClose(), children: _jsxs(ResponsiveDialogContent, { size: "sm", children: [_jsx(ResponsiveDialogHeader, { children: _jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(Truck, { className: "h-4 w-4" }), " Kar verplaatsen"] }) }), _jsxs(ResponsiveDialogBody, { className: "space-y-3 text-sm", children: [_jsxs("div", { className: "rounded-md border bg-muted/40 p-3", children: [_jsx("div", { className: "font-medium", children: cart.cartNumber }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [cart.order.order.customerName, " \u00B7 ", cart.order.order.orderNumber] })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs text-muted-foreground", children: "Nieuwe pickdatum" }), _jsx(Input, { type: "date", value: newDate, onChange: (e) => setNewDate(e.target.value) })] }), impact && (_jsxs("div", { className: "space-y-1", children: [impact.blockers.map((b, i) => (_jsxs("p", { className: "text-xs text-destructive", children: ["\u26A0 ", b] }, `b${i}`))), impact.warnings.map((w, i) => (_jsxs("p", { className: "text-xs text-amber-600", children: ["! ", w] }, `w${i}`))), impact.ok && impact.warnings.length === 0 && (_jsx("p", { className: "text-xs text-green-600", children: "\u2713 Verplaatsing is logistiek haalbaar." }))] }))] }), _jsxs(ResponsiveDialogFooter, { children: [_jsx(Button, { variant: "ghost", onClick: onClose, children: "Annuleren" }), _jsx(Button, { onClick: () => mutation.mutate(), disabled: !newDate || (impact ? !impact.ok : false) || mutation.isPending, children: mutation.isPending ? "Bezig…" : "Bevestig verplaatsing" })] })] }) }));
145
149
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VervoerderForm.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerderForm.tsx"],"names":[],"mappings":"AA8CA,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAyPD,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,+BA4XlD"}
1
+ {"version":3,"file":"VervoerderForm.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerderForm.tsx"],"names":[],"mappings":"AA+CA,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA2PD,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,+BAyalD"}
@@ -9,6 +9,7 @@ import { getCarrier, upsertCarrier, } from "../../lib/carriers.functions";
9
9
  import { DEFAULT_PICKUP_MOMENT } from "../../lib/planning";
10
10
  import { COUNTRIES, countryName } from "../../lib/countries";
11
11
  import { ServiceAreaSelect } from "./ServiceAreaSelect";
12
+ import { WeekdayPicker } from "./WeekdayPicker";
12
13
  const EMPTY = {
13
14
  name: "",
14
15
  contact_person: "",
@@ -21,6 +22,8 @@ const EMPTY = {
21
22
  service_countries: [],
22
23
  service_provinces: [],
23
24
  service_cities: [],
25
+ pickup_weekdays: [1, 2, 3, 4, 5],
26
+ delivery_weekdays: [1, 2, 3, 4, 5],
24
27
  };
25
28
  function FieldIcon({ icon: Icon }) {
26
29
  return (_jsx("div", { className: "flex items-center justify-center w-10 h-10 rounded-md bg-primary/10 text-primary shrink-0", children: _jsx(Icon, { className: "w-4 h-4" }) }));
@@ -111,6 +114,12 @@ export function VervoerderForm({ carrierId }) {
111
114
  service_countries: c.service_countries ?? [],
112
115
  service_provinces: c.service_provinces ?? [],
113
116
  service_cities: c.service_cities ?? [],
117
+ pickup_weekdays: Array.isArray(c.pickup_weekdays) && c.pickup_weekdays.length > 0
118
+ ? c.pickup_weekdays
119
+ : [1, 2, 3, 4, 5],
120
+ delivery_weekdays: Array.isArray(c.delivery_weekdays) && c.delivery_weekdays.length > 0
121
+ ? c.delivery_weekdays
122
+ : [1, 2, 3, 4, 5],
114
123
  });
115
124
  setRates(c.rates);
116
125
  }
@@ -181,7 +190,7 @@ export function VervoerderForm({ carrierId }) {
181
190
  } }, idx))) }), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setForm({
182
191
  ...form,
183
192
  pickup_moments: [...form.pickup_moments, { ...DEFAULT_PICKUP_MOMENT }],
184
- }), children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Ophaalmoment toevoegen"] })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { type: "checkbox", checked: form.is_default ?? false, onChange: (e) => setForm({ ...form, is_default: e.target.checked }), className: "h-4 w-4 rounded border" }), _jsxs("span", { children: ["Gebruik als ", _jsx("strong", { children: "standaard vervoerder" }), " voor de automatische planning (voor orders zonder eigen vervoerder)."] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Opmerkingen" }), _jsxs("div", { className: "flex gap-2", children: [_jsx(FieldIcon, { icon: FileText }), _jsx(Textarea, { value: form.notes ?? "", onChange: (e) => setForm({ ...form, notes: e.target.value }), placeholder: "Extra informatie over deze vervoerder...", rows: 3, className: "flex-1" })] })] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: "Bedieningsgebied" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Selecteer de landen, provincies en/of plaatsen waar deze vervoerder actief is. Een land dekt automatisch al zijn provincies en plaatsen." })] }), _jsx(CardContent, { children: _jsx(ServiceAreaSelect, { value: {
193
+ }), children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Ophaalmoment toevoegen"] })] }), _jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "w-4 h-4 text-primary" }), _jsx(Label, { className: "font-semibold", children: "Ophaaldagen" })] }), _jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Dagen waarop deze vervoerder karren bij ons komt ophalen." }), _jsx("div", { className: "mt-3", children: _jsx(WeekdayPicker, { value: form.pickup_weekdays ?? [1, 2, 3, 4, 5], onChange: (next) => setForm({ ...form, pickup_weekdays: next }), idPrefix: "carrier-pu-wd" }) })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Truck, { className: "w-4 h-4 text-primary" }), _jsx(Label, { className: "font-semibold", children: "Bezorgdagen" })] }), _jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Dagen waarop deze vervoerder bij de klant aflevert." }), _jsx("div", { className: "mt-3", children: _jsx(WeekdayPicker, { value: form.delivery_weekdays ?? [1, 2, 3, 4, 5], onChange: (next) => setForm({ ...form, delivery_weekdays: next }), idPrefix: "carrier-dl-wd" }) })] })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { type: "checkbox", checked: form.is_default ?? false, onChange: (e) => setForm({ ...form, is_default: e.target.checked }), className: "h-4 w-4 rounded border" }), _jsxs("span", { children: ["Gebruik als ", _jsx("strong", { children: "standaard vervoerder" }), " voor de automatische planning (voor orders zonder eigen vervoerder)."] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { children: "Opmerkingen" }), _jsxs("div", { className: "flex gap-2", children: [_jsx(FieldIcon, { icon: FileText }), _jsx(Textarea, { value: form.notes ?? "", onChange: (e) => setForm({ ...form, notes: e.target.value }), placeholder: "Extra informatie over deze vervoerder...", rows: 3, className: "flex-1" })] })] })] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { className: "text-base", children: "Bedieningsgebied" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Selecteer de landen, provincies en/of plaatsen waar deze vervoerder actief is. Een land dekt automatisch al zijn provincies en plaatsen." })] }), _jsx(CardContent, { children: _jsx(ServiceAreaSelect, { value: {
185
194
  countries: form.service_countries ?? [],
186
195
  provinces: form.service_provinces ?? [],
187
196
  cities: form.service_cities ?? [],
@@ -1 +1 @@
1
- {"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"AAyBA,wBAAgB,eAAe,gCA6L9B"}
1
+ {"version":3,"file":"VervoerdersPage.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/VervoerdersPage.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,gCA+L9B"}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
- import { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, toast, } from "@flowselections/core";
3
+ import { Button, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogDescription, AlertDialogTitle, toast, } from "@flowselections/core";
4
4
  import { Plus, Pencil, Trash2, Truck, ArrowUp, ArrowDown } from "lucide-react";
5
+ import { ResponsiveAlertDialogBody, ResponsiveAlertDialogContent, ResponsiveAlertDialogFooter, ResponsiveAlertDialogHeader, } from "../../components/ui/responsive-dialog";
5
6
  import { Link } from "@tanstack/react-router";
6
7
  import { useServerFn } from "@tanstack/react-start";
7
8
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
@@ -55,5 +56,5 @@ export function VervoerdersPage() {
55
56
  [ids[index], ids[target]] = [ids[target], ids[index]];
56
57
  reorderMutation.mutate(ids);
57
58
  };
58
- return (_jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Vervoerders" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Beheer vervoerders en hun verzendtarieven per land." })] }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] }), _jsx("div", { className: "border rounded-md bg-card", children: isLoading ? (_jsx("div", { className: "p-12 text-center text-muted-foreground", children: "Laden..." })) : error ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsxs("div", { className: "text-destructive", children: ["Fout bij laden: ", error.message] }), _jsx(Button, { variant: "outline", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : carriers.length === 0 ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsx(Truck, { className: "w-10 h-10 mx-auto text-muted-foreground" }), _jsx("div", { className: "font-medium", children: "Nog geen vervoerders" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Voeg een vervoerder toe om verzendtarieven in te stellen." }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-32", children: "Prioriteit" }), _jsx(TableHead, { children: "Bedrijfsnaam" }), _jsx(TableHead, { children: "Contactpersoon" }), _jsx(TableHead, { children: "E-mail" }), _jsx(TableHead, { children: "Telefoon" }), _jsx(TableHead, { children: "Levertijd" }), _jsx(TableHead, { children: "Landen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: carriers.map((c, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "w-6 text-sm font-medium tabular-nums text-muted-foreground", children: index + 1 }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, -1), disabled: index === 0 || reorderMutation.isPending, "aria-label": "Hoger", children: _jsx(ArrowUp, { className: "w-4 h-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, 1), disabled: index === carriers.length - 1 || reorderMutation.isPending, "aria-label": "Lager", children: _jsx(ArrowDown, { className: "w-4 h-4" }) })] }) }), _jsx(TableCell, { className: "font-medium", children: c.name }), _jsx(TableCell, { children: c.contact_person ?? "—" }), _jsx(TableCell, { children: c.email ?? "—" }), _jsx(TableCell, { children: c.phone ?? "—" }), _jsx(TableCell, { children: c.delivery_days != null ? `${c.delivery_days} dagen` : "—" }), _jsx(TableCell, { children: c.rate_count }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/afhandeling/vervoerders/$id/bewerken", params: { id: c.id }, children: _jsx(Pencil, { className: "w-4 h-4" }) }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setDeletingId(c.id), className: "text-destructive hover:text-destructive", children: _jsx(Trash2, { className: "w-4 h-4" }) })] }) })] }, c.id))) })] })) }), _jsx(AlertDialog, { open: !!deletingId, onOpenChange: (o) => !o && setDeletingId(null), children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: "Vervoerder verwijderen?" }), _jsx(AlertDialogDescription, { children: "Deze actie kan niet ongedaan gemaakt worden. Alle verzendtarieven worden ook verwijderd." })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: () => deletingId && deleteMutation.mutate(deletingId), className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", children: "Verwijderen" })] })] }) })] }));
59
+ return (_jsxs("div", { className: "p-6 space-y-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold", children: "Vervoerders" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Beheer vervoerders en hun verzendtarieven per land." })] }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] }), _jsx("div", { className: "border rounded-md bg-card", children: isLoading ? (_jsx("div", { className: "p-12 text-center text-muted-foreground", children: "Laden..." })) : error ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsxs("div", { className: "text-destructive", children: ["Fout bij laden: ", error.message] }), _jsx(Button, { variant: "outline", onClick: () => refetch(), children: "Opnieuw proberen" })] })) : carriers.length === 0 ? (_jsxs("div", { className: "p-12 text-center space-y-3", children: [_jsx(Truck, { className: "w-10 h-10 mx-auto text-muted-foreground" }), _jsx("div", { className: "font-medium", children: "Nog geen vervoerders" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "Voeg een vervoerder toe om verzendtarieven in te stellen." }), _jsx(Button, { asChild: true, children: _jsxs(Link, { to: "/afhandeling/vervoerders/nieuw", children: [_jsx(Plus, { className: "w-4 h-4 mr-1" }), "Vervoerder toevoegen"] }) })] })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "w-32", children: "Prioriteit" }), _jsx(TableHead, { children: "Bedrijfsnaam" }), _jsx(TableHead, { children: "Contactpersoon" }), _jsx(TableHead, { children: "E-mail" }), _jsx(TableHead, { children: "Telefoon" }), _jsx(TableHead, { children: "Levertijd" }), _jsx(TableHead, { children: "Landen" }), _jsx(TableHead, { className: "text-right", children: "Acties" })] }) }), _jsx(TableBody, { children: carriers.map((c, index) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "w-6 text-sm font-medium tabular-nums text-muted-foreground", children: index + 1 }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, -1), disabled: index === 0 || reorderMutation.isPending, "aria-label": "Hoger", children: _jsx(ArrowUp, { className: "w-4 h-4" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => move(index, 1), disabled: index === carriers.length - 1 || reorderMutation.isPending, "aria-label": "Lager", children: _jsx(ArrowDown, { className: "w-4 h-4" }) })] }) }), _jsx(TableCell, { className: "font-medium", children: c.name }), _jsx(TableCell, { children: c.contact_person ?? "—" }), _jsx(TableCell, { children: c.email ?? "—" }), _jsx(TableCell, { children: c.phone ?? "—" }), _jsx(TableCell, { children: c.delivery_days != null ? `${c.delivery_days} dagen` : "—" }), _jsx(TableCell, { children: c.rate_count }), _jsx(TableCell, { className: "text-right", children: _jsxs("div", { className: "flex justify-end gap-1", children: [_jsx(Button, { asChild: true, variant: "ghost", size: "sm", children: _jsx(Link, { to: "/afhandeling/vervoerders/$id/bewerken", params: { id: c.id }, children: _jsx(Pencil, { className: "w-4 h-4" }) }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setDeletingId(c.id), className: "text-destructive hover:text-destructive", children: _jsx(Trash2, { className: "w-4 h-4" }) })] }) })] }, c.id))) })] })) }), _jsx(AlertDialog, { open: !!deletingId, onOpenChange: (o) => !o && setDeletingId(null), children: _jsxs(ResponsiveAlertDialogContent, { size: "sm", children: [_jsx(ResponsiveAlertDialogHeader, { children: _jsx(AlertDialogTitle, { children: "Vervoerder verwijderen?" }) }), _jsx(ResponsiveAlertDialogBody, { children: _jsx(AlertDialogDescription, { children: "Deze actie kan niet ongedaan gemaakt worden. Alle verzendtarieven worden ook verwijderd." }) }), _jsxs(ResponsiveAlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: "Annuleren" }), _jsx(AlertDialogAction, { onClick: () => deletingId && deleteMutation.mutate(deletingId), className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", children: "Verwijderen" })] })] }) })] }));
59
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,oBAAoB,GAAG,MAAM,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4DD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,GACN,EAAE,mBAAmB,+BAwHrB"}
1
+ {"version":3,"file":"WeekAgendaView.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekAgendaView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,oBAAoB,GAAG,MAAM,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8DD,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,GACN,EAAE,mBAAmB,+BA4HrB"}
@@ -69,6 +69,8 @@ export function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayCl
69
69
  plantCount: Math.round((p.order.plantCount ?? 0) * ratio),
70
70
  movedEarlier: a.date.getTime() !== p.planning.pickStartDate.getTime(),
71
71
  splitPart: total > 1 ? { index: idx + 1, total } : undefined,
72
+ reason: p.planning.reason,
73
+ carrierName: p.planning.carrierName,
72
74
  });
73
75
  });
74
76
  }
@@ -81,6 +83,8 @@ export function WeekAgendaView({ planned, mode, isLoading, onOrderClick, onDayCl
81
83
  cartCount: p.order.cartCount ?? 0,
82
84
  plantCount: p.order.plantCount ?? 0,
83
85
  movedEarlier: false,
86
+ reason: p.planning.reason,
87
+ carrierName: p.planning.carrierName,
84
88
  });
85
89
  }
86
90
  }
@@ -130,11 +134,17 @@ function DayRow({ day, onOrderClick, onDayClick }) {
130
134
  return (_jsxs("div", { className: `rounded-lg border bg-card ${isToday ? "ring-1 ring-primary" : ""}`, children: [_jsxs("div", { className: "flex flex-wrap items-center gap-6 px-4 py-4 sm:px-6", children: [_jsxs("div", { className: "w-20 shrink-0", children: [_jsx("div", { className: "text-xs font-medium tracking-wider text-muted-foreground", children: WEEKDAY_LABELS[weekdayIdx] }), _jsx("div", { className: "mt-1 text-3xl font-bold leading-none", children: day.date.getDate() }), _jsxs("div", { className: "text-sm text-muted-foreground", children: [MONTHS_NL_SHORT[day.date.getMonth()], "."] })] }), _jsxs("div", { className: "flex flex-1 flex-wrap items-center gap-6", children: [_jsx(Stat, { icon: _jsx(Package, { className: "h-4 w-4 text-slate-500" }), bg: "bg-slate-100", value: day.bestellingen, label: "bestellingen" }), _jsx(Stat, { icon: _jsx(Truck, { className: "h-4 w-4 text-amber-600" }), bg: "bg-amber-100", value: day.karren, label: "karren" }), _jsx(Stat, { icon: _jsx(Sprout, { className: "h-4 w-4 text-green-600" }), bg: "bg-green-100", value: day.planten, label: "planten" })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [day.movedEarlierOrderIds.size > 0 && (_jsxs(Badge, { className: "bg-purple-500/10 text-purple-700 hover:bg-purple-500/10", variant: "secondary", title: "Aantal orders dat vervroegd is ingepland door Pickverdeling.", children: [_jsx(Scale, { className: "mr-1 h-3.5 w-3.5" }), day.movedEarlierOrderIds.size, " vervroegd"] })), day.verzendklaar > 0 && (_jsxs(Badge, { className: "bg-green-500/15 text-green-700 hover:bg-green-500/15", variant: "secondary", children: [_jsx(CheckCircle2, { className: "mr-1 h-3.5 w-3.5" }), day.verzendklaar, " verzendklaar"] })), day.voorbereiding > 0 && (_jsxs(Badge, { className: "bg-blue-500/10 text-blue-700 hover:bg-blue-500/10", variant: "secondary", children: [_jsx(Clock, { className: "mr-1 h-3.5 w-3.5" }), day.voorbereiding, " in voorbereiding"] })), onDayClick && day.bestellingen > 0 && (_jsx(Button, { size: "sm", variant: "outline", onClick: () => onDayClick(day.date), children: "Dagdetails" }))] })] }), onOrderClick && day.entries.length > 0 && (_jsx("div", { className: "border-t px-4 py-2 sm:px-6", children: _jsx("div", { className: "flex flex-wrap gap-2", children: day.entries.map((e, idx) => {
131
135
  const moved = e.movedEarlier;
132
136
  const split = e.splitPart;
133
- return (_jsxs("button", { onClick: () => onOrderClick(e.order), title: split
134
- ? `Deel ${split.index}/${split.total} — ${e.cartCount} karren deze dag (verdeeld picken).`
135
- : moved
136
- ? "Deze order is eerder ingepland vanwege Pickverdeling."
137
- : undefined, className: `flex items-center gap-1 rounded border px-2 py-1 text-xs hover:bg-muted ${moved || split ? "border-purple-300 bg-purple-50" : ""}`, children: [(moved || split) && _jsx(Scale, { className: "h-3 w-3 text-purple-600" }), _jsx("span", { className: "font-medium", children: e.order.orderNumber }), _jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", e.order.customerName] }), _jsxs("span", { className: "ml-1 text-purple-700", children: ["\u00B7 ", e.cartCount, " karren", split ? ` (deel ${split.index}/${split.total})` : ""] })] }, `${e.order.id}-${idx}`));
137
+ return (_jsxs("button", { onClick: () => onOrderClick(e.order), title: [
138
+ split
139
+ ? `Deel ${split.index}/${split.total} — ${e.cartCount} karren deze dag (verdeeld picken).`
140
+ : moved
141
+ ? "Deze order is eerder ingepland vanwege Pickverdeling."
142
+ : null,
143
+ e.carrierName ? `Vervoerder: ${e.carrierName}` : null,
144
+ e.reason ? `Planning: ${e.reason}` : null,
145
+ ]
146
+ .filter(Boolean)
147
+ .join("\n") || undefined, className: `flex items-center gap-1 rounded border px-2 py-1 text-xs hover:bg-muted ${moved || split ? "border-purple-300 bg-purple-50" : ""}`, children: [(moved || split) && _jsx(Scale, { className: "h-3 w-3 text-purple-600" }), _jsx("span", { className: "font-medium", children: e.order.orderNumber }), _jsxs("span", { className: "ml-1 text-muted-foreground", children: ["\u00B7 ", e.order.customerName] }), _jsxs("span", { className: "ml-1 text-purple-700", children: ["\u00B7 ", e.cartCount, " karren", split ? ` (deel ${split.index}/${split.total})` : ""] })] }, `${e.order.id}-${idx}`));
138
148
  }) }) }))] }));
139
149
  }
140
150
  function Stat({ icon, bg, value, label, }) {
@@ -0,0 +1,12 @@
1
+ interface WeekdayPickerProps {
2
+ value: number[];
3
+ onChange: (next: number[]) => void;
4
+ disabled?: boolean;
5
+ idPrefix?: string;
6
+ }
7
+ /**
8
+ * Reusable weekday-picker. Waarden zijn ISO-dagnummers (1=maandag … 7=zondag).
9
+ */
10
+ export declare function WeekdayPicker({ value, onChange, disabled, idPrefix, }: WeekdayPickerProps): import("react").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=WeekdayPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeekdayPicker.d.ts","sourceRoot":"","sources":["../../../src/components/afhandeling/WeekdayPicker.tsx"],"names":[],"mappings":"AAYA,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAe,GAChB,EAAE,kBAAkB,+BAmCpB"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Checkbox, Label } from "@flowselections/core";
3
+ const DAYS = [
4
+ { iso: 1, label: "Maandag" },
5
+ { iso: 2, label: "Dinsdag" },
6
+ { iso: 3, label: "Woensdag" },
7
+ { iso: 4, label: "Donderdag" },
8
+ { iso: 5, label: "Vrijdag" },
9
+ { iso: 6, label: "Zaterdag" },
10
+ { iso: 7, label: "Zondag" },
11
+ ];
12
+ /**
13
+ * Reusable weekday-picker. Waarden zijn ISO-dagnummers (1=maandag … 7=zondag).
14
+ */
15
+ export function WeekdayPicker({ value, onChange, disabled, idPrefix = "wd", }) {
16
+ const set = new Set(value ?? []);
17
+ const toggle = (iso, checked) => {
18
+ const next = new Set(set);
19
+ if (checked)
20
+ next.add(iso);
21
+ else
22
+ next.delete(iso);
23
+ onChange(Array.from(next).sort((a, b) => a - b));
24
+ };
25
+ return (_jsx("div", { className: "grid grid-cols-2 gap-2 sm:grid-cols-4", children: DAYS.map((d) => {
26
+ const id = `${idPrefix}-${d.iso}`;
27
+ const checked = set.has(d.iso);
28
+ return (_jsxs("label", { htmlFor: id, className: "flex items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm cursor-pointer hover:bg-accent", children: [_jsx(Checkbox, { id: id, checked: checked, disabled: disabled, onCheckedChange: (v) => toggle(d.iso, v === true) }), _jsx(Label, { htmlFor: id, className: "cursor-pointer select-none", children: d.label })] }, d.iso));
29
+ }) }));
30
+ }
@@ -10,6 +10,7 @@ export declare function renderPakbonHtml(order: {
10
10
  cartIndex: number;
11
11
  cartTotal: number;
12
12
  cratesOnCart: number | null;
13
+ cartNumber: string | null;
13
14
  lines: {
14
15
  description: string;
15
16
  crates: number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"PakbonTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/pickstation/PakbonTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC;CAC9E,GAAG,MAAM,CAqET;AAWD,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"PakbonTemplate.d.ts","sourceRoot":"","sources":["../../../src/components/pickstation/PakbonTemplate.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC;CAC9E,GAAG,MAAM,CA4FT;AAWD,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -20,18 +20,39 @@ export function renderPakbonHtml(order) {
20
20
  : `<tr><td colspan="3" style="text-align:center;color:#666">Geen regels</td></tr>`;
21
21
  const cartLabel = `Kar ${order.cartIndex} / ${order.cartTotal}`;
22
22
  const fustenLabel = order.cratesOnCart != null ? `${order.cratesOnCart}` : "—";
23
+ const cartNumber = order.cartNumber ?? `${order.orderNumber}-${order.cartIndex}`;
23
24
  return `<!doctype html>
24
25
  <html lang="nl">
25
26
  <head>
26
27
  <meta charset="utf-8">
27
- <title>Pakbon ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartLabel)}</title>
28
+ <title>Pakbon ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartNumber)}</title>
28
29
  <style>
29
- @page { size: A4; margin: 16mm; }
30
+ @page {
31
+ size: A4;
32
+ margin: 16mm;
33
+ @top-center { content: element(cartno); }
34
+ }
30
35
  body { font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; color:#111; }
31
36
  h1 { margin: 0 0 4px; font-size: 26px; }
32
- .sub { color:#444; margin-bottom: 18px; }
33
- .cart-badge { display:inline-block; margin-left:8px; padding:2px 10px; border-radius:999px; background:#111; color:#fff; font-size:14px; vertical-align:middle; }
34
- .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; margin: 18px 0 22px; }
37
+ .sub { color:#444; margin-bottom: 8px; }
38
+
39
+ /* Groot, vetgedrukt karnummer direct onder de titel — ook running header op elke pagina. */
40
+ .cart-number-hero {
41
+ position: running(cartno);
42
+ font-size: 88px;
43
+ font-weight: 900;
44
+ letter-spacing: 4px;
45
+ line-height: 1;
46
+ color: #000;
47
+ background: #fff;
48
+ border: 4px solid #000;
49
+ padding: 12px 20px;
50
+ display: inline-block;
51
+ margin: 6px 0 20px;
52
+ font-family: "Arial Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
53
+ }
54
+
55
+ .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; margin: 8px 0 22px; }
35
56
  .grid div { font-size: 14px; }
36
57
  .label { color:#666; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
37
58
  .value { font-size: 16px; font-weight: 600; }
@@ -43,8 +64,10 @@ export function renderPakbonHtml(order) {
43
64
  </style>
44
65
  </head>
45
66
  <body>
46
- <h1>Pakbon <span class="cart-badge">${escapeHtml(cartLabel)}</span></h1>
47
- <div class="sub">Order ${escapeHtml(order.orderNumber)}</div>
67
+ <h1>Pakbon</h1>
68
+ <div class="sub">Order ${escapeHtml(order.orderNumber)} · ${escapeHtml(cartLabel)}</div>
69
+
70
+ <div class="cart-number-hero">${escapeHtml(cartNumber)}</div>
48
71
 
49
72
  <div class="grid">
50
73
  <div><div class="label">Klant</div><div class="value">${escapeHtml(order.customerName)}</div></div>
@@ -60,7 +83,7 @@ export function renderPakbonHtml(order) {
60
83
  <tbody>${rows}</tbody>
61
84
  </table>
62
85
 
63
- <div class="barcode-fallback">*${escapeHtml(order.orderNumber)}-${order.cartIndex}*</div>
86
+ <div class="barcode-fallback">*${escapeHtml(order.orderNumber)}*</div>
64
87
 
65
88
  <div class="footer">Geprint via Pickstation · ${new Date().toLocaleString("nl-NL")}</div>
66
89
  </body>
@@ -1 +1 @@
1
- {"version":3,"file":"AfhandelingSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/components/settings/AfhandelingSettingsCard.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,uBAAuB,gCAoMtC"}
1
+ {"version":3,"file":"AfhandelingSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/components/settings/AfhandelingSettingsCard.tsx"],"names":[],"mappings":"AAsBA,wBAAgB,uBAAuB,gCAmOtC"}
@@ -3,8 +3,9 @@ import { useEffect, useState } from "react";
3
3
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
4
  import { useServerFn } from "@tanstack/react-start";
5
5
  import { Card, CardContent, CardDescription, CardHeader, CardTitle, Button, Input, Label, Switch, toast, } from "@flowselections/core";
6
- import { CalendarClock, Mail, Scale } from "lucide-react";
6
+ import { CalendarClock, CalendarDays, Mail, Scale } from "lucide-react";
7
7
  import { getAfhandelingSettings, updateAfhandelingSettings, } from "../../lib/afhandelingSettings.functions";
8
+ import { WeekdayPicker } from "../afhandeling/WeekdayPicker";
8
9
  export function AfhandelingSettingsCard() {
9
10
  const qc = useQueryClient();
10
11
  const fetchSettings = useServerFn(getAfhandelingSettings);
@@ -24,6 +25,7 @@ export function AfhandelingSettingsCard() {
24
25
  signupMailEnabled: false,
25
26
  signupMailLeadMinutes: 60,
26
27
  signupMailPurpose: "afhandeling_carrier_signup",
28
+ pickWeekdays: [1, 2, 3, 4, 5],
27
29
  };
28
30
  }
29
31
  },
@@ -35,6 +37,7 @@ export function AfhandelingSettingsCard() {
35
37
  const [mailEnabled, setMailEnabled] = useState(false);
36
38
  const [mailLead, setMailLead] = useState(60);
37
39
  const [mailPurpose, setMailPurpose] = useState("afhandeling_carrier_signup");
40
+ const [pickWeekdays, setPickWeekdays] = useState([1, 2, 3, 4, 5]);
38
41
  useEffect(() => {
39
42
  if (data) {
40
43
  setPickDays(data.pickDaysBeforeTransport);
@@ -44,6 +47,9 @@ export function AfhandelingSettingsCard() {
44
47
  setMailEnabled(Boolean(data.signupMailEnabled));
45
48
  setMailLead(data.signupMailLeadMinutes ?? 60);
46
49
  setMailPurpose(data.signupMailPurpose ?? "afhandeling_carrier_signup");
50
+ setPickWeekdays(Array.isArray(data.pickWeekdays) && data.pickWeekdays.length > 0
51
+ ? data.pickWeekdays
52
+ : [1, 2, 3, 4, 5]);
47
53
  }
48
54
  }, [data]);
49
55
  const mutation = useMutation({
@@ -56,6 +62,7 @@ export function AfhandelingSettingsCard() {
56
62
  signupMailEnabled: mailEnabled,
57
63
  signupMailLeadMinutes: mailLead,
58
64
  signupMailPurpose: mailPurpose,
65
+ pickWeekdays,
59
66
  },
60
67
  }),
61
68
  onSuccess: async () => {
@@ -68,5 +75,5 @@ export function AfhandelingSettingsCard() {
68
75
  },
69
76
  });
70
77
  const clamp = (n) => Math.max(0, Math.min(30, Math.floor(n) || 0));
71
- return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CalendarClock, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { children: "Afhandeling \u2014 Planning" })] }), _jsx(CardDescription, { children: "Centrale werkdag-instellingen voor de automatische order\u00ADplanning. Alle berekeningen tellen alleen werkdagen (ma\u2013vr)." })] }), _jsxs(CardContent, { className: "space-y-5", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "pickDays", children: "Aantal pickdagen (werkdagen v\u00F3\u00F3r ophaaldag)" }), _jsx(Input, { id: "pickDays", type: "number", min: 0, max: 30, value: pickDays, onChange: (e) => setPickDays(clamp(Number(e.target.value))) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Wordt vanaf de berekende ophaaldag teruggeteld om de uiterste pickdatum te bepalen." })] }), _jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Scale, { className: "h-4 w-4 text-primary" }), _jsx(Label, { htmlFor: "pickDistribution", className: "font-semibold", children: "Pickverdeling" })] }), _jsx("p", { className: "text-xs text-muted-foreground max-w-prose", children: "Verdeelt de pickbelasting automatisch over werkdagen. Orders mogen eerder ingepland worden, maar nooit later dan de berekende uiterste pickdatum \u2014 leverbetrouwbaarheid blijft gegarandeerd." })] }), _jsx(Switch, { id: "pickDistribution", checked: distributionEnabled, onCheckedChange: setDistributionEnabled })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "maxEarlier", children: "Maximaal aantal werkdagen eerder picken" }), _jsx(Input, { id: "maxEarlier", type: "number", min: 0, max: 30, value: maxEarlier, disabled: !distributionEnabled, onChange: (e) => setMaxEarlier(clamp(Number(e.target.value))) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "0 = geen vervroeging. Bijv. 2 = orders mogen maximaal 2 werkdagen voor hun uiterste pickdatum ingepland worden." })] })] }), _jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Mail, { className: "h-4 w-4 text-primary" }), _jsx(Label, { htmlFor: "mailEnabled", className: "font-semibold", children: "Aanmeldmail vervoerders" })] }), _jsx("p", { className: "text-xs text-muted-foreground max-w-prose", children: "Verstuurt automatisch een mail met de te verwachten karren naar de vervoerder v\u00F3\u00F3r de aanmelddeadline van het ophaalmoment. E\u00E9n mail per ophaaldag/-moment per vervoerder." })] }), _jsx(Switch, { id: "mailEnabled", checked: mailEnabled, onCheckedChange: setMailEnabled })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "mailLead", children: "Minuten v\u00F3\u00F3r aanmelddeadline versturen" }), _jsx(Input, { id: "mailLead", type: "number", min: 0, max: 1440, value: mailLead, disabled: !mailEnabled, onChange: (e) => setMailLead(Math.max(0, Math.min(1440, Math.floor(Number(e.target.value)) || 0))) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "mailPurpose", children: "E-mail-doeleinde (purpose)" }), _jsx(Input, { id: "mailPurpose", value: mailPurpose, disabled: !mailEnabled, onChange: (e) => setMailPurpose(e.target.value) }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Koppel dit doeleinde in de module ", _jsx("strong", { children: "E-mailkoppeling" }), " aan een actief send-adres. Standaard: ", _jsx("code", { children: "afhandeling_carrier_signup" }), "."] })] })] }), _jsxs("div", { className: "rounded-md bg-muted/50 p-3 text-xs text-muted-foreground", children: [_jsx("strong", { children: "Ophaaltijd" }), " en ", _jsx("strong", { children: "Aanmeldtijd" }), " stel je per vervoerder in (werkdagen v\u00F3\u00F3r bezorgdag). De vervoerder die als ", _jsx("strong", { children: "standaard" }), " is gemarkeerd, wordt gebruikt voor orders zonder eigen vervoerder."] }), _jsx(Button, { onClick: () => mutation.mutate(), disabled: mutation.isPending, children: mutation.isPending ? "Opslaan…" : "Opslaan" })] })] }));
78
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CalendarClock, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { children: "Afhandeling \u2014 Planning" })] }), _jsx(CardDescription, { children: "Centrale werkdag-instellingen voor de automatische order\u00ADplanning. Alle berekeningen tellen alleen werkdagen (ma\u2013vr)." })] }), _jsxs(CardContent, { className: "space-y-5", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "pickDays", children: "Aantal pickdagen (werkdagen v\u00F3\u00F3r ophaaldag)" }), _jsx(Input, { id: "pickDays", type: "number", min: 0, max: 30, value: pickDays, onChange: (e) => setPickDays(clamp(Number(e.target.value))) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Wordt vanaf de berekende ophaaldag teruggeteld om de uiterste pickdatum te bepalen." })] }), _jsxs("div", { className: "rounded-md border p-4 space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CalendarDays, { className: "h-4 w-4 text-primary" }), _jsx(Label, { className: "font-semibold", children: "Orderpickdagen" })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Selecteer de dagen waarop het systeem orders mag inplannen om te picken. Andere dagen worden automatisch overgeslagen." }), _jsx(WeekdayPicker, { value: pickWeekdays, onChange: setPickWeekdays, idPrefix: "pick-wd" }), pickWeekdays.length === 0 ? (_jsx("p", { className: "text-xs text-destructive", children: "Kies minimaal \u00E9\u00E9n pickdag; anders kan het systeem geen orders inplannen." })) : null] }), _jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Scale, { className: "h-4 w-4 text-primary" }), _jsx(Label, { htmlFor: "pickDistribution", className: "font-semibold", children: "Pickverdeling" })] }), _jsx("p", { className: "text-xs text-muted-foreground max-w-prose", children: "Verdeelt de pickbelasting automatisch over werkdagen. Orders mogen eerder ingepland worden, maar nooit later dan de berekende uiterste pickdatum \u2014 leverbetrouwbaarheid blijft gegarandeerd." })] }), _jsx(Switch, { id: "pickDistribution", checked: distributionEnabled, onCheckedChange: setDistributionEnabled })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "maxEarlier", children: "Maximaal aantal werkdagen eerder picken" }), _jsx(Input, { id: "maxEarlier", type: "number", min: 0, max: 30, value: maxEarlier, disabled: !distributionEnabled, onChange: (e) => setMaxEarlier(clamp(Number(e.target.value))) }), _jsx("p", { className: "text-xs text-muted-foreground", children: "0 = geen vervroeging. Bijv. 2 = orders mogen maximaal 2 werkdagen voor hun uiterste pickdatum ingepland worden." })] })] }), _jsxs("div", { className: "rounded-md border p-4 space-y-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Mail, { className: "h-4 w-4 text-primary" }), _jsx(Label, { htmlFor: "mailEnabled", className: "font-semibold", children: "Aanmeldmail vervoerders" })] }), _jsx("p", { className: "text-xs text-muted-foreground max-w-prose", children: "Verstuurt automatisch een mail met de te verwachten karren naar de vervoerder v\u00F3\u00F3r de aanmelddeadline van het ophaalmoment. E\u00E9n mail per ophaaldag/-moment per vervoerder." })] }), _jsx(Switch, { id: "mailEnabled", checked: mailEnabled, onCheckedChange: setMailEnabled })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "mailLead", children: "Minuten v\u00F3\u00F3r aanmelddeadline versturen" }), _jsx(Input, { id: "mailLead", type: "number", min: 0, max: 1440, value: mailLead, disabled: !mailEnabled, onChange: (e) => setMailLead(Math.max(0, Math.min(1440, Math.floor(Number(e.target.value)) || 0))) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "mailPurpose", children: "E-mail-doeleinde (purpose)" }), _jsx(Input, { id: "mailPurpose", value: mailPurpose, disabled: !mailEnabled, onChange: (e) => setMailPurpose(e.target.value) }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["Koppel dit doeleinde in de module ", _jsx("strong", { children: "E-mailkoppeling" }), " aan een actief send-adres. Standaard: ", _jsx("code", { children: "afhandeling_carrier_signup" }), "."] })] })] }), _jsxs("div", { className: "rounded-md bg-muted/50 p-3 text-xs text-muted-foreground", children: [_jsx("strong", { children: "Ophaaltijd" }), " en ", _jsx("strong", { children: "Aanmeldtijd" }), " stel je per vervoerder in (werkdagen v\u00F3\u00F3r bezorgdag). De vervoerder die als ", _jsx("strong", { children: "standaard" }), " is gemarkeerd, wordt gebruikt voor orders zonder eigen vervoerder."] }), _jsx(Button, { onClick: () => mutation.mutate(), disabled: mutation.isPending, children: mutation.isPending ? "Opslaan…" : "Opslaan" })] })] }));
72
79
  }
@@ -0,0 +1,20 @@
1
+ import type { ComponentProps, HTMLAttributes } from "react";
2
+ import { AlertDialogContent, AlertDialogFooter, AlertDialogHeader, DialogContent, DialogFooter, DialogHeader } from "@flowselections/core";
3
+ type DialogSize = "sm" | "md" | "lg" | "xl";
4
+ type DialogRows = "default" | "with-alert";
5
+ export declare function ResponsiveDialogContent({ className, style, size, rows, ...props }: ComponentProps<typeof DialogContent> & {
6
+ size?: DialogSize;
7
+ rows?: DialogRows;
8
+ }): import("react").JSX.Element;
9
+ export declare function ResponsiveDialogHeader({ className, ...props }: ComponentProps<typeof DialogHeader>): import("react").JSX.Element;
10
+ export declare function ResponsiveDialogBody({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
11
+ export declare function ResponsiveDialogFooter({ className, ...props }: ComponentProps<typeof DialogFooter>): import("react").JSX.Element;
12
+ export declare function ResponsiveAlertDialogContent({ className, style, size, rows, ...props }: ComponentProps<typeof AlertDialogContent> & {
13
+ size?: DialogSize;
14
+ rows?: DialogRows;
15
+ }): import("react").JSX.Element;
16
+ export declare function ResponsiveAlertDialogHeader({ className, ...props }: ComponentProps<typeof AlertDialogHeader>): import("react").JSX.Element;
17
+ export declare function ResponsiveAlertDialogBody({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
18
+ export declare function ResponsiveAlertDialogFooter({ className, ...props }: ComponentProps<typeof AlertDialogFooter>): import("react").JSX.Element;
19
+ export {};
20
+ //# sourceMappingURL=responsive-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive-dialog.d.ts","sourceRoot":"","sources":["../../../src/components/ui/responsive-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,cAAc,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,sBAAsB,CAAC;AAG9B,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,KAAK,UAAU,GAAG,SAAS,GAAG,YAAY,CAAC;AAsB3C,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,KAAK,EACL,IAAW,EACX,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,GAAG;IACxC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,+BAYA;AAED,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,+BAErC;AAED,wBAAgB,oBAAoB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,+BAE3F;AAED,wBAAgB,sBAAsB,CAAC,EACrC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,+BAUrC;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,IAAW,EACX,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,kBAAkB,CAAC,GAAG;IAC7C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,+BAYA;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,iBAAiB,CAAC,+BAE1C;AAED,wBAAgB,yBAAyB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,+BAEhG;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,iBAAiB,CAAC,+BAU1C"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AlertDialogContent, AlertDialogFooter, AlertDialogHeader, DialogContent, DialogFooter, DialogHeader, } from "@flowselections/core";
3
+ import { cn } from "../../lib/utils";
4
+ const WIDTH_BY_SIZE = {
5
+ sm: "min(40rem, calc(100vw - 2rem))",
6
+ md: "min(48rem, calc(100vw - 2rem))",
7
+ lg: "min(64rem, calc(100vw - 2rem))",
8
+ xl: "min(72rem, calc(100vw - 2rem))",
9
+ };
10
+ const ROWS_BY_TYPE = {
11
+ default: "grid-rows-[auto_minmax(0,1fr)_auto]",
12
+ "with-alert": "grid-rows-[auto_auto_minmax(0,1fr)_auto]",
13
+ };
14
+ function mergedStyle(size, style) {
15
+ return {
16
+ width: WIDTH_BY_SIZE[size],
17
+ maxWidth: "calc(100vw - 2rem)",
18
+ ...style,
19
+ };
20
+ }
21
+ export function ResponsiveDialogContent({ className, style, size = "lg", rows = "default", ...props }) {
22
+ return (_jsx(DialogContent, { className: cn("grid max-h-[calc(100vh-2rem)] gap-0 overflow-hidden p-0", ROWS_BY_TYPE[rows], className), style: mergedStyle(size, style), ...props }));
23
+ }
24
+ export function ResponsiveDialogHeader({ className, ...props }) {
25
+ return _jsx(DialogHeader, { className: cn("border-b px-6 py-5 pr-12", className), ...props });
26
+ }
27
+ export function ResponsiveDialogBody({ className, ...props }) {
28
+ return _jsx("div", { className: cn("min-h-0 overflow-y-auto px-6 py-4", className), ...props });
29
+ }
30
+ export function ResponsiveDialogFooter({ className, ...props }) {
31
+ return (_jsx(DialogFooter, { className: cn("border-t bg-background px-6 py-4 flex w-full min-w-0 flex-col gap-2 sm:flex-row sm:flex-wrap sm:justify-end [&>*]:w-full sm:[&>*]:w-auto", className), ...props }));
32
+ }
33
+ export function ResponsiveAlertDialogContent({ className, style, size = "md", rows = "default", ...props }) {
34
+ return (_jsx(AlertDialogContent, { className: cn("grid max-h-[calc(100vh-2rem)] gap-0 overflow-hidden p-0", ROWS_BY_TYPE[rows], className), style: mergedStyle(size, style), ...props }));
35
+ }
36
+ export function ResponsiveAlertDialogHeader({ className, ...props }) {
37
+ return _jsx(AlertDialogHeader, { className: cn("border-b px-6 py-5 pr-12", className), ...props });
38
+ }
39
+ export function ResponsiveAlertDialogBody({ className, ...props }) {
40
+ return _jsx("div", { className: cn("min-h-0 overflow-y-auto px-6 py-4", className), ...props });
41
+ }
42
+ export function ResponsiveAlertDialogFooter({ className, ...props }) {
43
+ return (_jsx(AlertDialogFooter, { className: cn("border-t bg-background px-6 py-4 flex w-full min-w-0 flex-col gap-2 sm:flex-row sm:flex-wrap sm:justify-end [&>*]:w-full sm:[&>*]:w-auto", className), ...props }));
44
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useOrderPlanning.d.ts","sourceRoot":"","sources":["../../src/hooks/useOrderPlanning.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI/D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,IAAI,sBAAsB,CAuHzD"}
1
+ {"version":3,"file":"useOrderPlanning.d.ts","sourceRoot":"","sources":["../../src/hooks/useOrderPlanning.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAI/D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,gBAAgB,IAAI,sBAAsB,CAoIzD"}
@@ -52,7 +52,7 @@ export function useOrderPlanning() {
52
52
  return await fetchSettings();
53
53
  }
54
54
  catch {
55
- return { pickDaysBeforeTransport: 1, transportRegisterDaysBefore: 1, pickDistributionEnabled: false, maxWorkdaysEarlierPick: 2 };
55
+ return { pickDaysBeforeTransport: 1, transportRegisterDaysBefore: 1, pickDistributionEnabled: false, maxWorkdaysEarlierPick: 2, signupMailEnabled: false, signupMailLeadMinutes: 60, signupMailPurpose: "afhandeling_carrier_signup", pickWeekdays: [1, 2, 3, 4, 5] };
56
56
  }
57
57
  },
58
58
  });
@@ -87,6 +87,7 @@ export function useOrderPlanning() {
87
87
  transportRegisterDaysBefore: 1,
88
88
  pickDistributionEnabled: false,
89
89
  maxWorkdaysEarlierPick: 2,
90
+ pickWeekdays: [1, 2, 3, 4, 5],
90
91
  };
91
92
  const carriers = carriersQuery.data?.carriers ?? [];
92
93
  const overrides = overridesQuery.data?.overrides ?? [];
@@ -94,6 +95,9 @@ export function useOrderPlanning() {
94
95
  const moments = defaultCarrier && defaultCarrier.pickup_moments.length > 0
95
96
  ? defaultCarrier.pickup_moments
96
97
  : [DEFAULT_PICKUP_MOMENT];
98
+ const carrierPickupWeekdays = defaultCarrier?.pickup_weekdays ?? [1, 2, 3, 4, 5];
99
+ const carrierDeliveryWeekdays = defaultCarrier?.delivery_weekdays ?? [1, 2, 3, 4, 5];
100
+ const pickWeekdays = settings.pickWeekdays ?? [1, 2, 3, 4, 5];
97
101
  const overrideMap = new Map();
98
102
  for (const o of overrides) {
99
103
  overrideMap.set(`${o.order_source}#${o.order_id}#${o.cart_index}`, {
@@ -101,17 +105,24 @@ export function useOrderPlanning() {
101
105
  movedFromDate: o.moved_from_date ? new Date(o.moved_from_date) : null,
102
106
  });
103
107
  }
104
- const initial = orders.map((order) => ({
105
- order,
106
- planning: calculateOrderPlanning(order.deliveryDate, {
108
+ const initial = orders.map((order) => {
109
+ const planning = calculateOrderPlanning(order.deliveryDate, {
107
110
  pickupMoments: moments,
108
111
  pickDurationWorkdays: settings.pickDaysBeforeTransport,
109
112
  orderCreatedAt: order.createdAt,
110
- }),
111
- }));
113
+ pickWeekdays,
114
+ carrierPickupWeekdays,
115
+ carrierDeliveryWeekdays,
116
+ });
117
+ if (planning && defaultCarrier) {
118
+ planning.carrierName = defaultCarrier.name;
119
+ }
120
+ return { order, planning };
121
+ });
112
122
  const distributed = distributePickDates(initial, {
113
123
  enabled: Boolean(settings.pickDistributionEnabled),
114
124
  maxWorkdaysEarlier: settings.maxWorkdaysEarlierPick ?? 0,
125
+ pickWeekdays,
115
126
  getCartCount: (it) => it.order.cartCount ?? 1,
116
127
  getCartOverride: (it, idx) => {
117
128
  const src = it.order.source;
@@ -6,6 +6,7 @@ export { NieuweLeveringPage } from "./components/afhandeling/NieuweLeveringPage"
6
6
  export { PickAgendaView } from "./components/afhandeling/PickAgendaView";
7
7
  export { PickingPage } from "./components/afhandeling/PickingPage";
8
8
  export { PlanningAgendaPage } from "./components/afhandeling/PlanningAgendaPage";
9
+ export { ControlePage } from "./components/afhandeling/ControlePage";
9
10
  export { AfhandelingSettingsCard } from "./components/settings/AfhandelingSettingsCard";
10
11
  export { VervoerdersSettingsCard } from "./components/settings/VervoerdersSettingsCard";
11
12
  export declare const floridayAfhandelingModule: FlowModule;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAKxF,eAAO,MAAM,yBAAyB,EAAE,UAiBvC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAKxF,eAAO,MAAM,yBAAyB,EAAE,UAkBvC,CAAC"}