@umituz/web-dashboard 2.0.7 → 2.0.8

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 (171) hide show
  1. package/package.json +35 -77
  2. package/src/domains/layouts/components/BrandLogo.tsx +83 -0
  3. package/src/domains/layouts/components/DashboardHeader.tsx +240 -0
  4. package/src/domains/layouts/components/DashboardLayout.tsx +155 -0
  5. package/src/domains/layouts/components/DashboardSidebar.tsx +152 -0
  6. package/src/domains/layouts/components/index.ts +8 -0
  7. package/src/domains/layouts/hooks/dashboard.ts +81 -0
  8. package/src/domains/layouts/hooks/index.ts +8 -0
  9. package/src/domains/layouts/index.ts +11 -0
  10. package/{dist/layouts/theme/default.js → src/domains/layouts/theme/default.ts} +18 -11
  11. package/src/domains/layouts/theme/index.ts +18 -0
  12. package/src/domains/layouts/theme/presets.ts +96 -0
  13. package/src/domains/layouts/theme/utils.ts +67 -0
  14. package/src/domains/layouts/types/index.ts +9 -0
  15. package/src/domains/layouts/types/layout.ts +43 -0
  16. package/src/domains/layouts/types/notification.ts +19 -0
  17. package/src/domains/layouts/types/sidebar.ts +35 -0
  18. package/src/domains/layouts/types/theme.ts +64 -0
  19. package/src/domains/layouts/types/user.ts +35 -0
  20. package/src/domains/layouts/utils/dashboard.ts +96 -0
  21. package/src/domains/layouts/utils/index.ts +11 -0
  22. package/src/domains/onboarding/components/AppFocusStep.tsx +113 -0
  23. package/src/domains/onboarding/components/OnboardingWizard.tsx +262 -0
  24. package/src/domains/onboarding/components/PlanStep.tsx +208 -0
  25. package/src/domains/onboarding/components/PlatformsStep.tsx +109 -0
  26. package/src/domains/onboarding/components/UserTypeStep.tsx +135 -0
  27. package/src/domains/onboarding/components/index.ts +9 -0
  28. package/src/domains/onboarding/hooks/index.ts +5 -0
  29. package/{dist/onboarding/hooks/index.js → src/domains/onboarding/hooks/useOnboarding.ts} +65 -19
  30. package/src/domains/onboarding/index.ts +35 -0
  31. package/src/domains/onboarding/types/index.ts +16 -0
  32. package/src/domains/onboarding/types/onboarding.ts +214 -0
  33. package/src/domains/onboarding/utils/index.ts +15 -0
  34. package/src/domains/onboarding/utils/onboarding.ts +166 -0
  35. package/src/domains/settings/components/SettingsLayout.tsx +144 -0
  36. package/src/domains/settings/components/SettingsSection.tsx +106 -0
  37. package/src/domains/settings/components/index.ts +6 -0
  38. package/src/domains/settings/hooks/index.ts +7 -0
  39. package/src/domains/settings/hooks/useSettings.ts +80 -0
  40. package/src/domains/settings/index.ts +22 -0
  41. package/src/domains/settings/types/index.ts +11 -0
  42. package/src/domains/settings/types/settings.ts +81 -0
  43. package/src/domains/settings/utils/index.ts +11 -0
  44. package/src/domains/settings/utils/settings.ts +80 -0
  45. package/dist/layouts/components/BrandLogo.d.ts +0 -18
  46. package/dist/layouts/components/BrandLogo.js +0 -88
  47. package/dist/layouts/components/BrandLogo.js.map +0 -1
  48. package/dist/layouts/components/DashboardHeader.d.ts +0 -36
  49. package/dist/layouts/components/DashboardHeader.js +0 -225
  50. package/dist/layouts/components/DashboardHeader.js.map +0 -1
  51. package/dist/layouts/components/DashboardLayout.d.ts +0 -45
  52. package/dist/layouts/components/DashboardLayout.js +0 -501
  53. package/dist/layouts/components/DashboardLayout.js.map +0 -1
  54. package/dist/layouts/components/DashboardSidebar.d.ts +0 -29
  55. package/dist/layouts/components/DashboardSidebar.js +0 -189
  56. package/dist/layouts/components/DashboardSidebar.js.map +0 -1
  57. package/dist/layouts/components/index.d.ts +0 -10
  58. package/dist/layouts/components/index.js +0 -502
  59. package/dist/layouts/components/index.js.map +0 -1
  60. package/dist/layouts/hooks/dashboard.d.ts +0 -35
  61. package/dist/layouts/hooks/dashboard.js +0 -57
  62. package/dist/layouts/hooks/dashboard.js.map +0 -1
  63. package/dist/layouts/hooks/index.d.ts +0 -3
  64. package/dist/layouts/hooks/index.js +0 -57
  65. package/dist/layouts/hooks/index.js.map +0 -1
  66. package/dist/layouts/index.d.ts +0 -17
  67. package/dist/layouts/index.js +0 -756
  68. package/dist/layouts/index.js.map +0 -1
  69. package/dist/layouts/theme/default.d.ts +0 -18
  70. package/dist/layouts/theme/default.js.map +0 -1
  71. package/dist/layouts/theme/index.d.ts +0 -4
  72. package/dist/layouts/theme/index.js +0 -184
  73. package/dist/layouts/theme/index.js.map +0 -1
  74. package/dist/layouts/theme/presets.d.ts +0 -14
  75. package/dist/layouts/theme/presets.js +0 -137
  76. package/dist/layouts/theme/presets.js.map +0 -1
  77. package/dist/layouts/theme/utils.d.ts +0 -22
  78. package/dist/layouts/theme/utils.js +0 -181
  79. package/dist/layouts/theme/utils.js.map +0 -1
  80. package/dist/layouts/types/index.d.ts +0 -6
  81. package/dist/layouts/types/index.js +0 -2
  82. package/dist/layouts/types/index.js.map +0 -1
  83. package/dist/layouts/types/layout.d.ts +0 -45
  84. package/dist/layouts/types/layout.js +0 -2
  85. package/dist/layouts/types/layout.js.map +0 -1
  86. package/dist/layouts/types/notification.d.ts +0 -20
  87. package/dist/layouts/types/notification.js +0 -2
  88. package/dist/layouts/types/notification.js.map +0 -1
  89. package/dist/layouts/types/sidebar.d.ts +0 -36
  90. package/dist/layouts/types/sidebar.js +0 -2
  91. package/dist/layouts/types/sidebar.js.map +0 -1
  92. package/dist/layouts/types/theme.d.ts +0 -64
  93. package/dist/layouts/types/theme.js +0 -2
  94. package/dist/layouts/types/theme.js.map +0 -1
  95. package/dist/layouts/types/user.d.ts +0 -37
  96. package/dist/layouts/types/user.js +0 -2
  97. package/dist/layouts/types/user.js.map +0 -1
  98. package/dist/layouts/utils/dashboard.d.ts +0 -57
  99. package/dist/layouts/utils/dashboard.js +0 -44
  100. package/dist/layouts/utils/dashboard.js.map +0 -1
  101. package/dist/layouts/utils/index.d.ts +0 -1
  102. package/dist/layouts/utils/index.js +0 -44
  103. package/dist/layouts/utils/index.js.map +0 -1
  104. package/dist/onboarding/components/AppFocusStep.d.ts +0 -26
  105. package/dist/onboarding/components/AppFocusStep.js +0 -86
  106. package/dist/onboarding/components/AppFocusStep.js.map +0 -1
  107. package/dist/onboarding/components/OnboardingWizard.d.ts +0 -13
  108. package/dist/onboarding/components/OnboardingWizard.js +0 -332
  109. package/dist/onboarding/components/OnboardingWizard.js.map +0 -1
  110. package/dist/onboarding/components/PlanStep.d.ts +0 -21
  111. package/dist/onboarding/components/PlanStep.js +0 -167
  112. package/dist/onboarding/components/PlanStep.js.map +0 -1
  113. package/dist/onboarding/components/PlatformsStep.d.ts +0 -26
  114. package/dist/onboarding/components/PlatformsStep.js +0 -86
  115. package/dist/onboarding/components/PlatformsStep.js.map +0 -1
  116. package/dist/onboarding/components/UserTypeStep.d.ts +0 -30
  117. package/dist/onboarding/components/UserTypeStep.js +0 -93
  118. package/dist/onboarding/components/UserTypeStep.js.map +0 -1
  119. package/dist/onboarding/components/index.d.ts +0 -9
  120. package/dist/onboarding/components/index.js +0 -738
  121. package/dist/onboarding/components/index.js.map +0 -1
  122. package/dist/onboarding/hooks/index.d.ts +0 -4
  123. package/dist/onboarding/hooks/index.js.map +0 -1
  124. package/dist/onboarding/hooks/useOnboarding.d.ts +0 -50
  125. package/dist/onboarding/hooks/useOnboarding.js +0 -100
  126. package/dist/onboarding/hooks/useOnboarding.js.map +0 -1
  127. package/dist/onboarding/index.d.ts +0 -11
  128. package/dist/onboarding/index.js +0 -913
  129. package/dist/onboarding/index.js.map +0 -1
  130. package/dist/onboarding/types/index.d.ts +0 -3
  131. package/dist/onboarding/types/index.js +0 -2
  132. package/dist/onboarding/types/index.js.map +0 -1
  133. package/dist/onboarding/types/onboarding.d.ts +0 -209
  134. package/dist/onboarding/types/onboarding.js +0 -2
  135. package/dist/onboarding/types/onboarding.js.map +0 -1
  136. package/dist/onboarding/utils/index.d.ts +0 -4
  137. package/dist/onboarding/utils/index.js +0 -83
  138. package/dist/onboarding/utils/index.js.map +0 -1
  139. package/dist/onboarding/utils/onboarding.d.ts +0 -106
  140. package/dist/onboarding/utils/onboarding.js +0 -83
  141. package/dist/onboarding/utils/onboarding.js.map +0 -1
  142. package/dist/settings/components/SettingsLayout.d.ts +0 -19
  143. package/dist/settings/components/SettingsLayout.js +0 -170
  144. package/dist/settings/components/SettingsLayout.js.map +0 -1
  145. package/dist/settings/components/SettingsSection.d.ts +0 -24
  146. package/dist/settings/components/SettingsSection.js +0 -73
  147. package/dist/settings/components/SettingsSection.js.map +0 -1
  148. package/dist/settings/components/index.d.ts +0 -5
  149. package/dist/settings/components/index.js +0 -169
  150. package/dist/settings/components/index.js.map +0 -1
  151. package/dist/settings/hooks/index.d.ts +0 -3
  152. package/dist/settings/hooks/index.js +0 -59
  153. package/dist/settings/hooks/index.js.map +0 -1
  154. package/dist/settings/hooks/useSettings.d.ts +0 -25
  155. package/dist/settings/hooks/useSettings.js +0 -59
  156. package/dist/settings/hooks/useSettings.js.map +0 -1
  157. package/dist/settings/index.d.ts +0 -7
  158. package/dist/settings/index.js +0 -259
  159. package/dist/settings/index.js.map +0 -1
  160. package/dist/settings/types/index.d.ts +0 -2
  161. package/dist/settings/types/index.js +0 -2
  162. package/dist/settings/types/index.js.map +0 -1
  163. package/dist/settings/types/settings.d.ts +0 -79
  164. package/dist/settings/types/settings.js +0 -2
  165. package/dist/settings/types/settings.js.map +0 -1
  166. package/dist/settings/utils/index.d.ts +0 -3
  167. package/dist/settings/utils/index.js +0 -39
  168. package/dist/settings/utils/index.js.map +0 -1
  169. package/dist/settings/utils/settings.d.ts +0 -50
  170. package/dist/settings/utils/settings.js +0 -39
  171. 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,8 @@
1
+ /**
2
+ * Layout Components Export
3
+ */
4
+
5
+ export { DashboardLayout } from './DashboardLayout';
6
+ export { DashboardHeader } from './DashboardHeader';
7
+ export { DashboardSidebar } from './DashboardSidebar';
8
+ export { BrandLogo } from './BrandLogo';
@@ -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
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Layout Hooks Export
3
+ */
4
+
5
+ export {
6
+ useNotifications,
7
+ useSidebar,
8
+ } from './dashboard';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @umituz/web-dashboard - Layouts Domain
3
+ *
4
+ * Dashboard Layout System
5
+ */
6
+
7
+ export * from './components';
8
+ export * from './hooks';
9
+ export * from './utils';
10
+ export * from './types';
11
+ export * from './theme';
@@ -1,7 +1,15 @@
1
- "use client";
1
+ /**
2
+ * Dashboard Theme - Default Themes
3
+ *
4
+ * Default light and dark theme configurations
5
+ */
2
6
 
3
- // src/domains/layouts/theme/default.ts
4
- var DEFAULT_DASHBOARD_THEME = {
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
- var DEFAULT_DASHBOARD_THEME_DARK = {
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
+ }