@pol-studios/ui 1.0.0
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/adapters/index.js +359 -0
- package/dist/auth/index.js +588 -0
- package/dist/canvas-UVNDA54X.node +0 -0
- package/dist/cards/index.js +872 -0
- package/dist/charts/index.js +54148 -0
- package/dist/components/chat-agent/index.js +21434 -0
- package/dist/components/index.js +148416 -0
- package/dist/contexts/index.js +188 -0
- package/dist/crud/index.js +6550 -0
- package/dist/data/index.js +372 -0
- package/dist/feedback/index.js +9534 -0
- package/dist/file/index.js +256 -0
- package/dist/forms/index.js +504 -0
- package/dist/hooks/index.js +345 -0
- package/dist/index.js +15650 -0
- package/dist/nav/index.js +1556 -0
- package/dist/navbar/index.js +45262 -0
- package/dist/primitives/index.js +15646 -0
- package/dist/providers/index.js +1927 -0
- package/dist/types/index.js +1 -0
- package/package.json +226 -0
- package/src/styles/globals.css +157 -0
|
@@ -0,0 +1,1927 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/providers/auth/AuthContext.tsx
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
var AuthContext = createContext(null);
|
|
7
|
+
AuthContext.displayName = "ComponentAuthContext";
|
|
8
|
+
function AuthProvider({
|
|
9
|
+
children,
|
|
10
|
+
value
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
|
|
13
|
+
}
|
|
14
|
+
function useComponentAuth() {
|
|
15
|
+
const context = useContext(AuthContext);
|
|
16
|
+
if (context === null) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
"useComponentAuth must be used within an AuthProvider. Make sure to wrap your component tree with <AuthProvider value={...}>. You can create the value using an adapter like createPolDbHooksAuthAdapter()."
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return context;
|
|
22
|
+
}
|
|
23
|
+
function useComponentAuthOptional() {
|
|
24
|
+
const context = useContext(AuthContext);
|
|
25
|
+
return context;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/providers/router/RouterContext.tsx
|
|
29
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
30
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
31
|
+
var RouterContext = createContext2(null);
|
|
32
|
+
function RouterProvider({ adapter, children }) {
|
|
33
|
+
return /* @__PURE__ */ jsx2(RouterContext.Provider, { value: adapter, children });
|
|
34
|
+
}
|
|
35
|
+
function useRouter() {
|
|
36
|
+
const context = useContext2(RouterContext);
|
|
37
|
+
if (!context) {
|
|
38
|
+
throw new Error("useRouter must be used within a RouterProvider. Make sure to wrap your app with <RouterProvider adapter={yourAdapter}>.");
|
|
39
|
+
}
|
|
40
|
+
return context;
|
|
41
|
+
}
|
|
42
|
+
function useNavigate() {
|
|
43
|
+
const router = useRouter();
|
|
44
|
+
return router.navigate;
|
|
45
|
+
}
|
|
46
|
+
function useLocation() {
|
|
47
|
+
const router = useRouter();
|
|
48
|
+
return router.useLocation();
|
|
49
|
+
}
|
|
50
|
+
function useParams() {
|
|
51
|
+
const router = useRouter();
|
|
52
|
+
return router.useParams();
|
|
53
|
+
}
|
|
54
|
+
function Link(props) {
|
|
55
|
+
const router = useRouter();
|
|
56
|
+
const LinkComponent = router.Link;
|
|
57
|
+
return /* @__PURE__ */ jsx2(LinkComponent, { ...props });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/providers/data/DataContext.tsx
|
|
61
|
+
import { createContext as createContext3, useContext as useContext3, useMemo } from "react";
|
|
62
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
63
|
+
var DataContext = createContext3(null);
|
|
64
|
+
function DataProvider({
|
|
65
|
+
adapter,
|
|
66
|
+
isReady = true,
|
|
67
|
+
children
|
|
68
|
+
}) {
|
|
69
|
+
const value = useMemo(
|
|
70
|
+
() => ({
|
|
71
|
+
adapter,
|
|
72
|
+
isReady
|
|
73
|
+
}),
|
|
74
|
+
[adapter, isReady]
|
|
75
|
+
);
|
|
76
|
+
return /* @__PURE__ */ jsx3(DataContext.Provider, { value, children });
|
|
77
|
+
}
|
|
78
|
+
function useDataAdapter() {
|
|
79
|
+
const context = useContext3(DataContext);
|
|
80
|
+
if (!context) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
"useDataAdapter must be used within a DataProvider. Make sure to wrap your application with <DataProvider adapter={yourAdapter}>."
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return context;
|
|
86
|
+
}
|
|
87
|
+
function useDataAdapterOptional() {
|
|
88
|
+
return useContext3(DataContext);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/providers/data/hooks/useDataQuery.ts
|
|
92
|
+
import { useState, useEffect, useCallback, useRef, useMemo as useMemo2 } from "react";
|
|
93
|
+
function useDataQuery(table, options = {}) {
|
|
94
|
+
const context = useDataAdapterOptional();
|
|
95
|
+
const adapter = context?.adapter;
|
|
96
|
+
const {
|
|
97
|
+
enabled = true,
|
|
98
|
+
filters,
|
|
99
|
+
sort,
|
|
100
|
+
pagination,
|
|
101
|
+
selectColumns,
|
|
102
|
+
realtime = false,
|
|
103
|
+
withCount = false,
|
|
104
|
+
cacheTime,
|
|
105
|
+
staleTime,
|
|
106
|
+
refetchOnWindowFocus,
|
|
107
|
+
refetchOnMount,
|
|
108
|
+
refetchInterval,
|
|
109
|
+
retry,
|
|
110
|
+
retryDelay,
|
|
111
|
+
transform,
|
|
112
|
+
onSuccess,
|
|
113
|
+
onError,
|
|
114
|
+
onSettled
|
|
115
|
+
} = options;
|
|
116
|
+
const [data, setData] = useState(void 0);
|
|
117
|
+
const [count, setCount] = useState(null);
|
|
118
|
+
const [error, setError] = useState(null);
|
|
119
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
120
|
+
const [isFetching, setIsFetching] = useState(false);
|
|
121
|
+
const abortControllerRef = useRef(null);
|
|
122
|
+
const retryCountRef = useRef(0);
|
|
123
|
+
const retryTimeoutRef = useRef(null);
|
|
124
|
+
const unsubscribeRef = useRef(null);
|
|
125
|
+
const refetchIntervalRef = useRef(null);
|
|
126
|
+
const hasDataRef = useRef(false);
|
|
127
|
+
const onSuccessRef = useRef(onSuccess);
|
|
128
|
+
const onErrorRef = useRef(onError);
|
|
129
|
+
const onSettledRef = useRef(onSettled);
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
onSuccessRef.current = onSuccess;
|
|
132
|
+
onErrorRef.current = onError;
|
|
133
|
+
onSettledRef.current = onSettled;
|
|
134
|
+
});
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
hasDataRef.current = data !== void 0;
|
|
137
|
+
}, [data]);
|
|
138
|
+
const stableFilters = useMemo2(() => filters, [JSON.stringify(filters)]);
|
|
139
|
+
const stableSort = useMemo2(() => sort, [JSON.stringify(sort)]);
|
|
140
|
+
const stablePagination = useMemo2(() => pagination, [JSON.stringify(pagination)]);
|
|
141
|
+
const queryParams = {
|
|
142
|
+
filters,
|
|
143
|
+
sort,
|
|
144
|
+
pagination,
|
|
145
|
+
select: selectColumns
|
|
146
|
+
};
|
|
147
|
+
const fetchData = useCallback(async () => {
|
|
148
|
+
if (!adapter) {
|
|
149
|
+
const err = new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
150
|
+
setError(err);
|
|
151
|
+
return { data: void 0, error: err };
|
|
152
|
+
}
|
|
153
|
+
if (!enabled) {
|
|
154
|
+
return { data: void 0, error: null };
|
|
155
|
+
}
|
|
156
|
+
if (abortControllerRef.current) {
|
|
157
|
+
abortControllerRef.current.abort();
|
|
158
|
+
}
|
|
159
|
+
abortControllerRef.current = new AbortController();
|
|
160
|
+
setIsFetching(true);
|
|
161
|
+
if (!hasDataRef.current) {
|
|
162
|
+
setIsLoading(true);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
let result;
|
|
166
|
+
let totalCount = null;
|
|
167
|
+
if (withCount) {
|
|
168
|
+
const response = await adapter.getManyWithCount(table, queryParams);
|
|
169
|
+
result = response.data;
|
|
170
|
+
totalCount = response.count;
|
|
171
|
+
} else {
|
|
172
|
+
result = await adapter.getMany(table, queryParams);
|
|
173
|
+
}
|
|
174
|
+
setData(result);
|
|
175
|
+
setCount(totalCount);
|
|
176
|
+
setError(null);
|
|
177
|
+
retryCountRef.current = 0;
|
|
178
|
+
onSuccessRef.current?.(result);
|
|
179
|
+
onSettledRef.current?.(result, null);
|
|
180
|
+
return { data: result, error: null };
|
|
181
|
+
} catch (err) {
|
|
182
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
183
|
+
const shouldRetry = retry === true || typeof retry === "number" && retryCountRef.current < retry;
|
|
184
|
+
if (shouldRetry) {
|
|
185
|
+
retryCountRef.current++;
|
|
186
|
+
const delay = retryDelay ?? 1e3 * retryCountRef.current;
|
|
187
|
+
return new Promise((resolve) => {
|
|
188
|
+
retryTimeoutRef.current = setTimeout(async () => {
|
|
189
|
+
retryTimeoutRef.current = null;
|
|
190
|
+
const result = await fetchData();
|
|
191
|
+
resolve(result);
|
|
192
|
+
}, delay);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
setError(error2);
|
|
196
|
+
onErrorRef.current?.(error2);
|
|
197
|
+
onSettledRef.current?.(void 0, error2);
|
|
198
|
+
return { data: void 0, error: error2 };
|
|
199
|
+
} finally {
|
|
200
|
+
setIsLoading(false);
|
|
201
|
+
setIsFetching(false);
|
|
202
|
+
}
|
|
203
|
+
}, [
|
|
204
|
+
adapter,
|
|
205
|
+
enabled,
|
|
206
|
+
table,
|
|
207
|
+
stableFilters,
|
|
208
|
+
stableSort,
|
|
209
|
+
stablePagination,
|
|
210
|
+
selectColumns,
|
|
211
|
+
withCount,
|
|
212
|
+
retry,
|
|
213
|
+
retryDelay
|
|
214
|
+
]);
|
|
215
|
+
const refetch = useCallback(async () => {
|
|
216
|
+
const result = await fetchData();
|
|
217
|
+
return {
|
|
218
|
+
data: result.data,
|
|
219
|
+
error: result.error,
|
|
220
|
+
isLoading: false,
|
|
221
|
+
// After fetch completes, loading is false
|
|
222
|
+
isError: result.error !== null,
|
|
223
|
+
isSuccess: result.error === null && result.data !== void 0,
|
|
224
|
+
isFetching: false,
|
|
225
|
+
// After fetch completes, fetching is false
|
|
226
|
+
refetch
|
|
227
|
+
};
|
|
228
|
+
}, [fetchData]);
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
if (enabled && adapter) {
|
|
231
|
+
fetchData();
|
|
232
|
+
}
|
|
233
|
+
return () => {
|
|
234
|
+
if (abortControllerRef.current) {
|
|
235
|
+
abortControllerRef.current.abort();
|
|
236
|
+
}
|
|
237
|
+
if (retryTimeoutRef.current) {
|
|
238
|
+
clearTimeout(retryTimeoutRef.current);
|
|
239
|
+
retryTimeoutRef.current = null;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}, [fetchData, enabled, adapter]);
|
|
243
|
+
useEffect(() => {
|
|
244
|
+
if (!realtime || !enabled || !adapter?.subscribe) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const handleRealtimeChange = (payload) => {
|
|
248
|
+
setData((currentData) => {
|
|
249
|
+
if (!currentData) return currentData;
|
|
250
|
+
switch (payload.eventType) {
|
|
251
|
+
case "INSERT":
|
|
252
|
+
if (payload.new) {
|
|
253
|
+
return [...currentData, payload.new];
|
|
254
|
+
}
|
|
255
|
+
return currentData;
|
|
256
|
+
case "UPDATE":
|
|
257
|
+
if (payload.new) {
|
|
258
|
+
return currentData.map((item) => {
|
|
259
|
+
const itemId = item?.id;
|
|
260
|
+
const newId = payload.new?.id;
|
|
261
|
+
if (itemId && newId && itemId === newId) {
|
|
262
|
+
return payload.new;
|
|
263
|
+
}
|
|
264
|
+
return item;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return currentData;
|
|
268
|
+
case "DELETE":
|
|
269
|
+
if (payload.old) {
|
|
270
|
+
const oldId = payload.old?.id;
|
|
271
|
+
if (oldId) {
|
|
272
|
+
return currentData.filter((item) => item?.id !== oldId);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return currentData;
|
|
276
|
+
default:
|
|
277
|
+
return currentData;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
unsubscribeRef.current = adapter.subscribe(table, handleRealtimeChange, stableFilters);
|
|
282
|
+
return () => {
|
|
283
|
+
if (unsubscribeRef.current) {
|
|
284
|
+
unsubscribeRef.current();
|
|
285
|
+
unsubscribeRef.current = null;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
}, [realtime, enabled, adapter, table, stableFilters]);
|
|
289
|
+
useEffect(() => {
|
|
290
|
+
if (!refetchInterval || !enabled) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
refetchIntervalRef.current = setInterval(fetchData, refetchInterval);
|
|
294
|
+
return () => {
|
|
295
|
+
if (refetchIntervalRef.current) {
|
|
296
|
+
clearInterval(refetchIntervalRef.current);
|
|
297
|
+
refetchIntervalRef.current = null;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}, [refetchInterval, enabled, fetchData]);
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
if (!refetchOnWindowFocus || !enabled) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const handleFocus = () => {
|
|
306
|
+
fetchData();
|
|
307
|
+
};
|
|
308
|
+
window.addEventListener("focus", handleFocus);
|
|
309
|
+
return () => {
|
|
310
|
+
window.removeEventListener("focus", handleFocus);
|
|
311
|
+
};
|
|
312
|
+
}, [refetchOnWindowFocus, enabled, fetchData]);
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (refetchOnMount && enabled && adapter) {
|
|
315
|
+
fetchData();
|
|
316
|
+
}
|
|
317
|
+
}, [refetchOnMount, enabled, adapter, fetchData]);
|
|
318
|
+
return {
|
|
319
|
+
data,
|
|
320
|
+
count,
|
|
321
|
+
error,
|
|
322
|
+
isLoading,
|
|
323
|
+
isError: error !== null,
|
|
324
|
+
isSuccess: error === null && data !== void 0,
|
|
325
|
+
isFetching,
|
|
326
|
+
refetch
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function useDataQueryById(table, id, options = {}) {
|
|
330
|
+
const context = useDataAdapterOptional();
|
|
331
|
+
const adapter = context?.adapter;
|
|
332
|
+
const { enabled = true, onSuccess, onError, onSettled, retry, retryDelay } = options;
|
|
333
|
+
const [data, setData] = useState(void 0);
|
|
334
|
+
const [error, setError] = useState(null);
|
|
335
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
336
|
+
const [isFetching, setIsFetching] = useState(false);
|
|
337
|
+
const retryCountRef = useRef(0);
|
|
338
|
+
const onSuccessRef = useRef(onSuccess);
|
|
339
|
+
const onErrorRef = useRef(onError);
|
|
340
|
+
const onSettledRef = useRef(onSettled);
|
|
341
|
+
useEffect(() => {
|
|
342
|
+
onSuccessRef.current = onSuccess;
|
|
343
|
+
onErrorRef.current = onError;
|
|
344
|
+
onSettledRef.current = onSettled;
|
|
345
|
+
});
|
|
346
|
+
const fetchData = useCallback(async () => {
|
|
347
|
+
if (!adapter || !id || !enabled) {
|
|
348
|
+
return { data: void 0, error: null };
|
|
349
|
+
}
|
|
350
|
+
setIsFetching(true);
|
|
351
|
+
if (data === void 0) {
|
|
352
|
+
setIsLoading(true);
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
const result = await adapter.getById(table, id);
|
|
356
|
+
setData(result);
|
|
357
|
+
setError(null);
|
|
358
|
+
retryCountRef.current = 0;
|
|
359
|
+
onSuccessRef.current?.(result);
|
|
360
|
+
onSettledRef.current?.(result, null);
|
|
361
|
+
return { data: result, error: null };
|
|
362
|
+
} catch (err) {
|
|
363
|
+
const error2 = err instanceof Error ? err : new Error(String(err));
|
|
364
|
+
const shouldRetry = retry === true || typeof retry === "number" && retryCountRef.current < retry;
|
|
365
|
+
if (shouldRetry) {
|
|
366
|
+
retryCountRef.current++;
|
|
367
|
+
const delay = retryDelay ?? 1e3 * retryCountRef.current;
|
|
368
|
+
return new Promise((resolve) => {
|
|
369
|
+
setTimeout(async () => {
|
|
370
|
+
const result = await fetchData();
|
|
371
|
+
resolve(result);
|
|
372
|
+
}, delay);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
setError(error2);
|
|
376
|
+
onErrorRef.current?.(error2);
|
|
377
|
+
onSettledRef.current?.(void 0, error2);
|
|
378
|
+
return { data: void 0, error: error2 };
|
|
379
|
+
} finally {
|
|
380
|
+
setIsLoading(false);
|
|
381
|
+
setIsFetching(false);
|
|
382
|
+
}
|
|
383
|
+
}, [adapter, id, enabled, table, retry, retryDelay]);
|
|
384
|
+
const refetch = useCallback(async () => {
|
|
385
|
+
const result = await fetchData();
|
|
386
|
+
return {
|
|
387
|
+
data: result.data ?? null,
|
|
388
|
+
error: result.error,
|
|
389
|
+
isLoading: false,
|
|
390
|
+
// After fetch completes, loading is false
|
|
391
|
+
isError: result.error !== null,
|
|
392
|
+
isSuccess: result.error === null && result.data !== void 0,
|
|
393
|
+
isFetching: false,
|
|
394
|
+
// After fetch completes, fetching is false
|
|
395
|
+
refetch
|
|
396
|
+
};
|
|
397
|
+
}, [fetchData]);
|
|
398
|
+
useEffect(() => {
|
|
399
|
+
if (enabled && adapter && id) {
|
|
400
|
+
fetchData();
|
|
401
|
+
}
|
|
402
|
+
}, [fetchData, enabled, adapter, id]);
|
|
403
|
+
return {
|
|
404
|
+
data: data ?? null,
|
|
405
|
+
error,
|
|
406
|
+
isLoading,
|
|
407
|
+
isError: error !== null,
|
|
408
|
+
isSuccess: error === null && data !== void 0,
|
|
409
|
+
isFetching,
|
|
410
|
+
refetch
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// src/providers/data/hooks/useDataMutation.ts
|
|
415
|
+
import { useState as useState2, useCallback as useCallback2, useRef as useRef2, useEffect as useEffect2 } from "react";
|
|
416
|
+
var initialMutationState = () => ({
|
|
417
|
+
data: void 0,
|
|
418
|
+
error: null,
|
|
419
|
+
status: "idle"
|
|
420
|
+
});
|
|
421
|
+
function useDataMutation(table, options = {}) {
|
|
422
|
+
const context = useDataAdapterOptional();
|
|
423
|
+
const adapter = context?.adapter;
|
|
424
|
+
const { primaryKey = "id", ...mutationOptions } = options;
|
|
425
|
+
const [states, setStates] = useState2({
|
|
426
|
+
insert: initialMutationState(),
|
|
427
|
+
update: initialMutationState(),
|
|
428
|
+
remove: initialMutationState()
|
|
429
|
+
});
|
|
430
|
+
const insertContextRef = useRef2(void 0);
|
|
431
|
+
const updateContextRef = useRef2(void 0);
|
|
432
|
+
const removeContextRef = useRef2(void 0);
|
|
433
|
+
const onMutateRef = useRef2(mutationOptions.onMutate);
|
|
434
|
+
const onSuccessRef = useRef2(mutationOptions.onSuccess);
|
|
435
|
+
const onErrorRef = useRef2(mutationOptions.onError);
|
|
436
|
+
const onSettledRef = useRef2(mutationOptions.onSettled);
|
|
437
|
+
useEffect2(() => {
|
|
438
|
+
onMutateRef.current = mutationOptions.onMutate;
|
|
439
|
+
onSuccessRef.current = mutationOptions.onSuccess;
|
|
440
|
+
onErrorRef.current = mutationOptions.onError;
|
|
441
|
+
onSettledRef.current = mutationOptions.onSettled;
|
|
442
|
+
});
|
|
443
|
+
const insertReset = useCallback2(() => {
|
|
444
|
+
setStates((s) => ({ ...s, insert: initialMutationState() }));
|
|
445
|
+
insertContextRef.current = void 0;
|
|
446
|
+
}, []);
|
|
447
|
+
const insertMutateAsync = useCallback2(
|
|
448
|
+
async (data) => {
|
|
449
|
+
setStates((s) => ({
|
|
450
|
+
...s,
|
|
451
|
+
insert: { ...s.insert, status: "loading", error: null }
|
|
452
|
+
}));
|
|
453
|
+
try {
|
|
454
|
+
if (!adapter) {
|
|
455
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
456
|
+
}
|
|
457
|
+
insertContextRef.current = await onMutateRef.current?.(data);
|
|
458
|
+
const result = await adapter.create(table, data);
|
|
459
|
+
setStates((s) => ({
|
|
460
|
+
...s,
|
|
461
|
+
insert: { data: result, error: null, status: "success" }
|
|
462
|
+
}));
|
|
463
|
+
onSuccessRef.current?.(result, data, insertContextRef.current);
|
|
464
|
+
onSettledRef.current?.(result, null, data, insertContextRef.current);
|
|
465
|
+
return result;
|
|
466
|
+
} catch (err) {
|
|
467
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
468
|
+
setStates((s) => ({
|
|
469
|
+
...s,
|
|
470
|
+
insert: { ...s.insert, error: mutationError, status: "error" }
|
|
471
|
+
}));
|
|
472
|
+
onErrorRef.current?.(mutationError, data, insertContextRef.current);
|
|
473
|
+
onSettledRef.current?.(void 0, mutationError, data, insertContextRef.current);
|
|
474
|
+
throw mutationError;
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
[adapter, table]
|
|
478
|
+
);
|
|
479
|
+
const insertMutate = useCallback2(
|
|
480
|
+
(data) => {
|
|
481
|
+
insertMutateAsync(data).catch(() => {
|
|
482
|
+
});
|
|
483
|
+
},
|
|
484
|
+
[insertMutateAsync]
|
|
485
|
+
);
|
|
486
|
+
const updateReset = useCallback2(() => {
|
|
487
|
+
setStates((s) => ({ ...s, update: initialMutationState() }));
|
|
488
|
+
updateContextRef.current = void 0;
|
|
489
|
+
}, []);
|
|
490
|
+
const updateMutateAsync = useCallback2(
|
|
491
|
+
async (data) => {
|
|
492
|
+
setStates((s) => ({
|
|
493
|
+
...s,
|
|
494
|
+
update: { ...s.update, status: "loading", error: null }
|
|
495
|
+
}));
|
|
496
|
+
try {
|
|
497
|
+
if (!adapter) {
|
|
498
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
499
|
+
}
|
|
500
|
+
const { id, ...updateData } = data;
|
|
501
|
+
if (!id) {
|
|
502
|
+
throw new Error("Update requires an id field");
|
|
503
|
+
}
|
|
504
|
+
updateContextRef.current = await onMutateRef.current?.(data);
|
|
505
|
+
const result = await adapter.update(table, id, updateData);
|
|
506
|
+
setStates((s) => ({
|
|
507
|
+
...s,
|
|
508
|
+
update: { data: result, error: null, status: "success" }
|
|
509
|
+
}));
|
|
510
|
+
onSuccessRef.current?.(result, data, updateContextRef.current);
|
|
511
|
+
onSettledRef.current?.(result, null, data, updateContextRef.current);
|
|
512
|
+
return result;
|
|
513
|
+
} catch (err) {
|
|
514
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
515
|
+
setStates((s) => ({
|
|
516
|
+
...s,
|
|
517
|
+
update: { ...s.update, error: mutationError, status: "error" }
|
|
518
|
+
}));
|
|
519
|
+
onErrorRef.current?.(mutationError, data, updateContextRef.current);
|
|
520
|
+
onSettledRef.current?.(void 0, mutationError, data, updateContextRef.current);
|
|
521
|
+
throw mutationError;
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
[adapter, table]
|
|
525
|
+
);
|
|
526
|
+
const updateMutate = useCallback2(
|
|
527
|
+
(data) => {
|
|
528
|
+
updateMutateAsync(data).catch(() => {
|
|
529
|
+
});
|
|
530
|
+
},
|
|
531
|
+
[updateMutateAsync]
|
|
532
|
+
);
|
|
533
|
+
const removeReset = useCallback2(() => {
|
|
534
|
+
setStates((s) => ({ ...s, remove: initialMutationState() }));
|
|
535
|
+
removeContextRef.current = void 0;
|
|
536
|
+
}, []);
|
|
537
|
+
const removeMutateAsync = useCallback2(
|
|
538
|
+
async (id) => {
|
|
539
|
+
setStates((s) => ({
|
|
540
|
+
...s,
|
|
541
|
+
remove: { ...s.remove, status: "loading", error: null }
|
|
542
|
+
}));
|
|
543
|
+
try {
|
|
544
|
+
if (!adapter) {
|
|
545
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
546
|
+
}
|
|
547
|
+
removeContextRef.current = await onMutateRef.current?.({ [primaryKey]: id });
|
|
548
|
+
await adapter.delete(table, id);
|
|
549
|
+
setStates((s) => ({
|
|
550
|
+
...s,
|
|
551
|
+
remove: { data: void 0, error: null, status: "success" }
|
|
552
|
+
}));
|
|
553
|
+
onSuccessRef.current?.(void 0, { [primaryKey]: id }, removeContextRef.current);
|
|
554
|
+
onSettledRef.current?.(void 0, null, { [primaryKey]: id }, removeContextRef.current);
|
|
555
|
+
} catch (err) {
|
|
556
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
557
|
+
setStates((s) => ({
|
|
558
|
+
...s,
|
|
559
|
+
remove: { ...s.remove, error: mutationError, status: "error" }
|
|
560
|
+
}));
|
|
561
|
+
onErrorRef.current?.(mutationError, { [primaryKey]: id }, removeContextRef.current);
|
|
562
|
+
onSettledRef.current?.(void 0, mutationError, { [primaryKey]: id }, removeContextRef.current);
|
|
563
|
+
throw mutationError;
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
[adapter, table, primaryKey]
|
|
567
|
+
);
|
|
568
|
+
const removeMutate = useCallback2(
|
|
569
|
+
(id) => {
|
|
570
|
+
removeMutateAsync(id).catch(() => {
|
|
571
|
+
});
|
|
572
|
+
},
|
|
573
|
+
[removeMutateAsync]
|
|
574
|
+
);
|
|
575
|
+
return {
|
|
576
|
+
insert: {
|
|
577
|
+
data: states.insert.data,
|
|
578
|
+
error: states.insert.error,
|
|
579
|
+
isLoading: states.insert.status === "loading",
|
|
580
|
+
isError: states.insert.status === "error",
|
|
581
|
+
isSuccess: states.insert.status === "success",
|
|
582
|
+
isIdle: states.insert.status === "idle",
|
|
583
|
+
mutate: insertMutate,
|
|
584
|
+
mutateAsync: insertMutateAsync,
|
|
585
|
+
reset: insertReset
|
|
586
|
+
},
|
|
587
|
+
update: {
|
|
588
|
+
data: states.update.data,
|
|
589
|
+
error: states.update.error,
|
|
590
|
+
isLoading: states.update.status === "loading",
|
|
591
|
+
isError: states.update.status === "error",
|
|
592
|
+
isSuccess: states.update.status === "success",
|
|
593
|
+
isIdle: states.update.status === "idle",
|
|
594
|
+
mutate: updateMutate,
|
|
595
|
+
mutateAsync: updateMutateAsync,
|
|
596
|
+
reset: updateReset
|
|
597
|
+
},
|
|
598
|
+
remove: {
|
|
599
|
+
data: states.remove.data,
|
|
600
|
+
error: states.remove.error,
|
|
601
|
+
isLoading: states.remove.status === "loading",
|
|
602
|
+
isError: states.remove.status === "error",
|
|
603
|
+
isSuccess: states.remove.status === "success",
|
|
604
|
+
isIdle: states.remove.status === "idle",
|
|
605
|
+
mutate: removeMutate,
|
|
606
|
+
mutateAsync: removeMutateAsync,
|
|
607
|
+
reset: removeReset
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
function useDataInsert(table, options = {}) {
|
|
612
|
+
const context = useDataAdapterOptional();
|
|
613
|
+
const adapter = context?.adapter;
|
|
614
|
+
const [data, setData] = useState2(void 0);
|
|
615
|
+
const [error, setError] = useState2(null);
|
|
616
|
+
const [status, setStatus] = useState2("idle");
|
|
617
|
+
const contextRef = useRef2(void 0);
|
|
618
|
+
const onMutateRef = useRef2(options.onMutate);
|
|
619
|
+
const onSuccessRef = useRef2(options.onSuccess);
|
|
620
|
+
const onErrorRef = useRef2(options.onError);
|
|
621
|
+
const onSettledRef = useRef2(options.onSettled);
|
|
622
|
+
useEffect2(() => {
|
|
623
|
+
onMutateRef.current = options.onMutate;
|
|
624
|
+
onSuccessRef.current = options.onSuccess;
|
|
625
|
+
onErrorRef.current = options.onError;
|
|
626
|
+
onSettledRef.current = options.onSettled;
|
|
627
|
+
});
|
|
628
|
+
const reset = useCallback2(() => {
|
|
629
|
+
setData(void 0);
|
|
630
|
+
setError(null);
|
|
631
|
+
setStatus("idle");
|
|
632
|
+
contextRef.current = void 0;
|
|
633
|
+
}, []);
|
|
634
|
+
const mutateAsync = useCallback2(
|
|
635
|
+
async (insertData) => {
|
|
636
|
+
setStatus("loading");
|
|
637
|
+
setError(null);
|
|
638
|
+
try {
|
|
639
|
+
if (!adapter) {
|
|
640
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
641
|
+
}
|
|
642
|
+
contextRef.current = await onMutateRef.current?.(insertData);
|
|
643
|
+
const result = await adapter.create(table, insertData);
|
|
644
|
+
setData(result);
|
|
645
|
+
setStatus("success");
|
|
646
|
+
onSuccessRef.current?.(result, insertData, contextRef.current);
|
|
647
|
+
onSettledRef.current?.(result, null, insertData, contextRef.current);
|
|
648
|
+
return result;
|
|
649
|
+
} catch (err) {
|
|
650
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
651
|
+
setError(mutationError);
|
|
652
|
+
setStatus("error");
|
|
653
|
+
onErrorRef.current?.(mutationError, insertData, contextRef.current);
|
|
654
|
+
onSettledRef.current?.(void 0, mutationError, insertData, contextRef.current);
|
|
655
|
+
throw mutationError;
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
[adapter, table]
|
|
659
|
+
);
|
|
660
|
+
const mutate = useCallback2(
|
|
661
|
+
(insertData) => {
|
|
662
|
+
mutateAsync(insertData).catch(() => {
|
|
663
|
+
});
|
|
664
|
+
},
|
|
665
|
+
[mutateAsync]
|
|
666
|
+
);
|
|
667
|
+
return {
|
|
668
|
+
data,
|
|
669
|
+
error,
|
|
670
|
+
isLoading: status === "loading",
|
|
671
|
+
isError: status === "error",
|
|
672
|
+
isSuccess: status === "success",
|
|
673
|
+
isIdle: status === "idle",
|
|
674
|
+
status,
|
|
675
|
+
mutate,
|
|
676
|
+
mutateAsync,
|
|
677
|
+
reset
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
function useDataUpdate(table, options = {}) {
|
|
681
|
+
const context = useDataAdapterOptional();
|
|
682
|
+
const adapter = context?.adapter;
|
|
683
|
+
const [data, setData] = useState2(void 0);
|
|
684
|
+
const [error, setError] = useState2(null);
|
|
685
|
+
const [status, setStatus] = useState2("idle");
|
|
686
|
+
const contextRef = useRef2(void 0);
|
|
687
|
+
const onMutateRef = useRef2(options.onMutate);
|
|
688
|
+
const onSuccessRef = useRef2(options.onSuccess);
|
|
689
|
+
const onErrorRef = useRef2(options.onError);
|
|
690
|
+
const onSettledRef = useRef2(options.onSettled);
|
|
691
|
+
useEffect2(() => {
|
|
692
|
+
onMutateRef.current = options.onMutate;
|
|
693
|
+
onSuccessRef.current = options.onSuccess;
|
|
694
|
+
onErrorRef.current = options.onError;
|
|
695
|
+
onSettledRef.current = options.onSettled;
|
|
696
|
+
});
|
|
697
|
+
const reset = useCallback2(() => {
|
|
698
|
+
setData(void 0);
|
|
699
|
+
setError(null);
|
|
700
|
+
setStatus("idle");
|
|
701
|
+
contextRef.current = void 0;
|
|
702
|
+
}, []);
|
|
703
|
+
const mutateAsync = useCallback2(
|
|
704
|
+
async (updateData) => {
|
|
705
|
+
setStatus("loading");
|
|
706
|
+
setError(null);
|
|
707
|
+
try {
|
|
708
|
+
if (!adapter) {
|
|
709
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
710
|
+
}
|
|
711
|
+
const { id, ...restData } = updateData;
|
|
712
|
+
contextRef.current = await onMutateRef.current?.(updateData);
|
|
713
|
+
const result = await adapter.update(table, id, restData);
|
|
714
|
+
setData(result);
|
|
715
|
+
setStatus("success");
|
|
716
|
+
onSuccessRef.current?.(result, updateData, contextRef.current);
|
|
717
|
+
onSettledRef.current?.(result, null, updateData, contextRef.current);
|
|
718
|
+
return result;
|
|
719
|
+
} catch (err) {
|
|
720
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
721
|
+
setError(mutationError);
|
|
722
|
+
setStatus("error");
|
|
723
|
+
onErrorRef.current?.(mutationError, updateData, contextRef.current);
|
|
724
|
+
onSettledRef.current?.(void 0, mutationError, updateData, contextRef.current);
|
|
725
|
+
throw mutationError;
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
[adapter, table]
|
|
729
|
+
);
|
|
730
|
+
const mutate = useCallback2(
|
|
731
|
+
(updateData) => {
|
|
732
|
+
mutateAsync(updateData).catch(() => {
|
|
733
|
+
});
|
|
734
|
+
},
|
|
735
|
+
[mutateAsync]
|
|
736
|
+
);
|
|
737
|
+
return {
|
|
738
|
+
data,
|
|
739
|
+
error,
|
|
740
|
+
isLoading: status === "loading",
|
|
741
|
+
isError: status === "error",
|
|
742
|
+
isSuccess: status === "success",
|
|
743
|
+
isIdle: status === "idle",
|
|
744
|
+
status,
|
|
745
|
+
mutate,
|
|
746
|
+
mutateAsync,
|
|
747
|
+
reset
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function useDataDelete(table, options = {}) {
|
|
751
|
+
const context = useDataAdapterOptional();
|
|
752
|
+
const adapter = context?.adapter;
|
|
753
|
+
const [data, setData] = useState2(void 0);
|
|
754
|
+
const [error, setError] = useState2(null);
|
|
755
|
+
const [status, setStatus] = useState2("idle");
|
|
756
|
+
const contextRef = useRef2(void 0);
|
|
757
|
+
const onMutateRef = useRef2(options.onMutate);
|
|
758
|
+
const onSuccessRef = useRef2(options.onSuccess);
|
|
759
|
+
const onErrorRef = useRef2(options.onError);
|
|
760
|
+
const onSettledRef = useRef2(options.onSettled);
|
|
761
|
+
useEffect2(() => {
|
|
762
|
+
onMutateRef.current = options.onMutate;
|
|
763
|
+
onSuccessRef.current = options.onSuccess;
|
|
764
|
+
onErrorRef.current = options.onError;
|
|
765
|
+
onSettledRef.current = options.onSettled;
|
|
766
|
+
});
|
|
767
|
+
const reset = useCallback2(() => {
|
|
768
|
+
setData(void 0);
|
|
769
|
+
setError(null);
|
|
770
|
+
setStatus("idle");
|
|
771
|
+
contextRef.current = void 0;
|
|
772
|
+
}, []);
|
|
773
|
+
const mutateAsync = useCallback2(
|
|
774
|
+
async (id) => {
|
|
775
|
+
setStatus("loading");
|
|
776
|
+
setError(null);
|
|
777
|
+
try {
|
|
778
|
+
if (!adapter) {
|
|
779
|
+
throw new Error("No DataAdapter available. Wrap your app with DataProvider.");
|
|
780
|
+
}
|
|
781
|
+
contextRef.current = await onMutateRef.current?.(id);
|
|
782
|
+
await adapter.delete(table, id);
|
|
783
|
+
setData(void 0);
|
|
784
|
+
setStatus("success");
|
|
785
|
+
onSuccessRef.current?.(void 0, id, contextRef.current);
|
|
786
|
+
onSettledRef.current?.(void 0, null, id, contextRef.current);
|
|
787
|
+
} catch (err) {
|
|
788
|
+
const mutationError = err instanceof Error ? err : new Error(String(err));
|
|
789
|
+
setError(mutationError);
|
|
790
|
+
setStatus("error");
|
|
791
|
+
onErrorRef.current?.(mutationError, id, contextRef.current);
|
|
792
|
+
onSettledRef.current?.(void 0, mutationError, id, contextRef.current);
|
|
793
|
+
throw mutationError;
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
[adapter, table]
|
|
797
|
+
);
|
|
798
|
+
const mutate = useCallback2(
|
|
799
|
+
(id) => {
|
|
800
|
+
mutateAsync(id).catch(() => {
|
|
801
|
+
});
|
|
802
|
+
},
|
|
803
|
+
[mutateAsync]
|
|
804
|
+
);
|
|
805
|
+
return {
|
|
806
|
+
data,
|
|
807
|
+
error,
|
|
808
|
+
isLoading: status === "loading",
|
|
809
|
+
isError: status === "error",
|
|
810
|
+
isSuccess: status === "success",
|
|
811
|
+
isIdle: status === "idle",
|
|
812
|
+
status,
|
|
813
|
+
mutate,
|
|
814
|
+
mutateAsync,
|
|
815
|
+
reset
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
// src/providers/config/types.ts
|
|
820
|
+
var DEFAULT_ROUTES = {
|
|
821
|
+
login: "/login",
|
|
822
|
+
signUp: "/sign-up",
|
|
823
|
+
forgotPassword: "/forgot-password",
|
|
824
|
+
home: "/",
|
|
825
|
+
notFound: "/404",
|
|
826
|
+
profile: "/profile",
|
|
827
|
+
settings: "/settings"
|
|
828
|
+
};
|
|
829
|
+
var DEFAULT_FEATURES = {
|
|
830
|
+
enableNotifications: true,
|
|
831
|
+
enableComments: true,
|
|
832
|
+
enableRealtime: false,
|
|
833
|
+
enableFileUploads: true,
|
|
834
|
+
enableDarkMode: true,
|
|
835
|
+
enableAnalytics: false,
|
|
836
|
+
enableSearch: true
|
|
837
|
+
};
|
|
838
|
+
var DEFAULT_THEME = {
|
|
839
|
+
defaultColorMode: "system",
|
|
840
|
+
borderRadius: "md"
|
|
841
|
+
};
|
|
842
|
+
var DEFAULT_LOCALIZATION = {
|
|
843
|
+
defaultLocale: "en-US",
|
|
844
|
+
supportedLocales: ["en-US"],
|
|
845
|
+
dateFormat: "MM/dd/yyyy",
|
|
846
|
+
timeFormat: "hh:mm a",
|
|
847
|
+
currency: "USD"
|
|
848
|
+
};
|
|
849
|
+
var DEFAULT_CONFIG = {
|
|
850
|
+
routes: DEFAULT_ROUTES,
|
|
851
|
+
features: DEFAULT_FEATURES,
|
|
852
|
+
theme: DEFAULT_THEME,
|
|
853
|
+
localization: DEFAULT_LOCALIZATION,
|
|
854
|
+
environment: "development"
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
// src/providers/config/ConfigContext.tsx
|
|
858
|
+
import React3, { createContext as createContext4, useContext as useContext4, useMemo as useMemo3, useState as useState3 } from "react";
|
|
859
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
860
|
+
function deepMerge(target, source) {
|
|
861
|
+
if (target === null || typeof target !== "object" || Array.isArray(target)) {
|
|
862
|
+
return source ?? target;
|
|
863
|
+
}
|
|
864
|
+
const result = { ...target };
|
|
865
|
+
for (const key in source) {
|
|
866
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
867
|
+
const sourceValue = source[key];
|
|
868
|
+
const targetValue = target[key];
|
|
869
|
+
if (sourceValue !== null && sourceValue !== void 0 && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && targetValue !== void 0 && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
870
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
871
|
+
} else if (sourceValue !== void 0) {
|
|
872
|
+
result[key] = sourceValue;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
var ConfigContext = createContext4(null);
|
|
879
|
+
var ConfigActionsContext = createContext4(null);
|
|
880
|
+
function ConfigProvider({ config, children }) {
|
|
881
|
+
const initialMergedConfig = useMemo3(() => {
|
|
882
|
+
if (!config) return DEFAULT_CONFIG;
|
|
883
|
+
return {
|
|
884
|
+
...DEFAULT_CONFIG,
|
|
885
|
+
...config,
|
|
886
|
+
routes: {
|
|
887
|
+
...DEFAULT_ROUTES,
|
|
888
|
+
...config.routes
|
|
889
|
+
},
|
|
890
|
+
features: {
|
|
891
|
+
...DEFAULT_FEATURES,
|
|
892
|
+
...config.features
|
|
893
|
+
},
|
|
894
|
+
theme: {
|
|
895
|
+
...DEFAULT_THEME,
|
|
896
|
+
...config.theme
|
|
897
|
+
},
|
|
898
|
+
localization: {
|
|
899
|
+
...DEFAULT_LOCALIZATION,
|
|
900
|
+
...config.localization
|
|
901
|
+
}
|
|
902
|
+
};
|
|
903
|
+
}, [config]);
|
|
904
|
+
const [configState, setConfigState] = useState3(initialMergedConfig);
|
|
905
|
+
React3.useEffect(() => {
|
|
906
|
+
setConfigState(initialMergedConfig);
|
|
907
|
+
}, [initialMergedConfig]);
|
|
908
|
+
const actions = useMemo3(() => ({
|
|
909
|
+
updateFeatureFlag: (key, value2) => {
|
|
910
|
+
setConfigState((prev) => ({
|
|
911
|
+
...prev,
|
|
912
|
+
features: { ...prev.features, [key]: value2 }
|
|
913
|
+
}));
|
|
914
|
+
},
|
|
915
|
+
updateRoute: (key, path) => {
|
|
916
|
+
setConfigState((prev) => ({
|
|
917
|
+
...prev,
|
|
918
|
+
routes: { ...prev.routes, [key]: path }
|
|
919
|
+
}));
|
|
920
|
+
},
|
|
921
|
+
updateConfig: (updates) => {
|
|
922
|
+
setConfigState((prev) => deepMerge(prev, updates));
|
|
923
|
+
},
|
|
924
|
+
resetConfig: () => {
|
|
925
|
+
setConfigState(initialMergedConfig);
|
|
926
|
+
}
|
|
927
|
+
}), [initialMergedConfig]);
|
|
928
|
+
const value = useMemo3(() => {
|
|
929
|
+
const isFeatureEnabled = (feature) => {
|
|
930
|
+
return configState.features?.[feature] ?? false;
|
|
931
|
+
};
|
|
932
|
+
const getRoute = (routeName) => {
|
|
933
|
+
return configState.routes[routeName] ?? "/";
|
|
934
|
+
};
|
|
935
|
+
return {
|
|
936
|
+
config: configState,
|
|
937
|
+
routes: configState.routes,
|
|
938
|
+
features: configState.features ?? DEFAULT_FEATURES,
|
|
939
|
+
isFeatureEnabled,
|
|
940
|
+
getRoute
|
|
941
|
+
};
|
|
942
|
+
}, [configState]);
|
|
943
|
+
return /* @__PURE__ */ jsx4(ConfigActionsContext.Provider, { value: actions, children: /* @__PURE__ */ jsx4(ConfigContext.Provider, { value, children }) });
|
|
944
|
+
}
|
|
945
|
+
function useComponentConfig() {
|
|
946
|
+
const context = useContext4(ConfigContext);
|
|
947
|
+
if (!context) {
|
|
948
|
+
throw new Error(
|
|
949
|
+
"useComponentConfig must be used within a ConfigProvider. Make sure to wrap your application with <ConfigProvider>."
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
return context;
|
|
953
|
+
}
|
|
954
|
+
function useComponentConfigOptional() {
|
|
955
|
+
const context = useContext4(ConfigContext);
|
|
956
|
+
if (!context) {
|
|
957
|
+
return {
|
|
958
|
+
config: DEFAULT_CONFIG,
|
|
959
|
+
routes: DEFAULT_ROUTES,
|
|
960
|
+
features: DEFAULT_FEATURES,
|
|
961
|
+
isFeatureEnabled: (feature) => DEFAULT_FEATURES[feature] ?? false,
|
|
962
|
+
getRoute: (routeName) => DEFAULT_ROUTES[routeName] ?? "/"
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
return context;
|
|
966
|
+
}
|
|
967
|
+
function useFeatureFlag(feature) {
|
|
968
|
+
const { isFeatureEnabled } = useComponentConfigOptional();
|
|
969
|
+
return isFeatureEnabled(feature);
|
|
970
|
+
}
|
|
971
|
+
function useRoute(routeName) {
|
|
972
|
+
const { getRoute } = useComponentConfigOptional();
|
|
973
|
+
return getRoute(routeName);
|
|
974
|
+
}
|
|
975
|
+
function useConfigActions() {
|
|
976
|
+
const context = useContext4(ConfigActionsContext);
|
|
977
|
+
if (!context) {
|
|
978
|
+
throw new Error(
|
|
979
|
+
"useConfigActions must be used within a ConfigProvider. Make sure to wrap your application with <ConfigProvider>."
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
return context;
|
|
983
|
+
}
|
|
984
|
+
function useConfigActionsOptional() {
|
|
985
|
+
const context = useContext4(ConfigActionsContext);
|
|
986
|
+
if (!context) {
|
|
987
|
+
return {
|
|
988
|
+
updateFeatureFlag: () => {
|
|
989
|
+
},
|
|
990
|
+
updateRoute: () => {
|
|
991
|
+
},
|
|
992
|
+
updateConfig: () => {
|
|
993
|
+
},
|
|
994
|
+
resetConfig: () => {
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
return context;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// src/providers/navigation/types.ts
|
|
1002
|
+
var DEFAULT_SIDEBAR_CONFIG = {
|
|
1003
|
+
links: [],
|
|
1004
|
+
collapsible: true,
|
|
1005
|
+
defaultCollapsed: false,
|
|
1006
|
+
expandedWidth: 256,
|
|
1007
|
+
collapsedWidth: 64
|
|
1008
|
+
};
|
|
1009
|
+
var DEFAULT_SIDEBAR_STATE = {
|
|
1010
|
+
isCollapsed: false,
|
|
1011
|
+
isVisible: true,
|
|
1012
|
+
activeLink: null,
|
|
1013
|
+
expandedSections: []
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
// src/providers/navigation/SidebarRegistry.tsx
|
|
1017
|
+
import React4, {
|
|
1018
|
+
createContext as createContext5,
|
|
1019
|
+
useCallback as useCallback3,
|
|
1020
|
+
useContext as useContext5,
|
|
1021
|
+
useMemo as useMemo4,
|
|
1022
|
+
useState as useState4
|
|
1023
|
+
} from "react";
|
|
1024
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1025
|
+
var SidebarContext = createContext5(null);
|
|
1026
|
+
function SidebarProvider({
|
|
1027
|
+
config,
|
|
1028
|
+
initialState,
|
|
1029
|
+
pathname,
|
|
1030
|
+
children
|
|
1031
|
+
}) {
|
|
1032
|
+
const mergedConfig = useMemo4(() => {
|
|
1033
|
+
const baseConfig = {
|
|
1034
|
+
...DEFAULT_SIDEBAR_CONFIG,
|
|
1035
|
+
...config
|
|
1036
|
+
};
|
|
1037
|
+
if (baseConfig.links.length > 0 && "links" in baseConfig.links[0]) {
|
|
1038
|
+
const normalizedLinks = baseConfig.links.map(
|
|
1039
|
+
(section, index) => ({
|
|
1040
|
+
...section,
|
|
1041
|
+
id: section.id ?? `section-${index}`
|
|
1042
|
+
})
|
|
1043
|
+
);
|
|
1044
|
+
return { ...baseConfig, links: normalizedLinks };
|
|
1045
|
+
}
|
|
1046
|
+
return baseConfig;
|
|
1047
|
+
}, [config]);
|
|
1048
|
+
const [state, setState] = useState4(() => ({
|
|
1049
|
+
...DEFAULT_SIDEBAR_STATE,
|
|
1050
|
+
...initialState,
|
|
1051
|
+
isCollapsed: initialState?.isCollapsed ?? mergedConfig.defaultCollapsed ?? false,
|
|
1052
|
+
activeLink: pathname ?? initialState?.activeLink ?? null
|
|
1053
|
+
}));
|
|
1054
|
+
React4.useEffect(() => {
|
|
1055
|
+
if (pathname !== void 0 && pathname !== state.activeLink) {
|
|
1056
|
+
setState((prev) => ({ ...prev, activeLink: pathname }));
|
|
1057
|
+
}
|
|
1058
|
+
}, [pathname, state.activeLink]);
|
|
1059
|
+
const actions = useMemo4(
|
|
1060
|
+
() => ({
|
|
1061
|
+
toggleCollapsed: () => setState((prev) => ({ ...prev, isCollapsed: !prev.isCollapsed })),
|
|
1062
|
+
setCollapsed: (collapsed) => setState((prev) => ({ ...prev, isCollapsed: collapsed })),
|
|
1063
|
+
toggleVisible: () => setState((prev) => ({ ...prev, isVisible: !prev.isVisible })),
|
|
1064
|
+
setVisible: (visible) => setState((prev) => ({ ...prev, isVisible: visible })),
|
|
1065
|
+
setActiveLink: (url) => setState((prev) => ({ ...prev, activeLink: url })),
|
|
1066
|
+
toggleSection: (sectionId) => setState((prev) => ({
|
|
1067
|
+
...prev,
|
|
1068
|
+
expandedSections: prev.expandedSections.includes(sectionId) ? prev.expandedSections.filter((id) => id !== sectionId) : [...prev.expandedSections, sectionId]
|
|
1069
|
+
})),
|
|
1070
|
+
expandSection: (sectionId) => setState((prev) => ({
|
|
1071
|
+
...prev,
|
|
1072
|
+
expandedSections: prev.expandedSections.includes(sectionId) ? prev.expandedSections : [...prev.expandedSections, sectionId]
|
|
1073
|
+
})),
|
|
1074
|
+
collapseSection: (sectionId) => setState((prev) => ({
|
|
1075
|
+
...prev,
|
|
1076
|
+
expandedSections: prev.expandedSections.filter(
|
|
1077
|
+
(id) => id !== sectionId
|
|
1078
|
+
)
|
|
1079
|
+
}))
|
|
1080
|
+
}),
|
|
1081
|
+
[]
|
|
1082
|
+
);
|
|
1083
|
+
const getAllLinks = useCallback3(() => {
|
|
1084
|
+
const collectLinks = (links2) => {
|
|
1085
|
+
return links2.flatMap((link) => [
|
|
1086
|
+
link,
|
|
1087
|
+
...link.children ? collectLinks(link.children) : []
|
|
1088
|
+
]);
|
|
1089
|
+
};
|
|
1090
|
+
const links = mergedConfig.links;
|
|
1091
|
+
if (links.length === 0) return [];
|
|
1092
|
+
const firstItem = links[0];
|
|
1093
|
+
if ("links" in firstItem) {
|
|
1094
|
+
return links.flatMap(
|
|
1095
|
+
(section) => collectLinks(section.links)
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
return collectLinks(links);
|
|
1099
|
+
}, [mergedConfig.links]);
|
|
1100
|
+
const isLinkActive = useCallback3(
|
|
1101
|
+
(url) => {
|
|
1102
|
+
if (!state.activeLink) return false;
|
|
1103
|
+
return state.activeLink === url || url !== "/" && state.activeLink.startsWith(url);
|
|
1104
|
+
},
|
|
1105
|
+
[state.activeLink]
|
|
1106
|
+
);
|
|
1107
|
+
const getFilteredLinks = useCallback3(
|
|
1108
|
+
(userAccess) => {
|
|
1109
|
+
const filterLinks = (links2) => {
|
|
1110
|
+
return links2.filter((link) => {
|
|
1111
|
+
if (!link.userAccess) return true;
|
|
1112
|
+
if (!userAccess) return false;
|
|
1113
|
+
return userAccess.includes(link.userAccess);
|
|
1114
|
+
}).map((link) => ({
|
|
1115
|
+
...link,
|
|
1116
|
+
children: link.children ? filterLinks(link.children) : void 0
|
|
1117
|
+
}));
|
|
1118
|
+
};
|
|
1119
|
+
const links = mergedConfig.links;
|
|
1120
|
+
if (links.length === 0) return [];
|
|
1121
|
+
const firstItem = links[0];
|
|
1122
|
+
if ("links" in firstItem) {
|
|
1123
|
+
return links.map((section) => ({
|
|
1124
|
+
...section,
|
|
1125
|
+
links: filterLinks(section.links)
|
|
1126
|
+
}));
|
|
1127
|
+
}
|
|
1128
|
+
return filterLinks(links);
|
|
1129
|
+
},
|
|
1130
|
+
[mergedConfig.links]
|
|
1131
|
+
);
|
|
1132
|
+
const value = useMemo4(
|
|
1133
|
+
() => ({
|
|
1134
|
+
config: mergedConfig,
|
|
1135
|
+
state,
|
|
1136
|
+
actions,
|
|
1137
|
+
getAllLinks,
|
|
1138
|
+
isLinkActive,
|
|
1139
|
+
getFilteredLinks
|
|
1140
|
+
}),
|
|
1141
|
+
[mergedConfig, state, actions, getAllLinks, isLinkActive, getFilteredLinks]
|
|
1142
|
+
);
|
|
1143
|
+
return /* @__PURE__ */ jsx5(SidebarContext.Provider, { value, children });
|
|
1144
|
+
}
|
|
1145
|
+
function useSidebar() {
|
|
1146
|
+
const context = useContext5(SidebarContext);
|
|
1147
|
+
if (!context) {
|
|
1148
|
+
throw new Error(
|
|
1149
|
+
"useSidebar must be used within a SidebarProvider. Make sure to wrap your application with <SidebarProvider>."
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
return context;
|
|
1153
|
+
}
|
|
1154
|
+
function useSidebarOptional() {
|
|
1155
|
+
return useContext5(SidebarContext);
|
|
1156
|
+
}
|
|
1157
|
+
function useSidebarState() {
|
|
1158
|
+
const { state } = useSidebar();
|
|
1159
|
+
return state;
|
|
1160
|
+
}
|
|
1161
|
+
function useSidebarActions() {
|
|
1162
|
+
const { actions } = useSidebar();
|
|
1163
|
+
return actions;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
// src/providers/navigation/NavContext.tsx
|
|
1167
|
+
import { createContext as createContext6, useEffect as useEffect3, useState as useState5 } from "react";
|
|
1168
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1169
|
+
var defaultNavContext = {
|
|
1170
|
+
currentPage: { title: "", location: "" },
|
|
1171
|
+
currentCallStack: /* @__PURE__ */ new Map(),
|
|
1172
|
+
setCurrentPage: () => {
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
var NavContext = createContext6(defaultNavContext);
|
|
1176
|
+
function isChildPath(parentPath, childPath) {
|
|
1177
|
+
const normalizedParent = parentPath?.endsWith("/") ? parentPath : parentPath + "/";
|
|
1178
|
+
const normalizedChild = childPath?.endsWith("/") ? childPath : childPath + "/";
|
|
1179
|
+
return normalizedChild.startsWith(normalizedParent);
|
|
1180
|
+
}
|
|
1181
|
+
function NavContextProvider({ children }) {
|
|
1182
|
+
const [currentPage, setCurrentPage] = useState5({ title: "", location: "" });
|
|
1183
|
+
const [currentCallStack, setCurrentCallStack] = useState5(/* @__PURE__ */ new Map());
|
|
1184
|
+
useEffect3(() => {
|
|
1185
|
+
setCurrentCallStack((prev) => {
|
|
1186
|
+
const newMap = /* @__PURE__ */ new Map();
|
|
1187
|
+
for (const [location, title] of prev.entries()) {
|
|
1188
|
+
if (isChildPath(location, currentPage.location) && location !== "") {
|
|
1189
|
+
newMap.set(location, title);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
newMap.set(currentPage.location, currentPage.title);
|
|
1193
|
+
return newMap;
|
|
1194
|
+
});
|
|
1195
|
+
}, [currentPage]);
|
|
1196
|
+
return /* @__PURE__ */ jsx6(
|
|
1197
|
+
NavContext.Provider,
|
|
1198
|
+
{
|
|
1199
|
+
value: {
|
|
1200
|
+
currentPage,
|
|
1201
|
+
currentCallStack,
|
|
1202
|
+
setCurrentPage: (title, location) => setCurrentPage({ title, location })
|
|
1203
|
+
},
|
|
1204
|
+
children
|
|
1205
|
+
}
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
// src/contexts/contexts/core/SelectedItemsContext.tsx
|
|
1210
|
+
import { createContext as createContext7, useEffect as useEffect4, useState as useState6 } from "react";
|
|
1211
|
+
import { isUsable } from "@pol-studios/utils";
|
|
1212
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1213
|
+
var defaultContextValue = {
|
|
1214
|
+
Items: [],
|
|
1215
|
+
SelectedItems: [],
|
|
1216
|
+
AddItem: () => {
|
|
1217
|
+
},
|
|
1218
|
+
// Empty function as placeholder
|
|
1219
|
+
RemoveItem: () => {
|
|
1220
|
+
},
|
|
1221
|
+
// Empty function as placeholder
|
|
1222
|
+
SetSelectedItems: () => {
|
|
1223
|
+
},
|
|
1224
|
+
// Corrected function as placeholder
|
|
1225
|
+
UpdateItem: () => {
|
|
1226
|
+
}
|
|
1227
|
+
// Corrected function as placeholder
|
|
1228
|
+
};
|
|
1229
|
+
function createSelectedItemsContext() {
|
|
1230
|
+
const context = createContext7(defaultContextValue);
|
|
1231
|
+
const Provider = ({ children, Items, initialSelectedItems = [] }) => {
|
|
1232
|
+
const [selectedItems, setSelectedItems] = useState6(initialSelectedItems);
|
|
1233
|
+
const [items, setItems] = useState6([]);
|
|
1234
|
+
useEffect4(() => {
|
|
1235
|
+
setItems(Items);
|
|
1236
|
+
}, [Items]);
|
|
1237
|
+
useEffect4(() => {
|
|
1238
|
+
setSelectedItems(
|
|
1239
|
+
(previousItems) => previousItems.map((x) => Items.find((i) => i.id == x.id)).filter((x) => x != null)
|
|
1240
|
+
);
|
|
1241
|
+
}, [Items]);
|
|
1242
|
+
function addSelectedItem(item) {
|
|
1243
|
+
setSelectedItems([...selectedItems, item]);
|
|
1244
|
+
}
|
|
1245
|
+
function removeSelectedItem(item) {
|
|
1246
|
+
setSelectedItems(selectedItems.filter((x) => x !== item));
|
|
1247
|
+
}
|
|
1248
|
+
function updateItem(item, newProperties) {
|
|
1249
|
+
if (isUsable(item)) {
|
|
1250
|
+
const newValue = { ...item, ...newProperties ?? {} };
|
|
1251
|
+
setItems(items.map((x) => x.id == item.id ? newValue : x));
|
|
1252
|
+
setSelectedItems(selectedItems.map((x) => x.id == item.id ? newValue : x));
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
return /* @__PURE__ */ jsx7(
|
|
1256
|
+
context.Provider,
|
|
1257
|
+
{
|
|
1258
|
+
value: {
|
|
1259
|
+
Items: items,
|
|
1260
|
+
SelectedItems: selectedItems,
|
|
1261
|
+
AddItem: addSelectedItem,
|
|
1262
|
+
RemoveItem: removeSelectedItem,
|
|
1263
|
+
SetSelectedItems: setSelectedItems,
|
|
1264
|
+
UpdateItem: updateItem
|
|
1265
|
+
},
|
|
1266
|
+
children
|
|
1267
|
+
}
|
|
1268
|
+
);
|
|
1269
|
+
};
|
|
1270
|
+
return { context, Provider };
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/contexts/contexts/SelectedFixturesContext.tsx
|
|
1274
|
+
var {
|
|
1275
|
+
context: SelectedFixturesContext,
|
|
1276
|
+
Provider: SelectedFixturesProvider
|
|
1277
|
+
} = createSelectedItemsContext();
|
|
1278
|
+
|
|
1279
|
+
// src/providers/notifications/types.ts
|
|
1280
|
+
var DEFAULT_STORAGE_KEY = "pol-notifications-unread";
|
|
1281
|
+
var DEFAULT_NOTIFICATION_CONFIG = {
|
|
1282
|
+
basePath: "/notifications",
|
|
1283
|
+
defaultRoute: "/notifications",
|
|
1284
|
+
showToast: true,
|
|
1285
|
+
toastDuration: 5e3,
|
|
1286
|
+
maxDisplayCount: 50,
|
|
1287
|
+
pollInterval: 3e4,
|
|
1288
|
+
enableRealtime: false,
|
|
1289
|
+
persistUnread: true,
|
|
1290
|
+
storageKey: DEFAULT_STORAGE_KEY
|
|
1291
|
+
};
|
|
1292
|
+
var DEFAULT_NOTIFICATION_STATE = {
|
|
1293
|
+
notifications: [],
|
|
1294
|
+
unreadCount: 0,
|
|
1295
|
+
isLoading: false,
|
|
1296
|
+
error: null,
|
|
1297
|
+
lastFetchedAt: null
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
// src/providers/notifications/NotificationRegistry.tsx
|
|
1301
|
+
import {
|
|
1302
|
+
createContext as createContext8,
|
|
1303
|
+
useCallback as useCallback4,
|
|
1304
|
+
useContext as useContext6,
|
|
1305
|
+
useEffect as useEffect5,
|
|
1306
|
+
useMemo as useMemo5,
|
|
1307
|
+
useState as useState7
|
|
1308
|
+
} from "react";
|
|
1309
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1310
|
+
function loadUnreadFromStorage(storageKey) {
|
|
1311
|
+
try {
|
|
1312
|
+
const stored = localStorage.getItem(storageKey);
|
|
1313
|
+
if (stored) {
|
|
1314
|
+
return new Set(JSON.parse(stored));
|
|
1315
|
+
}
|
|
1316
|
+
} catch (e) {
|
|
1317
|
+
console.warn("Failed to load notifications from storage:", e);
|
|
1318
|
+
}
|
|
1319
|
+
return /* @__PURE__ */ new Set();
|
|
1320
|
+
}
|
|
1321
|
+
var MAX_PERSISTED_UNREAD_IDS = 500;
|
|
1322
|
+
function saveUnreadToStorage(storageKey, unreadIds) {
|
|
1323
|
+
try {
|
|
1324
|
+
const idsArray = [...unreadIds];
|
|
1325
|
+
const limitedIds = idsArray.slice(-MAX_PERSISTED_UNREAD_IDS);
|
|
1326
|
+
localStorage.setItem(storageKey, JSON.stringify(limitedIds));
|
|
1327
|
+
} catch (e) {
|
|
1328
|
+
console.warn("Failed to save notifications to storage:", e);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
var NotificationContext = createContext8(
|
|
1332
|
+
null
|
|
1333
|
+
);
|
|
1334
|
+
function NotificationProvider({
|
|
1335
|
+
config,
|
|
1336
|
+
handlers: initialHandlers = [],
|
|
1337
|
+
navigate,
|
|
1338
|
+
fetchFn,
|
|
1339
|
+
markAsReadFn,
|
|
1340
|
+
deleteFn,
|
|
1341
|
+
children
|
|
1342
|
+
}) {
|
|
1343
|
+
const mergedConfig = useMemo5(
|
|
1344
|
+
() => ({
|
|
1345
|
+
...DEFAULT_NOTIFICATION_CONFIG,
|
|
1346
|
+
...config
|
|
1347
|
+
}),
|
|
1348
|
+
[config]
|
|
1349
|
+
);
|
|
1350
|
+
const storageKey = mergedConfig.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
1351
|
+
const persistEnabled = mergedConfig.persistUnread !== false;
|
|
1352
|
+
const [handlers, setHandlers] = useState7(initialHandlers);
|
|
1353
|
+
const [persistedUnreadIds, setPersistedUnreadIds] = useState7(
|
|
1354
|
+
() => persistEnabled ? loadUnreadFromStorage(storageKey) : /* @__PURE__ */ new Set()
|
|
1355
|
+
);
|
|
1356
|
+
const [state, setState] = useState7(
|
|
1357
|
+
DEFAULT_NOTIFICATION_STATE
|
|
1358
|
+
);
|
|
1359
|
+
useEffect5(() => {
|
|
1360
|
+
if (persistEnabled) {
|
|
1361
|
+
saveUnreadToStorage(storageKey, persistedUnreadIds);
|
|
1362
|
+
}
|
|
1363
|
+
}, [persistEnabled, storageKey, persistedUnreadIds]);
|
|
1364
|
+
useEffect5(() => {
|
|
1365
|
+
if (persistEnabled && state.notifications.length > 0) {
|
|
1366
|
+
const unreadIds = new Set(
|
|
1367
|
+
state.notifications.filter((n) => !n.isRead).map((n) => n.id)
|
|
1368
|
+
);
|
|
1369
|
+
setPersistedUnreadIds(unreadIds);
|
|
1370
|
+
}
|
|
1371
|
+
}, [persistEnabled, state.notifications]);
|
|
1372
|
+
const clearPersistedData = useCallback4(() => {
|
|
1373
|
+
try {
|
|
1374
|
+
localStorage.removeItem(storageKey);
|
|
1375
|
+
} catch (e) {
|
|
1376
|
+
console.warn("Failed to clear persisted notifications:", e);
|
|
1377
|
+
}
|
|
1378
|
+
setPersistedUnreadIds(/* @__PURE__ */ new Set());
|
|
1379
|
+
}, [storageKey]);
|
|
1380
|
+
const registerHandler = useCallback4((handler) => {
|
|
1381
|
+
setHandlers((prev) => {
|
|
1382
|
+
const typesToAdd = Array.isArray(handler.types) ? handler.types : [handler.types];
|
|
1383
|
+
const filtered = prev.filter((h) => {
|
|
1384
|
+
const existingTypes = Array.isArray(h.types) ? h.types : [h.types];
|
|
1385
|
+
return !existingTypes.some((t) => typesToAdd.includes(t));
|
|
1386
|
+
});
|
|
1387
|
+
return [...filtered, handler];
|
|
1388
|
+
});
|
|
1389
|
+
}, []);
|
|
1390
|
+
const unregisterHandler = useCallback4((types) => {
|
|
1391
|
+
const typesToRemove = Array.isArray(types) ? types : [types];
|
|
1392
|
+
setHandlers(
|
|
1393
|
+
(prev) => prev.filter((h) => {
|
|
1394
|
+
const existingTypes = Array.isArray(h.types) ? h.types : [h.types];
|
|
1395
|
+
return !existingTypes.some((t) => typesToRemove.includes(t));
|
|
1396
|
+
})
|
|
1397
|
+
);
|
|
1398
|
+
}, []);
|
|
1399
|
+
const getHandlers = useCallback4(() => handlers, [handlers]);
|
|
1400
|
+
const findHandler = useCallback4(
|
|
1401
|
+
(type) => {
|
|
1402
|
+
return handlers.find((handler) => {
|
|
1403
|
+
const handlerTypes = Array.isArray(handler.types) ? handler.types : [handler.types];
|
|
1404
|
+
return handlerTypes.includes(type);
|
|
1405
|
+
});
|
|
1406
|
+
},
|
|
1407
|
+
[handlers]
|
|
1408
|
+
);
|
|
1409
|
+
const getNotificationRoute = useCallback4(
|
|
1410
|
+
(notification) => {
|
|
1411
|
+
const handler = findHandler(notification.type);
|
|
1412
|
+
if (!handler) {
|
|
1413
|
+
return mergedConfig.defaultRoute ?? "/notifications";
|
|
1414
|
+
}
|
|
1415
|
+
const params = {
|
|
1416
|
+
type: notification.type,
|
|
1417
|
+
entityId: notification.entityId,
|
|
1418
|
+
entityType: notification.entityType,
|
|
1419
|
+
params: notification.metadata
|
|
1420
|
+
};
|
|
1421
|
+
if (handler.canHandle && !handler.canHandle(params)) {
|
|
1422
|
+
return mergedConfig.defaultRoute ?? "/notifications";
|
|
1423
|
+
}
|
|
1424
|
+
return handler.getRoute(params);
|
|
1425
|
+
},
|
|
1426
|
+
[findHandler, mergedConfig.defaultRoute]
|
|
1427
|
+
);
|
|
1428
|
+
const actions = useMemo5(
|
|
1429
|
+
() => ({
|
|
1430
|
+
markAsRead: async (notificationId) => {
|
|
1431
|
+
if (markAsReadFn) {
|
|
1432
|
+
await markAsReadFn(notificationId);
|
|
1433
|
+
}
|
|
1434
|
+
setState((prev) => ({
|
|
1435
|
+
...prev,
|
|
1436
|
+
notifications: prev.notifications.map(
|
|
1437
|
+
(n) => n.id === notificationId ? { ...n, isRead: true } : n
|
|
1438
|
+
),
|
|
1439
|
+
unreadCount: Math.max(0, prev.unreadCount - 1)
|
|
1440
|
+
}));
|
|
1441
|
+
},
|
|
1442
|
+
markAllAsRead: async () => {
|
|
1443
|
+
let currentUnreadIds = [];
|
|
1444
|
+
setState((prev) => {
|
|
1445
|
+
currentUnreadIds = prev.notifications.filter((n) => !n.isRead).map((n) => n.id);
|
|
1446
|
+
return prev;
|
|
1447
|
+
});
|
|
1448
|
+
if (markAsReadFn && currentUnreadIds.length > 0) {
|
|
1449
|
+
await Promise.all(currentUnreadIds.map((id) => markAsReadFn(id)));
|
|
1450
|
+
}
|
|
1451
|
+
setState((prev) => ({
|
|
1452
|
+
...prev,
|
|
1453
|
+
notifications: prev.notifications.map((n) => ({
|
|
1454
|
+
...n,
|
|
1455
|
+
isRead: true
|
|
1456
|
+
})),
|
|
1457
|
+
unreadCount: 0
|
|
1458
|
+
}));
|
|
1459
|
+
},
|
|
1460
|
+
deleteNotification: async (notificationId) => {
|
|
1461
|
+
if (deleteFn) {
|
|
1462
|
+
await deleteFn(notificationId);
|
|
1463
|
+
}
|
|
1464
|
+
setState((prev) => {
|
|
1465
|
+
const notification = prev.notifications.find(
|
|
1466
|
+
(n) => n.id === notificationId
|
|
1467
|
+
);
|
|
1468
|
+
return {
|
|
1469
|
+
...prev,
|
|
1470
|
+
notifications: prev.notifications.filter(
|
|
1471
|
+
(n) => n.id !== notificationId
|
|
1472
|
+
),
|
|
1473
|
+
unreadCount: notification && !notification.isRead ? Math.max(0, prev.unreadCount - 1) : prev.unreadCount
|
|
1474
|
+
};
|
|
1475
|
+
});
|
|
1476
|
+
},
|
|
1477
|
+
clearAll: async () => {
|
|
1478
|
+
let currentNotificationIds = [];
|
|
1479
|
+
setState((prev) => {
|
|
1480
|
+
currentNotificationIds = prev.notifications.map((n) => n.id);
|
|
1481
|
+
return prev;
|
|
1482
|
+
});
|
|
1483
|
+
if (deleteFn && currentNotificationIds.length > 0) {
|
|
1484
|
+
await Promise.all(currentNotificationIds.map((id) => deleteFn(id)));
|
|
1485
|
+
}
|
|
1486
|
+
setState((prev) => ({
|
|
1487
|
+
...prev,
|
|
1488
|
+
notifications: [],
|
|
1489
|
+
unreadCount: 0
|
|
1490
|
+
}));
|
|
1491
|
+
},
|
|
1492
|
+
fetchNotifications: async () => {
|
|
1493
|
+
if (!fetchFn) {
|
|
1494
|
+
return state.notifications;
|
|
1495
|
+
}
|
|
1496
|
+
setState((prev) => ({ ...prev, isLoading: true, error: null }));
|
|
1497
|
+
try {
|
|
1498
|
+
const notifications = await fetchFn();
|
|
1499
|
+
const notificationsWithPersistedState = persistEnabled && persistedUnreadIds.size > 0 ? notifications.map((n) => ({
|
|
1500
|
+
...n,
|
|
1501
|
+
isRead: persistedUnreadIds.has(n.id) ? false : n.isRead
|
|
1502
|
+
})) : notifications;
|
|
1503
|
+
const unreadCount = notificationsWithPersistedState.filter(
|
|
1504
|
+
(n) => !n.isRead
|
|
1505
|
+
).length;
|
|
1506
|
+
setState((prev) => ({
|
|
1507
|
+
...prev,
|
|
1508
|
+
notifications: notificationsWithPersistedState,
|
|
1509
|
+
unreadCount,
|
|
1510
|
+
isLoading: false,
|
|
1511
|
+
lastFetchedAt: /* @__PURE__ */ new Date()
|
|
1512
|
+
}));
|
|
1513
|
+
return notificationsWithPersistedState;
|
|
1514
|
+
} catch (error) {
|
|
1515
|
+
setState((prev) => ({
|
|
1516
|
+
...prev,
|
|
1517
|
+
isLoading: false,
|
|
1518
|
+
error
|
|
1519
|
+
}));
|
|
1520
|
+
throw error;
|
|
1521
|
+
}
|
|
1522
|
+
},
|
|
1523
|
+
navigateToNotification: (notification) => {
|
|
1524
|
+
const handler = findHandler(notification.type);
|
|
1525
|
+
if (handler?.onClick) {
|
|
1526
|
+
handler.onClick({
|
|
1527
|
+
type: notification.type,
|
|
1528
|
+
entityId: notification.entityId,
|
|
1529
|
+
entityType: notification.entityType,
|
|
1530
|
+
params: notification.metadata
|
|
1531
|
+
});
|
|
1532
|
+
return;
|
|
1533
|
+
}
|
|
1534
|
+
const route = getNotificationRoute(notification);
|
|
1535
|
+
if (navigate) {
|
|
1536
|
+
navigate(route);
|
|
1537
|
+
} else {
|
|
1538
|
+
window.location.href = route;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}),
|
|
1542
|
+
[
|
|
1543
|
+
state.notifications,
|
|
1544
|
+
fetchFn,
|
|
1545
|
+
markAsReadFn,
|
|
1546
|
+
deleteFn,
|
|
1547
|
+
findHandler,
|
|
1548
|
+
getNotificationRoute,
|
|
1549
|
+
navigate,
|
|
1550
|
+
persistEnabled,
|
|
1551
|
+
persistedUnreadIds
|
|
1552
|
+
]
|
|
1553
|
+
);
|
|
1554
|
+
const value = useMemo5(
|
|
1555
|
+
() => ({
|
|
1556
|
+
config: mergedConfig,
|
|
1557
|
+
state,
|
|
1558
|
+
actions,
|
|
1559
|
+
getNotificationRoute,
|
|
1560
|
+
registerHandler,
|
|
1561
|
+
unregisterHandler,
|
|
1562
|
+
getHandlers,
|
|
1563
|
+
clearPersistedData
|
|
1564
|
+
}),
|
|
1565
|
+
[
|
|
1566
|
+
mergedConfig,
|
|
1567
|
+
state,
|
|
1568
|
+
actions,
|
|
1569
|
+
getNotificationRoute,
|
|
1570
|
+
registerHandler,
|
|
1571
|
+
unregisterHandler,
|
|
1572
|
+
getHandlers,
|
|
1573
|
+
clearPersistedData
|
|
1574
|
+
]
|
|
1575
|
+
);
|
|
1576
|
+
return /* @__PURE__ */ jsx8(NotificationContext.Provider, { value, children });
|
|
1577
|
+
}
|
|
1578
|
+
function useNotifications() {
|
|
1579
|
+
const context = useContext6(NotificationContext);
|
|
1580
|
+
if (!context) {
|
|
1581
|
+
throw new Error(
|
|
1582
|
+
"useNotifications must be used within a NotificationProvider. Make sure to wrap your application with <NotificationProvider>."
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
return context;
|
|
1586
|
+
}
|
|
1587
|
+
function useNotificationsOptional() {
|
|
1588
|
+
return useContext6(NotificationContext);
|
|
1589
|
+
}
|
|
1590
|
+
function useNotificationActions() {
|
|
1591
|
+
const { actions } = useNotifications();
|
|
1592
|
+
return actions;
|
|
1593
|
+
}
|
|
1594
|
+
function useNotificationState() {
|
|
1595
|
+
const { state } = useNotifications();
|
|
1596
|
+
return state;
|
|
1597
|
+
}
|
|
1598
|
+
function useUnreadCount() {
|
|
1599
|
+
const { state } = useNotifications();
|
|
1600
|
+
return state.unreadCount;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
// src/providers/notifications/handlers.ts
|
|
1604
|
+
var MAX_ROUTE_CACHE_SIZE = 100;
|
|
1605
|
+
function createAsyncHandler(config, supabase) {
|
|
1606
|
+
const resolvedRoutes = /* @__PURE__ */ new Map();
|
|
1607
|
+
return {
|
|
1608
|
+
types: config.types,
|
|
1609
|
+
canHandle: config.canHandle,
|
|
1610
|
+
getRoute: (params) => {
|
|
1611
|
+
const cacheKey = `${params.type}-${params.entityId}`;
|
|
1612
|
+
const cached = resolvedRoutes.get(cacheKey);
|
|
1613
|
+
if (cached) {
|
|
1614
|
+
return cached;
|
|
1615
|
+
}
|
|
1616
|
+
return "/notifications";
|
|
1617
|
+
},
|
|
1618
|
+
onClick: async (params) => {
|
|
1619
|
+
try {
|
|
1620
|
+
const result = await config.resolveRoute(params, supabase);
|
|
1621
|
+
if (result) {
|
|
1622
|
+
const cacheKey = `${params.type}-${params.entityId}`;
|
|
1623
|
+
if (resolvedRoutes.size >= MAX_ROUTE_CACHE_SIZE) {
|
|
1624
|
+
const firstKey = resolvedRoutes.keys().next().value;
|
|
1625
|
+
if (firstKey) resolvedRoutes.delete(firstKey);
|
|
1626
|
+
}
|
|
1627
|
+
resolvedRoutes.set(cacheKey, result.to);
|
|
1628
|
+
let url = result.to;
|
|
1629
|
+
if (result.params) {
|
|
1630
|
+
for (const [key, value] of Object.entries(result.params)) {
|
|
1631
|
+
url = url.replace(`$${key}`, String(value));
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
window.location.href = url;
|
|
1635
|
+
}
|
|
1636
|
+
} catch (error) {
|
|
1637
|
+
console.error("Failed to navigate to notification:", error);
|
|
1638
|
+
config.onError?.(error, params);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
var commentEntityRoutes = {
|
|
1644
|
+
EquipmentFixtureUnit: (entityId, projectDatabaseId) => ({
|
|
1645
|
+
to: `/project-databases/${projectDatabaseId}/equipment-units/${entityId}/tag`,
|
|
1646
|
+
params: { projectDatabaseId, equipmentUnitId: entityId }
|
|
1647
|
+
}),
|
|
1648
|
+
PunchListItem: (entityId, projectDatabaseId) => ({
|
|
1649
|
+
to: `/project-databases/${projectDatabaseId}/punch-lists?punchListItemId=${entityId}`,
|
|
1650
|
+
params: { projectDatabaseId }
|
|
1651
|
+
})
|
|
1652
|
+
};
|
|
1653
|
+
function createPortalOneNotificationHandlers(supabase, navigate) {
|
|
1654
|
+
const nav = navigate || ((url) => {
|
|
1655
|
+
window.location.href = url;
|
|
1656
|
+
});
|
|
1657
|
+
return [
|
|
1658
|
+
// Comment handler - resolves comment location from CommentSection
|
|
1659
|
+
{
|
|
1660
|
+
types: "Comment",
|
|
1661
|
+
getRoute: () => "/notifications",
|
|
1662
|
+
// Fallback, actual resolution is async
|
|
1663
|
+
onClick: async (params) => {
|
|
1664
|
+
try {
|
|
1665
|
+
if (!params.entityId) return;
|
|
1666
|
+
const comment = await supabase.from("Comment").select("*, CommentSection!inner(*)").eq("id", params.entityId).single();
|
|
1667
|
+
if (!comment.data) {
|
|
1668
|
+
console.log("Comment not found");
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
const commentData = comment.data;
|
|
1672
|
+
const route = await resolveCommentEntityRoute(
|
|
1673
|
+
commentData.CommentSection.entityTableName,
|
|
1674
|
+
commentData.CommentSection.entityId,
|
|
1675
|
+
supabase
|
|
1676
|
+
);
|
|
1677
|
+
if (route) {
|
|
1678
|
+
nav(route);
|
|
1679
|
+
}
|
|
1680
|
+
} catch (error) {
|
|
1681
|
+
console.error("Failed to navigate to Comment notification:", error);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
},
|
|
1685
|
+
// CommentTag handler - resolves through Comment
|
|
1686
|
+
{
|
|
1687
|
+
types: "CommentTag",
|
|
1688
|
+
getRoute: () => "/notifications",
|
|
1689
|
+
// Fallback, actual resolution is async
|
|
1690
|
+
onClick: async (params) => {
|
|
1691
|
+
try {
|
|
1692
|
+
if (!params.entityId) return;
|
|
1693
|
+
const commentTag = await supabase.from("CommentTag").select("id, commentId").eq("id", params.entityId).single();
|
|
1694
|
+
if (!commentTag.data) {
|
|
1695
|
+
console.log("CommentTag not found");
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
const tagData = commentTag.data;
|
|
1699
|
+
const comment = await supabase.from("Comment").select("*, CommentSection!inner(*)").eq("id", tagData.commentId).single();
|
|
1700
|
+
if (!comment.data) {
|
|
1701
|
+
console.log("Comment not found");
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
const commentData = comment.data;
|
|
1705
|
+
const route = await resolveCommentEntityRoute(
|
|
1706
|
+
commentData.CommentSection.entityTableName,
|
|
1707
|
+
commentData.CommentSection.entityId,
|
|
1708
|
+
supabase
|
|
1709
|
+
);
|
|
1710
|
+
if (route) {
|
|
1711
|
+
nav(route);
|
|
1712
|
+
}
|
|
1713
|
+
} catch (error) {
|
|
1714
|
+
console.error("Failed to navigate to CommentTag notification:", error);
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
];
|
|
1719
|
+
}
|
|
1720
|
+
async function resolveCommentEntityRoute(entityTableName, entityId, supabase) {
|
|
1721
|
+
switch (entityTableName) {
|
|
1722
|
+
case "EquipmentFixtureUnit": {
|
|
1723
|
+
const unit = await supabase.from("EquipmentFixtureUnit").select("*").eq("id", entityId).single();
|
|
1724
|
+
if (!unit.data) {
|
|
1725
|
+
console.log("Unit not found");
|
|
1726
|
+
return null;
|
|
1727
|
+
}
|
|
1728
|
+
const unitData = unit.data;
|
|
1729
|
+
return `/project-databases/${unitData.projectDatabaseId}/equipment-units/${entityId}/tag`;
|
|
1730
|
+
}
|
|
1731
|
+
case "PunchListItem": {
|
|
1732
|
+
const punchList = await supabase.from("PunchListItem").select("*, PunchList!inner(*, PunchListPage!inner(*))").eq("id", entityId).maybeSingle();
|
|
1733
|
+
if (!punchList.data) {
|
|
1734
|
+
console.log("PunchList not found");
|
|
1735
|
+
return null;
|
|
1736
|
+
}
|
|
1737
|
+
const punchData = punchList.data;
|
|
1738
|
+
if (punchData.PunchList.PunchListPage.tableName === "ProjectDatabase") {
|
|
1739
|
+
return `/project-databases/${punchData.PunchList.PunchListPage.entityId}/punch-lists?punchListItemId=${entityId}`;
|
|
1740
|
+
}
|
|
1741
|
+
return null;
|
|
1742
|
+
}
|
|
1743
|
+
default:
|
|
1744
|
+
return null;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
function convertLegacyHandler(types, legacyHandler, supabase, navigate, onError) {
|
|
1748
|
+
const nav = navigate || ((url) => {
|
|
1749
|
+
window.location.href = url;
|
|
1750
|
+
});
|
|
1751
|
+
return {
|
|
1752
|
+
types,
|
|
1753
|
+
getRoute: () => "/notifications",
|
|
1754
|
+
// Fallback for sync access
|
|
1755
|
+
onClick: async (params) => {
|
|
1756
|
+
try {
|
|
1757
|
+
if (!params.entityId) return;
|
|
1758
|
+
const result = await legacyHandler(params.entityId, supabase);
|
|
1759
|
+
if (result) {
|
|
1760
|
+
let url = result.to;
|
|
1761
|
+
if (result.params) {
|
|
1762
|
+
for (const [key, value] of Object.entries(result.params)) {
|
|
1763
|
+
url = url.replace(`$${key}`, String(value));
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
nav(url);
|
|
1767
|
+
}
|
|
1768
|
+
} catch (error) {
|
|
1769
|
+
console.error("Failed to navigate to notification:", error);
|
|
1770
|
+
onError?.(error, params);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
// src/providers/alert/AlertContext.tsx
|
|
1777
|
+
import { createContext as createContext9, useContext as useContext7, useState as useState8 } from "react";
|
|
1778
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1779
|
+
var defaultAlertState = {
|
|
1780
|
+
isOpen: false,
|
|
1781
|
+
title: "",
|
|
1782
|
+
description: "",
|
|
1783
|
+
confirmTitle: "Confirm",
|
|
1784
|
+
cancelTitle: "Cancel",
|
|
1785
|
+
variant: "default",
|
|
1786
|
+
onConfirm: () => {
|
|
1787
|
+
},
|
|
1788
|
+
onCancel: () => {
|
|
1789
|
+
}
|
|
1790
|
+
};
|
|
1791
|
+
var defaultContextValue2 = {
|
|
1792
|
+
showAlert: async () => false,
|
|
1793
|
+
hideAlert: () => {
|
|
1794
|
+
},
|
|
1795
|
+
alertState: defaultAlertState
|
|
1796
|
+
};
|
|
1797
|
+
var AlertContext = createContext9(defaultContextValue2);
|
|
1798
|
+
var useAlert = () => {
|
|
1799
|
+
const context = useContext7(AlertContext);
|
|
1800
|
+
if (!context) {
|
|
1801
|
+
throw new Error("useAlert must be used within an AlertProvider");
|
|
1802
|
+
}
|
|
1803
|
+
return { hideAlert: context.hideAlert, showAlert: context.showAlert };
|
|
1804
|
+
};
|
|
1805
|
+
var AlertProvider = ({ children }) => {
|
|
1806
|
+
const [alertState, setAlertState] = useState8(defaultAlertState);
|
|
1807
|
+
async function showAlert({
|
|
1808
|
+
title,
|
|
1809
|
+
description,
|
|
1810
|
+
confirmTitle,
|
|
1811
|
+
cancelTitle,
|
|
1812
|
+
variant = "default"
|
|
1813
|
+
}) {
|
|
1814
|
+
const result = await new Promise(
|
|
1815
|
+
(resolve) => setAlertState({
|
|
1816
|
+
isOpen: true,
|
|
1817
|
+
title,
|
|
1818
|
+
description,
|
|
1819
|
+
confirmTitle: confirmTitle || "Confirm",
|
|
1820
|
+
cancelTitle: cancelTitle || "Cancel",
|
|
1821
|
+
variant,
|
|
1822
|
+
onConfirm: () => resolve(true),
|
|
1823
|
+
onCancel: () => resolve(false)
|
|
1824
|
+
})
|
|
1825
|
+
);
|
|
1826
|
+
return result;
|
|
1827
|
+
}
|
|
1828
|
+
const hideAlert = () => {
|
|
1829
|
+
setAlertState({ ...alertState, isOpen: false });
|
|
1830
|
+
};
|
|
1831
|
+
return /* @__PURE__ */ jsx9(AlertContext.Provider, { value: { alertState, showAlert, hideAlert }, children });
|
|
1832
|
+
};
|
|
1833
|
+
|
|
1834
|
+
// src/providers/PolComponentsProvider.tsx
|
|
1835
|
+
import { Fragment, jsx as jsx10 } from "react/jsx-runtime";
|
|
1836
|
+
function PolComponentsProvider({ config, children }) {
|
|
1837
|
+
let content = children;
|
|
1838
|
+
if (config.notifications) {
|
|
1839
|
+
content = /* @__PURE__ */ jsx10(
|
|
1840
|
+
NotificationProvider,
|
|
1841
|
+
{
|
|
1842
|
+
config: config.notifications.config,
|
|
1843
|
+
handlers: config.notifications.handlers,
|
|
1844
|
+
children: content
|
|
1845
|
+
}
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
if (config.sidebar) {
|
|
1849
|
+
content = /* @__PURE__ */ jsx10(SidebarProvider, { config: config.sidebar, children: content });
|
|
1850
|
+
}
|
|
1851
|
+
content = /* @__PURE__ */ jsx10(ConfigProvider, { config: config.config, children: content });
|
|
1852
|
+
if (config.data) {
|
|
1853
|
+
content = /* @__PURE__ */ jsx10(DataProvider, { adapter: config.data, children: content });
|
|
1854
|
+
}
|
|
1855
|
+
if (config.auth) {
|
|
1856
|
+
content = /* @__PURE__ */ jsx10(AuthProvider, { value: config.auth, children: content });
|
|
1857
|
+
}
|
|
1858
|
+
content = /* @__PURE__ */ jsx10(RouterProvider, { adapter: config.router, children: content });
|
|
1859
|
+
return /* @__PURE__ */ jsx10(Fragment, { children: content });
|
|
1860
|
+
}
|
|
1861
|
+
export {
|
|
1862
|
+
AlertContext,
|
|
1863
|
+
AlertProvider,
|
|
1864
|
+
AuthContext,
|
|
1865
|
+
AuthProvider,
|
|
1866
|
+
ConfigActionsContext,
|
|
1867
|
+
ConfigContext,
|
|
1868
|
+
ConfigProvider,
|
|
1869
|
+
DEFAULT_CONFIG,
|
|
1870
|
+
DEFAULT_FEATURES,
|
|
1871
|
+
DEFAULT_LOCALIZATION,
|
|
1872
|
+
DEFAULT_NOTIFICATION_CONFIG,
|
|
1873
|
+
DEFAULT_NOTIFICATION_STATE,
|
|
1874
|
+
DEFAULT_ROUTES,
|
|
1875
|
+
DEFAULT_SIDEBAR_CONFIG,
|
|
1876
|
+
DEFAULT_SIDEBAR_STATE,
|
|
1877
|
+
DEFAULT_STORAGE_KEY,
|
|
1878
|
+
DEFAULT_THEME,
|
|
1879
|
+
DataContext,
|
|
1880
|
+
DataProvider,
|
|
1881
|
+
Link,
|
|
1882
|
+
NavContext,
|
|
1883
|
+
NavContextProvider,
|
|
1884
|
+
NotificationContext,
|
|
1885
|
+
NotificationProvider,
|
|
1886
|
+
PolComponentsProvider,
|
|
1887
|
+
RouterContext,
|
|
1888
|
+
RouterProvider,
|
|
1889
|
+
SelectedFixturesContext,
|
|
1890
|
+
SelectedFixturesProvider,
|
|
1891
|
+
SidebarContext,
|
|
1892
|
+
SidebarProvider,
|
|
1893
|
+
commentEntityRoutes,
|
|
1894
|
+
convertLegacyHandler,
|
|
1895
|
+
createAsyncHandler,
|
|
1896
|
+
createPortalOneNotificationHandlers,
|
|
1897
|
+
useAlert,
|
|
1898
|
+
useComponentAuth,
|
|
1899
|
+
useComponentAuthOptional,
|
|
1900
|
+
useComponentConfig,
|
|
1901
|
+
useComponentConfigOptional,
|
|
1902
|
+
useConfigActions,
|
|
1903
|
+
useConfigActionsOptional,
|
|
1904
|
+
useDataAdapter,
|
|
1905
|
+
useDataAdapterOptional,
|
|
1906
|
+
useDataDelete,
|
|
1907
|
+
useDataInsert,
|
|
1908
|
+
useDataMutation,
|
|
1909
|
+
useDataQuery,
|
|
1910
|
+
useDataQueryById,
|
|
1911
|
+
useDataUpdate,
|
|
1912
|
+
useFeatureFlag,
|
|
1913
|
+
useLocation,
|
|
1914
|
+
useNavigate,
|
|
1915
|
+
useNotificationActions,
|
|
1916
|
+
useNotificationState,
|
|
1917
|
+
useNotifications,
|
|
1918
|
+
useNotificationsOptional,
|
|
1919
|
+
useParams,
|
|
1920
|
+
useRoute,
|
|
1921
|
+
useRouter,
|
|
1922
|
+
useSidebar,
|
|
1923
|
+
useSidebarActions,
|
|
1924
|
+
useSidebarOptional,
|
|
1925
|
+
useSidebarState,
|
|
1926
|
+
useUnreadCount
|
|
1927
|
+
};
|