@flowselections/floriday-verkoop-module 1.0.10 → 1.0.12

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 (37) hide show
  1. package/dist-lib/components/verkoop/AnalyticsCards.d.ts +1 -1
  2. package/dist-lib/components/verkoop/AnalyticsCards.d.ts.map +1 -1
  3. package/dist-lib/components/verkoop/AnalyticsCards.js +1 -7
  4. package/dist-lib/components/verkoop/CreateOrderPage.d.ts.map +1 -1
  5. package/dist-lib/components/verkoop/CreateOrderPage.js +217 -189
  6. package/dist-lib/components/verkoop/SalesOrderDetailView.d.ts.map +1 -1
  7. package/dist-lib/components/verkoop/SalesOrderDetailView.js +1 -1
  8. package/dist-lib/components/verkoop/SalesOrdersTable.d.ts.map +1 -1
  9. package/dist-lib/components/verkoop/SalesOrdersTable.js +19 -40
  10. package/dist-lib/components/verkoop/SearchableSelect.d.ts +19 -0
  11. package/dist-lib/components/verkoop/SearchableSelect.d.ts.map +1 -0
  12. package/dist-lib/components/verkoop/SearchableSelect.js +21 -0
  13. package/dist-lib/integrations/supabase/auth-middleware.d.ts +1486 -35
  14. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
  15. package/dist-lib/integrations/supabase/client.d.ts +1486 -35
  16. package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
  17. package/dist-lib/integrations/supabase/client.server.d.ts +1486 -35
  18. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
  19. package/dist-lib/integrations/supabase/types.d.ts +1515 -34
  20. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  21. package/dist-lib/lib/create-order.functions.d.ts +75223 -0
  22. package/dist-lib/lib/create-order.functions.d.ts.map +1 -0
  23. package/dist-lib/lib/create-order.functions.js +188 -0
  24. package/dist-lib/lib/floriday-public.functions.d.ts +10157 -0
  25. package/dist-lib/lib/floriday-public.functions.d.ts.map +1 -1
  26. package/dist-lib/lib/floriday-writes.functions.d.ts +7255 -0
  27. package/dist-lib/lib/floriday-writes.functions.d.ts.map +1 -1
  28. package/dist-lib/lib/salesorders-mapping.d.ts +4 -0
  29. package/dist-lib/lib/salesorders-mapping.d.ts.map +1 -1
  30. package/dist-lib/lib/salesorders-mapping.js +14 -3
  31. package/dist-lib/lib/salesorders.functions.d.ts +4614 -261
  32. package/dist-lib/lib/salesorders.functions.d.ts.map +1 -1
  33. package/dist-lib/lib/tradeitems.functions.d.ts +1486 -35
  34. package/dist-lib/lib/tradeitems.functions.d.ts.map +1 -1
  35. package/dist-lib/lib/useSalesOrdersQuery.d.ts.map +1 -1
  36. package/dist-lib/lib/useSalesOrdersQuery.js +166 -26
  37. package/package.json +1 -1
@@ -2,8 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Badge, Checkbox, Skeleton, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@flowselections/core";
4
4
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@flowselections/core";
5
- import { MoreVertical, Package, CheckCircle2, XCircle, Truck, FileText, ImageIcon, ArrowDown, } from "lucide-react";
6
- const eur = new Intl.NumberFormat("nl-NL", { style: "currency", currency: "EUR" });
5
+ import { MoreVertical, Package, ArrowDown } from "lucide-react";
7
6
  function formatDateShort(iso) {
8
7
  if (!iso)
9
8
  return { date: "—", time: "" };
@@ -30,39 +29,21 @@ function formatDateLong(iso) {
30
29
  minute: "2-digit",
31
30
  });
32
31
  }
