@flowselections/floriday-klanten-module 1.0.27 → 1.0.29
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/klanten/BewerkKlant.d.ts.map +1 -1
- package/dist-lib/components/klanten/BewerkKlant.js +2 -1
- package/dist-lib/components/klanten/DeliveryLocationsTab.d.ts.map +1 -1
- package/dist-lib/components/klanten/DeliveryLocationsTab.js +67 -8
- package/dist-lib/components/klanten/ImportKlanten.d.ts.map +1 -1
- package/dist-lib/components/klanten/ImportKlanten.js +2 -1
- package/dist-lib/components/klanten/KlantenOverzicht.d.ts.map +1 -1
- package/dist-lib/components/klanten/KlantenOverzicht.js +61 -18
- package/dist-lib/components/klanten/LocalDiscountFormDialog.d.ts.map +1 -1
- package/dist-lib/components/klanten/LocalDiscountFormDialog.js +2 -1
- package/dist-lib/components/klanten/LocalDiscountsTab.d.ts.map +1 -1
- package/dist-lib/components/klanten/LocalDiscountsTab.js +2 -1
- package/dist-lib/components/klanten/LogisticsStrategyCard.d.ts.map +1 -1
- package/dist-lib/components/klanten/LogisticsStrategyCard.js +2 -1
- package/dist-lib/components/klanten/NieuweKlant.d.ts.map +1 -1
- package/dist-lib/components/klanten/NieuweKlant.js +2 -1
- package/dist-lib/components/klanten/OvernemenTwinfieldKlant.d.ts.map +1 -1
- package/dist-lib/components/klanten/OvernemenTwinfieldKlant.js +2 -1
- package/dist-lib/components/klanten/RouteError.d.ts +6 -0
- package/dist-lib/components/klanten/RouteError.d.ts.map +1 -0
- package/dist-lib/components/klanten/RouteError.js +13 -0
- package/dist-lib/lib/customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/customers.functions.js +39 -35
- package/dist-lib/lib/errors.d.ts +7 -0
- package/dist-lib/lib/errors.d.ts.map +1 -0
- package/dist-lib/lib/errors.js +36 -0
- package/dist-lib/lib/external-customers.functions.d.ts +1 -1
- package/dist-lib/lib/external-customers.functions.d.ts.map +1 -1
- package/dist-lib/lib/external-customers.functions.js +28 -12
- package/dist-lib/lib/persisted-state.d.ts +7 -0
- package/dist-lib/lib/persisted-state.d.ts.map +1 -0
- package/dist-lib/lib/persisted-state.js +92 -0
- package/dist-lib/lib/price-groups-local.functions.d.ts +3 -3
- package/package.json +2 -2
|
@@ -7,12 +7,31 @@ const listInput = z.object({
|
|
|
7
7
|
search: z.string().trim().max(255).optional().default(""),
|
|
8
8
|
providers: z.array(z.string()).optional(),
|
|
9
9
|
status: z.enum(["all", "active"]).optional().default("all"),
|
|
10
|
-
|
|
10
|
+
/** Optioneel plafond; standaard onbeperkt (alle klanten). */
|
|
11
|
+
limit: z.number().int().min(1).optional(),
|
|
11
12
|
});
|
|
12
13
|
async function admin() {
|
|
13
14
|
const { supabaseAdmin } = await import("../integrations/supabase/client.server");
|
|
14
15
|
return supabaseAdmin;
|
|
15
16
|
}
|
|
17
|
+
/** Postgres levert nooit meer dan 1000 rijen per aanvraag; lees in blokken door. */
|
|
18
|
+
const PAGE = 1000;
|
|
19
|
+
async function fetchAllRows(build, label, max) {
|
|
20
|
+
const out = [];
|
|
21
|
+
for (let offset = 0;; offset += PAGE) {
|
|
22
|
+
const size = max ? Math.min(PAGE, max - out.length) : PAGE;
|
|
23
|
+
if (size <= 0)
|
|
24
|
+
break;
|
|
25
|
+
const { data, error } = await build().range(offset, offset + size - 1);
|
|
26
|
+
if (error)
|
|
27
|
+
throw new Error(`${label}: ${error.message}`);
|
|
28
|
+
const chunk = (data ?? []);
|
|
29
|
+
out.push(...chunk);
|
|
30
|
+
if (chunk.length < size)
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
16
35
|
export const listExternalProviders = createServerFn({ method: "GET" })
|
|
17
36
|
.middleware([requireSupabaseAuth])
|
|
18
37
|
.handler(async () => {
|
|
@@ -44,17 +63,14 @@ export const listExternalCustomers = createServerFn({ method: "POST" })
|
|
|
44
63
|
if (requested.length === 0) {
|
|
45
64
|
return { customers: [], providers, last_fetched_at: null };
|
|
46
65
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (error)
|
|
56
|
-
throw new Error(`external_customers_grouped: ${error.message}`);
|
|
57
|
-
let customers = (rows ?? []);
|
|
66
|
+
const build = () => {
|
|
67
|
+
const q = sb
|
|
68
|
+
.from("external_customers_grouped")
|
|
69
|
+
.select(GROUPED_COLS)
|
|
70
|
+
.overlaps("providers", requested);
|
|
71
|
+
return data.status === "active" ? q.eq("is_active", true) : q;
|
|
72
|
+
};
|
|
73
|
+
let customers = await fetchAllRows(build, "external_customers_grouped", data.limit);
|
|
58
74
|
if (data.search) {
|
|
59
75
|
const s = data.search.toLowerCase();
|
|
60
76
|
customers = customers.filter((c) => [c.display_name, c.commercial_name, c.email, c.city, c.contact_person, c.gln, c.vat_number]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type StorageKind = "session" | "local";
|
|
2
|
+
export declare function usePersistedState<T>(key: string, initial: T, kind?: StorageKind): readonly [T, import("react").Dispatch<import("react").SetStateAction<T>>];
|
|
3
|
+
export declare function markReturnToList(): void;
|
|
4
|
+
export declare function consumeReturnToList(): boolean;
|
|
5
|
+
export declare function clearPersistedState(keys: string[]): void;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=persisted-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persisted-state.d.ts","sourceRoot":"","sources":["../../src/lib/persisted-state.ts"],"names":[],"mappings":"AASA,KAAK,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;AAmBvC,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,GAAE,WAAuB,6EA4B1F;AASD,wBAAgB,gBAAgB,SAO/B;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAW7C;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAUjD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* State die bewaard blijft tijdens client-side navigatie (en na reload via
|
|
4
|
+
* sessionStorage). SSR-veilig: eerste render gebruikt altijd de default of de
|
|
5
|
+
* in-memory waarde, sessionStorage wordt na hydratie ingelezen.
|
|
6
|
+
*/
|
|
7
|
+
const memoryStore = new Map();
|
|
8
|
+
function storageFor(kind) {
|
|
9
|
+
try {
|
|
10
|
+
return kind === "local" ? localStorage : sessionStorage;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function readStored(key, kind) {
|
|
17
|
+
try {
|
|
18
|
+
const raw = storageFor(kind)?.getItem(key);
|
|
19
|
+
return raw ? JSON.parse(raw) : undefined;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function usePersistedState(key, initial, kind = "session") {
|
|
26
|
+
const [value, setValue] = useState(() => memoryStore.has(key) ? memoryStore.get(key) : initial);
|
|
27
|
+
const [hydrated, setHydrated] = useState(false);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (hydrated)
|
|
30
|
+
return;
|
|
31
|
+
setHydrated(true);
|
|
32
|
+
if (memoryStore.has(key))
|
|
33
|
+
return;
|
|
34
|
+
const stored = readStored(key, kind);
|
|
35
|
+
if (stored !== undefined) {
|
|
36
|
+
memoryStore.set(key, stored);
|
|
37
|
+
setValue(stored);
|
|
38
|
+
}
|
|
39
|
+
}, [key, hydrated, kind]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!hydrated)
|
|
42
|
+
return;
|
|
43
|
+
memoryStore.set(key, value);
|
|
44
|
+
try {
|
|
45
|
+
storageFor(kind)?.setItem(key, JSON.stringify(value));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* storage niet beschikbaar */
|
|
49
|
+
}
|
|
50
|
+
}, [key, value, hydrated, kind]);
|
|
51
|
+
return [value, setValue];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Markeer dat de gebruiker binnen de klantenflow blijft, zodat het
|
|
55
|
+
* paginanummer bewaard blijft bij "terug naar klanten" maar wél reset
|
|
56
|
+
* wanneer het overzicht vers wordt geopend vanuit een andere module.
|
|
57
|
+
*/
|
|
58
|
+
const RETURN_KEY = "klanten:returning";
|
|
59
|
+
export function markReturnToList() {
|
|
60
|
+
try {
|
|
61
|
+
sessionStorage.setItem(RETURN_KEY, "1");
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* storage niet beschikbaar */
|
|
65
|
+
}
|
|
66
|
+
memoryStore.set(RETURN_KEY, true);
|
|
67
|
+
}
|
|
68
|
+
export function consumeReturnToList() {
|
|
69
|
+
const inMemory = memoryStore.get(RETURN_KEY) === true;
|
|
70
|
+
let stored = false;
|
|
71
|
+
try {
|
|
72
|
+
stored = sessionStorage.getItem(RETURN_KEY) === "1";
|
|
73
|
+
sessionStorage.removeItem(RETURN_KEY);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* storage niet beschikbaar */
|
|
77
|
+
}
|
|
78
|
+
memoryStore.delete(RETURN_KEY);
|
|
79
|
+
return inMemory || stored;
|
|
80
|
+
}
|
|
81
|
+
export function clearPersistedState(keys) {
|
|
82
|
+
for (const key of keys) {
|
|
83
|
+
memoryStore.delete(key);
|
|
84
|
+
try {
|
|
85
|
+
sessionStorage.removeItem(key);
|
|
86
|
+
localStorage.removeItem(key);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
/* storage niet beschikbaar */
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -33,9 +33,9 @@ declare const priceGroupInputSchema: z.ZodObject<{
|
|
|
33
33
|
}>>>;
|
|
34
34
|
rounding: z.ZodDefault<z.ZodEnum<{
|
|
35
35
|
none: "none";
|
|
36
|
+
nearest: "nearest";
|
|
36
37
|
up: "up";
|
|
37
38
|
down: "down";
|
|
38
|
-
nearest: "nearest";
|
|
39
39
|
}>>;
|
|
40
40
|
rounding_step: z.ZodOptional<z.ZodNumber>;
|
|
41
41
|
is_active: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -59517,7 +59517,7 @@ export declare const createCustomerPriceGroup: import("@tanstack/start-client-co
|
|
|
59517
59517
|
price_scope: "incl_delivery" | "excl_delivery";
|
|
59518
59518
|
include_stickers: boolean;
|
|
59519
59519
|
unit: string;
|
|
59520
|
-
rounding: "none" | "
|
|
59520
|
+
rounding: "none" | "nearest" | "up" | "down";
|
|
59521
59521
|
is_active: boolean;
|
|
59522
59522
|
calc_type?: "discount" | "surcharge" | null | undefined;
|
|
59523
59523
|
calc_value_type?: "fixed" | "percentage" | null | undefined;
|
|
@@ -79368,7 +79368,7 @@ export declare const updateCustomerPriceGroup: import("@tanstack/start-client-co
|
|
|
79368
79368
|
price_scope: "incl_delivery" | "excl_delivery";
|
|
79369
79369
|
include_stickers: boolean;
|
|
79370
79370
|
unit: string;
|
|
79371
|
-
rounding: "none" | "
|
|
79371
|
+
rounding: "none" | "nearest" | "up" | "down";
|
|
79372
79372
|
is_active: boolean;
|
|
79373
79373
|
calc_type?: "discount" | "surcharge" | null | undefined;
|
|
79374
79374
|
calc_value_type?: "fixed" | "percentage" | null | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowselections/floriday-klanten-module",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.29",
|
|
4
4
|
"private": false,
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@cloudflare/vite-plugin": "^1.25.5",
|
|
52
52
|
"@eslint/js": "^9.32.0",
|
|
53
53
|
"@flowselections/core": "1.0.16",
|
|
54
|
-
"@lovable.dev/vite-tanstack-config": "2.
|
|
54
|
+
"@lovable.dev/vite-tanstack-config": "2.9.1",
|
|
55
55
|
"@rsbuild/core": "^1.0.0",
|
|
56
56
|
"@tailwindcss/vite": "^4.2.1",
|
|
57
57
|
"@tanstack/react-query": "^5.83.0",
|