@umituz/web-dashboard 6.1.0 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -73
- package/package.json +5 -9
- package/src/config/DashboardConfig.ts +19 -68
- package/src/domains/analytics/components/index.ts +0 -6
- package/src/domains/analytics/hooks/index.ts +0 -6
- package/src/domains/analytics/hooks/useAnalytics.ts +2 -20
- package/src/domains/analytics/index.ts +0 -10
- package/src/domains/analytics/services/AnalyticsEngineService.ts +7 -74
- package/src/domains/analytics/services/PerformanceService.ts +27 -138
- package/src/domains/analytics/services/index.ts +0 -4
- package/src/domains/analytics/types/analytics.ts +100 -270
- package/src/domains/analytics/types/index.ts +0 -6
- package/src/domains/analytics/utils/analytics.test.ts +2 -9
- package/src/domains/analytics/utils/analytics.ts +1 -22
- package/src/domains/analytics/utils/index.ts +0 -6
- package/src/domains/calendar/config.ts +0 -7
- package/src/domains/calendar/hooks/index.ts +0 -4
- package/src/domains/calendar/hooks/useCalendar.ts +7 -27
- package/src/domains/calendar/index.ts +0 -4
- package/src/domains/calendar/services/CalendarService.ts +0 -21
- package/src/domains/calendar/services/index.ts +0 -4
- package/src/domains/calendar/types/calendar.types.ts +9 -53
- package/src/domains/calendar/utils/contentItemMapper.test.ts +0 -4
- package/src/domains/calendar/utils/contentItemMapper.ts +0 -31
- package/src/domains/calendar/utils/index.ts +0 -26
- package/src/domains/layouts/components/index.ts +0 -4
- package/src/domains/layouts/hooks/dashboard.ts +0 -21
- package/src/domains/layouts/hooks/index.ts +0 -4
- package/src/domains/layouts/index.ts +0 -6
- package/src/domains/layouts/theme/default.ts +0 -12
- package/src/domains/layouts/theme/index.ts +0 -4
- package/src/domains/layouts/theme/presets.ts +0 -9
- package/src/domains/layouts/theme/utils.ts +0 -15
- package/src/domains/layouts/types/index.ts +0 -4
- package/src/domains/layouts/types/layout.ts +18 -56
- package/src/domains/layouts/types/notification.ts +4 -17
- package/src/domains/layouts/types/sidebar.ts +8 -28
- package/src/domains/layouts/types/theme.ts +23 -59
- package/src/domains/layouts/types/user.ts +9 -30
- package/src/domains/layouts/utils/dashboard.ts +4 -48
- package/src/domains/layouts/utils/index.ts +0 -4
- package/src/domains/modules/build.tsx +2 -16
- package/src/domains/modules/types.ts +8 -23
- package/src/domains/onboarding/calc/calc.test.ts +1 -9
- package/src/domains/onboarding/calc/card-stack-motion-curve.ts +0 -6
- package/src/domains/onboarding/calc/count-with-locale.ts +0 -8
- package/src/domains/onboarding/calc/duration-equal-split.ts +0 -12
- package/src/domains/onboarding/calc/elapsed-millis.ts +0 -6
- package/src/domains/onboarding/calc/progress-percentage.ts +1 -11
- package/src/domains/onboarding/calc/slider-value-bounds.ts +1 -11
- package/src/domains/onboarding/calc/step-index-clamp.ts +0 -9
- package/src/domains/onboarding/calc/swipe-gesture-curve.ts +0 -13
- package/src/domains/onboarding/components/{shared/AnimationWrapper.tsx → AnimationWrapper.tsx} +0 -4
- package/src/domains/onboarding/components/{shared/OnboardingErrorBoundary.tsx → OnboardingErrorBoundary.tsx} +7 -27
- package/src/domains/onboarding/components/OnboardingFlow.test.tsx +8 -30
- package/src/domains/onboarding/components/OnboardingFlow.tsx +13 -61
- package/src/domains/onboarding/components/OnboardingIntl.tsx +1 -11
- package/src/domains/onboarding/components/PrimaryButton.tsx +40 -0
- package/src/domains/onboarding/components/ProgressBar.tsx +32 -0
- package/src/domains/onboarding/components/QuestionWrapper.tsx +28 -0
- package/src/domains/onboarding/components/ScreenContainer.tsx +19 -0
- package/src/domains/onboarding/components/{shared/SwipeCard.test.tsx → SwipeCard.test.tsx} +1 -3
- package/src/domains/onboarding/components/{shared/SwipeCard.tsx → SwipeCard.tsx} +10 -28
- package/src/domains/onboarding/components/renderBundledIcon.tsx +7 -0
- package/src/domains/onboarding/components/screens/AccountGateScreen.tsx +7 -17
- package/src/domains/onboarding/components/screens/AppDemoScreen.tsx +4 -10
- package/src/domains/onboarding/components/screens/ComparisonScreen.tsx +12 -22
- package/src/domains/onboarding/components/screens/GoalQuestionScreen.tsx +9 -6
- package/src/domains/onboarding/components/screens/PainPointsScreen.tsx +10 -10
- package/src/domains/onboarding/components/screens/PaywallScreen.tsx +22 -38
- package/src/domains/onboarding/components/screens/PermissionPrimingScreen.tsx +14 -29
- package/src/domains/onboarding/components/screens/PersonalizedSolutionScreen.tsx +10 -23
- package/src/domains/onboarding/components/screens/PreferencesScreen.tsx +13 -27
- package/src/domains/onboarding/components/screens/ProcessingScreen.tsx +11 -27
- package/src/domains/onboarding/components/screens/SocialProofScreen.tsx +22 -51
- package/src/domains/onboarding/components/screens/TinderCardsScreen.tsx +13 -30
- package/src/domains/onboarding/components/screens/ValueDeliveryScreen.tsx +13 -29
- package/src/domains/onboarding/components/screens/WelcomeScreen.tsx +12 -32
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingAnalytics.test.tsx +1 -1
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingAnalytics.ts +3 -16
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingProgress.test.tsx +2 -2
- package/src/domains/onboarding/{components/hooks → hooks}/useOnboardingProgress.ts +10 -21
- package/src/domains/onboarding/{components/hooks → hooks}/usePermissionPriming.ts +3 -10
- package/src/domains/onboarding/{components/hooks → hooks}/useReducedMotion.ts +0 -5
- package/src/domains/onboarding/index.ts +16 -45
- package/src/domains/onboarding/predicates/has-handler.ts +0 -4
- package/src/domains/onboarding/predicates/icon-name-resolves.ts +1 -17
- package/src/domains/onboarding/predicates/permission-granted.ts +0 -5
- package/src/domains/onboarding/predicates/permission-supports.ts +1 -11
- package/src/domains/onboarding/predicates/predicates.test.ts +6 -20
- package/src/domains/onboarding/predicates/screen-emits-data.ts +0 -4
- package/src/domains/onboarding/predicates/storage-available.ts +0 -8
- package/src/domains/onboarding/templates/TemplateDemoFallback.tsx +19 -39
- package/src/domains/onboarding/templates/art-onboarding.ts +1 -11
- package/src/domains/onboarding/templates/health-onboarding.ts +0 -5
- package/src/domains/onboarding/templates/platform-onboarding.ts +0 -9
- package/src/domains/onboarding/templates/video-onboarding.ts +0 -5
- package/src/domains/onboarding/test/setup.ts +1 -8
- package/src/domains/onboarding/types/config.ts +7 -18
- package/src/domains/onboarding/types/labels.ts +25 -59
- package/src/domains/onboarding/types/screens.ts +3 -11
- package/src/domains/onboarding/utils/analytics-dispatch.ts +2 -21
- package/src/domains/onboarding/utils/default-storage-key.ts +0 -1
- package/src/domains/onboarding/utils/index.ts +0 -1
- package/src/domains/onboarding/utils/local-storage-bridge.ts +1 -21
- package/src/domains/onboarding/utils/permission-bridge.ts +0 -8
- package/src/domains/onboarding/validation/flow-structure-check.ts +0 -6
- package/src/domains/onboarding/validation/permission-status-check.ts +0 -5
- package/src/domains/onboarding/validation/screen-config-check.ts +0 -5
- package/src/domains/onboarding/validation/stored-progress-check.ts +1 -10
- package/src/domains/onboarding/validation/validation.test.ts +1 -6
- package/src/domains/permissions/hasPermission.ts +0 -8
- package/src/domains/permissions/types.ts +0 -20
- package/src/domains/settings/components/index.ts +0 -4
- package/src/domains/settings/hooks/index.ts +0 -4
- package/src/domains/settings/hooks/useSettings.ts +1 -26
- package/src/domains/settings/index.ts +0 -6
- package/src/domains/settings/types/index.ts +0 -4
- package/src/domains/settings/types/settings.ts +23 -67
- package/src/domains/settings/utils/index.ts +0 -4
- package/src/domains/settings/utils/settings.ts +0 -45
- package/src/styles/dashboard.css +818 -2
- package/src/domains/onboarding/components/shared/OptionCard.tsx +0 -73
- package/src/domains/onboarding/components/shared/PrimaryButton.tsx +0 -58
- package/src/domains/onboarding/components/shared/ProgressBar.tsx +0 -51
- package/src/domains/onboarding/components/shared/QuestionWrapper.tsx +0 -36
- package/src/domains/onboarding/components/shared/ScreenContainer.tsx +0 -29
- package/src/domains/onboarding/components/shared/index.ts +0 -16
- package/src/domains/onboarding/components/shared/renderBundledIcon.tsx +0 -20
- package/src/domains/onboarding/onboarding.css +0 -1
- package/src/domains/onboarding/theme/cn.ts +0 -10
- package/src/domains/onboarding/theme/index.css +0 -131
- package/src/domains/onboarding/theme/index.ts +0 -12
- package/src/domains/onboarding/theme/tokens.ts +0 -122
- /package/src/domains/onboarding/{components/hooks → hooks}/index.ts +0 -0
|
@@ -1,25 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Domain Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Content item status
|
|
7
|
-
*/
|
|
8
1
|
export type ContentStatus = 'draft' | 'scheduled' | 'published' | 'failed';
|
|
9
2
|
|
|
10
|
-
/**
|
|
11
|
-
* Content item type
|
|
12
|
-
*/
|
|
13
3
|
export type ContentType = 'post' | 'story' | 'reel' | 'tweet' | 'article';
|
|
14
4
|
|
|
15
|
-
/**
|
|
16
|
-
* Calendar view type
|
|
17
|
-
*/
|
|
18
5
|
export type CalendarView = 'month' | 'week' | 'day' | 'timeline';
|
|
19
6
|
|
|
20
|
-
/**
|
|
21
|
-
* Content item
|
|
22
|
-
*/
|
|
23
7
|
export interface ContentItem {
|
|
24
8
|
id: string;
|
|
25
9
|
title: string;
|
|
@@ -36,9 +20,6 @@ export interface ContentItem {
|
|
|
36
20
|
updated_at?: string;
|
|
37
21
|
}
|
|
38
22
|
|
|
39
|
-
/**
|
|
40
|
-
* Calendar event
|
|
41
|
-
*/
|
|
42
23
|
export interface CalendarEvent {
|
|
43
24
|
id: string;
|
|
44
25
|
title: string;
|
|
@@ -48,9 +29,6 @@ export interface CalendarEvent {
|
|
|
48
29
|
color?: string;
|
|
49
30
|
}
|
|
50
31
|
|
|
51
|
-
/**
|
|
52
|
-
* Calendar filter
|
|
53
|
-
*/
|
|
54
32
|
export interface CalendarFilter {
|
|
55
33
|
search?: string;
|
|
56
34
|
platforms?: string[];
|
|
@@ -62,34 +40,18 @@ export interface CalendarFilter {
|
|
|
62
40
|
};
|
|
63
41
|
}
|
|
64
42
|
|
|
65
|
-
/**
|
|
66
|
-
* Calendar configuration
|
|
67
|
-
*/
|
|
68
43
|
export interface CalendarConfig {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
end: number; // 0-23
|
|
79
|
-
};
|
|
80
|
-
/** Enable drag and drop */
|
|
81
|
-
enableDragDrop?: boolean;
|
|
82
|
-
/** Show platform filters */
|
|
83
|
-
showPlatformFilters?: boolean;
|
|
84
|
-
/** Available platforms */
|
|
85
|
-
platforms?: string[];
|
|
86
|
-
/** Time slot duration in minutes */
|
|
87
|
-
slotDuration?: number;
|
|
44
|
+
defaultView?: CalendarView;
|
|
45
|
+
showWeekends?: boolean;
|
|
46
|
+
startOfWeek?: number;
|
|
47
|
+
hourRange?: {
|
|
48
|
+
start: number; end: number; };
|
|
49
|
+
enableDragDrop?: boolean;
|
|
50
|
+
showPlatformFilters?: boolean;
|
|
51
|
+
platforms?: string[];
|
|
52
|
+
slotDuration?: number;
|
|
88
53
|
}
|
|
89
54
|
|
|
90
|
-
/**
|
|
91
|
-
* Content item creation params
|
|
92
|
-
*/
|
|
93
55
|
export interface CreateContentItemParams {
|
|
94
56
|
title: string;
|
|
95
57
|
description: string;
|
|
@@ -102,9 +64,6 @@ export interface CreateContentItemParams {
|
|
|
102
64
|
tags?: string[];
|
|
103
65
|
}
|
|
104
66
|
|
|
105
|
-
/**
|
|
106
|
-
* Content item update params
|
|
107
|
-
*/
|
|
108
67
|
export interface UpdateContentItemParams {
|
|
109
68
|
title?: string;
|
|
110
69
|
description?: string;
|
|
@@ -116,9 +75,6 @@ export interface UpdateContentItemParams {
|
|
|
116
75
|
tags?: string[];
|
|
117
76
|
}
|
|
118
77
|
|
|
119
|
-
/**
|
|
120
|
-
* Calendar service interface
|
|
121
|
-
*/
|
|
122
78
|
export interface ICalendarService {
|
|
123
79
|
getContentItems(userId: string, filter?: CalendarFilter): Promise<ContentItem[]>;
|
|
124
80
|
getContentItemById(id: string): Promise<ContentItem | null>;
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Content Item Mapper
|
|
3
|
-
*
|
|
4
|
-
* Type-safe transformation between wire-format documents and domain ContentItem objects.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import type { ContentItem, ContentStatus, ContentType } from '../types/calendar.types';
|
|
8
2
|
|
|
9
|
-
/**
|
|
10
|
-
* Raw wire document shape for calendar_items records
|
|
11
|
-
*/
|
|
12
3
|
interface CalendarItemDocument {
|
|
13
4
|
title?: string;
|
|
14
5
|
description?: string;
|
|
@@ -27,44 +18,27 @@ interface CalendarItemDocument {
|
|
|
27
18
|
updated_at?: string | { toDate: () => Date };
|
|
28
19
|
}
|
|
29
20
|
|
|
30
|
-
/**
|
|
31
|
-
* Firestore document with id
|
|
32
|
-
*/
|
|
33
21
|
export interface FirestoreDocument<T = Record<string, unknown>> {
|
|
34
22
|
id: string;
|
|
35
23
|
data: () => T;
|
|
36
24
|
}
|
|
37
25
|
|
|
38
|
-
/**
|
|
39
|
-
* Convert Firebase timestamp value to ISO string.
|
|
40
|
-
* A missing value maps to the epoch rather than "now" — missing data
|
|
41
|
-
* must not masquerade as freshly-scheduled content in date-sorted views.
|
|
42
|
-
*/
|
|
43
26
|
const toIsoString = (value: string | { toDate: () => Date } | undefined): string => {
|
|
44
27
|
if (!value) return new Date(0).toISOString();
|
|
45
28
|
if (typeof value === 'string') return value;
|
|
46
29
|
return value.toDate().toISOString();
|
|
47
30
|
};
|
|
48
31
|
|
|
49
|
-
/**
|
|
50
|
-
* Normalize status string to ContentStatus union
|
|
51
|
-
*/
|
|
52
32
|
const normalizeStatus = (status: string | undefined): ContentStatus => {
|
|
53
33
|
const valid: ContentStatus[] = ['draft', 'scheduled', 'published', 'failed'];
|
|
54
34
|
return valid.includes(status as ContentStatus) ? (status as ContentStatus) : 'draft';
|
|
55
35
|
};
|
|
56
36
|
|
|
57
|
-
/**
|
|
58
|
-
* Normalize type string to ContentType union
|
|
59
|
-
*/
|
|
60
37
|
const normalizeType = (type: string | undefined): ContentType => {
|
|
61
38
|
const valid: ContentType[] = ['post', 'story', 'reel', 'tweet', 'article'];
|
|
62
39
|
return valid.includes(type as ContentType) ? (type as ContentType) : 'post';
|
|
63
40
|
};
|
|
64
41
|
|
|
65
|
-
/**
|
|
66
|
-
* Map calendar_items document to ContentItem
|
|
67
|
-
*/
|
|
68
42
|
export const mapCalendarDocument = (doc: FirestoreDocument<CalendarItemDocument>): ContentItem => {
|
|
69
43
|
const data = doc.data();
|
|
70
44
|
return {
|
|
@@ -79,11 +53,6 @@ export const mapCalendarDocument = (doc: FirestoreDocument<CalendarItemDocument>
|
|
|
79
53
|
};
|
|
80
54
|
};
|
|
81
55
|
|
|
82
|
-
/**
|
|
83
|
-
* Map posts document to ContentItem.
|
|
84
|
-
* Missing display fields fall back to empty strings so the consuming
|
|
85
|
-
* UI can render its own (localized) placeholder — no package-side copy.
|
|
86
|
-
*/
|
|
87
56
|
export const mapPostDocument = (doc: FirestoreDocument<CalendarItemDocument>): ContentItem => {
|
|
88
57
|
const data = doc.data();
|
|
89
58
|
return {
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calendar Domain Utilities
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
import type { CalendarConfig } from '../types/calendar.types';
|
|
6
2
|
|
|
7
3
|
export { mapCalendarDocument, mapPostDocument } from './contentItemMapper';
|
|
8
4
|
export type { FirestoreDocument } from './contentItemMapper';
|
|
9
5
|
|
|
10
|
-
/**
|
|
11
|
-
* Get week dates for a given date
|
|
12
|
-
*/
|
|
13
6
|
export function getWeekDates(date: Date, startOfWeek: number = 0): Date[] {
|
|
14
7
|
const week: Date[] = [];
|
|
15
8
|
const current = new Date(date);
|
|
@@ -26,9 +19,6 @@ export function getWeekDates(date: Date, startOfWeek: number = 0): Date[] {
|
|
|
26
19
|
return week;
|
|
27
20
|
}
|
|
28
21
|
|
|
29
|
-
/**
|
|
30
|
-
* Get month days
|
|
31
|
-
*/
|
|
32
22
|
export function getMonthDays(date: Date): Date[] {
|
|
33
23
|
const year = date.getFullYear();
|
|
34
24
|
const month = date.getMonth();
|
|
@@ -44,17 +34,10 @@ export function getMonthDays(date: Date): Date[] {
|
|
|
44
34
|
return days;
|
|
45
35
|
}
|
|
46
36
|
|
|
47
|
-
/**
|
|
48
|
-
* Check if date is in range
|
|
49
|
-
*/
|
|
50
37
|
export function isDateInRange(date: Date, range: { start: Date; end: Date }): boolean {
|
|
51
38
|
return date >= range.start && date <= range.end;
|
|
52
39
|
}
|
|
53
40
|
|
|
54
|
-
/**
|
|
55
|
-
* Format date for display.
|
|
56
|
-
* The locale is taken as a parameter so the consumer can decide.
|
|
57
|
-
*/
|
|
58
41
|
export function formatDate(
|
|
59
42
|
date: Date,
|
|
60
43
|
format: 'short' | 'long' | 'time' = 'short',
|
|
@@ -74,9 +57,6 @@ export function formatDate(
|
|
|
74
57
|
});
|
|
75
58
|
}
|
|
76
59
|
|
|
77
|
-
/**
|
|
78
|
-
* Check if dates are same day
|
|
79
|
-
*/
|
|
80
60
|
export function isSameDay(date1: Date, date2: Date): boolean {
|
|
81
61
|
return (
|
|
82
62
|
date1.getFullYear() === date2.getFullYear() &&
|
|
@@ -85,9 +65,6 @@ export function isSameDay(date1: Date, date2: Date): boolean {
|
|
|
85
65
|
);
|
|
86
66
|
}
|
|
87
67
|
|
|
88
|
-
/**
|
|
89
|
-
* Get date range for a view
|
|
90
|
-
*/
|
|
91
68
|
export function getViewRange(
|
|
92
69
|
view: 'month' | 'week',
|
|
93
70
|
date: Date,
|
|
@@ -106,9 +83,6 @@ export function getViewRange(
|
|
|
106
83
|
return { start: firstDay, end: lastDay };
|
|
107
84
|
}
|
|
108
85
|
|
|
109
|
-
/**
|
|
110
|
-
* Generate time slots
|
|
111
|
-
*/
|
|
112
86
|
export function generateTimeSlots(
|
|
113
87
|
startHour: number,
|
|
114
88
|
endHour: number,
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Hooks
|
|
3
|
-
*
|
|
4
|
-
* Custom React hooks for dashboard functionality
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import { useState, useCallback } from "react";
|
|
8
2
|
import type { DashboardNotification } from "../types/notification";
|
|
9
3
|
|
|
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
4
|
export function useNotifications(initialNotifications: DashboardNotification[] = []) {
|
|
19
5
|
const [notifications, setNotifications] = useState<DashboardNotification[]>(initialNotifications);
|
|
20
6
|
|
|
@@ -46,13 +32,6 @@ export function useNotifications(initialNotifications: DashboardNotification[] =
|
|
|
46
32
|
};
|
|
47
33
|
}
|
|
48
34
|
|
|
49
|
-
/**
|
|
50
|
-
* Use Sidebar Hook
|
|
51
|
-
*
|
|
52
|
-
* Manages sidebar state
|
|
53
|
-
*
|
|
54
|
-
* @returns Sidebar state and actions
|
|
55
|
-
*/
|
|
56
35
|
export function useSidebar(initialCollapsed = false) {
|
|
57
36
|
const [collapsed, setCollapsed] = useState(initialCollapsed);
|
|
58
37
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Theme - Default Themes
|
|
3
|
-
*
|
|
4
|
-
* Default light and dark theme configurations
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import type { DashboardTheme } from '../types/theme';
|
|
8
2
|
|
|
9
|
-
/**
|
|
10
|
-
* Default dashboard theme (light mode)
|
|
11
|
-
*/
|
|
12
3
|
export const DEFAULT_DASHBOARD_THEME: DashboardTheme = {
|
|
13
4
|
primary: "hsl(222.2 47.4% 11.2%)",
|
|
14
5
|
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
@@ -32,9 +23,6 @@ export const DEFAULT_DASHBOARD_THEME: DashboardTheme = {
|
|
|
32
23
|
radius: "0.5rem",
|
|
33
24
|
};
|
|
34
25
|
|
|
35
|
-
/**
|
|
36
|
-
* Default dashboard theme (dark mode)
|
|
37
|
-
*/
|
|
38
26
|
export const DEFAULT_DASHBOARD_THEME_DARK: DashboardTheme = {
|
|
39
27
|
primary: "hsl(217.2 91.2% 59.8%)",
|
|
40
28
|
secondary: "hsl(217.2 32.6% 17.5%)",
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Theme - Presets
|
|
3
|
-
*
|
|
4
|
-
* Pre-configured theme presets
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import type { DashboardThemePreset } from '../types/theme';
|
|
8
2
|
import { DEFAULT_DASHBOARD_THEME, DEFAULT_DASHBOARD_THEME_DARK } from './default';
|
|
9
3
|
|
|
10
|
-
/**
|
|
11
|
-
* Available theme presets
|
|
12
|
-
*/
|
|
13
4
|
export const DASHBOARD_THEME_PRESETS: DashboardThemePreset[] = [
|
|
14
5
|
{
|
|
15
6
|
name: "default",
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Theme - Utilities
|
|
3
|
-
*
|
|
4
|
-
* Theme utility functions
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import type { DashboardTheme, DashboardThemePreset } from '../types/theme';
|
|
8
2
|
import { DEFAULT_DASHBOARD_THEME, DEFAULT_DASHBOARD_THEME_DARK } from './default';
|
|
9
3
|
import { DASHBOARD_THEME_PRESETS } from './presets';
|
|
10
4
|
|
|
11
|
-
/**
|
|
12
|
-
* Apply theme to document root via CSS variables
|
|
13
|
-
*/
|
|
14
5
|
export function applyDashboardTheme(theme: DashboardTheme): void {
|
|
15
6
|
if (typeof document === "undefined") return;
|
|
16
7
|
|
|
@@ -45,16 +36,10 @@ export function applyDashboardTheme(theme: DashboardTheme): void {
|
|
|
45
36
|
});
|
|
46
37
|
}
|
|
47
38
|
|
|
48
|
-
/**
|
|
49
|
-
* Get theme preset by name
|
|
50
|
-
*/
|
|
51
39
|
export function getDashboardThemePreset(name: string): DashboardThemePreset | undefined {
|
|
52
40
|
return DASHBOARD_THEME_PRESETS.find((preset) => preset.name === name);
|
|
53
41
|
}
|
|
54
42
|
|
|
55
|
-
/**
|
|
56
|
-
* Merge custom theme with default theme
|
|
57
|
-
*/
|
|
58
43
|
export function mergeDashboardTheme(
|
|
59
44
|
customTheme: Partial<DashboardTheme>,
|
|
60
45
|
dark = false
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layout Types Export
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
1
|
export type { SidebarItem, SidebarGroup } from './sidebar';
|
|
6
2
|
export type { DashboardHeaderProps, DashboardSidebarProps, DashboardLayoutConfig, HeaderProfileItem } from './layout';
|
|
7
3
|
export type { DashboardTheme, DashboardThemePreset } from './theme';
|
|
@@ -1,67 +1,29 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Types - Layout
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for layout components
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Dashboard header props
|
|
9
|
-
*/
|
|
10
1
|
export interface DashboardHeaderProps {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/** Current page title */
|
|
18
|
-
title: string;
|
|
19
|
-
/** Current resolved theme; defaults to "light" rendering when omitted */
|
|
20
|
-
theme?: "light" | "dark";
|
|
21
|
-
/** Theme toggle handler — the toggle button is hidden when omitted */
|
|
22
|
-
onToggleTheme?: () => void;
|
|
2
|
+
collapsed: boolean;
|
|
3
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
4
|
+
setMobileOpen: (open: boolean) => void;
|
|
5
|
+
title: string;
|
|
6
|
+
theme?: "light" | "dark";
|
|
7
|
+
onToggleTheme?: () => void;
|
|
23
8
|
}
|
|
24
9
|
|
|
25
|
-
/**
|
|
26
|
-
* Host-injected profile-menu entry — the extension seam for pages the
|
|
27
|
-
* skeleton does not own (billing, referrals, anything). Rendered above
|
|
28
|
-
* Settings; `to` navigates, `onSelect` runs, both close the menu.
|
|
29
|
-
*/
|
|
30
10
|
export interface HeaderProfileItem {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
icon?: React.ReactNode;
|
|
37
|
-
/** Route to navigate to */
|
|
38
|
-
to?: string;
|
|
39
|
-
/** Click handler (runs after navigation when both are set) */
|
|
40
|
-
onSelect?: () => void;
|
|
11
|
+
key: string;
|
|
12
|
+
label: string;
|
|
13
|
+
icon?: React.ReactNode;
|
|
14
|
+
to?: string;
|
|
15
|
+
onSelect?: () => void;
|
|
41
16
|
}
|
|
42
17
|
|
|
43
|
-
/**
|
|
44
|
-
* Dashboard sidebar props
|
|
45
|
-
*/
|
|
46
18
|
export interface DashboardSidebarProps {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/** Toggle sidebar collapsed state */
|
|
50
|
-
setCollapsed: (collapsed: boolean) => void;
|
|
19
|
+
collapsed: boolean;
|
|
20
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
51
21
|
}
|
|
52
22
|
|
|
53
|
-
/**
|
|
54
|
-
* Dashboard layout configuration
|
|
55
|
-
*/
|
|
56
23
|
export interface DashboardLayoutConfig {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
defaultTitle?: string;
|
|
63
|
-
/** Brand name */
|
|
64
|
-
brandName?: string;
|
|
65
|
-
/** Brand tagline */
|
|
66
|
-
brandTagline?: string;
|
|
24
|
+
sidebarGroups: import('./sidebar').SidebarGroup[];
|
|
25
|
+
extraTitleMap?: Record<string, string>;
|
|
26
|
+
defaultTitle?: string;
|
|
27
|
+
brandName?: string;
|
|
28
|
+
brandTagline?: string;
|
|
67
29
|
}
|
|
@@ -1,19 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Types - Notification
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for notification system
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Notification item
|
|
9
|
-
*/
|
|
10
1
|
export interface DashboardNotification {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/** Whether notification is read */
|
|
16
|
-
read: boolean;
|
|
17
|
-
/** Creation timestamp */
|
|
18
|
-
createdAt: Date | string | number;
|
|
2
|
+
id: string;
|
|
3
|
+
text: string;
|
|
4
|
+
read: boolean;
|
|
5
|
+
createdAt: Date | string | number;
|
|
19
6
|
}
|
|
@@ -1,35 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Types - Sidebar
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for sidebar components
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
1
|
import type { LucideIcon } from "lucide-react";
|
|
8
2
|
|
|
9
|
-
/**
|
|
10
|
-
* Single sidebar menu item
|
|
11
|
-
*/
|
|
12
3
|
export interface SidebarItem {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
path: string;
|
|
19
|
-
/** Filter by app type (optional) */
|
|
20
|
-
requiredApp?: 'mobile' | 'web';
|
|
21
|
-
/** Enable/disable this item (default: true) */
|
|
22
|
-
enabled?: boolean;
|
|
4
|
+
label: string;
|
|
5
|
+
icon: LucideIcon;
|
|
6
|
+
path: string;
|
|
7
|
+
requiredApp?: 'mobile' | 'web';
|
|
8
|
+
enabled?: boolean;
|
|
23
9
|
}
|
|
24
10
|
|
|
25
|
-
/**
|
|
26
|
-
* Group of sidebar items with a title
|
|
27
|
-
*/
|
|
28
11
|
export interface SidebarGroup {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
items: SidebarItem[];
|
|
33
|
-
/** Optional: Route to title mapping for page headers */
|
|
34
|
-
titleMap?: Record<string, string>;
|
|
12
|
+
title: string;
|
|
13
|
+
items: SidebarItem[];
|
|
14
|
+
titleMap?: Record<string, string>;
|
|
35
15
|
}
|
|
@@ -1,64 +1,28 @@
|
|
|
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
1
|
export interface DashboardTheme {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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;
|
|
2
|
+
primary?: string;
|
|
3
|
+
secondary?: string;
|
|
4
|
+
sidebarBackground?: string;
|
|
5
|
+
sidebarForeground?: string;
|
|
6
|
+
sidebarBorder?: string;
|
|
7
|
+
headerBackground?: string;
|
|
8
|
+
background?: string;
|
|
9
|
+
foreground?: string;
|
|
10
|
+
border?: string;
|
|
11
|
+
accent?: string;
|
|
12
|
+
accentForeground?: string;
|
|
13
|
+
destructive?: string;
|
|
14
|
+
destructiveForeground?: string;
|
|
15
|
+
muted?: string;
|
|
16
|
+
mutedForeground?: string;
|
|
17
|
+
card?: string;
|
|
18
|
+
cardForeground?: string;
|
|
19
|
+
popover?: string;
|
|
20
|
+
popoverForeground?: string;
|
|
21
|
+
radius?: string;
|
|
52
22
|
}
|
|
53
23
|
|
|
54
|
-
/**
|
|
55
|
-
* Theme preset for quick setup
|
|
56
|
-
*/
|
|
57
24
|
export interface DashboardThemePreset {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
theme: DashboardTheme;
|
|
62
|
-
/** Whether this is a dark theme */
|
|
63
|
-
dark?: boolean;
|
|
25
|
+
name: string;
|
|
26
|
+
theme: DashboardTheme;
|
|
27
|
+
dark?: boolean;
|
|
64
28
|
}
|