@umituz/web-dashboard 2.0.0 → 2.0.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/index.d.ts +10 -0
- package/dist/components/index.js +502 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +57 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +756 -0
- package/dist/index.js.map +1 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.js +184 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +44 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +19 -51
package/dist/index.js
ADDED
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/domains/layouts/components/DashboardLayout.tsx
|
|
4
|
+
import { useState as useState3, useEffect } from "react";
|
|
5
|
+
import { useLocation as useLocation2, Outlet, Navigate } from "react-router-dom";
|
|
6
|
+
import { Skeleton } from "@umituz/web-design-system/atoms";
|
|
7
|
+
|
|
8
|
+
// src/domains/layouts/components/DashboardSidebar.tsx
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { Link, useLocation } from "react-router-dom";
|
|
11
|
+
import { useTranslation } from "react-i18next";
|
|
12
|
+
import { Button } from "@umituz/web-design-system/atoms";
|
|
13
|
+
|
|
14
|
+
// src/domains/layouts/components/BrandLogo.tsx
|
|
15
|
+
import { cn } from "@umituz/web-design-system/utils";
|
|
16
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
17
|
+
var BrandLogo = ({ className, size = 32 }) => {
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"svg",
|
|
20
|
+
{
|
|
21
|
+
width: size,
|
|
22
|
+
height: size,
|
|
23
|
+
viewBox: "0 0 100 100",
|
|
24
|
+
fill: "none",
|
|
25
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
26
|
+
className: cn("shrink-0", className),
|
|
27
|
+
children: [
|
|
28
|
+
/* @__PURE__ */ jsx(
|
|
29
|
+
"rect",
|
|
30
|
+
{
|
|
31
|
+
x: "15",
|
|
32
|
+
y: "65",
|
|
33
|
+
width: "70",
|
|
34
|
+
height: "15",
|
|
35
|
+
rx: "4",
|
|
36
|
+
fill: "hsl(var(--primary))"
|
|
37
|
+
}
|
|
38
|
+
),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"rect",
|
|
41
|
+
{
|
|
42
|
+
x: "25",
|
|
43
|
+
y: "25",
|
|
44
|
+
width: "12",
|
|
45
|
+
height: "40",
|
|
46
|
+
rx: "2",
|
|
47
|
+
fill: "hsl(var(--primary))"
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"rect",
|
|
52
|
+
{
|
|
53
|
+
x: "44",
|
|
54
|
+
y: "35",
|
|
55
|
+
width: "12",
|
|
56
|
+
height: "30",
|
|
57
|
+
rx: "2",
|
|
58
|
+
fill: "hsl(var(--primary))"
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"rect",
|
|
63
|
+
{
|
|
64
|
+
x: "63",
|
|
65
|
+
y: "20",
|
|
66
|
+
width: "12",
|
|
67
|
+
height: "45",
|
|
68
|
+
rx: "2",
|
|
69
|
+
fill: "hsl(var(--primary))"
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
/* @__PURE__ */ jsx(
|
|
73
|
+
"rect",
|
|
74
|
+
{
|
|
75
|
+
x: "20",
|
|
76
|
+
y: "45",
|
|
77
|
+
width: "60",
|
|
78
|
+
height: "10",
|
|
79
|
+
rx: "2",
|
|
80
|
+
fill: "hsl(var(--secondary))"
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"circle",
|
|
85
|
+
{
|
|
86
|
+
cx: "50",
|
|
87
|
+
cy: "20",
|
|
88
|
+
r: "5",
|
|
89
|
+
fill: "hsl(var(--secondary))"
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// src/domains/layouts/components/DashboardSidebar.tsx
|
|
98
|
+
import { PenTool, Menu, ChevronLeft, ChevronDown, ChevronRight } from "lucide-react";
|
|
99
|
+
|
|
100
|
+
// src/domains/layouts/utils/dashboard.ts
|
|
101
|
+
function formatNotificationTime(createdAt, t) {
|
|
102
|
+
const date = new Date(createdAt);
|
|
103
|
+
const secs = Math.floor((Date.now() - date.getTime()) / 1e3);
|
|
104
|
+
if (secs < 60) return t("dashboard.activityFeed.times.justNow");
|
|
105
|
+
if (secs < 3600) return t("dashboard.activityFeed.times.minutesAgo", { val: Math.floor(secs / 60) });
|
|
106
|
+
if (secs < 86400) return t("dashboard.activityFeed.times.hoursAgo", { val: Math.floor(secs / 3600) });
|
|
107
|
+
return t("dashboard.activityFeed.times.daysAgo", { val: Math.floor(secs / 86400) });
|
|
108
|
+
}
|
|
109
|
+
function isPathActive(currentPath, targetPath) {
|
|
110
|
+
return currentPath === targetPath;
|
|
111
|
+
}
|
|
112
|
+
function getPageTitle(pathname, sidebarGroups, extraTitleMap) {
|
|
113
|
+
for (const group of sidebarGroups) {
|
|
114
|
+
const item = group.items.find((i) => i.path === pathname);
|
|
115
|
+
if (item) return item.label;
|
|
116
|
+
}
|
|
117
|
+
if (extraTitleMap?.[pathname]) {
|
|
118
|
+
return extraTitleMap[pathname];
|
|
119
|
+
}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
function filterSidebarItems(items, user) {
|
|
123
|
+
return items.filter((item) => {
|
|
124
|
+
if (item.enabled === false) return false;
|
|
125
|
+
if (!item.requiredApp) return true;
|
|
126
|
+
if (item.requiredApp === "mobile") return user?.hasMobileApp ?? false;
|
|
127
|
+
if (item.requiredApp === "web") return user?.hasWebApp ?? false;
|
|
128
|
+
return true;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function generateNotificationId() {
|
|
132
|
+
return crypto.randomUUID();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/domains/layouts/components/DashboardSidebar.tsx
|
|
136
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
137
|
+
var DashboardSidebar = ({
|
|
138
|
+
collapsed,
|
|
139
|
+
setCollapsed,
|
|
140
|
+
sidebarGroups,
|
|
141
|
+
brandName = "App",
|
|
142
|
+
brandTagline = "grow smarter",
|
|
143
|
+
createPostRoute = "/dashboard/create",
|
|
144
|
+
user
|
|
145
|
+
}) => {
|
|
146
|
+
const location = useLocation();
|
|
147
|
+
const { t } = useTranslation();
|
|
148
|
+
const [collapsedGroups, setCollapsedGroups] = useState({});
|
|
149
|
+
const toggleGroup = (title) => {
|
|
150
|
+
setCollapsedGroups((prev) => ({
|
|
151
|
+
...prev,
|
|
152
|
+
[title]: !prev[title]
|
|
153
|
+
}));
|
|
154
|
+
};
|
|
155
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col", children: [
|
|
156
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex h-16 items-center gap-3 border-b border-sidebar-border px-4 transition-all duration-300", children: [
|
|
157
|
+
/* @__PURE__ */ jsx2(BrandLogo, { size: 32 }),
|
|
158
|
+
!collapsed && /* @__PURE__ */ jsxs2("div", { className: "flex flex-col -gap-1", children: [
|
|
159
|
+
/* @__PURE__ */ jsx2("span", { className: "text-2xl font-black text-sidebar-foreground tracking-tighter leading-none", children: brandName }),
|
|
160
|
+
/* @__PURE__ */ jsx2("span", { className: "text-[11px] font-bold text-primary/70 lowercase tracking-tight mt-2 ml-1 select-none underline decoration-primary/40 underline-offset-[6px] decoration-2", children: brandTagline })
|
|
161
|
+
] })
|
|
162
|
+
] }),
|
|
163
|
+
/* @__PURE__ */ jsx2("div", { className: "px-3 py-4 border-b border-sidebar-border/50", children: /* @__PURE__ */ jsx2(Link, { to: createPostRoute, children: /* @__PURE__ */ jsxs2(
|
|
164
|
+
Button,
|
|
165
|
+
{
|
|
166
|
+
variant: "default",
|
|
167
|
+
className: `w-full gap-3 shadow-glow transition-all active:scale-95 group overflow-hidden rounded-xl ${collapsed ? "px-0 justify-center h-10 w-10 mx-auto" : "justify-start px-4 h-11"}`,
|
|
168
|
+
title: collapsed ? t("sidebar.createPost") : void 0,
|
|
169
|
+
children: [
|
|
170
|
+
/* @__PURE__ */ jsx2(PenTool, { className: `shrink-0 transition-transform duration-300 ${collapsed ? "h-5 w-5" : "h-4 w-4 group-hover:scale-110"}` }),
|
|
171
|
+
!collapsed && /* @__PURE__ */ jsx2("span", { className: "font-bold tracking-tight", children: t("sidebar.createPost") })
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
) }) }),
|
|
175
|
+
/* @__PURE__ */ jsx2("nav", { className: "flex-1 overflow-y-auto px-2 py-3 scrollbar-hide", children: /* @__PURE__ */ jsx2("div", { className: "space-y-6", children: sidebarGroups.map((group) => {
|
|
176
|
+
const filteredItems = filterSidebarItems(group.items, user);
|
|
177
|
+
if (filteredItems.length === 0) return null;
|
|
178
|
+
const isGroupCollapsed = collapsedGroups[group.title];
|
|
179
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-1", children: [
|
|
180
|
+
!collapsed && /* @__PURE__ */ jsxs2(
|
|
181
|
+
"button",
|
|
182
|
+
{
|
|
183
|
+
onClick: () => toggleGroup(group.title),
|
|
184
|
+
className: "w-full flex items-center justify-between px-3 mb-2 group/header",
|
|
185
|
+
children: [
|
|
186
|
+
/* @__PURE__ */ jsx2("span", { className: "text-[10px] font-bold uppercase tracking-widest text-sidebar-foreground/40 group-hover/header:text-sidebar-foreground/70 transition-colors", children: group.title === "sidebar.ai" ? `${brandName} AI` : t(group.title) }),
|
|
187
|
+
isGroupCollapsed ? /* @__PURE__ */ jsx2(ChevronRight, { className: "h-3 w-3 text-sidebar-foreground/30 flex-shrink-0 group-hover/header:text-sidebar-foreground/50 transition-colors" }) : /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3 w-3 text-sidebar-foreground/30 flex-shrink-0 group-hover/header:text-sidebar-foreground/50 transition-colors" })
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
),
|
|
191
|
+
(!isGroupCollapsed || collapsed) && filteredItems.map((item) => {
|
|
192
|
+
const active = location.pathname === item.path;
|
|
193
|
+
return /* @__PURE__ */ jsxs2(
|
|
194
|
+
Link,
|
|
195
|
+
{
|
|
196
|
+
to: item.path,
|
|
197
|
+
className: `flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 ${active ? "bg-sidebar-accent text-sidebar-accent-foreground shadow-sm" : "text-sidebar-foreground/70 hover:bg-sidebar-accent/40 hover:text-sidebar-foreground"} ${collapsed ? "justify-center" : ""}`,
|
|
198
|
+
title: collapsed ? t(item.label) : void 0,
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ jsx2(item.icon, { className: `h-4 w-4 shrink-0 transition-transform ${active && "scale-110"}` }),
|
|
201
|
+
!collapsed && /* @__PURE__ */ jsx2("span", { children: t(item.label) })
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
item.path
|
|
205
|
+
);
|
|
206
|
+
})
|
|
207
|
+
] }, group.title);
|
|
208
|
+
}) }) }),
|
|
209
|
+
/* @__PURE__ */ jsx2("div", { className: "border-t border-sidebar-border p-3", children: /* @__PURE__ */ jsxs2("div", { className: `flex items-center ${collapsed ? "justify-center" : "justify-between"}`, children: [
|
|
210
|
+
!collapsed && /* @__PURE__ */ jsx2("p", { className: "text-[10px] uppercase tracking-wider text-sidebar-foreground/40 font-bold px-2", children: t("sidebar.system") }),
|
|
211
|
+
/* @__PURE__ */ jsx2(Button, { variant: "ghost", size: "icon", onClick: () => setCollapsed(!collapsed), className: "text-sidebar-foreground/70", children: collapsed ? /* @__PURE__ */ jsx2(Menu, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx2(ChevronLeft, { className: "h-4 w-4" }) })
|
|
212
|
+
] }) })
|
|
213
|
+
] });
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// src/domains/layouts/components/DashboardHeader.tsx
|
|
217
|
+
import React, { useState as useState2 } from "react";
|
|
218
|
+
import {
|
|
219
|
+
Bell,
|
|
220
|
+
X,
|
|
221
|
+
Sun,
|
|
222
|
+
Moon,
|
|
223
|
+
Menu as Menu2,
|
|
224
|
+
User,
|
|
225
|
+
Settings,
|
|
226
|
+
LogOut,
|
|
227
|
+
ChevronDown as ChevronDown2,
|
|
228
|
+
CreditCard
|
|
229
|
+
} from "lucide-react";
|
|
230
|
+
import { Button as Button2 } from "@umituz/web-design-system/atoms";
|
|
231
|
+
import { useNavigate } from "react-router-dom";
|
|
232
|
+
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
233
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
234
|
+
var DashboardHeader = ({
|
|
235
|
+
collapsed,
|
|
236
|
+
setCollapsed,
|
|
237
|
+
setMobileOpen,
|
|
238
|
+
title,
|
|
239
|
+
user,
|
|
240
|
+
notifications = [],
|
|
241
|
+
onLogout,
|
|
242
|
+
onMarkAllRead,
|
|
243
|
+
onDismissNotification,
|
|
244
|
+
settingsRoute = "/dashboard/settings",
|
|
245
|
+
profileRoute = "/dashboard/profile",
|
|
246
|
+
billingRoute = "/dashboard/billing"
|
|
247
|
+
}) => {
|
|
248
|
+
const navigate = useNavigate();
|
|
249
|
+
const { t } = useTranslation2();
|
|
250
|
+
const [notifOpen, setNotifOpen] = useState2(false);
|
|
251
|
+
const [profileOpen, setProfileOpen] = useState2(false);
|
|
252
|
+
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
253
|
+
const markAllRead = () => {
|
|
254
|
+
onMarkAllRead?.();
|
|
255
|
+
};
|
|
256
|
+
const handleLogout = async () => {
|
|
257
|
+
try {
|
|
258
|
+
await onLogout?.();
|
|
259
|
+
navigate("/login");
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const ThemeToggle = () => {
|
|
264
|
+
const [resolvedTheme, setResolvedTheme] = React.useState("light");
|
|
265
|
+
return /* @__PURE__ */ jsx3(
|
|
266
|
+
Button2,
|
|
267
|
+
{
|
|
268
|
+
variant: "ghost",
|
|
269
|
+
size: "icon",
|
|
270
|
+
onClick: () => setResolvedTheme(resolvedTheme === "light" ? "dark" : "light"),
|
|
271
|
+
className: "text-muted-foreground h-9 w-9",
|
|
272
|
+
title: resolvedTheme === "dark" ? t("common.tooltips.switchLight") : t("common.tooltips.switchDark"),
|
|
273
|
+
children: resolvedTheme === "dark" ? /* @__PURE__ */ jsx3(Sun, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(Moon, { className: "h-4 w-4" })
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
return /* @__PURE__ */ jsxs3("header", { className: "flex h-14 items-center justify-between border-b border-border bg-card/50 backdrop-blur-md px-4 shrink-0 z-30", children: [
|
|
278
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
|
|
279
|
+
/* @__PURE__ */ jsx3(Button2, { variant: "ghost", size: "icon", className: "md:hidden", onClick: () => setMobileOpen(true), children: /* @__PURE__ */ jsx3(Menu2, { className: "h-5 w-5" }) }),
|
|
280
|
+
collapsed && /* @__PURE__ */ jsx3(Button2, { variant: "ghost", size: "icon", className: "hidden md:inline-flex", onClick: () => setCollapsed(false), children: /* @__PURE__ */ jsx3(Menu2, { className: "h-5 w-5" }) }),
|
|
281
|
+
/* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold text-foreground", children: title })
|
|
282
|
+
] }),
|
|
283
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
284
|
+
/* @__PURE__ */ jsx3(ThemeToggle, {}),
|
|
285
|
+
/* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
286
|
+
/* @__PURE__ */ jsxs3(
|
|
287
|
+
Button2,
|
|
288
|
+
{
|
|
289
|
+
variant: "ghost",
|
|
290
|
+
size: "icon",
|
|
291
|
+
className: "text-muted-foreground relative h-9 w-9",
|
|
292
|
+
onClick: () => {
|
|
293
|
+
setNotifOpen(!notifOpen);
|
|
294
|
+
setProfileOpen(false);
|
|
295
|
+
},
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ jsx3(Bell, { className: "h-4 w-4" }),
|
|
298
|
+
unreadCount > 0 && /* @__PURE__ */ jsxs3("span", { className: "absolute top-2 right-2 flex h-2 w-2", children: [
|
|
299
|
+
/* @__PURE__ */ jsx3("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-destructive opacity-75" }),
|
|
300
|
+
/* @__PURE__ */ jsx3("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-destructive" })
|
|
301
|
+
] })
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
notifOpen && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
306
|
+
/* @__PURE__ */ jsx3("div", { className: "fixed inset-0 z-40", onClick: () => setNotifOpen(false) }),
|
|
307
|
+
/* @__PURE__ */ jsxs3("div", { className: "absolute top-12 right-0 w-80 bg-popover border border-border rounded-xl shadow-xl z-50 overflow-hidden animate-in fade-in zoom-in-95 duration-200", children: [
|
|
308
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between px-4 py-3 border-b border-border bg-muted/50", children: [
|
|
309
|
+
/* @__PURE__ */ jsx3("h3", { className: "text-xs font-bold uppercase tracking-wider text-foreground", children: t("dashboard.notifications.title") }),
|
|
310
|
+
unreadCount > 0 && /* @__PURE__ */ jsx3("button", { onClick: markAllRead, className: "text-[10px] font-bold text-primary hover:underline uppercase", children: t("dashboard.notifications.markAllRead") })
|
|
311
|
+
] }),
|
|
312
|
+
/* @__PURE__ */ jsxs3("div", { className: "max-h-[400px] overflow-y-auto", children: [
|
|
313
|
+
notifications.map((n) => /* @__PURE__ */ jsxs3("div", { className: `px-4 py-3 border-b border-border last:border-0 flex items-start gap-3 transition-colors hover:bg-muted/30 ${!n.read ? "bg-primary/5" : ""}`, children: [
|
|
314
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
|
|
315
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-foreground leading-snug", children: n.text }),
|
|
316
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-[10px] text-muted-foreground mt-1 flex items-center gap-1", children: [
|
|
317
|
+
/* @__PURE__ */ jsx3("span", { className: "inline-block w-1 h-1 rounded-full bg-muted-foreground/30" }),
|
|
318
|
+
formatNotificationTime(n.createdAt, t)
|
|
319
|
+
] })
|
|
320
|
+
] }),
|
|
321
|
+
/* @__PURE__ */ jsx3(
|
|
322
|
+
"button",
|
|
323
|
+
{
|
|
324
|
+
onClick: () => onDismissNotification?.(n.id),
|
|
325
|
+
className: "text-muted-foreground/50 hover:text-foreground shrink-0 transition-colors",
|
|
326
|
+
children: /* @__PURE__ */ jsx3(X, { className: "h-3 w-3" })
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
] }, n.id)),
|
|
330
|
+
notifications.length === 0 && /* @__PURE__ */ jsxs3("div", { className: "px-4 py-10 text-center", children: [
|
|
331
|
+
/* @__PURE__ */ jsx3("div", { className: "mx-auto w-10 h-10 rounded-full bg-muted flex items-center justify-center mb-3", children: /* @__PURE__ */ jsx3(Bell, { className: "h-5 w-5 text-muted-foreground/50" }) }),
|
|
332
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: t("dashboard.notifications.none") })
|
|
333
|
+
] })
|
|
334
|
+
] })
|
|
335
|
+
] })
|
|
336
|
+
] })
|
|
337
|
+
] }),
|
|
338
|
+
/* @__PURE__ */ jsx3("div", { className: "h-6 w-px bg-border mx-1" }),
|
|
339
|
+
/* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
340
|
+
/* @__PURE__ */ jsxs3(
|
|
341
|
+
"button",
|
|
342
|
+
{
|
|
343
|
+
onClick: () => {
|
|
344
|
+
setProfileOpen(!profileOpen);
|
|
345
|
+
setNotifOpen(false);
|
|
346
|
+
},
|
|
347
|
+
className: "flex items-center gap-2 p-1 pl-1 rounded-full hover:bg-muted transition-colors group",
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsx3("div", { className: "w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-[10px] font-bold text-primary overflow-hidden border border-primary/20 ring-primary/20 group-hover:ring-4 transition-all", children: user?.avatar && /* @__PURE__ */ jsx3("img", { src: user.avatar, alt: "User", className: "w-full h-full object-cover" }) }),
|
|
350
|
+
/* @__PURE__ */ jsx3(ChevronDown2, { className: `h-4 w-4 text-muted-foreground transition-transform duration-200 ${profileOpen && "rotate-180"}` })
|
|
351
|
+
]
|
|
352
|
+
}
|
|
353
|
+
),
|
|
354
|
+
profileOpen && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
355
|
+
/* @__PURE__ */ jsx3("div", { className: "fixed inset-0 z-40", onClick: () => setProfileOpen(false) }),
|
|
356
|
+
/* @__PURE__ */ jsxs3("div", { className: "absolute top-12 right-0 w-56 bg-popover border border-border rounded-xl shadow-xl z-50 overflow-hidden animate-in fade-in zoom-in-95 duration-200 p-1.5", children: [
|
|
357
|
+
/* @__PURE__ */ jsxs3("div", { className: "px-3 py-2 border-b border-border/50 mb-1", children: [
|
|
358
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm font-bold text-foreground", children: user?.name || t("common.roles.user") }),
|
|
359
|
+
/* @__PURE__ */ jsx3("p", { className: "text-xs text-muted-foreground truncate", children: user?.email })
|
|
360
|
+
] }),
|
|
361
|
+
/* @__PURE__ */ jsxs3("div", { className: "space-y-0.5", children: [
|
|
362
|
+
/* @__PURE__ */ jsxs3(
|
|
363
|
+
"button",
|
|
364
|
+
{
|
|
365
|
+
onClick: () => {
|
|
366
|
+
navigate(profileRoute);
|
|
367
|
+
setProfileOpen(false);
|
|
368
|
+
},
|
|
369
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-sm text-foreground hover:bg-muted rounded-lg transition-colors",
|
|
370
|
+
children: [
|
|
371
|
+
/* @__PURE__ */ jsx3(User, { className: "h-4 w-4 text-muted-foreground" }),
|
|
372
|
+
t("common.profile")
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
/* @__PURE__ */ jsxs3(
|
|
377
|
+
"button",
|
|
378
|
+
{
|
|
379
|
+
onClick: () => {
|
|
380
|
+
navigate(billingRoute);
|
|
381
|
+
setProfileOpen(false);
|
|
382
|
+
},
|
|
383
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-sm text-foreground hover:bg-muted rounded-lg transition-colors",
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsx3(CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
386
|
+
t("common.billing")
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
),
|
|
390
|
+
/* @__PURE__ */ jsxs3(
|
|
391
|
+
"button",
|
|
392
|
+
{
|
|
393
|
+
onClick: () => {
|
|
394
|
+
navigate(settingsRoute);
|
|
395
|
+
setProfileOpen(false);
|
|
396
|
+
},
|
|
397
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-sm text-foreground hover:bg-muted rounded-lg transition-colors",
|
|
398
|
+
children: [
|
|
399
|
+
/* @__PURE__ */ jsx3(Settings, { className: "h-4 w-4 text-muted-foreground" }),
|
|
400
|
+
t("common.settings")
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
)
|
|
404
|
+
] }),
|
|
405
|
+
/* @__PURE__ */ jsx3("div", { className: "h-px bg-border my-1.5" }),
|
|
406
|
+
/* @__PURE__ */ jsxs3(
|
|
407
|
+
"button",
|
|
408
|
+
{
|
|
409
|
+
onClick: handleLogout,
|
|
410
|
+
className: "flex w-full items-center gap-2.5 px-3 py-2 text-sm text-destructive hover:bg-destructive/10 rounded-lg transition-colors font-medium",
|
|
411
|
+
children: [
|
|
412
|
+
/* @__PURE__ */ jsx3(LogOut, { className: "h-4 w-4" }),
|
|
413
|
+
t("common.logout")
|
|
414
|
+
]
|
|
415
|
+
}
|
|
416
|
+
)
|
|
417
|
+
] })
|
|
418
|
+
] })
|
|
419
|
+
] })
|
|
420
|
+
] })
|
|
421
|
+
] });
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// src/domains/layouts/components/DashboardLayout.tsx
|
|
425
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
426
|
+
var DashboardLayout = ({
|
|
427
|
+
config,
|
|
428
|
+
user,
|
|
429
|
+
authLoading = false,
|
|
430
|
+
isAuthenticated = true,
|
|
431
|
+
notifications = [],
|
|
432
|
+
onLogout,
|
|
433
|
+
onMarkAllRead,
|
|
434
|
+
onDismissNotification,
|
|
435
|
+
loginRoute = "/login"
|
|
436
|
+
}) => {
|
|
437
|
+
const location = useLocation2();
|
|
438
|
+
const [collapsed, setCollapsed] = useState3(false);
|
|
439
|
+
const [mobileOpen, setMobileOpen] = useState3(false);
|
|
440
|
+
const [loading, setLoading] = useState3(true);
|
|
441
|
+
useEffect(() => {
|
|
442
|
+
setLoading(true);
|
|
443
|
+
const timer = setTimeout(() => setLoading(false), 300);
|
|
444
|
+
return () => clearTimeout(timer);
|
|
445
|
+
}, [location.pathname]);
|
|
446
|
+
useEffect(() => {
|
|
447
|
+
setMobileOpen(false);
|
|
448
|
+
}, [location.pathname]);
|
|
449
|
+
if (authLoading) return null;
|
|
450
|
+
if (!isAuthenticated) return /* @__PURE__ */ jsx4(Navigate, { to: loginRoute, replace: true });
|
|
451
|
+
const activeItem = config.sidebarGroups.flatMap((group) => group.items).find((i) => i.path === location.pathname);
|
|
452
|
+
const getTitle = () => {
|
|
453
|
+
if (!activeItem) return config.extraTitleMap?.[location.pathname] || "Dashboard";
|
|
454
|
+
return activeItem.label;
|
|
455
|
+
};
|
|
456
|
+
const currentTitle = getTitle();
|
|
457
|
+
return /* @__PURE__ */ jsxs4("div", { className: "flex h-screen w-full bg-background font-sans", children: [
|
|
458
|
+
/* @__PURE__ */ jsx4(
|
|
459
|
+
"aside",
|
|
460
|
+
{
|
|
461
|
+
className: `hidden md:flex flex-col shrink-0 border-r border-sidebar-border bg-sidebar transition-all duration-300 ${collapsed ? "w-16" : "w-60"}`,
|
|
462
|
+
children: /* @__PURE__ */ jsx4(
|
|
463
|
+
DashboardSidebar,
|
|
464
|
+
{
|
|
465
|
+
collapsed,
|
|
466
|
+
setCollapsed,
|
|
467
|
+
sidebarGroups: config.sidebarGroups,
|
|
468
|
+
brandName: config.brandName,
|
|
469
|
+
brandTagline: config.brandTagline,
|
|
470
|
+
user
|
|
471
|
+
}
|
|
472
|
+
)
|
|
473
|
+
}
|
|
474
|
+
),
|
|
475
|
+
mobileOpen && /* @__PURE__ */ jsxs4("div", { className: "fixed inset-0 z-50 md:hidden", children: [
|
|
476
|
+
/* @__PURE__ */ jsx4("div", { className: "absolute inset-0 bg-background/80 backdrop-blur-sm", onClick: () => setMobileOpen(false) }),
|
|
477
|
+
/* @__PURE__ */ jsx4("aside", { className: "absolute left-0 top-0 h-full w-60 border-r border-sidebar-border bg-sidebar shadow-xl", children: /* @__PURE__ */ jsx4(
|
|
478
|
+
DashboardSidebar,
|
|
479
|
+
{
|
|
480
|
+
collapsed: false,
|
|
481
|
+
setCollapsed: () => setMobileOpen(false),
|
|
482
|
+
sidebarGroups: config.sidebarGroups,
|
|
483
|
+
brandName: config.brandName,
|
|
484
|
+
brandTagline: config.brandTagline,
|
|
485
|
+
user
|
|
486
|
+
}
|
|
487
|
+
) })
|
|
488
|
+
] }),
|
|
489
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-1 flex-col overflow-hidden min-w-0", children: [
|
|
490
|
+
/* @__PURE__ */ jsx4(
|
|
491
|
+
DashboardHeader,
|
|
492
|
+
{
|
|
493
|
+
collapsed,
|
|
494
|
+
setCollapsed,
|
|
495
|
+
setMobileOpen,
|
|
496
|
+
title: currentTitle,
|
|
497
|
+
user,
|
|
498
|
+
notifications,
|
|
499
|
+
onLogout,
|
|
500
|
+
onMarkAllRead,
|
|
501
|
+
onDismissNotification
|
|
502
|
+
}
|
|
503
|
+
),
|
|
504
|
+
/* @__PURE__ */ jsx4("main", { className: "flex-1 overflow-y-auto p-4 md:p-8", children: loading ? /* @__PURE__ */ jsxs4("div", { className: "mx-auto w-full max-w-7xl space-y-6", children: [
|
|
505
|
+
/* @__PURE__ */ jsx4(Skeleton, { className: "h-8 w-1/3 rounded-xl" }),
|
|
506
|
+
/* @__PURE__ */ jsx4("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx4(Skeleton, { className: "h-28 rounded-2xl" }, i)) }),
|
|
507
|
+
/* @__PURE__ */ jsx4(Skeleton, { className: "h-64 rounded-[32px]" })
|
|
508
|
+
] }) : /* @__PURE__ */ jsx4(Outlet, {}) })
|
|
509
|
+
] })
|
|
510
|
+
] });
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
// src/domains/layouts/hooks/dashboard.ts
|
|
514
|
+
import { useState as useState4, useCallback } from "react";
|
|
515
|
+
function useNotifications(initialNotifications = []) {
|
|
516
|
+
const [notifications, setNotifications] = useState4(initialNotifications);
|
|
517
|
+
const markAllRead = useCallback(() => {
|
|
518
|
+
setNotifications(
|
|
519
|
+
(prev) => prev.map((n) => ({ ...n, read: true }))
|
|
520
|
+
);
|
|
521
|
+
}, []);
|
|
522
|
+
const dismiss = useCallback((id) => {
|
|
523
|
+
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
524
|
+
}, []);
|
|
525
|
+
const add = useCallback((notification) => {
|
|
526
|
+
const newNotification = {
|
|
527
|
+
...notification,
|
|
528
|
+
id: crypto.randomUUID(),
|
|
529
|
+
read: false,
|
|
530
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
531
|
+
};
|
|
532
|
+
setNotifications((prev) => [newNotification, ...prev]);
|
|
533
|
+
}, []);
|
|
534
|
+
return {
|
|
535
|
+
notifications,
|
|
536
|
+
markAllRead,
|
|
537
|
+
dismiss,
|
|
538
|
+
add
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
function useSidebar(initialCollapsed = false) {
|
|
542
|
+
const [collapsed, setCollapsed] = useState4(initialCollapsed);
|
|
543
|
+
const [mobileOpen, setMobileOpen] = useState4(false);
|
|
544
|
+
const toggle = useCallback(() => {
|
|
545
|
+
setCollapsed((prev) => !prev);
|
|
546
|
+
}, []);
|
|
547
|
+
const openMobile = useCallback(() => {
|
|
548
|
+
setMobileOpen(true);
|
|
549
|
+
}, []);
|
|
550
|
+
const closeMobile = useCallback(() => {
|
|
551
|
+
setMobileOpen(false);
|
|
552
|
+
}, []);
|
|
553
|
+
return {
|
|
554
|
+
collapsed,
|
|
555
|
+
setCollapsed,
|
|
556
|
+
toggle,
|
|
557
|
+
mobileOpen,
|
|
558
|
+
setMobileOpen,
|
|
559
|
+
openMobile,
|
|
560
|
+
closeMobile
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// src/domains/layouts/theme/default.ts
|
|
565
|
+
var DEFAULT_DASHBOARD_THEME = {
|
|
566
|
+
primary: "hsl(222.2 47.4% 11.2%)",
|
|
567
|
+
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
568
|
+
sidebarBackground: "hsl(222.2 47.4% 11.2%)",
|
|
569
|
+
sidebarForeground: "hsl(210 40% 98%)",
|
|
570
|
+
sidebarBorder: "hsl(217.2 32.6% 17.5%)",
|
|
571
|
+
headerBackground: "hsla(0, 0%, 100%, 0.8)",
|
|
572
|
+
background: "hsl(0 0% 100%)",
|
|
573
|
+
foreground: "hsl(222.2 84% 4.9%)",
|
|
574
|
+
border: "hsl(214.3 31.8% 91.4%)",
|
|
575
|
+
accent: "hsl(217.2 91.2% 59.8%)",
|
|
576
|
+
accentForeground: "hsl(0 0% 100%)",
|
|
577
|
+
destructive: "hsl(0 84.2% 60.2%)",
|
|
578
|
+
destructiveForeground: "hsl(0 0% 98%)",
|
|
579
|
+
muted: "hsl(210 40% 96.1%)",
|
|
580
|
+
mutedForeground: "hsl(215.4 16.3% 46.9%)",
|
|
581
|
+
card: "hsl(0 0% 100%)",
|
|
582
|
+
cardForeground: "hsl(222.2 84% 4.9%)",
|
|
583
|
+
popover: "hsl(0 0% 100%)",
|
|
584
|
+
popoverForeground: "hsl(222.2 84% 4.9%)",
|
|
585
|
+
radius: "0.5rem"
|
|
586
|
+
};
|
|
587
|
+
var DEFAULT_DASHBOARD_THEME_DARK = {
|
|
588
|
+
primary: "hsl(217.2 91.2% 59.8%)",
|
|
589
|
+
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
590
|
+
sidebarBackground: "hsl(222.2 47.4% 11.2%)",
|
|
591
|
+
sidebarForeground: "hsl(210 40% 98%)",
|
|
592
|
+
sidebarBorder: "hsl(217.2 32.6% 17.5%)",
|
|
593
|
+
headerBackground: "hsla(222.2 47.4% 11.2%, 0.8)",
|
|
594
|
+
background: "hsl(222.2 84% 4.9%)",
|
|
595
|
+
foreground: "hsl(210 40% 98%)",
|
|
596
|
+
border: "hsl(217.2 32.6% 17.5%)",
|
|
597
|
+
accent: "hsl(217.2 91.2% 59.8%)",
|
|
598
|
+
accentForeground: "hsl(0 0% 100%)",
|
|
599
|
+
destructive: "hsl(0 62.8% 30.6%)",
|
|
600
|
+
destructiveForeground: "hsl(0 0% 98%)",
|
|
601
|
+
muted: "hsl(217.2 32.6% 17.5%)",
|
|
602
|
+
mutedForeground: "hsl(215 20.2% 65.1%)",
|
|
603
|
+
card: "hsl(222.2 84% 4.9%)",
|
|
604
|
+
cardForeground: "hsl(210 40% 98%)",
|
|
605
|
+
popover: "hsl(222.2 84% 4.9%)",
|
|
606
|
+
popoverForeground: "hsl(210 40% 98%)",
|
|
607
|
+
radius: "0.5rem"
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
// src/domains/layouts/theme/presets.ts
|
|
611
|
+
var DASHBOARD_THEME_PRESETS = [
|
|
612
|
+
{
|
|
613
|
+
name: "default",
|
|
614
|
+
theme: DEFAULT_DASHBOARD_THEME,
|
|
615
|
+
dark: false
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
name: "default-dark",
|
|
619
|
+
theme: DEFAULT_DASHBOARD_THEME_DARK,
|
|
620
|
+
dark: true
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
name: "blue",
|
|
624
|
+
theme: {
|
|
625
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
626
|
+
primary: "hsl(221.2 83.2% 53.3%)",
|
|
627
|
+
accent: "hsl(221.2 83.2% 53.3%)"
|
|
628
|
+
},
|
|
629
|
+
dark: false
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
name: "blue-dark",
|
|
633
|
+
theme: {
|
|
634
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
635
|
+
primary: "hsl(221.2 83.2% 53.3%)",
|
|
636
|
+
accent: "hsl(221.2 83.2% 53.3%)"
|
|
637
|
+
},
|
|
638
|
+
dark: true
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
name: "purple",
|
|
642
|
+
theme: {
|
|
643
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
644
|
+
primary: "hsl(271.5 81.3% 55.9%)",
|
|
645
|
+
accent: "hsl(271.5 81.3% 55.9%)"
|
|
646
|
+
},
|
|
647
|
+
dark: false
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
name: "purple-dark",
|
|
651
|
+
theme: {
|
|
652
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
653
|
+
primary: "hsl(271.5 81.3% 55.9%)",
|
|
654
|
+
accent: "hsl(271.5 81.3% 55.9%)"
|
|
655
|
+
},
|
|
656
|
+
dark: true
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: "green",
|
|
660
|
+
theme: {
|
|
661
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
662
|
+
primary: "hsl(142.1 76.2% 36.3%)",
|
|
663
|
+
accent: "hsl(142.1 76.2% 36.3%)"
|
|
664
|
+
},
|
|
665
|
+
dark: false
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
name: "green-dark",
|
|
669
|
+
theme: {
|
|
670
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
671
|
+
primary: "hsl(142.1 76.2% 36.3%)",
|
|
672
|
+
accent: "hsl(142.1 76.2% 36.3%)"
|
|
673
|
+
},
|
|
674
|
+
dark: true
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
name: "orange",
|
|
678
|
+
theme: {
|
|
679
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
680
|
+
primary: "hsl(24.6 95% 53.1%)",
|
|
681
|
+
accent: "hsl(24.6 95% 53.1%)"
|
|
682
|
+
},
|
|
683
|
+
dark: false
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: "orange-dark",
|
|
687
|
+
theme: {
|
|
688
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
689
|
+
primary: "hsl(24.6 95% 53.1%)",
|
|
690
|
+
accent: "hsl(24.6 95% 53.1%)"
|
|
691
|
+
},
|
|
692
|
+
dark: true
|
|
693
|
+
}
|
|
694
|
+
];
|
|
695
|
+
|
|
696
|
+
// src/domains/layouts/theme/utils.ts
|
|
697
|
+
function applyDashboardTheme(theme) {
|
|
698
|
+
if (typeof document === "undefined") return;
|
|
699
|
+
const root = document.documentElement;
|
|
700
|
+
const cssVars = {
|
|
701
|
+
"--primary": theme.primary,
|
|
702
|
+
"--secondary": theme.secondary,
|
|
703
|
+
"--sidebar": theme.sidebarBackground,
|
|
704
|
+
"--sidebar-foreground": theme.sidebarForeground,
|
|
705
|
+
"--sidebar-border": theme.sidebarBorder,
|
|
706
|
+
"--background": theme.background,
|
|
707
|
+
"--foreground": theme.foreground,
|
|
708
|
+
"--border": theme.border,
|
|
709
|
+
"--accent": theme.accent,
|
|
710
|
+
"--accent-foreground": theme.accentForeground,
|
|
711
|
+
"--destructive": theme.destructive,
|
|
712
|
+
"--destructive-foreground": theme.destructiveForeground,
|
|
713
|
+
"--muted": theme.muted,
|
|
714
|
+
"--muted-foreground": theme.mutedForeground,
|
|
715
|
+
"--card": theme.card,
|
|
716
|
+
"--card-foreground": theme.cardForeground,
|
|
717
|
+
"--popover": theme.popover,
|
|
718
|
+
"--popover-foreground": theme.popoverForeground,
|
|
719
|
+
"--radius": theme.radius
|
|
720
|
+
};
|
|
721
|
+
Object.entries(cssVars).forEach(([key, value]) => {
|
|
722
|
+
if (value) {
|
|
723
|
+
root.style.setProperty(key, value);
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
function getDashboardThemePreset(name) {
|
|
728
|
+
return DASHBOARD_THEME_PRESETS.find((preset) => preset.name === name);
|
|
729
|
+
}
|
|
730
|
+
function mergeDashboardTheme(customTheme, dark = false) {
|
|
731
|
+
const baseTheme = dark ? DEFAULT_DASHBOARD_THEME_DARK : DEFAULT_DASHBOARD_THEME;
|
|
732
|
+
return {
|
|
733
|
+
...baseTheme,
|
|
734
|
+
...customTheme
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
export {
|
|
738
|
+
BrandLogo,
|
|
739
|
+
DASHBOARD_THEME_PRESETS,
|
|
740
|
+
DEFAULT_DASHBOARD_THEME,
|
|
741
|
+
DEFAULT_DASHBOARD_THEME_DARK,
|
|
742
|
+
DashboardHeader,
|
|
743
|
+
DashboardLayout,
|
|
744
|
+
DashboardSidebar,
|
|
745
|
+
applyDashboardTheme,
|
|
746
|
+
filterSidebarItems,
|
|
747
|
+
formatNotificationTime,
|
|
748
|
+
generateNotificationId,
|
|
749
|
+
getDashboardThemePreset,
|
|
750
|
+
getPageTitle,
|
|
751
|
+
isPathActive,
|
|
752
|
+
mergeDashboardTheme,
|
|
753
|
+
useNotifications,
|
|
754
|
+
useSidebar
|
|
755
|
+
};
|
|
756
|
+
//# sourceMappingURL=index.js.map
|