@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.
@@ -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
+ };