@variamosple/variamos-components 0.2.5 → 0.4.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.
Files changed (55) hide show
  1. package/README.md +29 -42
  2. package/dist/Common/Events.d.ts +3 -2
  3. package/dist/Common/Events.js +18 -11
  4. package/dist/Common/fieldOf.d.ts +2 -0
  5. package/dist/Common/fieldOf.js +7 -0
  6. package/dist/Common/isAllowedFor.d.ts +7 -0
  7. package/dist/Common/isAllowedFor.js +9 -0
  8. package/dist/Components/AuthWrapper/index.js +6 -6
  9. package/dist/Components/ConfirmationModal/index.js +3 -3
  10. package/dist/Components/Footer/index.js +1 -1
  11. package/dist/Components/Header/BugFormModal.d.ts +2 -0
  12. package/dist/Components/Header/BugFormModal.js +39 -37
  13. package/dist/Components/Header/HeaderOptions.js +79 -86
  14. package/dist/Components/Header/MenuItem.js +24 -34
  15. package/dist/Components/Header/SubHeader.js +17 -29
  16. package/dist/Components/Header/index.js +25 -13
  17. package/dist/Components/Header/submitBugReport.d.ts +14 -0
  18. package/dist/Components/Header/submitBugReport.js +22 -0
  19. package/dist/Components/NotAuthorized/index.js +1 -1
  20. package/dist/Components/Notifications/NotificationBell.js +10 -10
  21. package/dist/Components/Notifications/NotificationCard.d.ts +9 -0
  22. package/dist/Components/Notifications/NotificationCard.js +81 -0
  23. package/dist/Components/Notifications/NotificationDrawer.js +139 -191
  24. package/dist/Components/Notifications/NotificationSettings.js +32 -28
  25. package/dist/Components/Notifications/mutedEventTypes.js +9 -9
  26. package/dist/Components/Notifications/notificationText.d.ts +7 -0
  27. package/dist/Components/Notifications/notificationText.js +38 -0
  28. package/dist/Components/Paginator/index.js +22 -22
  29. package/dist/Components/ProtectedRoute/index.js +18 -18
  30. package/dist/Components/index.d.ts +1 -1
  31. package/dist/Components/index.js +10 -10
  32. package/dist/Context/AnalyticsContext.d.ts +2 -2
  33. package/dist/Context/AnalyticsContext.js +15 -15
  34. package/dist/Context/MenuContext.js +39 -47
  35. package/dist/Context/NotificationContext.d.ts +2 -14
  36. package/dist/Context/NotificationContext.js +393 -458
  37. package/dist/Context/SessionContext.js +72 -78
  38. package/dist/Context/index.d.ts +1 -1
  39. package/dist/Context/index.js +11 -11
  40. package/dist/Context/notificationAccessToken.d.ts +1 -3
  41. package/dist/Context/notificationAccessToken.js +15 -19
  42. package/dist/Context/notificationApi.d.ts +43 -0
  43. package/dist/Context/notificationApi.js +83 -0
  44. package/dist/Context/storedSessionToken.d.ts +8 -0
  45. package/dist/Context/storedSessionToken.js +11 -0
  46. package/dist/Context/useNotificationState.d.ts +35 -0
  47. package/dist/Context/useNotificationState.js +92 -0
  48. package/dist/Hooks/useDebouncedValue.js +20 -16
  49. package/dist/Hooks/usePaginatedQuery.js +14 -20
  50. package/dist/Hooks/useQuery.js +6 -6
  51. package/dist/Model/ResponseModel.d.ts +2 -2
  52. package/dist/Model/ResponseModel.js +9 -4
  53. package/dist/Model/SessionInfoResponse.d.ts +0 -1
  54. package/dist/main.js +21 -21
  55. package/package.json +19 -17
@@ -1,97 +1,91 @@
1
1
  import { jsx as G } from "react/jsx-runtime";
