@variamosple/variamos-components 0.2.0 → 0.2.1
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/Components/Header/index.js +33 -26
- package/dist/Components/Notifications/NotificationBell.js +5 -5
- package/dist/Components/Notifications/NotificationDrawer.js +104 -68
- package/dist/Context/NotificationContext.d.ts +1 -0
- package/dist/Context/NotificationContext.js +273 -260
- package/package.json +1 -1
|
@@ -1,47 +1,54 @@
|
|
|
1
|
-
import { jsxs as o, jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsxs as o, jsx as e, Fragment as g } from "react/jsx-runtime";
|
|
2
|
+
import { useState as N } from "react";
|
|
3
|
+
import { Navbar as a, Container as k, Nav as n } from "react-bootstrap";
|
|
3
4
|
import "../../Context/AnalyticsContext.js";
|
|
4
|
-
import { useMenu as
|
|
5
|
-
import { useRouter as
|
|
6
|
-
import { useSession as
|
|
5
|
+
import { useMenu as w } from "../../Context/MenuContext.js";
|
|
6
|
+
import { useRouter as C } from "../../Context/RouterContext.js";
|
|
7
|
+
import { useSession as S } from "../../Context/SessionContext.js";
|
|
7
8
|
import "../../Context/NotificationContext.js";
|
|
8
|
-
import { HeaderOptions as
|
|
9
|
-
import { MenuItemComponent as
|
|
10
|
-
import { SubHeader as
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
import { HeaderOptions as b } from "./HeaderOptions.js";
|
|
10
|
+
import { MenuItemComponent as m } from "./MenuItem.js";
|
|
11
|
+
import { SubHeader as v } from "./SubHeader.js";
|
|
12
|
+
import { NotificationBell as x } from "../Notifications/NotificationBell.js";
|
|
13
|
+
import { NotificationDrawer as D } from "../Notifications/NotificationDrawer.js";
|
|
14
|
+
const E = ({
|
|
15
|
+
logoUrl: s,
|
|
16
|
+
logoAlt: l = "App logo",
|
|
17
|
+
signInUrl: c,
|
|
18
|
+
adminApiUrl: p
|
|
16
19
|
}) => {
|
|
17
|
-
const { items:
|
|
20
|
+
const { items: d } = w(), { navigate: f } = C(), { isAuthenticated: r, isLoading: h } = S(), [u, t] = N(!1);
|
|
18
21
|
return /* @__PURE__ */ o("header", { className: "sticky-top", children: [
|
|
19
|
-
/* @__PURE__ */ e(
|
|
20
|
-
/* @__PURE__ */ e(
|
|
22
|
+
/* @__PURE__ */ e(a, { bg: "dark", variant: "dark", children: /* @__PURE__ */ o(k, { fluid: !0, children: [
|
|
23
|
+
/* @__PURE__ */ e(a.Brand, { onClick: () => f("/"), children: /* @__PURE__ */ e(
|
|
21
24
|
"img",
|
|
22
25
|
{
|
|
23
|
-
src:
|
|
26
|
+
src: s,
|
|
24
27
|
height: "30",
|
|
25
28
|
className: "d-inline-block align-top",
|
|
26
|
-
alt:
|
|
29
|
+
alt: l
|
|
27
30
|
}
|
|
28
31
|
) }),
|
|
29
|
-
/* @__PURE__ */ e(
|
|
30
|
-
/* @__PURE__ */ o(
|
|
31
|
-
/* @__PURE__ */
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
/* @__PURE__ */ e(n, { className: "me-auto", children: d.map((i) => /* @__PURE__ */ e(m, { ...i }, i.title)) }),
|
|
33
|
+
/* @__PURE__ */ o(n, { className: "me-5 pe-5 align-items-center", children: [
|
|
34
|
+
r && /* @__PURE__ */ o(g, { children: [
|
|
35
|
+
/* @__PURE__ */ e(x, { onClick: () => t(!0), className: "me-2" }),
|
|
36
|
+
/* @__PURE__ */ e(D, { show: u, onClose: () => t(!1) })
|
|
37
|
+
] }),
|
|
38
|
+
/* @__PURE__ */ e(b, { adminApiUrl: p }),
|
|
39
|
+
!h && !r && /* @__PURE__ */ e(
|
|
40
|
+
m,
|
|
34
41
|
{
|
|
35
42
|
title: "Sign In",
|
|
36
43
|
type: "location",
|
|
37
|
-
location:
|
|
44
|
+
location: c
|
|
38
45
|
}
|
|
39
46
|
)
|
|
40
47
|
] })
|
|
41
48
|
] }) }),
|
|
42
|
-
/* @__PURE__ */ e(
|
|
49
|
+
/* @__PURE__ */ e(v, {})
|
|
43
50
|
] });
|
|
44
51
|
};
|
|
45
52
|
export {
|
|
46
|
-
|
|
53
|
+
E as Header
|
|
47
54
|
};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { Button as a, Badge as n } from "react-bootstrap";
|
|
3
|
-
import { Bell as
|
|
4
|
-
import { useNotifications as
|
|
3
|
+
import { Bell as l } from "react-bootstrap-icons";
|
|
4
|
+
import { useNotifications as s } from "../../Context/NotificationContext.js";
|
|
5
5
|
const f = ({
|
|
6
6
|
onClick: o,
|
|
7
7
|
className: i = ""
|
|
8
8
|
}) => {
|
|
9
|
-
const { unreadCount: t } =
|
|
9
|
+
const { unreadCount: t } = s();
|
|
10
10
|
return /* @__PURE__ */ r(
|
|
11
11
|
a,
|
|
12
12
|
{
|
|
13
13
|
variant: "link",
|
|
14
14
|
onClick: o,
|
|
15
|
-
className: `position-relative p-2 text-
|
|
15
|
+
className: `position-relative p-2 text-light ${i}`,
|
|
16
16
|
"aria-label": "Notifications",
|
|
17
17
|
style: { boxShadow: "none" },
|
|
18
18
|
children: [
|
|
19
|
-
/* @__PURE__ */ e(
|
|
19
|
+
/* @__PURE__ */ e(l, { size: 22 }),
|
|
20
20
|
t > 0 && /* @__PURE__ */ e(
|
|
21
21
|
n,
|
|
22
22
|
{
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsxs as i, jsx as e, Fragment as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { Offcanvas as
|
|
4
|
-
import { ArrowLeft as
|
|
5
|
-
import { useNotifications as
|
|
6
|
-
import { NotificationSettings as
|
|
7
|
-
const
|
|
1
|
+
import { jsxs as i, jsx as e, Fragment as N } from "react/jsx-runtime";
|
|
2
|
+
import { useState as y, useEffect as L } from "react";
|
|
3
|
+
import { Offcanvas as d, Button as r, Nav as c, Spinner as E } from "react-bootstrap";
|
|
4
|
+
import { ArrowLeft as M, Gear as H, Inbox as I, Trash as b, CheckAll as K, CircleFill as R } from "react-bootstrap-icons";
|
|
5
|
+
import { useNotifications as _ } from "../../Context/NotificationContext.js";
|
|
6
|
+
import { NotificationSettings as B } from "./NotificationSettings.js";
|
|
7
|
+
const F = {
|
|
8
8
|
review_assigned: {
|
|
9
9
|
title: "Language Review Assigned",
|
|
10
10
|
body: "You have been assigned to review the translation for {{languageName}}."
|
|
@@ -16,50 +16,55 @@ const _ = {
|
|
|
16
16
|
test_template: {
|
|
17
17
|
title: "Notification Test",
|
|
18
18
|
body: "Hello {{name}}, this is a real-time notification test."
|
|
19
|
+
},
|
|
20
|
+
admin_alert: {
|
|
21
|
+
title: "{{title}}",
|
|
22
|
+
body: "{{body}}"
|
|
19
23
|
}
|
|
20
|
-
},
|
|
21
|
-
show:
|
|
22
|
-
onClose:
|
|
24
|
+
}, G = ({
|
|
25
|
+
show: m,
|
|
26
|
+
onClose: u
|
|
23
27
|
}) => {
|
|
24
28
|
const {
|
|
25
|
-
notifications:
|
|
26
|
-
isLoading:
|
|
27
|
-
fetchNotifications:
|
|
28
|
-
markAsRead:
|
|
29
|
-
markAllAsRead:
|
|
30
|
-
emptyTrash:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
notifications: f,
|
|
30
|
+
isLoading: v,
|
|
31
|
+
fetchNotifications: k,
|
|
32
|
+
markAsRead: w,
|
|
33
|
+
markAllAsRead: S,
|
|
34
|
+
emptyTrash: T,
|
|
35
|
+
deleteNotification: z
|
|
36
|
+
} = _(), [n, C] = y("inbox"), [p, x] = y(!1);
|
|
37
|
+
L(() => {
|
|
38
|
+
m && k(n);
|
|
39
|
+
}, [m, n]);
|
|
40
|
+
const g = (t, a) => {
|
|
36
41
|
let s = t;
|
|
37
|
-
for (const
|
|
38
|
-
s = s.replace(new RegExp(`{{${
|
|
42
|
+
for (const l of Object.keys(a))
|
|
43
|
+
s = s.replace(new RegExp(`{{${l}}}`, "g"), String(a[l]));
|
|
39
44
|
return s;
|
|
40
45
|
}, j = (t) => {
|
|
41
|
-
const
|
|
46
|
+
const a = F[t.templateKey] || {
|
|
42
47
|
title: "New Alert",
|
|
43
48
|
body: `Notification template: ${t.templateKey}`
|
|
44
49
|
};
|
|
45
50
|
return {
|
|
46
|
-
title:
|
|
47
|
-
body:
|
|
51
|
+
title: g(a.title, t.variables),
|
|
52
|
+
body: g(a.body, t.variables)
|
|
48
53
|
};
|
|
49
54
|
}, A = (t) => new Date(t).toLocaleDateString(void 0, {
|
|
50
55
|
hour: "2-digit",
|
|
51
56
|
minute: "2-digit"
|
|
52
57
|
});
|
|
53
|
-
return /* @__PURE__ */ i(
|
|
54
|
-
/* @__PURE__ */ e(
|
|
58
|
+
return /* @__PURE__ */ i(d, { show: m, onHide: u, placement: "end", className: "text-dark", children: [
|
|
59
|
+
/* @__PURE__ */ e(d.Header, { closeButton: !0, className: "border-bottom", children: /* @__PURE__ */ e(d.Title, { className: "d-flex align-items-center w-100", children: p ? /* @__PURE__ */ i(N, { children: [
|
|
55
60
|
/* @__PURE__ */ e(
|
|
56
61
|
r,
|
|
57
62
|
{
|
|
58
63
|
variant: "link",
|
|
59
64
|
className: "p-0 me-2 text-dark",
|
|
60
|
-
onClick: () =>
|
|
65
|
+
onClick: () => x(!1),
|
|
61
66
|
"aria-label": "Back",
|
|
62
|
-
children: /* @__PURE__ */ e(
|
|
67
|
+
children: /* @__PURE__ */ e(M, { size: 20 })
|
|
63
68
|
}
|
|
64
69
|
),
|
|
65
70
|
/* @__PURE__ */ e("span", { children: "Settings" })
|
|
@@ -70,42 +75,42 @@ const _ = {
|
|
|
70
75
|
{
|
|
71
76
|
variant: "link",
|
|
72
77
|
className: "p-0 text-secondary",
|
|
73
|
-
onClick: () =>
|
|
78
|
+
onClick: () => x(!0),
|
|
74
79
|
"aria-label": "Notification Settings",
|
|
75
80
|
style: { boxShadow: "none" },
|
|
76
|
-
children: /* @__PURE__ */ e(
|
|
81
|
+
children: /* @__PURE__ */ e(H, { size: 20 })
|
|
77
82
|
}
|
|
78
83
|
)
|
|
79
84
|
] }) }) }),
|
|
80
|
-
/* @__PURE__ */ e(
|
|
85
|
+
/* @__PURE__ */ e(d.Body, { className: "p-0 d-flex flex-column h-100", children: p ? /* @__PURE__ */ e("div", { className: "p-3", children: /* @__PURE__ */ e(B, {}) }) : /* @__PURE__ */ i(N, { children: [
|
|
81
86
|
/* @__PURE__ */ i(
|
|
82
|
-
|
|
87
|
+
c,
|
|
83
88
|
{
|
|
84
89
|
variant: "tabs",
|
|
85
|
-
activeKey:
|
|
86
|
-
onSelect: (t) =>
|
|
90
|
+
activeKey: n,
|
|
91
|
+
onSelect: (t) => C(t),
|
|
87
92
|
className: "px-3 pt-2 bg-light border-bottom",
|
|
88
93
|
children: [
|
|
89
|
-
/* @__PURE__ */ e(
|
|
90
|
-
/* @__PURE__ */ e(
|
|
94
|
+
/* @__PURE__ */ e(c.Item, { children: /* @__PURE__ */ i(c.Link, { eventKey: "inbox", className: "d-flex align-items-center", children: [
|
|
95
|
+
/* @__PURE__ */ e(I, { className: "me-2" }),
|
|
91
96
|
"Inbox"
|
|
92
97
|
] }) }),
|
|
93
|
-
/* @__PURE__ */ e(
|
|
94
|
-
/* @__PURE__ */ e(
|
|
98
|
+
/* @__PURE__ */ e(c.Item, { children: /* @__PURE__ */ i(c.Link, { eventKey: "trash", className: "d-flex align-items-center", children: [
|
|
99
|
+
/* @__PURE__ */ e(b, { className: "me-2" }),
|
|
95
100
|
"Trash"
|
|
96
101
|
] }) })
|
|
97
102
|
]
|
|
98
103
|
}
|
|
99
104
|
),
|
|
100
|
-
|
|
105
|
+
f.length > 0 && /* @__PURE__ */ e("div", { className: "d-flex justify-content-end align-items-center p-2 bg-light border-bottom px-3", children: n === "inbox" ? /* @__PURE__ */ i(
|
|
101
106
|
r,
|
|
102
107
|
{
|
|
103
108
|
variant: "link",
|
|
104
109
|
size: "sm",
|
|
105
110
|
className: "p-0 text-primary text-decoration-none d-flex align-items-center",
|
|
106
|
-
onClick:
|
|
111
|
+
onClick: S,
|
|
107
112
|
children: [
|
|
108
|
-
/* @__PURE__ */ e(
|
|
113
|
+
/* @__PURE__ */ e(K, { className: "me-1", size: 18 }),
|
|
109
114
|
"Mark all as read"
|
|
110
115
|
]
|
|
111
116
|
}
|
|
@@ -115,44 +120,75 @@ const _ = {
|
|
|
115
120
|
variant: "link",
|
|
116
121
|
size: "sm",
|
|
117
122
|
className: "p-0 text-danger text-decoration-none d-flex align-items-center",
|
|
118
|
-
onClick:
|
|
123
|
+
onClick: T,
|
|
119
124
|
children: [
|
|
120
|
-
/* @__PURE__ */ e(
|
|
125
|
+
/* @__PURE__ */ e(b, { className: "me-1", size: 16 }),
|
|
121
126
|
"Empty Trash"
|
|
122
127
|
]
|
|
123
128
|
}
|
|
124
129
|
) }),
|
|
125
|
-
/* @__PURE__ */ e("div", { className: "flex-grow-1 overflow-auto", children:
|
|
126
|
-
const { title:
|
|
130
|
+
/* @__PURE__ */ e("div", { className: "flex-grow-1 overflow-auto bg-light pt-3", children: v ? /* @__PURE__ */ e("div", { className: "text-center py-5", children: /* @__PURE__ */ e(E, { animation: "border", variant: "primary" }) }) : f.length === 0 ? /* @__PURE__ */ e("div", { className: "text-center py-5 text-muted", children: /* @__PURE__ */ e("p", { className: "mb-0", children: n === "inbox" ? "Your inbox is empty!" : "No deleted notifications." }) }) : /* @__PURE__ */ e("div", { className: "px-3", children: f.map((t) => {
|
|
131
|
+
const { title: a, body: s } = j(t), l = n === "inbox" && !t.isRead;
|
|
127
132
|
return /* @__PURE__ */ e(
|
|
128
|
-
|
|
133
|
+
"div",
|
|
129
134
|
{
|
|
130
|
-
className: `p-3
|
|
131
|
-
style: {
|
|
135
|
+
className: `p-3 mb-2 rounded border shadow-sm ${l ? "bg-white border-primary-subtle" : "bg-white border-light"}`,
|
|
136
|
+
style: {
|
|
137
|
+
transition: "all 0.2s ease-in-out",
|
|
138
|
+
borderLeft: l ? "4px solid #0d6efd" : "1px solid #dee2e6"
|
|
139
|
+
},
|
|
132
140
|
children: /* @__PURE__ */ i("div", { className: "d-flex justify-content-between align-items-start", children: [
|
|
133
|
-
/* @__PURE__ */ i("div", { className: "pe-
|
|
141
|
+
/* @__PURE__ */ i("div", { className: "pe-2 flex-grow-1", children: [
|
|
134
142
|
/* @__PURE__ */ e(
|
|
135
143
|
"h6",
|
|
136
144
|
{
|
|
137
|
-
className: `mb-1 ${
|
|
138
|
-
style: { fontSize: "0.
|
|
139
|
-
children:
|
|
145
|
+
className: `mb-1 ${l ? "fw-bold text-dark" : "text-secondary fw-semibold"}`,
|
|
146
|
+
style: { fontSize: "0.9rem", lineHeight: "1.25" },
|
|
147
|
+
children: a
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
/* @__PURE__ */ e(
|
|
151
|
+
"p",
|
|
152
|
+
{
|
|
153
|
+
className: "mb-2 text-muted",
|
|
154
|
+
style: { fontSize: "0.8rem", color: "#6c757d", lineHeight: "1.3" },
|
|
155
|
+
children: s
|
|
140
156
|
}
|
|
141
157
|
),
|
|
142
|
-
/* @__PURE__ */ e("
|
|
143
|
-
/* @__PURE__ */ e("span", { className: "text-muted", style: { fontSize: "0.75rem" }, children: A(t.createdAt) })
|
|
158
|
+
/* @__PURE__ */ e("span", { className: "text-muted d-block", style: { fontSize: "0.7rem" }, children: A(t.createdAt) })
|
|
144
159
|
] }),
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
/* @__PURE__ */ i("div", { className: "d-flex align-items-center gap-2", children: [
|
|
161
|
+
l && /* @__PURE__ */ e(
|
|
162
|
+
r,
|
|
163
|
+
{
|
|
164
|
+
variant: "link",
|
|
165
|
+
className: "p-1 text-primary border-0 d-flex align-items-center",
|
|
166
|
+
onClick: () => w(t.id),
|
|
167
|
+
title: "Mark as read",
|
|
168
|
+
style: { boxShadow: "none" },
|
|
169
|
+
children: /* @__PURE__ */ e(R, { size: 8, className: "text-primary" })
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
n === "inbox" && /* @__PURE__ */ e(
|
|
173
|
+
r,
|
|
174
|
+
{
|
|
175
|
+
variant: "link",
|
|
176
|
+
className: "p-1 text-secondary border-0 d-flex align-items-center",
|
|
177
|
+
onClick: () => z(t.id),
|
|
178
|
+
title: "Move to trash",
|
|
179
|
+
style: { boxShadow: "none" },
|
|
180
|
+
onMouseEnter: (h) => {
|
|
181
|
+
const o = h.currentTarget.querySelector("svg");
|
|
182
|
+
o && (o.style.fill = "#dc3545");
|
|
183
|
+
},
|
|
184
|
+
onMouseLeave: (h) => {
|
|
185
|
+
const o = h.currentTarget.querySelector("svg");
|
|
186
|
+
o && (o.style.fill = "currentColor");
|
|
187
|
+
},
|
|
188
|
+
children: /* @__PURE__ */ e(b, { size: 14, style: { transition: "fill 0.2s" } })
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
] })
|
|
156
192
|
] })
|
|
157
193
|
},
|
|
158
194
|
t.id
|
|
@@ -162,5 +198,5 @@ const _ = {
|
|
|
162
198
|
] });
|
|
163
199
|
};
|
|
164
200
|
export {
|
|
165
|
-
|
|
201
|
+
G as NotificationDrawer
|
|
166
202
|
};
|
|
@@ -21,6 +21,7 @@ interface NotificationContextType {
|
|
|
21
21
|
markAsRead: (id: string) => Promise<void>;
|
|
22
22
|
markAllAsRead: () => Promise<void>;
|
|
23
23
|
emptyTrash: () => Promise<void>;
|
|
24
|
+
deleteNotification: (id: string) => Promise<void>;
|
|
24
25
|
fetchPreferences: () => Promise<void>;
|
|
25
26
|
updatePreferences: (updates: Partial<UserNotificationPreferences>) => Promise<void>;
|
|
26
27
|
}
|