33
- function StatusBadges({ status }) {
34
- const items = [
35
- {
36
- key: "cancelled",
37
- active: status.isCancelled,
38
- icon: XCircle,
39
- label: "Geannuleerd",
40
- classes: "bg-destructive/10 text-destructive",
41
- },
42
- {
43
- key: "shipped",
44
- active: status.isShipped,
45
- icon: Truck,
46
- label: "Verzonden",
47
- classes: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
48
- },
49
- {
50
- key: "confirmed",
51
- active: status.isConfirmed,
52
- icon: CheckCircle2,
53
- label: "Bevestigd",
54
- classes: "bg-primary/10 text-primary",
55
- },
56
- {
57
- key: "invoiced",
58
- active: status.isInvoiced,
59
- icon: FileText,
60
- label: "Gefactureerd",
61
- classes: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
62
- },
63
- ];
64
- return (_jsx("div", { className: "flex items-center gap-1", children: items.map((it) => (_jsx("span", { title: it.label, className: "inline-flex h-7 w-7 items-center justify-center rounded-md " +
65
- (it.active ? it.classes : "bg-muted text-muted-foreground/40"), children: _jsx(it.icon, { className: "h-4 w-4" }) }, it.key))) }));
32
+ function StatusTag({ status, rawOrder, }) {
33
+ const rawStatus = String(rawOrder?.status ?? "").toUpperCase();
34
+ if (status.isCancelled || rawStatus === "CANCELLED") {
35
+ return (_jsx(Badge, { variant: "outline", className: "border-destructive/30 bg-destructive/10 text-destructive", children: "Geannuleerd" }));
36
+ }
37
+ if (rawStatus === "DELIVERED" || (status.isShipped && status.isInvoiced)) {
38
+ return (_jsx(Badge, { variant: "outline", className: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400", children: "Geleverd" }));
39
+ }
40
+ if (rawStatus === "SHIPPED" || status.isShipped) {
41
+ return (_jsx(Badge, { variant: "outline", className: "border-blue-500/30 bg-blue-500/10 text-blue-600 dark:text-blue-400", children: "Onderweg" }));
42
+ }
43
+ if (rawStatus === "COMMITTED" || status.isConfirmed) {
44
+ return (_jsx(Badge, { variant: "outline", className: "border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400", children: "Verzend klaar" }));
45
+ }
46
+ return (_jsx(Badge, { variant: "outline", className: "border-muted-foreground/30 bg-muted text-muted-foreground", children: "Nog picken" }));
66
47
  }
67
48
  export function SalesOrdersTable({ orders, loading, onSelectOrder, }) {
68
49
  const [selected, setSelected] = useState(new Set());
@@ -72,12 +53,10 @@ export function SalesOrdersTable({ orders, loading, onSelectOrder, }) {
72
53
  n.has(id) ? n.delete(id) : n.add(id);
73
54
  return n;
74
55
  });
75
- return (_jsx("div", { className: "rounded-lg border border-border bg-card", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { className: "w-10", children: _jsx(Checkbox, { checked: allChecked, onCheckedChange: (v) => setSelected(v === true ? new Set(orders.map((o) => o.id)) : new Set()) }) }), _jsx(TableHead, { children: "Order" }), _jsx(TableHead, { children: _jsxs("span", { className: "inline-flex items-center gap-1", children: ["Bestelmoment ", _jsx(ArrowDown, { className: "h-3 w-3" })] }) }), _jsx(TableHead, { children: "Aantal" }), _jsx(TableHead, { children: "Klant" }), _jsx(TableHead, { children: "Levering" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "w-10" })] }) }), _jsxs(TableBody, { children: [loading &&
76
- Array.from({ length: 6 }).map((_, i) => (_jsx(TableRow, { children: Array.from({ length: 8 }).map((__, j) => (_jsx(TableCell, { children: _jsx(Skeleton, { className: "h-6 w-full" }) }, j))) }, `s-${i}`))), !loading && orders.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 8, className: "py-12 text-center text-muted-foreground", children: "Geen verkooporders gevonden." }) })), !loading &&
56
+ return (_jsx("div", { className: "rounded-lg border border-border bg-card", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableHead, { className: "w-10", children: _jsx(Checkbox, { checked: allChecked, onCheckedChange: (v) => setSelected(v === true ? new Set(orders.map((o) => o.id)) : new Set()) }) }), _jsx(TableHead, { children: "Omzet" }), _jsx(TableHead, { children: _jsxs("span", { className: "inline-flex items-center gap-1", children: ["Bestelmoment ", _jsx(ArrowDown, { className: "h-3 w-3" })] }) }), _jsx(TableHead, { children: "Karren" }), _jsx(TableHead, { children: "Fusten" }), _jsx(TableHead, { children: "Klant" }), _jsx(TableHead, { children: "Levering" }), _jsx(TableHead, { children: "Status" }), _jsx(TableHead, { className: "w-10" })] }) }), _jsxs(TableBody, { children: [loading &&
57
+ Array.from({ length: 6 }).map((_, i) => (_jsx(TableRow, { children: Array.from({ length: 9 }).map((__, j) => (_jsx(TableCell, { children: _jsx(Skeleton, { className: "h-6 w-full" }) }, j))) }, `s-${i}`))), !loading && orders.length === 0 && (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: 9, className: "py-12 text-center text-muted-foreground", children: "Geen verkooporders gevonden." }) })), !loading &&
77
58
  orders.map((o) => {
78
59
  const ordered = formatDateShort(o.orderedAt);
79
- return (_jsxs(TableRow, { className: "align-top cursor-pointer", onClick: () => onSelectOrder?.(o), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(o.id), onCheckedChange: () => toggle(o.id) }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted", children: o.imageUrl ? (
80
- // eslint-disable-next-line @next/next/no-img-element
81
- _jsx("img", { src: o.imageUrl, alt: "", className: "h-full w-full object-cover" })) : (_jsx(ImageIcon, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate font-medium text-foreground", children: o.productName }), _jsx("div", { className: "truncate text-xs text-muted-foreground", children: o.sku || o.orderNumber })] })] }) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Package, { className: "h-4 w-4 text-primary" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: ordered.time })] })] }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "font-medium text-foreground", children: [o.quantity.multiplier, " \u00D7 ", o.quantity.count, " \u00D7 ", eur.format(o.quantity.unitPrice)] }), _jsx("div", { className: "text-xs text-muted-foreground", children: eur.format(o.revenue) })] }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: o.customer.name }), o.isLocal && (_jsx(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: "Lokaal" }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [o.customer.postalCode, o.customer.city].filter(Boolean).join(" ") })] }), _jsx(TableCell, { className: "text-sm text-foreground", children: formatDateLong(o.deliveryAt) }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StatusBadges, { status: o.status }), o.orderNumber && (_jsx(Badge, { variant: "outline", className: "font-mono text-xs", children: o.orderNumber }))] }) }), _jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { children: "Bewerken" }), _jsx(DropdownMenuItem, { children: "Details bekijken" }), _jsx(DropdownMenuItem, { children: "Bevestigen" }), _jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", children: "Annuleren" })] })] }) })] }, o.id));
60
+ return (_jsxs(TableRow, { className: "align-top cursor-pointer", onClick: () => onSelectOrder?.(o), children: [_jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected.has(o.id), onCheckedChange: () => toggle(o.id) }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "font-medium text-foreground", children: ["\u20AC ", o.revenue.toFixed(2)] }), o.orderNumber && (_jsx("div", { className: "text-xs text-muted-foreground", children: o.orderNumber }))] }), _jsx(TableCell, { children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Package, { className: "h-4 w-4 text-primary" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-foreground", children: ordered.date }), _jsx("div", { className: "text-xs text-muted-foreground", children: ordered.time })] })] }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.karCount }) }), _jsx(TableCell, { children: _jsx("div", { className: "font-medium text-foreground", children: o.fustCount }) }), _jsxs(TableCell, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-foreground", children: o.customer.name }), o.isLocal && (_jsx(Badge, { variant: "outline", className: "border-primary/30 text-primary", children: "Lokaal" }))] }), _jsx("div", { className: "text-xs text-muted-foreground", children: [o.customer.postalCode, o.customer.city].filter(Boolean).join(" ") })] }), _jsx(TableCell, { className: "text-sm text-foreground", children: formatDateLong(o.deliveryAt) }), _jsx(TableCell, { children: _jsx(StatusTag, { status: o.status, rawOrder: o.raw?.order }) }), _jsx(TableCell, { onClick: (e) => e.stopPropagation(), children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground", children: _jsx(MoreVertical, { className: "h-4 w-4" }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { children: "Bewerken" }), _jsx(DropdownMenuItem, { children: "Details bekijken" }), _jsx(DropdownMenuItem, { children: "Bevestigen" }), _jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", children: "Annuleren" })] })] }) })] }, o.id));
82
61
  })] })] }) }));
