@umituz/web-dashboard 2.0.7 → 2.0.9
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/package.json +35 -77
- package/src/domains/layouts/components/BrandLogo.tsx +83 -0
- package/src/domains/layouts/components/DashboardHeader.tsx +240 -0
- package/src/domains/layouts/components/DashboardLayout.tsx +155 -0
- package/src/domains/layouts/components/DashboardSidebar.tsx +152 -0
- package/src/domains/layouts/components/index.ts +8 -0
- package/src/domains/layouts/hooks/dashboard.ts +81 -0
- package/src/domains/layouts/hooks/index.ts +8 -0
- package/src/domains/layouts/index.ts +11 -0
- package/{dist/layouts/theme/default.js → src/domains/layouts/theme/default.ts} +18 -11
- package/src/domains/layouts/theme/index.ts +18 -0
- package/src/domains/layouts/theme/presets.ts +96 -0
- package/src/domains/layouts/theme/utils.ts +67 -0
- package/src/domains/layouts/types/index.ts +9 -0
- package/src/domains/layouts/types/layout.ts +43 -0
- package/src/domains/layouts/types/notification.ts +19 -0
- package/src/domains/layouts/types/sidebar.ts +35 -0
- package/src/domains/layouts/types/theme.ts +64 -0
- package/src/domains/layouts/types/user.ts +35 -0
- package/src/domains/layouts/utils/dashboard.ts +96 -0
- package/src/domains/layouts/utils/index.ts +11 -0
- package/src/domains/onboarding/components/AppFocusStep.tsx +113 -0
- package/src/domains/onboarding/components/OnboardingWizard.tsx +262 -0
- package/src/domains/onboarding/components/PlanStep.tsx +208 -0
- package/src/domains/onboarding/components/PlatformsStep.tsx +109 -0
- package/src/domains/onboarding/components/UserTypeStep.tsx +135 -0
- package/src/domains/onboarding/components/index.ts +9 -0
- package/src/domains/onboarding/hooks/index.ts +5 -0
- package/{dist/onboarding/hooks/index.js → src/domains/onboarding/hooks/useOnboarding.ts} +65 -19
- package/src/domains/onboarding/index.ts +35 -0
- package/src/domains/onboarding/types/index.ts +16 -0
- package/src/domains/onboarding/types/onboarding.ts +214 -0
- package/src/domains/onboarding/utils/index.ts +15 -0
- package/src/domains/onboarding/utils/onboarding.ts +166 -0
- package/src/domains/settings/components/SettingsLayout.tsx +144 -0
- package/src/domains/settings/components/SettingsSection.tsx +106 -0
- package/src/domains/settings/components/index.ts +6 -0
- package/src/domains/settings/hooks/index.ts +7 -0
- package/src/domains/settings/hooks/useSettings.ts +80 -0
- package/src/domains/settings/index.ts +22 -0
- package/src/domains/settings/types/index.ts +11 -0
- package/src/domains/settings/types/settings.ts +81 -0
- package/src/domains/settings/utils/index.ts +11 -0
- package/src/domains/settings/utils/settings.ts +80 -0
- package/dist/layouts/components/BrandLogo.d.ts +0 -18
- package/dist/layouts/components/BrandLogo.js +0 -88
- package/dist/layouts/components/BrandLogo.js.map +0 -1
- package/dist/layouts/components/DashboardHeader.d.ts +0 -36
- package/dist/layouts/components/DashboardHeader.js +0 -225
- package/dist/layouts/components/DashboardHeader.js.map +0 -1
- package/dist/layouts/components/DashboardLayout.d.ts +0 -45
- package/dist/layouts/components/DashboardLayout.js +0 -501
- package/dist/layouts/components/DashboardLayout.js.map +0 -1
- package/dist/layouts/components/DashboardSidebar.d.ts +0 -29
- package/dist/layouts/components/DashboardSidebar.js +0 -189
- package/dist/layouts/components/DashboardSidebar.js.map +0 -1
- package/dist/layouts/components/index.d.ts +0 -10
- package/dist/layouts/components/index.js +0 -502
- package/dist/layouts/components/index.js.map +0 -1
- package/dist/layouts/hooks/dashboard.d.ts +0 -35
- package/dist/layouts/hooks/dashboard.js +0 -57
- package/dist/layouts/hooks/dashboard.js.map +0 -1
- package/dist/layouts/hooks/index.d.ts +0 -3
- package/dist/layouts/hooks/index.js +0 -57
- package/dist/layouts/hooks/index.js.map +0 -1
- package/dist/layouts/index.d.ts +0 -17
- package/dist/layouts/index.js +0 -756
- package/dist/layouts/index.js.map +0 -1
- package/dist/layouts/theme/default.d.ts +0 -18
- package/dist/layouts/theme/default.js.map +0 -1
- package/dist/layouts/theme/index.d.ts +0 -4
- package/dist/layouts/theme/index.js +0 -184
- package/dist/layouts/theme/index.js.map +0 -1
- package/dist/layouts/theme/presets.d.ts +0 -14
- package/dist/layouts/theme/presets.js +0 -137
- package/dist/layouts/theme/presets.js.map +0 -1
- package/dist/layouts/theme/utils.d.ts +0 -22
- package/dist/layouts/theme/utils.js +0 -181
- package/dist/layouts/theme/utils.js.map +0 -1
- package/dist/layouts/types/index.d.ts +0 -6
- package/dist/layouts/types/index.js +0 -2
- package/dist/layouts/types/index.js.map +0 -1
- package/dist/layouts/types/layout.d.ts +0 -45
- package/dist/layouts/types/layout.js +0 -2
- package/dist/layouts/types/layout.js.map +0 -1
- package/dist/layouts/types/notification.d.ts +0 -20
- package/dist/layouts/types/notification.js +0 -2
- package/dist/layouts/types/notification.js.map +0 -1
- package/dist/layouts/types/sidebar.d.ts +0 -36
- package/dist/layouts/types/sidebar.js +0 -2
- package/dist/layouts/types/sidebar.js.map +0 -1
- package/dist/layouts/types/theme.d.ts +0 -64
- package/dist/layouts/types/theme.js +0 -2
- package/dist/layouts/types/theme.js.map +0 -1
- package/dist/layouts/types/user.d.ts +0 -37
- package/dist/layouts/types/user.js +0 -2
- package/dist/layouts/types/user.js.map +0 -1
- package/dist/layouts/utils/dashboard.d.ts +0 -57
- package/dist/layouts/utils/dashboard.js +0 -44
- package/dist/layouts/utils/dashboard.js.map +0 -1
- package/dist/layouts/utils/index.d.ts +0 -1
- package/dist/layouts/utils/index.js +0 -44
- package/dist/layouts/utils/index.js.map +0 -1
- package/dist/onboarding/components/AppFocusStep.d.ts +0 -26
- package/dist/onboarding/components/AppFocusStep.js +0 -86
- package/dist/onboarding/components/AppFocusStep.js.map +0 -1
- package/dist/onboarding/components/OnboardingWizard.d.ts +0 -13
- package/dist/onboarding/components/OnboardingWizard.js +0 -332
- package/dist/onboarding/components/OnboardingWizard.js.map +0 -1
- package/dist/onboarding/components/PlanStep.d.ts +0 -21
- package/dist/onboarding/components/PlanStep.js +0 -167
- package/dist/onboarding/components/PlanStep.js.map +0 -1
- package/dist/onboarding/components/PlatformsStep.d.ts +0 -26
- package/dist/onboarding/components/PlatformsStep.js +0 -86
- package/dist/onboarding/components/PlatformsStep.js.map +0 -1
- package/dist/onboarding/components/UserTypeStep.d.ts +0 -30
- package/dist/onboarding/components/UserTypeStep.js +0 -93
- package/dist/onboarding/components/UserTypeStep.js.map +0 -1
- package/dist/onboarding/components/index.d.ts +0 -9
- package/dist/onboarding/components/index.js +0 -738
- package/dist/onboarding/components/index.js.map +0 -1
- package/dist/onboarding/hooks/index.d.ts +0 -4
- package/dist/onboarding/hooks/index.js.map +0 -1
- package/dist/onboarding/hooks/useOnboarding.d.ts +0 -50
- package/dist/onboarding/hooks/useOnboarding.js +0 -100
- package/dist/onboarding/hooks/useOnboarding.js.map +0 -1
- package/dist/onboarding/index.d.ts +0 -11
- package/dist/onboarding/index.js +0 -913
- package/dist/onboarding/index.js.map +0 -1
- package/dist/onboarding/types/index.d.ts +0 -3
- package/dist/onboarding/types/index.js +0 -2
- package/dist/onboarding/types/index.js.map +0 -1
- package/dist/onboarding/types/onboarding.d.ts +0 -209
- package/dist/onboarding/types/onboarding.js +0 -2
- package/dist/onboarding/types/onboarding.js.map +0 -1
- package/dist/onboarding/utils/index.d.ts +0 -4
- package/dist/onboarding/utils/index.js +0 -83
- package/dist/onboarding/utils/index.js.map +0 -1
- package/dist/onboarding/utils/onboarding.d.ts +0 -106
- package/dist/onboarding/utils/onboarding.js +0 -83
- package/dist/onboarding/utils/onboarding.js.map +0 -1
- package/dist/settings/components/SettingsLayout.d.ts +0 -19
- package/dist/settings/components/SettingsLayout.js +0 -170
- package/dist/settings/components/SettingsLayout.js.map +0 -1
- package/dist/settings/components/SettingsSection.d.ts +0 -24
- package/dist/settings/components/SettingsSection.js +0 -73
- package/dist/settings/components/SettingsSection.js.map +0 -1
- package/dist/settings/components/index.d.ts +0 -5
- package/dist/settings/components/index.js +0 -169
- package/dist/settings/components/index.js.map +0 -1
- package/dist/settings/hooks/index.d.ts +0 -3
- package/dist/settings/hooks/index.js +0 -59
- package/dist/settings/hooks/index.js.map +0 -1
- package/dist/settings/hooks/useSettings.d.ts +0 -25
- package/dist/settings/hooks/useSettings.js +0 -59
- package/dist/settings/hooks/useSettings.js.map +0 -1
- package/dist/settings/index.d.ts +0 -7
- package/dist/settings/index.js +0 -259
- package/dist/settings/index.js.map +0 -1
- package/dist/settings/types/index.d.ts +0 -2
- package/dist/settings/types/index.js +0 -2
- package/dist/settings/types/index.js.map +0 -1
- package/dist/settings/types/settings.d.ts +0 -79
- package/dist/settings/types/settings.js +0 -2
- package/dist/settings/types/settings.js.map +0 -1
- package/dist/settings/utils/index.d.ts +0 -3
- package/dist/settings/utils/index.js +0 -39
- package/dist/settings/utils/index.js.map +0 -1
- package/dist/settings/utils/settings.d.ts +0 -50
- package/dist/settings/utils/settings.js +0 -39
- package/dist/settings/utils/settings.js.map +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Link, useLocation } from "react-router-dom";
|
|
3
|
+
import { useTranslation } from "react-i18next";
|
|
4
|
+
|
|
5
|
+
import { Button } from "@umituz/web-design-system/atoms";
|
|
6
|
+
import { BrandLogo } from "./BrandLogo";
|
|
7
|
+
import { PenTool, Menu, ChevronLeft, ChevronDown, ChevronRight } from "lucide-react";
|
|
8
|
+
import type { DashboardSidebarProps } from "../types/layout";
|
|
9
|
+
import type { DashboardUser } from "../types/user";
|
|
10
|
+
import type { SidebarGroup } from "../types/sidebar";
|
|
11
|
+
import { filterSidebarItems } from "../utils/dashboard";
|
|
12
|
+
|
|
13
|
+
interface DashboardSidebarPropsExtended extends DashboardSidebarProps {
|
|
14
|
+
/** Sidebar groups configuration */
|
|
15
|
+
sidebarGroups: SidebarGroup[];
|
|
16
|
+
/** Brand name */
|
|
17
|
+
brandName?: string;
|
|
18
|
+
/** Brand tagline */
|
|
19
|
+
brandTagline?: string;
|
|
20
|
+
/** Create post route */
|
|
21
|
+
createPostRoute?: string;
|
|
22
|
+
/** Auth user */
|
|
23
|
+
user?: DashboardUser;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Dashboard Sidebar Component
|
|
28
|
+
*
|
|
29
|
+
* Displays collapsible sidebar with navigation menu items.
|
|
30
|
+
* Supports app-based filtering (mobile/web) and collapsible groups.
|
|
31
|
+
*
|
|
32
|
+
* @param props - Dashboard sidebar props
|
|
33
|
+
*/
|
|
34
|
+
export const DashboardSidebar = ({
|
|
35
|
+
collapsed,
|
|
36
|
+
setCollapsed,
|
|
37
|
+
sidebarGroups,
|
|
38
|
+
brandName = "App",
|
|
39
|
+
brandTagline = "grow smarter",
|
|
40
|
+
createPostRoute = "/dashboard/create",
|
|
41
|
+
user,
|
|
42
|
+
}: DashboardSidebarPropsExtended) => {
|
|
43
|
+
const location = useLocation();
|
|
44
|
+
const { t } = useTranslation();
|
|
45
|
+
const [collapsedGroups, setCollapsedGroups] = useState<Record<string, boolean>>({});
|
|
46
|
+
|
|
47
|
+
const toggleGroup = (title: string) => {
|
|
48
|
+
setCollapsedGroups(prev => ({
|
|
49
|
+
...prev,
|
|
50
|
+
[title]: !prev[title]
|
|
51
|
+
}));
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="flex h-full flex-col">
|
|
56
|
+
{/* Brand Section */}
|
|
57
|
+
<div className="flex h-16 items-center gap-3 border-b border-sidebar-border px-4 transition-all duration-300">
|
|
58
|
+
<BrandLogo size={32} />
|
|
59
|
+
{!collapsed && (
|
|
60
|
+
<div className="flex flex-col -gap-1">
|
|
61
|
+
<span className="text-2xl font-black text-sidebar-foreground tracking-tighter leading-none">{brandName}</span>
|
|
62
|
+
<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">
|
|
63
|
+
{brandTagline}
|
|
64
|
+
</span>
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{/* Create Button */}
|
|
70
|
+
<div className="px-3 py-4 border-b border-sidebar-border/50">
|
|
71
|
+
<Link to={createPostRoute}>
|
|
72
|
+
<Button
|
|
73
|
+
variant="default"
|
|
74
|
+
className={`w-full gap-3 shadow-glow transition-all active:scale-95 group overflow-hidden rounded-xl ${
|
|
75
|
+
collapsed ? "px-0 justify-center h-10 w-10 mx-auto" : "justify-start px-4 h-11"
|
|
76
|
+
}`}
|
|
77
|
+
title={collapsed ? t('sidebar.createPost') : undefined}
|
|
78
|
+
>
|
|
79
|
+
<PenTool className={`shrink-0 transition-transform duration-300 ${collapsed ? "h-5 w-5" : "h-4 w-4 group-hover:scale-110"}`} />
|
|
80
|
+
{!collapsed && <span className="font-bold tracking-tight">{t('sidebar.createPost')}</span>}
|
|
81
|
+
</Button>
|
|
82
|
+
</Link>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
{/* Navigation */}
|
|
86
|
+
<nav className="flex-1 overflow-y-auto px-2 py-3 scrollbar-hide">
|
|
87
|
+
<div className="space-y-6">
|
|
88
|
+
{sidebarGroups.map((group) => {
|
|
89
|
+
const filteredItems = filterSidebarItems(group.items, user);
|
|
90
|
+
|
|
91
|
+
if (filteredItems.length === 0) return null;
|
|
92
|
+
|
|
93
|
+
const isGroupCollapsed = collapsedGroups[group.title];
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div key={group.title} className="space-y-1">
|
|
97
|
+
{!collapsed && (
|
|
98
|
+
<button
|
|
99
|
+
onClick={() => toggleGroup(group.title)}
|
|
100
|
+
className="w-full flex items-center justify-between px-3 mb-2 group/header"
|
|
101
|
+
>
|
|
102
|
+
<span className="text-[10px] font-bold uppercase tracking-widest text-sidebar-foreground/40 group-hover/header:text-sidebar-foreground/70 transition-colors">
|
|
103
|
+
{group.title === "sidebar.ai" ? `${brandName} AI` : t(group.title)}
|
|
104
|
+
</span>
|
|
105
|
+
{isGroupCollapsed ? (
|
|
106
|
+
<ChevronRight className="h-3 w-3 text-sidebar-foreground/30 flex-shrink-0 group-hover/header:text-sidebar-foreground/50 transition-colors" />
|
|
107
|
+
) : (
|
|
108
|
+
<ChevronDown className="h-3 w-3 text-sidebar-foreground/30 flex-shrink-0 group-hover/header:text-sidebar-foreground/50 transition-colors" />
|
|
109
|
+
)}
|
|
110
|
+
</button>
|
|
111
|
+
)}
|
|
112
|
+
|
|
113
|
+
{(!isGroupCollapsed || collapsed) && filteredItems.map((item) => {
|
|
114
|
+
const active = location.pathname === item.path;
|
|
115
|
+
return (
|
|
116
|
+
<Link
|
|
117
|
+
key={item.path}
|
|
118
|
+
to={item.path}
|
|
119
|
+
className={`flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200 ${
|
|
120
|
+
active
|
|
121
|
+
? "bg-sidebar-accent text-sidebar-accent-foreground shadow-sm"
|
|
122
|
+
: "text-sidebar-foreground/70 hover:bg-sidebar-accent/40 hover:text-sidebar-foreground"
|
|
123
|
+
} ${collapsed ? "justify-center" : ""}`}
|
|
124
|
+
title={collapsed ? t(item.label) : undefined}
|
|
125
|
+
>
|
|
126
|
+
<item.icon className={`h-4 w-4 shrink-0 transition-transform ${active && "scale-110"}`} />
|
|
127
|
+
{!collapsed && <span>{t(item.label)}</span>}
|
|
128
|
+
</Link>
|
|
129
|
+
);
|
|
130
|
+
})}
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
})}
|
|
134
|
+
</div>
|
|
135
|
+
</nav>
|
|
136
|
+
|
|
137
|
+
{/* Collapse Toggle */}
|
|
138
|
+
<div className="border-t border-sidebar-border p-3">
|
|
139
|
+
<div className={`flex items-center ${collapsed ? "justify-center" : "justify-between"}`}>
|
|
140
|
+
{!collapsed && (
|
|
141
|
+
<p className="text-[10px] uppercase tracking-wider text-sidebar-foreground/40 font-bold px-2">
|
|
142
|
+
{t('sidebar.system')}
|
|
143
|
+
</p>
|
|
144
|
+
)}
|
|
145
|
+
<Button variant="ghost" size="icon" onClick={() => setCollapsed(!collapsed)} className="text-sidebar-foreground/70">
|
|
146
|
+
{collapsed ? <Menu className="h-4 w-4" /> : <ChevronLeft className="h-4 w-4" />}
|
|
147
|
+
</Button>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Hooks
|
|
3
|
+
*
|
|
4
|
+
* Custom React hooks for dashboard functionality
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback } from "react";
|
|
8
|
+
import type { DashboardNotification } from "../types/notification";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Use Notifications Hook
|
|
12
|
+
*
|
|
13
|
+
* Manages notification state and actions
|
|
14
|
+
*
|
|
15
|
+
* @param initialNotifications - Initial notification list
|
|
16
|
+
* @returns Notification state and actions
|
|
17
|
+
*/
|
|
18
|
+
export function useNotifications(initialNotifications: DashboardNotification[] = []) {
|
|
19
|
+
const [notifications, setNotifications] = useState<DashboardNotification[]>(initialNotifications);
|
|
20
|
+
|
|
21
|
+
const markAllRead = useCallback(() => {
|
|
22
|
+
setNotifications((prev) =>
|
|
23
|
+
prev.map((n) => ({ ...n, read: true }))
|
|
24
|
+
);
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
const dismiss = useCallback((id: string) => {
|
|
28
|
+
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
const add = useCallback((notification: Omit<DashboardNotification, "id">) => {
|
|
32
|
+
const newNotification: DashboardNotification = {
|
|
33
|
+
...notification,
|
|
34
|
+
id: crypto.randomUUID(),
|
|
35
|
+
read: false,
|
|
36
|
+
createdAt: new Date(),
|
|
37
|
+
};
|
|
38
|
+
setNotifications((prev) => [newNotification, ...prev]);
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
notifications,
|
|
43
|
+
markAllRead,
|
|
44
|
+
dismiss,
|
|
45
|
+
add,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Use Sidebar Hook
|
|
51
|
+
*
|
|
52
|
+
* Manages sidebar state
|
|
53
|
+
*
|
|
54
|
+
* @returns Sidebar state and actions
|
|
55
|
+
*/
|
|
56
|
+
export function useSidebar(initialCollapsed = false) {
|
|
57
|
+
const [collapsed, setCollapsed] = useState(initialCollapsed);
|
|
58
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
59
|
+
|
|
60
|
+
const toggle = useCallback(() => {
|
|
61
|
+
setCollapsed((prev) => !prev);
|
|
62
|
+
}, []);
|
|
63
|
+
|
|
64
|
+
const openMobile = useCallback(() => {
|
|
65
|
+
setMobileOpen(true);
|
|
66
|
+
}, []);
|
|
67
|
+
|
|
68
|
+
const closeMobile = useCallback(() => {
|
|
69
|
+
setMobileOpen(false);
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
collapsed,
|
|
74
|
+
setCollapsed,
|
|
75
|
+
toggle,
|
|
76
|
+
mobileOpen,
|
|
77
|
+
setMobileOpen: setMobileOpen,
|
|
78
|
+
openMobile,
|
|
79
|
+
closeMobile,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Theme - Default Themes
|
|
3
|
+
*
|
|
4
|
+
* Default light and dark theme configurations
|
|
5
|
+
*/
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
import type { DashboardTheme } from '../types/theme';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default dashboard theme (light mode)
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_DASHBOARD_THEME: DashboardTheme = {
|
|
5
13
|
primary: "hsl(222.2 47.4% 11.2%)",
|
|
6
14
|
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
7
15
|
sidebarBackground: "hsl(222.2 47.4% 11.2%)",
|
|
@@ -21,9 +29,13 @@ var DEFAULT_DASHBOARD_THEME = {
|
|
|
21
29
|
cardForeground: "hsl(222.2 84% 4.9%)",
|
|
22
30
|
popover: "hsl(0 0% 100%)",
|
|
23
31
|
popoverForeground: "hsl(222.2 84% 4.9%)",
|
|
24
|
-
radius: "0.5rem"
|
|
32
|
+
radius: "0.5rem",
|
|
25
33
|
};
|
|
26
|
-
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Default dashboard theme (dark mode)
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_DASHBOARD_THEME_DARK: DashboardTheme = {
|
|
27
39
|
primary: "hsl(217.2 91.2% 59.8%)",
|
|
28
40
|
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
29
41
|
sidebarBackground: "hsl(222.2 47.4% 11.2%)",
|
|
@@ -43,10 +55,5 @@ var DEFAULT_DASHBOARD_THEME_DARK = {
|
|
|
43
55
|
cardForeground: "hsl(210 40% 98%)",
|
|
44
56
|
popover: "hsl(222.2 84% 4.9%)",
|
|
45
57
|
popoverForeground: "hsl(210 40% 98%)",
|
|
46
|
-
radius: "0.5rem"
|
|
47
|
-
};
|
|
48
|
-
export {
|
|
49
|
-
DEFAULT_DASHBOARD_THEME,
|
|
50
|
-
DEFAULT_DASHBOARD_THEME_DARK
|
|
58
|
+
radius: "0.5rem",
|
|
51
59
|
};
|
|
52
|
-
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Theme Export
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
DEFAULT_DASHBOARD_THEME,
|
|
7
|
+
DEFAULT_DASHBOARD_THEME_DARK,
|
|
8
|
+
} from './default';
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
DASHBOARD_THEME_PRESETS,
|
|
12
|
+
} from './presets';
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
applyDashboardTheme,
|
|
16
|
+
getDashboardThemePreset,
|
|
17
|
+
mergeDashboardTheme,
|
|
18
|
+
} from './utils';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Theme - Presets
|
|
3
|
+
*
|
|
4
|
+
* Pre-configured theme presets
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DashboardThemePreset } from '../types/theme';
|
|
8
|
+
import { DEFAULT_DASHBOARD_THEME, DEFAULT_DASHBOARD_THEME_DARK } from './default';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Available theme presets
|
|
12
|
+
*/
|
|
13
|
+
export const DASHBOARD_THEME_PRESETS: DashboardThemePreset[] = [
|
|
14
|
+
{
|
|
15
|
+
name: "default",
|
|
16
|
+
theme: DEFAULT_DASHBOARD_THEME,
|
|
17
|
+
dark: false,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "default-dark",
|
|
21
|
+
theme: DEFAULT_DASHBOARD_THEME_DARK,
|
|
22
|
+
dark: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "blue",
|
|
26
|
+
theme: {
|
|
27
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
28
|
+
primary: "hsl(221.2 83.2% 53.3%)",
|
|
29
|
+
accent: "hsl(221.2 83.2% 53.3%)",
|
|
30
|
+
},
|
|
31
|
+
dark: false,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "blue-dark",
|
|
35
|
+
theme: {
|
|
36
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
37
|
+
primary: "hsl(221.2 83.2% 53.3%)",
|
|
38
|
+
accent: "hsl(221.2 83.2% 53.3%)",
|
|
39
|
+
},
|
|
40
|
+
dark: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "purple",
|
|
44
|
+
theme: {
|
|
45
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
46
|
+
primary: "hsl(271.5 81.3% 55.9%)",
|
|
47
|
+
accent: "hsl(271.5 81.3% 55.9%)",
|
|
48
|
+
},
|
|
49
|
+
dark: false,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "purple-dark",
|
|
53
|
+
theme: {
|
|
54
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
55
|
+
primary: "hsl(271.5 81.3% 55.9%)",
|
|
56
|
+
accent: "hsl(271.5 81.3% 55.9%)",
|
|
57
|
+
},
|
|
58
|
+
dark: true,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "green",
|
|
62
|
+
theme: {
|
|
63
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
64
|
+
primary: "hsl(142.1 76.2% 36.3%)",
|
|
65
|
+
accent: "hsl(142.1 76.2% 36.3%)",
|
|
66
|
+
},
|
|
67
|
+
dark: false,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "green-dark",
|
|
71
|
+
theme: {
|
|
72
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
73
|
+
primary: "hsl(142.1 76.2% 36.3%)",
|
|
74
|
+
accent: "hsl(142.1 76.2% 36.3%)",
|
|
75
|
+
},
|
|
76
|
+
dark: true,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "orange",
|
|
80
|
+
theme: {
|
|
81
|
+
...DEFAULT_DASHBOARD_THEME,
|
|
82
|
+
primary: "hsl(24.6 95% 53.1%)",
|
|
83
|
+
accent: "hsl(24.6 95% 53.1%)",
|
|
84
|
+
},
|
|
85
|
+
dark: false,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "orange-dark",
|
|
89
|
+
theme: {
|
|
90
|
+
...DEFAULT_DASHBOARD_THEME_DARK,
|
|
91
|
+
primary: "hsl(24.6 95% 53.1%)",
|
|
92
|
+
accent: "hsl(24.6 95% 53.1%)",
|
|
93
|
+
},
|
|
94
|
+
dark: true,
|
|
95
|
+
},
|
|
96
|
+
];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Theme - Utilities
|
|
3
|
+
*
|
|
4
|
+
* Theme utility functions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DashboardTheme, DashboardThemePreset } from '../types/theme';
|
|
8
|
+
import { DEFAULT_DASHBOARD_THEME, DEFAULT_DASHBOARD_THEME_DARK } from './default';
|
|
9
|
+
import { DASHBOARD_THEME_PRESETS } from './presets';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Apply theme to document root via CSS variables
|
|
13
|
+
*/
|
|
14
|
+
export function applyDashboardTheme(theme: DashboardTheme): void {
|
|
15
|
+
if (typeof document === "undefined") return;
|
|
16
|
+
|
|
17
|
+
const root = document.documentElement;
|
|
18
|
+
|
|
19
|
+
const cssVars: Record<string, string | undefined> = {
|
|
20
|
+
"--primary": theme.primary,
|
|
21
|
+
"--secondary": theme.secondary,
|
|
22
|
+
"--sidebar": theme.sidebarBackground,
|
|
23
|
+
"--sidebar-foreground": theme.sidebarForeground,
|
|
24
|
+
"--sidebar-border": theme.sidebarBorder,
|
|
25
|
+
"--background": theme.background,
|
|
26
|
+
"--foreground": theme.foreground,
|
|
27
|
+
"--border": theme.border,
|
|
28
|
+
"--accent": theme.accent,
|
|
29
|
+
"--accent-foreground": theme.accentForeground,
|
|
30
|
+
"--destructive": theme.destructive,
|
|
31
|
+
"--destructive-foreground": theme.destructiveForeground,
|
|
32
|
+
"--muted": theme.muted,
|
|
33
|
+
"--muted-foreground": theme.mutedForeground,
|
|
34
|
+
"--card": theme.card,
|
|
35
|
+
"--card-foreground": theme.cardForeground,
|
|
36
|
+
"--popover": theme.popover,
|
|
37
|
+
"--popover-foreground": theme.popoverForeground,
|
|
38
|
+
"--radius": theme.radius,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
Object.entries(cssVars).forEach(([key, value]) => {
|
|
42
|
+
if (value) {
|
|
43
|
+
root.style.setProperty(key, value);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get theme preset by name
|
|
50
|
+
*/
|
|
51
|
+
export function getDashboardThemePreset(name: string): DashboardThemePreset | undefined {
|
|
52
|
+
return DASHBOARD_THEME_PRESETS.find((preset) => preset.name === name);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Merge custom theme with default theme
|
|
57
|
+
*/
|
|
58
|
+
export function mergeDashboardTheme(
|
|
59
|
+
customTheme: Partial<DashboardTheme>,
|
|
60
|
+
dark = false
|
|
61
|
+
): DashboardTheme {
|
|
62
|
+
const baseTheme = dark ? DEFAULT_DASHBOARD_THEME_DARK : DEFAULT_DASHBOARD_THEME;
|
|
63
|
+
return {
|
|
64
|
+
...baseTheme,
|
|
65
|
+
...customTheme,
|
|
66
|
+
} as DashboardTheme;
|
|
67
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Types Export
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type { SidebarItem, SidebarGroup } from './sidebar';
|
|
6
|
+
export type { DashboardHeaderProps, DashboardSidebarProps, DashboardLayoutConfig } from './layout';
|
|
7
|
+
export type { DashboardTheme, DashboardThemePreset } from './theme';
|
|
8
|
+
export type { DashboardNotification } from './notification';
|
|
9
|
+
export type { DashboardUser, UserNavMenuItem } from './user';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Types - Layout
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for layout components
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Dashboard header props
|
|
9
|
+
*/
|
|
10
|
+
export interface DashboardHeaderProps {
|
|
11
|
+
/** Whether sidebar is collapsed */
|
|
12
|
+
collapsed: boolean;
|
|
13
|
+
/** Toggle sidebar collapsed state */
|
|
14
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
15
|
+
/** Toggle mobile menu open state */
|
|
16
|
+
setMobileOpen: (open: boolean) => void;
|
|
17
|
+
/** Current page title */
|
|
18
|
+
title: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Dashboard sidebar props
|
|
23
|
+
*/
|
|
24
|
+
export interface DashboardSidebarProps {
|
|
25
|
+
/** Whether sidebar is collapsed */
|
|
26
|
+
collapsed: boolean;
|
|
27
|
+
/** Toggle sidebar collapsed state */
|
|
28
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dashboard layout configuration
|
|
33
|
+
*/
|
|
34
|
+
export interface DashboardLayoutConfig {
|
|
35
|
+
/** Sidebar groups */
|
|
36
|
+
sidebarGroups: import('./sidebar').SidebarGroup[];
|
|
37
|
+
/** Extra title mappings for routes */
|
|
38
|
+
extraTitleMap?: Record<string, string>;
|
|
39
|
+
/** Brand name */
|
|
40
|
+
brandName?: string;
|
|
41
|
+
/** Brand tagline */
|
|
42
|
+
brandTagline?: string;
|
|
43
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Types - Notification
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for notification system
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Notification item
|
|
9
|
+
*/
|
|
10
|
+
export interface DashboardNotification {
|
|
11
|
+
/** Unique ID */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Notification text */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Whether notification is read */
|
|
16
|
+
read: boolean;
|
|
17
|
+
/** Creation timestamp */
|
|
18
|
+
createdAt: Date | string | number;
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Types - Sidebar
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for sidebar components
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { LucideIcon } from "lucide-react";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Single sidebar menu item
|
|
11
|
+
*/
|
|
12
|
+
export interface SidebarItem {
|
|
13
|
+
/** Display label (can be i18n key) */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Icon from lucide-react */
|
|
16
|
+
icon: LucideIcon;
|
|
17
|
+
/** Route path */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Filter by app type (optional) */
|
|
20
|
+
requiredApp?: 'mobile' | 'web';
|
|
21
|
+
/** Enable/disable this item (default: true) */
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Group of sidebar items with a title
|
|
27
|
+
*/
|
|
28
|
+
export interface SidebarGroup {
|
|
29
|
+
/** Group title (can be i18n key) */
|
|
30
|
+
title: string;
|
|
31
|
+
/** Items in this group */
|
|
32
|
+
items: SidebarItem[];
|
|
33
|
+
/** Optional: Route to title mapping for page headers */
|
|
34
|
+
titleMap?: Record<string, string>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Types - Theme
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for theme system
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Dashboard theme configuration
|
|
9
|
+
* Extends CSS variables for customization
|
|
10
|
+
*/
|
|
11
|
+
export interface DashboardTheme {
|
|
12
|
+
/** Primary color (CSS variable compatible) */
|
|
13
|
+
primary?: string;
|
|
14
|
+
/** Secondary color */
|
|
15
|
+
secondary?: string;
|
|
16
|
+
/** Sidebar background */
|
|
17
|
+
sidebarBackground?: string;
|
|
18
|
+
/** Sidebar foreground */
|
|
19
|
+
sidebarForeground?: string;
|
|
20
|
+
/** Sidebar border */
|
|
21
|
+
sidebarBorder?: string;
|
|
22
|
+
/** Header background */
|
|
23
|
+
headerBackground?: string;
|
|
24
|
+
/** Background color */
|
|
25
|
+
background?: string;
|
|
26
|
+
/** Foreground color */
|
|
27
|
+
foreground?: string;
|
|
28
|
+
/** Border color */
|
|
29
|
+
border?: string;
|
|
30
|
+
/** Accent color */
|
|
31
|
+
accent?: string;
|
|
32
|
+
/** Accent foreground */
|
|
33
|
+
accentForeground?: string;
|
|
34
|
+
/** Destructive color */
|
|
35
|
+
destructive?: string;
|
|
36
|
+
/** Destructive foreground */
|
|
37
|
+
destructiveForeground?: string;
|
|
38
|
+
/** Muted background */
|
|
39
|
+
muted?: string;
|
|
40
|
+
/** Muted foreground */
|
|
41
|
+
mutedForeground?: string;
|
|
42
|
+
/** Card background */
|
|
43
|
+
card?: string;
|
|
44
|
+
/** Card foreground */
|
|
45
|
+
cardForeground?: string;
|
|
46
|
+
/** Popover background */
|
|
47
|
+
popover?: string;
|
|
48
|
+
/** Popover foreground */
|
|
49
|
+
popoverForeground?: string;
|
|
50
|
+
/** Radius (border-radius) */
|
|
51
|
+
radius?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Theme preset for quick setup
|
|
56
|
+
*/
|
|
57
|
+
export interface DashboardThemePreset {
|
|
58
|
+
/** Preset name */
|
|
59
|
+
name: string;
|
|
60
|
+
/** Theme configuration */
|
|
61
|
+
theme: DashboardTheme;
|
|
62
|
+
/** Whether this is a dark theme */
|
|
63
|
+
dark?: boolean;
|
|
64
|
+
}
|