@flowselections/floriday-voorraad 1.0.11 → 1.0.13
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.
- package/dist-lib/components/voorraad/ConnectionBadge.d.ts +6 -0
- package/dist-lib/components/voorraad/ConnectionBadge.d.ts.map +1 -0
- package/dist-lib/components/voorraad/ConnectionBadge.js +12 -0
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +18 -10
- package/dist-lib/components/voorraad/VoorraadTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadTable.js +10 -2
- package/dist-lib/hooks/useFloridayConnection.d.ts +9 -4
- package/dist-lib/hooks/useFloridayConnection.d.ts.map +1 -1
- package/dist-lib/hooks/useFloridayConnection.js +23 -23
- package/dist-lib/hooks/useFlorydayCustomers.d.ts +17 -0
- package/dist-lib/hooks/useFlorydayCustomers.d.ts.map +1 -0
- package/dist-lib/hooks/useFlorydayCustomers.js +65 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts +22 -0
- package/dist-lib/hooks/useLocalTradeItems.d.ts.map +1 -0
- package/dist-lib/hooks/useLocalTradeItems.js +100 -0
- package/dist-lib/hooks/useVoorraadData.d.ts +5 -0
- package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadData.js +37 -10
- package/dist-lib/index.d.ts +1 -1
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -1
- package/dist-lib/integrations/supabase/auth-middleware.d.ts +2493 -32
- package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.d.ts +2493 -32
- package/dist-lib/integrations/supabase/client.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.js +1 -1
- package/dist-lib/integrations/supabase/client.server.d.ts +2493 -32
- package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/client.server.js +1 -1
- package/dist-lib/integrations/supabase/types.d.ts +2606 -82
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +10 -0
- package/dist-lib/lib/floriday-client.d.ts +10 -12
- package/dist-lib/lib/floriday-client.d.ts.map +1 -1
- package/dist-lib/lib/floriday-client.js +32 -15
- package/dist-lib/styles.css +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FloridayActiveConnection } from "../../lib/floriday-client";
|
|
2
|
+
export declare function ConnectionBadge({ connection, loading, }: {
|
|
3
|
+
connection: FloridayActiveConnection | null;
|
|
4
|
+
loading?: boolean;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=ConnectionBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionBadge.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/ConnectionBadge.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,OAAO,GACR,EAAE;IACD,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,2CAqBA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from "@flowselections/core";
|
|
3
|
+
export function ConnectionBadge({ connection, loading, }) {
|
|
4
|
+
if (loading) {
|
|
5
|
+
return _jsx(Badge, { variant: "secondary", children: "Floriday laden..." });
|
|
6
|
+
}
|
|
7
|
+
if (!connection) {
|
|
8
|
+
return (_jsx(Badge, { variant: "destructive", children: "Geen actieve Floriday-connectie" }));
|
|
9
|
+
}
|
|
10
|
+
const env = connection.active_environment || connection.environment;
|
|
11
|
+
return (_jsxs(Badge, { variant: "secondary", className: "gap-1.5", children: [_jsx("span", { className: "font-medium", children: "Floriday" }), _jsx("span", { className: "opacity-60", children: "\u00B7" }), _jsx("span", { className: "uppercase tracking-wide text-[10px]", children: env }), _jsx("span", { className: "opacity-60", children: "\u00B7" }), _jsx("span", { children: connection.organization_name || connection.label })] }));
|
|
12
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoorraadPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VoorraadPage.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadPage.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,YAAY,4CAqF3B"}
|
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
3
|
import { Link } from "@tanstack/react-router";
|
|
4
|
-
import { Button, Card, Input } from "@flowselections/core";
|
|
4
|
+
import { Button, Card, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@flowselections/core";
|
|
5
5
|
import { Plus, RefreshCw, Search } from "lucide-react";
|
|
6
6
|
import { useFloridayConnection } from "../../hooks/useFloridayConnection";
|
|
7
7
|
import { useVoorraadData } from "../../hooks/useVoorraadData";
|
|
8
|
-
import {
|
|
8
|
+
import { ConnectionBadge } from "./ConnectionBadge";
|
|
9
9
|
import { ExcelExportButton } from "./ExcelExportButton";
|
|
10
10
|
import { VoorraadTable } from "./VoorraadTable";
|
|
11
11
|
export function VoorraadPage() {
|
|
12
|
-
const {
|
|
12
|
+
const { activeConnection, activeId, loading: connLoading, error: connError, } = useFloridayConnection();
|
|
13
13
|
const { items, loading, error, reload } = useVoorraadData(activeId);
|
|
14
14
|
const [search, setSearch] = useState("");
|
|
15
|
+
const [publishFilter, setPublishFilter] = useState("all");
|
|
15
16
|
const filtered = useMemo(() => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
i.
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
const q = search.trim().toLowerCase();
|
|
18
|
+
return items.filter((i) => {
|
|
19
|
+
if (publishFilter === "published" && !i.published)
|
|
20
|
+
return false;
|
|
21
|
+
if (publishFilter === "local" && i.published)
|
|
22
|
+
return false;
|
|
23
|
+
if (!q)
|
|
24
|
+
return true;
|
|
25
|
+
return (i.name.toLowerCase().includes(q) ||
|
|
26
|
+
(i.articleNumber ?? "").toLowerCase().includes(q));
|
|
27
|
+
});
|
|
28
|
+
}, [items, search, publishFilter]);
|
|
29
|
+
const localCount = items.filter((i) => !i.published).length;
|
|
30
|
+
return (_jsxs("main", { className: "p-6 space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs("div", { className: "relative flex-1 min-w-[240px] max-w-md", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }), _jsx(Input, { value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Zoek op product of artikelnummer...", className: "pl-9" })] }), _jsxs(Select, { value: publishFilter, onValueChange: (v) => setPublishFilter(v), children: [_jsx(SelectTrigger, { className: "w-[200px]", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "all", children: "Alle producten" }), _jsx(SelectItem, { value: "published", children: "Gepubliceerd" }), _jsxs(SelectItem, { value: "local", children: ["Niet gepubliceerd", localCount > 0 ? ` (${localCount})` : ""] })] })] }), _jsx(ConnectionBadge, { connection: activeConnection, loading: connLoading }), _jsxs(Button, { variant: "outline", onClick: reload, disabled: loading || !activeId, children: [_jsx(RefreshCw, { className: `mr-2 h-4 w-4 ${loading ? "animate-spin" : ""}` }), "Vernieuwen"] }), _jsx(ExcelExportButton, { items: filtered }), _jsx(Button, { asChild: true, disabled: !activeId, children: _jsxs(Link, { to: "/voorraad/nieuw", children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Artikel toevoegen"] }) })] }), connError && (_jsxs(Card, { className: "border-destructive/40 bg-destructive/5 p-4 text-sm", children: ["Floriday-connectie laden mislukt: ", connError] })), error && (_jsxs(Card, { className: "border-destructive/40 bg-destructive/5 p-4 text-sm", children: ["Voorraad laden mislukt: ", error] })), _jsxs(Card, { className: "overflow-hidden", children: [_jsxs("div", { className: "px-4 py-2 border-b text-xs text-muted-foreground", children: [filtered.length, " producten ", search && `(gefilterd uit ${items.length})`, " · ", "live data uit gedeelde cache (sync elke 5 min)", localCount > 0 && ` · ${localCount} niet-gepubliceerd`] }), _jsx(VoorraadTable, { items: filtered, loading: loading })] })] }));
|
|
23
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoorraadTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadTable.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VoorraadTable.d.ts","sourceRoot":"","sources":["../../../src/components/voorraad/VoorraadTable.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAW3D,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,2CAqGA"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from "@tanstack/react-router";
|
|
3
|
+
import { Badge } from "@flowselections/core";
|
|
2
4
|
import { Package } from "lucide-react";
|
|
3
5
|
const columns = [
|
|
4
6
|
{ key: "quantity", label: "Liggend" },
|
|
@@ -16,7 +18,13 @@ export function VoorraadTable({ items, loading, }) {
|
|
|
16
18
|
return (_jsx("p", { className: "text-sm text-muted-foreground p-6", children: "Geen producten gevonden voor deze connectie." }));
|
|
17
19
|
}
|
|
18
20
|
return (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-muted/50 text-left", children: _jsxs("tr", { children: [_jsx("th", { className: "p-3 w-14" }), _jsx("th", { className: "p-3", children: "Product" }), _jsx("th", { className: "p-3", children: "Artikelnummer" }), columns.map((c) => (_jsx("th", { className: "p-3 text-right whitespace-nowrap", children: c.label }, c.key)))] }) }), _jsx("tbody", { children: items.map((item) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const isLocal = !item.published;
|
|
22
|
+
const low = !isLocal &&
|
|
23
|
+
item.minQuantity > 0 &&
|
|
24
|
+
item.availableQuantity < item.minQuantity;
|
|
25
|
+
const nameContent = (_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("span", { className: isLocal
|
|
26
|
+
? "font-medium text-foreground hover:underline"
|
|
27
|
+
: "font-medium text-foreground", children: item.name }), isLocal && (_jsx(Badge, { variant: "outline", className: "text-[10px] font-normal text-muted-foreground border-amber-500/40 bg-amber-500/10", children: "Niet gepubliceerd" }))] }));
|
|
28
|
+
return (_jsxs("tr", { className: "border-t hover:bg-muted/30", children: [_jsx("td", { className: "p-2", children: item.imageUrl ? (_jsx("img", { src: item.imageUrl, alt: item.name, className: "h-10 w-10 rounded object-cover", loading: "lazy" })) : (_jsx("div", { className: "h-10 w-10 rounded bg-muted flex items-center justify-center", children: _jsx(Package, { className: "h-4 w-4 text-muted-foreground" }) })) }), _jsxs("td", { className: "p-3", children: [isLocal && item.localId ? (_jsx(Link, { to: "/voorraad/$id", params: { id: item.localId }, children: nameContent })) : (nameContent), low && (_jsx("div", { className: "text-xs text-destructive", children: "onder minimumvoorraad" }))] }), _jsx("td", { className: "p-3 font-mono text-xs", children: item.articleNumber || "—" }), columns.map((c) => (_jsx("td", { className: "p-3 text-right tabular-nums text-muted-foreground", children: isLocal ? "—" : Number(item[c.key] ?? 0) }, c.key)))] }, item.id));
|
|
21
29
|
}) })] }) }));
|
|
22
30
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { FloridayActiveConnection } from "../lib/floriday-client";
|
|
2
|
+
/**
|
|
3
|
+
* Reads the single active Floriday connection for the currently selected
|
|
4
|
+
* environment (staging/live) via the Auth-module's
|
|
5
|
+
* `get_active_floriday_connection_public` RPC. No tokens or secrets are
|
|
6
|
+
* exposed.
|
|
7
|
+
*/
|
|
2
8
|
export declare function useFloridayConnection(): {
|
|
3
|
-
|
|
9
|
+
activeConnection: FloridayActiveConnection | null;
|
|
4
10
|
activeId: string | null;
|
|
5
|
-
|
|
6
|
-
activeConnection: FloridayConnection | null;
|
|
11
|
+
environment: string | null;
|
|
7
12
|
loading: boolean;
|
|
8
13
|
error: string | null;
|
|
9
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFloridayConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFloridayConnection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFloridayConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useFloridayConnection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,qBAAqB;;;;;;EA+BpC"}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
/**
|
|
4
|
+
* Reads the single active Floriday connection for the currently selected
|
|
5
|
+
* environment (staging/live) via the Auth-module's
|
|
6
|
+
* `get_active_floriday_connection_public` RPC. No tokens or secrets are
|
|
7
|
+
* exposed.
|
|
8
|
+
*/
|
|
4
9
|
export function useFloridayConnection() {
|
|
5
|
-
const [
|
|
6
|
-
const [activeId, setActiveIdState] = useState(null);
|
|
10
|
+
const [activeConnection, setActive] = useState(null);
|
|
7
11
|
const [loading, setLoading] = useState(true);
|
|
8
12
|
const [error, setError] = useState(null);
|
|
9
13
|
useEffect(() => {
|
|
10
14
|
let mounted = true;
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
.then((rows) => {
|
|
15
|
+
(async () => {
|
|
16
|
+
const { data, error } = await supabase.rpc("get_active_floriday_connection_public");
|
|
14
17
|
if (!mounted)
|
|
15
18
|
return;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
if (error) {
|
|
20
|
+
setError(error.message);
|
|
21
|
+
setActive(null);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const row = (data ?? [])[0];
|
|
25
|
+
setActive(row && row.id ? row : null);
|
|
26
|
+
}
|
|
27
|
+
setLoading(false);
|
|
28
|
+
})();
|
|
23
29
|
return () => {
|
|
24
30
|
mounted = false;
|
|
25
31
|
};
|
|
26
32
|
}, []);
|
|
27
|
-
const setActiveId = (id) => {
|
|
28
|
-
setActiveIdState(id);
|
|
29
|
-
if (typeof window !== "undefined")
|
|
30
|
-
localStorage.setItem(STORAGE_KEY, id);
|
|
31
|
-
};
|
|
32
33
|
return {
|
|
33
|
-
|
|
34
|
-
activeId,
|
|
35
|
-
|
|
36
|
-
activeConnection: connections.find((c) => c.id === activeId) ?? null,
|
|
34
|
+
activeConnection,
|
|
35
|
+
activeId: activeConnection?.id ?? null,
|
|
36
|
+
environment: activeConnection?.active_environment ?? null,
|
|
37
37
|
loading,
|
|
38
38
|
error,
|
|
39
39
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface FloridayCustomer {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
hasRealName: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reads buyer organisations from the shared `floriday_connections_cache`
|
|
8
|
+
* (which contains buyer org id + name per supplier connection).
|
|
9
|
+
* If `buyer_organization_name` is NULL (Auth-module hasn't synced names yet),
|
|
10
|
+
* we fall back to a short, readable label so the UI never shows a raw UUID.
|
|
11
|
+
*/
|
|
12
|
+
export declare function useFlorydayCustomers(connectionId: string | null): {
|
|
13
|
+
customers: FloridayCustomer[];
|
|
14
|
+
loading: boolean;
|
|
15
|
+
error: string | null;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useFlorydayCustomers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFlorydayCustomers.d.ts","sourceRoot":"","sources":["../../src/hooks/useFlorydayCustomers.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;EAoD/D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
function shortId(id) {
|
|
4
|
+
return `Klant ${id.slice(0, 8)}…${id.slice(-4)}`;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reads buyer organisations from the shared `floriday_connections_cache`
|
|
8
|
+
* (which contains buyer org id + name per supplier connection).
|
|
9
|
+
* If `buyer_organization_name` is NULL (Auth-module hasn't synced names yet),
|
|
10
|
+
* we fall back to a short, readable label so the UI never shows a raw UUID.
|
|
11
|
+
*/
|
|
12
|
+
export function useFlorydayCustomers(connectionId) {
|
|
13
|
+
const [customers, setCustomers] = useState([]);
|
|
14
|
+
const [loading, setLoading] = useState(false);
|
|
15
|
+
const [error, setError] = useState(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
let mounted = true;
|
|
18
|
+
if (!connectionId) {
|
|
19
|
+
setCustomers([]);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
setLoading(true);
|
|
23
|
+
setError(null);
|
|
24
|
+
supabase
|
|
25
|
+
.from("floriday_connections_cache")
|
|
26
|
+
.select("buyer_organization_id,buyer_organization_name")
|
|
27
|
+
.eq("connection_id", connectionId)
|
|
28
|
+
.eq("is_deleted", false)
|
|
29
|
+
.then(({ data, error }) => {
|
|
30
|
+
if (!mounted)
|
|
31
|
+
return;
|
|
32
|
+
if (error) {
|
|
33
|
+
setError(error.message);
|
|
34
|
+
setCustomers([]);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const out = [];
|
|
39
|
+
for (const row of data ?? []) {
|
|
40
|
+
const id = row.buyer_organization_id;
|
|
41
|
+
if (!id || seen.has(id))
|
|
42
|
+
continue;
|
|
43
|
+
seen.add(id);
|
|
44
|
+
const real = (row.buyer_organization_name ?? "").trim();
|
|
45
|
+
out.push({
|
|
46
|
+
id,
|
|
47
|
+
name: real.length > 0 ? real : shortId(id),
|
|
48
|
+
hasRealName: real.length > 0,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Real names first (alphabetical), then fallback labels.
|
|
52
|
+
out.sort((a, b) => {
|
|
53
|
+
if (a.hasRealName !== b.hasRealName)
|
|
54
|
+
return a.hasRealName ? -1 : 1;
|
|
55
|
+
return a.name.localeCompare(b.name);
|
|
56
|
+
});
|
|
57
|
+
setCustomers(out);
|
|
58
|
+
})
|
|
59
|
+
.then(() => mounted && setLoading(false));
|
|
60
|
+
return () => {
|
|
61
|
+
mounted = false;
|
|
62
|
+
};
|
|
63
|
+
}, [connectionId]);
|
|
64
|
+
return { customers, loading, error };
|
|
65
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { WizardData } from "../lib/floriday-payload";
|
|
2
|
+
import type { TradeItem } from "../lib/floriday-client";
|
|
3
|
+
export interface LocalTradeItemRow {
|
|
4
|
+
id: string;
|
|
5
|
+
connection_id: string | null;
|
|
6
|
+
data: WizardData;
|
|
7
|
+
updated_at: string;
|
|
8
|
+
created_at: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function useLocalTradeItems(connectionId: string | null): {
|
|
11
|
+
items: TradeItem[];
|
|
12
|
+
loading: boolean;
|
|
13
|
+
reload: () => Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
export declare function getLocalTradeItem(id: string): Promise<LocalTradeItemRow | null>;
|
|
16
|
+
export declare function upsertLocalTradeItem(params: {
|
|
17
|
+
id?: string;
|
|
18
|
+
connectionId: string;
|
|
19
|
+
data: WizardData;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
export declare function deleteLocalTradeItem(id: string): Promise<void>;
|
|
22
|
+
//# sourceMappingURL=useLocalTradeItems.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLocalTradeItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useLocalTradeItems.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAwBD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;EA+B7D;AAED,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQrF;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BlB;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
function draftToTradeItem(row) {
|
|
4
|
+
const d = row.data ?? {};
|
|
5
|
+
const firstImage = Array.isArray(d.images) && d.images.length > 0 ? d.images[0] : null;
|
|
6
|
+
const imageUrl = (firstImage && (firstImage.url || firstImage.previewUrl)) ?? null;
|
|
7
|
+
return {
|
|
8
|
+
id: `local:${row.id}`,
|
|
9
|
+
localId: row.id,
|
|
10
|
+
name: d.name || d.vbnName || "(naamloos)",
|
|
11
|
+
articleNumber: d.articleCode || d.gtin || "",
|
|
12
|
+
imageUrl,
|
|
13
|
+
quantity: 0,
|
|
14
|
+
minQuantity: 0,
|
|
15
|
+
reservedQuantity: 0,
|
|
16
|
+
availableQuantity: 0,
|
|
17
|
+
incomingQuantity: 0,
|
|
18
|
+
economicQuantity: 0,
|
|
19
|
+
raw: row,
|
|
20
|
+
published: false,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function useLocalTradeItems(connectionId) {
|
|
24
|
+
const [items, setItems] = useState([]);
|
|
25
|
+
const [loading, setLoading] = useState(false);
|
|
26
|
+
const load = useCallback(async () => {
|
|
27
|
+
if (!connectionId) {
|
|
28
|
+
setItems([]);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
setLoading(true);
|
|
32
|
+
try {
|
|
33
|
+
const { data, error } = await supabase
|
|
34
|
+
.from("trade_item_drafts")
|
|
35
|
+
.select("id,connection_id,data,updated_at,created_at")
|
|
36
|
+
.eq("connection_id", connectionId)
|
|
37
|
+
.order("updated_at", { ascending: false })
|
|
38
|
+
.limit(1000);
|
|
39
|
+
if (error)
|
|
40
|
+
throw error;
|
|
41
|
+
setItems((data ?? []).map((r) => draftToTradeItem(r)));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
setItems([]);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
setLoading(false);
|
|
48
|
+
}
|
|
49
|
+
}, [connectionId]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
load();
|
|
52
|
+
}, [load]);
|
|
53
|
+
return { items, loading, reload: load };
|
|
54
|
+
}
|
|
55
|
+
export async function getLocalTradeItem(id) {
|
|
56
|
+
const { data, error } = await supabase
|
|
57
|
+
.from("trade_item_drafts")
|
|
58
|
+
.select("id,connection_id,data,updated_at,created_at")
|
|
59
|
+
.eq("id", id)
|
|
60
|
+
.maybeSingle();
|
|
61
|
+
if (error)
|
|
62
|
+
throw new Error(error.message);
|
|
63
|
+
return data ?? null;
|
|
64
|
+
}
|
|
65
|
+
export async function upsertLocalTradeItem(params) {
|
|
66
|
+
const userRes = await supabase.auth.getUser();
|
|
67
|
+
const userId = userRes.data.user?.id;
|
|
68
|
+
if (!userId)
|
|
69
|
+
throw new Error("Niet ingelogd");
|
|
70
|
+
if (params.id) {
|
|
71
|
+
const { error } = await supabase
|
|
72
|
+
.from("trade_item_drafts")
|
|
73
|
+
.update({
|
|
74
|
+
data: params.data,
|
|
75
|
+
connection_id: params.connectionId,
|
|
76
|
+
updated_at: new Date().toISOString(),
|
|
77
|
+
})
|
|
78
|
+
.eq("id", params.id);
|
|
79
|
+
if (error)
|
|
80
|
+
throw new Error(error.message);
|
|
81
|
+
return params.id;
|
|
82
|
+
}
|
|
83
|
+
const { data, error } = await supabase
|
|
84
|
+
.from("trade_item_drafts")
|
|
85
|
+
.insert({
|
|
86
|
+
user_id: userId,
|
|
87
|
+
connection_id: params.connectionId,
|
|
88
|
+
data: params.data,
|
|
89
|
+
})
|
|
90
|
+
.select("id")
|
|
91
|
+
.single();
|
|
92
|
+
if (error)
|
|
93
|
+
throw new Error(error.message);
|
|
94
|
+
return data.id;
|
|
95
|
+
}
|
|
96
|
+
export async function deleteLocalTradeItem(id) {
|
|
97
|
+
const { error } = await supabase.from("trade_item_drafts").delete().eq("id", id);
|
|
98
|
+
if (error)
|
|
99
|
+
throw new Error(error.message);
|
|
100
|
+
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { type TradeItem } from "../lib/floriday-client";
|
|
2
|
+
/**
|
|
3
|
+
* Reads trade items from the shared `floriday_trade_items_cache` (gepubliceerd,
|
|
4
|
+
* gevuld door de Auth-module elke 5 min) en merget lokale, niet-gepubliceerde
|
|
5
|
+
* producten uit `trade_item_drafts`.
|
|
6
|
+
*/
|
|
2
7
|
export declare function useVoorraadData(connectionId: string | null): {
|
|
3
8
|
items: TradeItem[];
|
|
4
9
|
loading: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVoorraadData.d.ts","sourceRoot":"","sources":["../../src/hooks/useVoorraadData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useVoorraadData.d.ts","sourceRoot":"","sources":["../../src/hooks/useVoorraadData.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG5E;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;;;;;EAqD1D"}
|
|
@@ -1,30 +1,57 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { supabase } from "../integrations/supabase/client";
|
|
3
|
+
import { normaliseTradeItem } from "../lib/floriday-client";
|
|
4
|
+
import { useLocalTradeItems } from "./useLocalTradeItems";
|
|
5
|
+
/**
|
|
6
|
+
* Reads trade items from the shared `floriday_trade_items_cache` (gepubliceerd,
|
|
7
|
+
* gevuld door de Auth-module elke 5 min) en merget lokale, niet-gepubliceerde
|
|
8
|
+
* producten uit `trade_item_drafts`.
|
|
9
|
+
*/
|
|
3
10
|
export function useVoorraadData(connectionId) {
|
|
4
|
-
const [
|
|
11
|
+
const [publishedItems, setPublishedItems] = useState([]);
|
|
5
12
|
const [loading, setLoading] = useState(false);
|
|
6
13
|
const [error, setError] = useState(null);
|
|
7
|
-
const
|
|
14
|
+
const { items: localItems, loading: localLoading, reload: reloadLocal, } = useLocalTradeItems(connectionId);
|
|
15
|
+
const loadPublished = useCallback(async () => {
|
|
8
16
|
if (!connectionId) {
|
|
9
|
-
|
|
17
|
+
setPublishedItems([]);
|
|
10
18
|
return;
|
|
11
19
|
}
|
|
12
20
|
setLoading(true);
|
|
13
21
|
setError(null);
|
|
14
22
|
try {
|
|
15
|
-
const data = await
|
|
16
|
-
|
|
23
|
+
const { data, error } = await supabase
|
|
24
|
+
.from("floriday_trade_items_cache")
|
|
25
|
+
.select("data,floriday_id,is_deleted")
|
|
26
|
+
.eq("connection_id", connectionId)
|
|
27
|
+
.eq("is_deleted", false)
|
|
28
|
+
.limit(1000);
|
|
29
|
+
if (error)
|
|
30
|
+
throw error;
|
|
31
|
+
const normalised = (data ?? [])
|
|
32
|
+
.map((row) => normaliseTradeItem({ ...row.data, id: row.floriday_id }))
|
|
33
|
+
.filter((i) => i.id)
|
|
34
|
+
.map((i) => ({ ...i, published: true }));
|
|
35
|
+
setPublishedItems(normalised);
|
|
17
36
|
}
|
|
18
37
|
catch (e) {
|
|
19
38
|
setError(e.message);
|
|
20
|
-
|
|
39
|
+
setPublishedItems([]);
|
|
21
40
|
}
|
|
22
41
|
finally {
|
|
23
42
|
setLoading(false);
|
|
24
43
|
}
|
|
25
44
|
}, [connectionId]);
|
|
26
45
|
useEffect(() => {
|
|
27
|
-
|
|
28
|
-
}, [
|
|
29
|
-
|
|
46
|
+
loadPublished();
|
|
47
|
+
}, [loadPublished]);
|
|
48
|
+
const reload = useCallback(async () => {
|
|
49
|
+
await Promise.all([loadPublished(), reloadLocal()]);
|
|
50
|
+
}, [loadPublished, reloadLocal]);
|
|
51
|
+
return {
|
|
52
|
+
items: [...localItems, ...publishedItems],
|
|
53
|
+
loading: loading || localLoading,
|
|
54
|
+
error,
|
|
55
|
+
reload,
|
|
56
|
+
};
|
|
30
57
|
}
|
package/dist-lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FlowModule } from "@flowselections/core";
|
|
2
2
|
export * from './_core-safelist';
|
|
3
3
|
export { VoorraadPage } from './components/voorraad/VoorraadPage';
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const floridayVoorraadModule: FlowModule;
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAIlE,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAIlE,eAAO,MAAM,sBAAsB,EAAE,UAYpC,CAAC"}
|
package/dist-lib/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Package } from "lucide-react";
|
|
|
5
5
|
export * from './_core-safelist';
|
|
6
6
|
export { VoorraadPage } from './components/voorraad/VoorraadPage';
|
|
7
7
|
import { VoorraadSettingsCard } from "./components/settings/VoorraadSettingsCard";
|
|
8
|
-
export const
|
|
8
|
+
export const floridayVoorraadModule = {
|
|
9
9
|
id: "voorraad",
|
|
10
10
|
name: "Voorraad",
|
|
11
11
|
version: "1.0.0",
|