83
62
  }
@@ -0,0 +1,19 @@
1
+ export interface SearchableOption {
2
+ value: string;
3
+ label: string;
4
+ hint?: string | null;
5
+ }
6
+ interface SearchableSelectProps {
7
+ value: string | null;
8
+ options: SearchableOption[];
9
+ placeholder?: string;
10
+ emptyLabel?: string;
11
+ allowClear?: boolean;
12
+ clearLabel?: string;
13
+ onChange: (value: string | null) => void;
14
+ className?: string;
15
+ disabled?: boolean;
16
+ }
17
+ export declare function SearchableSelect({ value, options, placeholder, emptyLabel, allowClear, clearLabel, onChange, className, disabled, }: SearchableSelectProps): import("react/jsx-runtime").JSX.Element;
18
+ export {};
19
+ //# sourceMappingURL=SearchableSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../src/components/verkoop/SearchableSelect.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EAAE,OAAO,EAAE,WAAuB,EAAE,UAA6B,EACtE,UAAiB,EAAE,UAAiC,EACpD,QAAQ,EAAE,SAAS,EAAE,QAAgB,GACtC,EAAE,qBAAqB,2CAuFvB"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from "react";
3
+ import { Button, Input, Popover, PopoverContent, PopoverTrigger, } from "@flowselections/core";
4
+ import { Check, ChevronsUpDown, Search } from "lucide-react";
5
+ export function SearchableSelect({ value, options, placeholder = "Kies...", emptyLabel = "Geen resultaat", allowClear = true, clearLabel = "— Geen koppeling —", onChange, className, disabled = false, }) {
6
+ const [open, setOpen] = useState(false);
7
+ const [q, setQ] = useState("");
8
+ const selected = useMemo(() => options.find((o) => o.value === value) ?? null, [options, value]);
9
+ const filtered = useMemo(() => {
10
+ const needle = q.trim().toLowerCase();
11
+ if (!needle)
12
+ return options.slice(0, 200);
13
+ return options
14
+ .filter((o) => o.label.toLowerCase().includes(needle) ||
15
+ (o.hint ?? "").toLowerCase().includes(needle))
16
+ .slice(0, 200);
17
+ }, [options, q]);
18
+ return (_jsxs(Popover, { open: open, onOpenChange: (o) => { if (disabled)
19
+ return; setOpen(o); if (!o)
20
+ setQ(""); }, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "outline", role: "combobox", "aria-expanded": open, disabled: disabled, className: `w-full justify-between font-normal ${className ?? ""}`, children: [_jsx("span", { className: `truncate ${selected ? "" : "text-muted-foreground"}`, children: selected?.label ?? placeholder }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsxs(PopoverContent, { className: "w-[--radix-popover-trigger-width] p-0", align: "start", children: [_jsx("div", { className: "p-2 border-b", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), _jsx(Input, { autoFocus: true, value: q, onChange: (e) => setQ(e.target.value), placeholder: `Zoek in ${options.length} items...`, className: "pl-8 h-9" })] }) }), _jsxs("div", { className: "max-h-64 overflow-y-auto py-1", children: [allowClear && (_jsxs("button", { type: "button", className: "w-full text-left text-sm px-3 py-2 hover:bg-accent flex items-center gap-2", onClick: () => { onChange(null); setOpen(false); }, children: [value === null && _jsx(Check, { className: "h-3 w-3" }), _jsx("span", { className: "text-muted-foreground italic", children: clearLabel })] })), filtered.length === 0 ? (_jsx("div", { className: "px-3 py-6 text-sm text-muted-foreground text-center", children: emptyLabel })) : (filtered.map((o) => (_jsxs("button", { type: "button", className: "w-full text-left text-sm px-3 py-2 hover:bg-accent flex items-start gap-2", onClick: () => { onChange(o.value); setOpen(false); }, children: [_jsx(Check, { className: `h-3 w-3 mt-1 shrink-0 ${value === o.value ? "" : "invisible"}` }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "truncate", children: o.label }), o.hint && _jsx("div", { className: "text-xs text-muted-foreground truncate", children: o.hint })] })] }, o.value)))), filtered.length === 200 && (_jsx("div", { className: "px-3 py-2 text-xs text-muted-foreground text-center border-t", children: "Toon eerste 200 resultaten \u2014 verfijn je zoekopdracht" }))] })] })] }));
21
+ }