2
- import { createContext as K, useState as T, useEffect as k, useContext as N } from "react";
3
- import { Events as V } from "../Common/Events.js";
4
- import { usePageVisibility as z } from "../Hooks/usePageVisibility.js";
5
- const y = K(void 0), x = "guestId", f = (d) => {
6
- d && V.publish("variamosNavigate", d);
7
- }, m = (d) => {
8
- d && localStorage.setItem("authToken", d);
9
- }, J = ({
10
- loginUrl: d,
11
- getSessionInfo: e,
12
- requestSignUp: v,
13
- requestSignIn: w,
14
- requestSignInAsGuest: C,
15
- requestLogout: P,
16
- children: b
2
+ import { createContext as L, useState as g, useEffect as d, useContext as T } from "react";
3
+ import { Events as _ } from "../Common/Events.js";
4
+ import { usePageVisibility as j } from "../Hooks/usePageVisibility.js";
5
+ import { forgetStoredSessionToken as s } from "./storedSessionToken.js";
6
+ const I = L(void 0), w = "guestId", E = (r) => {
7
+ r && _.publish("variamosNavigate", r);
8
+ };
9
+ function f(r, i) {
10
+ var a, c;
11
+ return r != null && r.errorCode ? (i(null), !1) : (i(((a = r == null ? void 0 : r.data) == null ? void 0 : a.user) ?? null), E((c = r == null ? void 0 : r.data) == null ? void 0 : c.redirect), !0);
12
+ }
13
+ const S = "Sign in error.", V = ({
14
+ loginUrl: r,
15
+ getSessionInfo: i,
16
+ requestSignUp: a,
17
+ requestSignIn: c,
18
+ requestSignInAsGuest: l,
19
+ requestLogout: y,
20
+ children: C
17
21
  }) => {
18
- const [E, t] = T(null), [A, c] = T(!0), g = !!E, I = z();
19
- k(() => {
20
- c(!0), e().then((o) => {
21
- var a, n, i;
22
- o != null && o.errorCode ? t(null) : (m((a = o == null ? void 0 : o.data) == null ? void 0 : a.authToken), t(((n = o == null ? void 0 : o.data) == null ? void 0 : n.user) ?? null), f((i = o == null ? void 0 : o.data) == null ? void 0 : i.redirect));
23
- }).catch(() => {
24
- t(null);
25
- }).finally(() => c(!1));
26
- }, [e]), k(() => {
27
- if (g && I) {
28
- const o = () => {
29
- e().then((n) => {
30
- var i, r, h;
31
- n != null && n.errorCode ? t(null) : (m((i = n == null ? void 0 : n.data) == null ? void 0 : i.authToken), t(((r = n == null ? void 0 : n.data) == null ? void 0 : r.user) ?? null), f((h = n == null ? void 0 : n.data) == null ? void 0 : h.redirect));
32
- }).catch(() => {
33
- t(null);
34
- });
35
- };
36
- o();
37
- const a = setInterval(() => {
38
- o();
39
- }, 6e4);
40
- return () => clearInterval(a);
41
- }
42
- }, [g, I, e]);
43
- const L = (o) => {
44
- if (!v)
22
+ const [h, e] = g(null), [x, o] = g(!0), u = h !== null, m = j();
23
+ d(() => {
24
+ s();
25
+ }, []), d(() => {
26
+ o(!0), i().then((t) => f(t, e)).catch(() => {
27
+ e(null);
28
+ }).finally(() => o(!1));
29
+ }, [i]), d(() => {
30
+ if (!(u && m)) return;
31
+ const t = () => {
32
+ i().then((R) => f(R, e)).catch(() => {
33
+ e(null);
34
+ });
35
+ };
36
+ t();
37
+ const n = setInterval(t, 6e4);
38
+ return () => clearInterval(n);
39
+ }, [u, m, i]);
40
+ const v = (t) => i().then((n) => (f(n, e) || t.withError(
41
+ n.errorCode ?? 500,
42
+ n.message ?? S
43
+ ), t)).catch(() => (e(null), t.withError(500, S))), P = (t) => {
44
+ if (!a)
45
45
  throw new Error("requestSignUp is not defined.");
46
- return c(!0), v(o).finally(() => c(!1));
47
- }, U = (o) => {
48
- if (!w)
46
+ return o(!0), a(t).finally(() => o(!1));
47
+ }, b = (t) => {
48
+ if (!c)
49
49
  throw new Error("requestSignIn is not defined.");
50
- return c(!0), w(o).then((a) => a != null && a.errorCode ? a : e().then((n) => {
51
- var i, r, h;
52
- return n != null && n.errorCode ? (t(null), a.withError(n.errorCode, n.message)) : (m((i = n == null ? void 0 : n.data) == null ? void 0 : i.authToken), t(((r = n == null ? void 0 : n.data) == null ? void 0 : r.user) ?? null), f((h = n == null ? void 0 : n.data) == null ? void 0 : h.redirect)), a;
53
- }).catch(() => (t(null), a.withError(500, "Sign in error.")))).finally(() => c(!1));
54
- }, j = () => {
55
- if (!C)
50
+ return o(!0), c(t).then(
51
+ (n) => n != null && n.errorCode ? n : v(n)
52
+ ).finally(() => o(!1));
53
+ }, A = () => {
54
+ if (!l)
56
55
  throw new Error("requestSignInAsGuest is not defined.");
57
- c(!0);
58
- const o = localStorage.getItem(x);
59
- return C(o).then((a) => {
56
+ return o(!0), l(localStorage.getItem(w)).then((t) => {
60
57
  var n;
61
- return a != null && a.errorCode ? a : (localStorage.setItem(x, ((n = a == null ? void 0 : a.data) == null ? void 0 : n.id) || ""), e().then((i) => {
62
- var r, h, S;
63
- return i != null && i.errorCode ? (t(null), a.withError(i.errorCode, i.message)) : (m((r = i == null ? void 0 : i.data) == null ? void 0 : r.authToken), t(((h = i == null ? void 0 : i.data) == null ? void 0 : h.user) ?? null), f((S = i == null ? void 0 : i.data) == null ? void 0 : S.redirect)), a;
64
- }).catch(() => (t(null), a.withError(500, "Sign in error."))));
65
- }).finally(() => c(!1));
66
- }, q = () => {
67
- P().then(() => {
68
- localStorage.removeItem("authToken"), f(d), setTimeout(() => {
69
- t(null);
58
+ return t != null && t.errorCode ? t : (localStorage.setItem(w, ((n = t == null ? void 0 : t.data) == null ? void 0 : n.id) || ""), v(t));
59
+ }).finally(() => o(!1));
60
+ }, N = () => {
61
+ y().then(() => {
62
+ s(), E(r), setTimeout(() => {
63
+ e(null);
70
64
  }, 200);
71
65
  });
72
66
  };
73
67
  return /* @__PURE__ */ G(
74
- y.Provider,
68
+ I.Provider,
75
69
  {
76
70
  value: {
77
- user: E,
78
- isAuthenticated: g,
79
- logout: q,
80
- signUp: L,
81
- signIn: U,
82
- signInAsGuest: j,
83
- isLoading: A
71
+ user: h,
72
+ isAuthenticated: u,
73
+ logout: N,
74
+ signUp: P,
75
+ signIn: b,
76
+ signInAsGuest: A,
77
+ isLoading: x
84
78
  },
85
- children: b
79
+ children: C
86
80
  }
87
81
  );
88
- }, M = () => {
89
- const d = N(y);
90
- if (d === void 0)
82
+ }, z = () => {
83
+ const r = T(I);
84
+ if (r === void 0)
91
85
  throw new Error("useSession must be used within a SessionProvider");
92
- return d;
86
+ return r;
93
87
  };
94
88
  export {
95
- J as SessionProvider,
96
- M as useSession
89
+ V as SessionProvider,
90
+ z as useSession
97
91
  };
@@ -1,5 +1,5 @@
1
1
  export * from './AnalyticsContext';
2
2
  export * from './MenuContext';
3
+ export * from './NotificationContext';
3
4
  export * from './RouterContext';
4
5
  export * from './SessionContext';
5
- export * from './NotificationContext';
@@ -1,21 +1,21 @@
1
1
  import { AnalyticsContext as t, AnalyticsProvider as r, PAGE_VISIT_EVENT as i } from "./AnalyticsContext.js";
2
2
  import { MenuContext as n, MenuContextProvider as u, useMenu as x } from "./MenuContext.js";
3
- import { RouterContext as a, getBasePath as P, isAbsoluteUrl as m, useRouter as p } from "./RouterContext.js";
4
- import { SessionProvider as d, useSession as l } from "./SessionContext.js";
5
- import { NotificationProvider as A, useNotifications as C } from "./NotificationContext.js";
3
+ import { NotificationProvider as a, useNotifications as P } from "./NotificationContext.js";
4
+ import { RouterContext as p, getBasePath as c, isAbsoluteUrl as d, useRouter as l } from "./RouterContext.js";
5
+ import { SessionProvider as A, useSession as C } from "./SessionContext.js";
6
6
  export {
7
7
  t as AnalyticsContext,
8
8
  r as AnalyticsProvider,
9
9
  n as MenuContext,
10
10
  u as MenuContextProvider,
11
- A as NotificationProvider,
11
+ a as NotificationProvider,
12
12
  i as PAGE_VISIT_EVENT,
13
- a as RouterContext,
14
- d as SessionProvider,
15
- P as getBasePath,
16
- m as isAbsoluteUrl,
13
+ p as RouterContext,
14
+ A as SessionProvider,
15
+ c as getBasePath,
16
+ d as isAbsoluteUrl,
17
17
  x as useMenu,
18
- C as useNotifications,
19
- p as useRouter,
20
- l as useSession
18
+ P as useNotifications,
19
+ l as useRouter,
20
+ C as useSession
21
21
  };
@@ -10,8 +10,6 @@ export interface NotificationAccessToken {
10
10
  export declare function accessTokenUrl(adminApiUrl: string): string;
11
11
  export interface AccessTokenProviderOptions {
12
12
  url: string;
13
- /** Session token of the platform, sent to the admin service. */
14
- getSessionToken?: () => string | null;
15
13
  fetchImpl?: typeof fetch;
16
14
  now?: () => number;
17
15
  /** A token is renewed this long before it expires. */
@@ -26,4 +24,4 @@ export interface AccessTokenProvider {
26
24
  * Keeps one token in memory, renews it shortly before it expires, and
27
25
  * shares a single request between concurrent callers.
28
26
  */
29
- export declare function createAccessTokenProvider({ url, getSessionToken, fetchImpl, now, refreshMarginMs, }: AccessTokenProviderOptions): AccessTokenProvider;
27
+ export declare function createAccessTokenProvider({ url, fetchImpl, now, refreshMarginMs, }: AccessTokenProviderOptions): AccessTokenProvider;
@@ -1,31 +1,27 @@
1
- function g(t) {
1
+ import { fieldOf as s } from "../Common/fieldOf.js";
2
+ function d(t) {
2
3
  return `${t.replace(/\/+$/, "").replace(/\/v1$/, "")}/v1/notifications/access-token`;
3
4
  }
4
- function y({
5
+ function k({
5
6
  url: t,
6
- getSessionToken: s = () => localStorage.getItem("authToken"),
7
- fetchImpl: p = (...e) => fetch(...e),
8
- now: f = Date.now,
9
- refreshMarginMs: k = 6e4
7
+ fetchImpl: o = (...e) => fetch(...e),
8
+ now: i = Date.now,
9
+ refreshMarginMs: u = 6e4
10
10
  }) {
11
11
  let e = null, n = null;
12
- const d = async () => {
13
- var a, o;
12
+ const f = async () => {
14
13
  try {
15
- const c = s(), l = await p(t, {
16
- credentials: "include",
17
- headers: c ? { Authorization: `Bearer ${c}` } : {}
18
- });
19
- if (!l.ok) return null;
20
- const i = await l.json(), r = (a = i.data) == null ? void 0 : a.token, u = Date.parse(String((o = i.data) == null ? void 0 : o.expiresAt));
21
- return typeof r != "string" || Number.isNaN(u) ? null : (e = { token: r, expiresAt: u }, r);
14
+ const c = await o(t, { credentials: "include" });
15
+ if (!c.ok) return null;
16
+ const l = s(await c.json(), "data"), r = s(l, "token"), a = Date.parse(String(s(l, "expiresAt")));
17
+ return typeof r != "string" || Number.isNaN(a) ? null : (e = { token: r, expiresAt: a }, r);
22
18
  } catch {
23
19
  return null;
24
20
  }
25
21
  };
26
22
  return {
27
- async get() {
28
- return e && f() < e.expiresAt - k ? e.token : (n ?? (n = d().finally(() => {
23
+ get() {
24
+ return e && i() < e.expiresAt - u ? Promise.resolve(e.token) : (n ?? (n = f().finally(() => {
29
25
  n = null;
30
26
  })), n);
31
27
  },
@@ -35,6 +31,6 @@ function y({
35
31
  };
36
32
  }
37
33
  export {
38
- g as accessTokenUrl,
39
- y as createAccessTokenProvider
34
+ d as accessTokenUrl,
35
+ k as createAccessTokenProvider
40
36
  };
@@ -0,0 +1,43 @@
1
+ export interface NotificationItem {
2
+ id: string;
3
+ templateKey: string;
4
+ variables: Record<string, unknown>;
5
+ metadata: Record<string, unknown>;
6
+ isRead: boolean;
7
+ createdAt: string;
8
+ }
9
+ export interface UserNotificationPreferences {
10
+ emailEnabled: boolean;
11
+ inAppEnabled: boolean;
12
+ mutedEventTypes: string[];
13
+ }
14
+ export type NotificationFolder = "inbox" | "trash";
15
+ /** A notification sent by the service, or null if a field is missing. */
16
+ export declare function notificationItemOf(value: unknown): NotificationItem | null;
17
+ /** The preferences sent by the service, or null if a field is missing. */
18
+ export declare function preferencesOf(value: unknown): UserNotificationPreferences | null;
19
+ export interface NotificationApiOptions {
20
+ apiUrl: string;
21
+ recipientId: string;
22
+ getHeaders: () => Promise<Record<string, string>>;
23
+ fetchImpl?: typeof fetch;
24
+ }
25
+ export interface NotificationPage {
26
+ folder: NotificationFolder;
27
+ page: number;
28
+ limit: number;
29
+ }
30
+ /**
31
+ * Calls to the notification service. Each one resolves to null (or false)
32
+ * when the service refuses; a network error rejects.
33
+ */
34
+ export declare function createNotificationApi({ apiUrl, recipientId, getHeaders, fetchImpl, }: NotificationApiOptions): {
35
+ list({ folder, page, limit, }: NotificationPage): Promise<NotificationItem[] | null>;
36
+ markAsRead(id: string): Promise<boolean>;
37
+ markAllAsRead(): Promise<boolean>;
38
+ emptyTrash(): Promise<boolean>;
39
+ remove(id: string): Promise<boolean>;
40
+ preferences(): Promise<UserNotificationPreferences | null>;
41
+ updatePreferences(updates: Partial<UserNotificationPreferences>): Promise<UserNotificationPreferences | null>;
42
+ };
43
+ export type NotificationApi = ReturnType<typeof createNotificationApi>;
@@ -0,0 +1,83 @@
1
+ import { fieldOf as r } from "../Common/fieldOf.js";
2
+ const d = (e) => typeof e == "object" && e !== null ? Object.fromEntries(Object.entries(e)) : {};
3
+ function m(e) {
4
+ const a = r(e, "id"), i = r(e, "templateKey"), s = r(e, "isRead"), n = r(e, "createdAt");
5
+ return typeof a != "string" || typeof i != "string" || typeof s != "boolean" || typeof n != "string" ? null : {
6
+ id: a,
7
+ templateKey: i,
8
+ variables: d(r(e, "variables")),
9
+ metadata: d(r(e, "metadata")),
10
+ isRead: s,
11
+ createdAt: n
12
+ };
13
+ }
14
+ function y(e) {
15
+ const a = r(e, "emailEnabled"), i = r(e, "inAppEnabled"), s = r(e, "mutedEventTypes");
16
+ return typeof a != "boolean" || typeof i != "boolean" || !Array.isArray(s) ? null : {
17
+ emailEnabled: a,
18
+ inAppEnabled: i,
19
+ mutedEventTypes: s.filter((n) => typeof n == "string")
20
+ };
21
+ }
22
+ function E({
23
+ apiUrl: e,
24
+ recipientId: a,
25
+ getHeaders: i,
26
+ fetchImpl: s = fetch
27
+ }) {
28
+ const n = `recipientId=${a}`, o = async (t, f, p) => {
29
+ const c = await s(`${e}/notifications${t}`, {
30
+ method: f,
31
+ headers: await i(),
32
+ body: p
33
+ });
34
+ return c.ok ? c : null;
35
+ }, l = async (t) => t ? t.json() : null;
36
+ return {
37
+ async list({
38
+ folder: t,
39
+ page: f,
40
+ limit: p
41
+ }) {
42
+ const c = await l(
43
+ await o(
44
+ `?${n}&page=${f}&limit=${p}&folder=${t}`
45
+ )
46
+ );
47
+ return Array.isArray(c) ? c.map(m).filter((u) => u !== null) : null;
48
+ },
49
+ async markAsRead(t) {
50
+ return await o(`/${t}/read`, "PATCH") !== null;
51
+ },
52
+ async markAllAsRead() {
53
+ return await o(`/read-all?${n}`, "PATCH") !== null;
54
+ },
55
+ async emptyTrash() {
56
+ return await o(`/trash?${n}`, "DELETE") !== null;
57
+ },
58
+ async remove(t) {
59
+ return await o(`/${t}`, "DELETE") !== null;
60
+ },
61
+ async preferences() {
62
+ return y(
63
+ await l(await o(`/preferences?${n}`))
64
+ );
65
+ },
66
+ async updatePreferences(t) {
67
+ return y(
68
+ await l(
69
+ await o(
70
+ `/preferences?${n}`,
71
+ "PATCH",
72
+ JSON.stringify(t)
73
+ )
74
+ )
75
+ );
76
+ }
77
+ };
78
+ }
79
+ export {
80
+ E as createNotificationApi,
81
+ m as notificationItemOf,
82
+ y as preferencesOf
83
+ };
@@ -0,0 +1,8 @@
1
+ /** Key under which versions before 0.4.0 kept the session token. */
2
+ export declare const STORED_TOKEN_KEY = "authToken";
3
+ /**
4
+ * Removes the session token that versions before 0.4.0 kept in the browser
5
+ * storage, where any script of the page can read it. The session lives in
6
+ * the httpOnly cookie of the admin service alone (EV-117).
7
+ */
8
+ export declare function forgetStoredSessionToken(storage?: Pick<Storage, "removeItem"> | undefined): void;
@@ -0,0 +1,11 @@
1
+ const e = "authToken";
2
+ function n(o = globalThis.localStorage) {
3
+ try {
4
+ o == null || o.removeItem(e);
5
+ } catch {
6
+ }
7
+ }
8
+ export {
9
+ e as STORED_TOKEN_KEY,
10
+ n as forgetStoredSessionToken
11
+ };
@@ -0,0 +1,35 @@
1
+ import { Dispatch, SetStateAction } from 'react';
2
+ import { NotificationApi, NotificationFolder, NotificationItem, UserNotificationPreferences } from './notificationApi';
3
+ export declare function logFailure(failure: string, action: () => Promise<void>): Promise<void>;
4
+ /** The notifications shown, the unread count, and how to load them. */
5
+ export declare function useNotificationList(api: NotificationApi | null): {
6
+ notifications: NotificationItem[];
7
+ unreadCount: number;
8
+ isLoading: boolean;
9
+ setNotifications: Dispatch<SetStateAction<NotificationItem[]>>;
10
+ setUnreadCount: Dispatch<SetStateAction<number>>;
11
+ fetchNotifications: (folder?: NotificationFolder, page?: number, limit?: number) => Promise<void>;
12
+ receive: (item: NotificationItem) => void;
13
+ clear: () => void;
14
+ };
15
+ interface NotificationChanges {
16
+ api: NotificationApi | null;
17
+ notifications: NotificationItem[];
18
+ setNotifications: Dispatch<SetStateAction<NotificationItem[]>>;
19
+ setUnreadCount: Dispatch<SetStateAction<number>>;
20
+ }
21
+ /** Marking as read and deleting, applied to the list once the service agrees. */
22
+ export declare function useNotificationChanges({ api, notifications, setNotifications, setUnreadCount, }: NotificationChanges): {
23
+ markAsRead: (id: string) => Promise<void>;
24
+ markAllAsRead: () => Promise<void>;
25
+ emptyTrash: () => Promise<void>;
26
+ deleteNotification: (id: string) => Promise<void>;
27
+ };
28
+ /** The notification preferences of the signed-in user. */
29
+ export declare function useNotificationPreferences(api: NotificationApi | null): {
30
+ preferences: UserNotificationPreferences | null;
31
+ fetchPreferences: () => Promise<void>;
32
+ updatePreferences: (updates: Partial<UserNotificationPreferences>) => Promise<void>;
33
+ clearPreferences: () => void;
34
+ };
35
+ export {};
@@ -0,0 +1,92 @@
1
+ import { useCallback as f, useMemo as F, useState as y } from "react";
2
+ async function i(e, s) {
3
+ try {
4
+ await s();
5
+ } catch (t) {
6
+ console.error(e, t);
7
+ }
8
+ }
9
+ const R = (e) => e.filter((s) => !s.isRead).length;
10
+ function A(e) {
11
+ const [s, t] = y([]), [c, l] = y(0), [m, a] = y(!1), d = f(
12
+ async (n = "inbox", r = 1, h = 10) => {
13
+ e && (a(!0), await i("Failed to fetch notifications:", async () => {
14
+ const w = await e.list({ folder: n, page: r, limit: h });
15
+ w && (t(w), n === "inbox" && l(R(w)));
16
+ }), a(!1));
17
+ },
18
+ [e]
19
+ ), o = f((n) => {
20
+ t((r) => [n, ...r]), l((r) => r + 1);
21
+ }, []), u = f(() => {
22
+ t([]), l(0);
23
+ }, []);
24
+ return {
25
+ notifications: s,
26
+ unreadCount: c,
27
+ isLoading: m,
28
+ setNotifications: t,
29
+ setUnreadCount: l,
30
+ fetchNotifications: d,
31
+ receive: o,
32
+ clear: u
33
+ };
34
+ }
35
+ function P({
36
+ api: e,
37
+ notifications: s,
38
+ setNotifications: t,
39
+ setUnreadCount: c
40
+ }) {
41
+ const l = f(
42
+ (o) => i("Failed to mark notification as read:", async () => {
43
+ await (e == null ? void 0 : e.markAsRead(o)) && (t(
44
+ (u) => u.map((n) => n.id === o ? { ...n, isRead: !0 } : n)
45
+ ), c((u) => Math.max(0, u - 1)));
46
+ }),
47
+ [e, t, c]
48
+ ), m = f(
49
+ () => i("Failed to mark all notifications as read:", async () => {
50
+ await (e == null ? void 0 : e.markAllAsRead()) && (t((o) => o.map((u) => ({ ...u, isRead: !0 }))), c(0));
51
+ }),
52
+ [e, t, c]
53
+ ), a = f(
54
+ () => i("Failed to empty trash:", async () => {
55
+ await (e == null ? void 0 : e.emptyTrash()) && t([]);
56
+ }),
57
+ [e, t]
58
+ ), d = f(
59
+ (o) => i("Failed to delete notification:", async () => {
60
+ var n;
61
+ const u = ((n = s.find((r) => r.id === o)) == null ? void 0 : n.isRead) === !1;
62
+ await (e == null ? void 0 : e.remove(o)) && (t((r) => r.filter((h) => h.id !== o)), u && c((r) => Math.max(0, r - 1)));
63
+ }),
64
+ [e, s, t, c]
65
+ );
66
+ return F(
67
+ () => ({ markAsRead: l, markAllAsRead: m, emptyTrash: a, deleteNotification: d }),
68
+ [l, m, a, d]
69
+ );
70
+ }
71
+ function g(e) {
72
+ const [s, t] = y(null), c = f(
73
+ () => i("Failed to fetch preferences:", async () => {
74
+ const a = await (e == null ? void 0 : e.preferences());
75
+ a && t(a);
76
+ }),
77
+ [e]
78
+ ), l = f(
79
+ (a) => i("Failed to update preferences:", async () => {
80
+ const d = await (e == null ? void 0 : e.updatePreferences(a));
81
+ d && t(d);
82
+ }),
83
+ [e]
84
+ ), m = f(() => t(null), []);
85
+ return { preferences: s, fetchPreferences: c, updatePreferences: l, clearPreferences: m };
86
+ }
87
+ export {
88
+ i as logFailure,
89
+ P as useNotificationChanges,
90
+ A as useNotificationList,
91
+ g as useNotificationPreferences
92
+ };
@@ -1,19 +1,23 @@
1
- import { useState as r, useEffect as i, useCallback as m } from "react";
2
- let e;
3
- function l(t, u) {
4
- const [c, o] = r(t);
5
- i(() => (e = setTimeout(() => {
6
- o(t);
7
- }, u), () => {
8
- clearTimeout(e);
9
- }), [t, u]);
10
- const s = m((n) => {
11
- clearTimeout(e), e = setTimeout(() => {
12
- o(n);
13
- }, u);
14
- }, []);
15
- return [c, s];
1
+ import { useState as s, useRef as i, useEffect as m, useCallback as f } from "react";
2
+ function b(u, e) {
3
+ const [o, r] = s(u), t = i(
4
+ void 0
5
+ );
6
+ m(() => (t.current = setTimeout(() => {
7
+ r(u);
8
+ }, e), () => {
9
+ clearTimeout(t.current);
10
+ }), [u, e]);
11
+ const c = f(
12
+ (n) => {
13
+ clearTimeout(t.current), t.current = setTimeout(() => {
14
+ r(n);
15
+ }, e);
16
+ },
17
+ [e]
18
+ );
19
+ return [o, c];
16
20
  }
17
21
  export {
18
- l as useDebouncedValue
22
+ b as useDebouncedValue
19
23
  };
@@ -1,32 +1,26 @@
1
1
  import { useState as t, useCallback as u } from "react";
2
- function T({
3
- queryFunction: s,
2
+ function S({
3
+ queryFunction: n,
4
4
  initialPage: c = 1
5
5
  }) {
6
- const [g, i] = t([]), [n, d] = t(null), [P, l] = t(c), [m, C] = t(1), [b, f] = t(1), [h, r] = t(!1), [I] = t(null), o = u(
7
- (a) => (d(a), r(!0), l(a.pageNumber || 1), s(a).then((e) => (i(e.data ?? []), C(e.totalCount || 0), f(
8
- Math.ceil((e.totalCount || 0) / a.pageSize)
9
- ), e)).finally(() => {
6
+ const [i, g] = t([]), [e, d] = t(null), [f, l] = t(c), [P, m] = t(1), [C, b] = t(1), [h, r] = t(!1), [I] = t(null), s = u(
7
+ (a) => (d(a), r(!0), l(a.pageNumber || 1), n(a).then((o) => (g(o.data ?? []), m(o.totalCount || 0), b(Math.ceil((o.totalCount || 0) / a.pageSize)), o)).finally(() => {
10
8
  r(!1);
11
9
  })),
12
- [s]
10
+ [n]
13
11
  ), D = u(
14
12
  (a) => {
15
- o(
16
- Object.assign(n, {
17
- pageNumber: a
18
- })
19
- );
13
+ e && s(Object.assign(e, { pageNumber: a }));
20
14
  },
21
- [n, o]
15
+ [e, s]
22
16
  );
23
17
  return {
24
- data: g,
25
- loadData: o,
26
- filter: n,
27
- currentPage: P,
28
- totalItems: m,
29
- totalPages: b,
18
+ data: i,
19
+ loadData: s,
20
+ filter: e,
21
+ currentPage: f,
22
+ totalItems: P,
23
+ totalPages: C,
30
24
  isLoading: h,
31
25
  error: I,
32
26
  onPageChange: D,
@@ -34,5 +28,5 @@ function T({
34
28
  };
35
29
  }
36
30
  export {
37
- T as usePaginatedQuery
31
+ S as usePaginatedQuery
38
32
  };