@umituz/web-dashboard 4.6.5 → 4.7.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/package.json +3 -10
- package/src/{domain/config → config}/DashboardConfig.ts +1 -1
- package/src/config/index.ts +1 -0
- package/src/{domain/config/CalendarConfig.ts → domains/calendar/config.ts} +1 -1
- package/src/domains/calendar/hooks/useCalendar.ts +1 -1
- package/src/domains/calendar/index.ts +1 -0
- package/src/domains/calendar/utils/index.ts +0 -6
- package/src/domains/layouts/components/DashboardHeader.tsx +21 -13
- package/src/domains/layouts/types/index.ts +1 -1
- package/src/domains/layouts/types/layout.ts +18 -0
- package/src/index.ts +2 -14
- package/src/styles/dashboard.css +1 -652
- package/src/domain/config/index.ts +0 -6
- package/src/domains/onboarding/components/AppFocusStep.tsx +0 -144
- package/src/domains/onboarding/components/OnboardingWizard.tsx +0 -188
- package/src/domains/onboarding/components/PlanStep.tsx +0 -241
- package/src/domains/onboarding/components/PlatformsStep.tsx +0 -129
- package/src/domains/onboarding/components/StepNavigation.tsx +0 -108
- package/src/domains/onboarding/components/StepProgress.tsx +0 -62
- package/src/domains/onboarding/components/UserTypeStep.tsx +0 -114
- package/src/domains/onboarding/components/index.ts +0 -13
- package/src/domains/onboarding/hooks/index.ts +0 -5
- package/src/domains/onboarding/hooks/useOnboarding.ts +0 -156
- package/src/domains/onboarding/index.ts +0 -36
- package/src/domains/onboarding/types/index.ts +0 -16
- package/src/domains/onboarding/types/onboarding.ts +0 -254
- package/src/domains/onboarding/utils/i18nKeys.ts +0 -72
- package/src/domains/onboarding/utils/index.ts +0 -17
- package/src/domains/onboarding/utils/onboarding.ts +0 -166
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Onboarding Types
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for onboarding system
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { LucideIcon } from "lucide-react";
|
|
8
|
-
import type { ComponentType, ReactElement } from "react";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Onboarding error — the message is an i18n key.
|
|
12
|
-
*/
|
|
13
|
-
export interface OnboardingError {
|
|
14
|
-
/** Step where the error occurred */
|
|
15
|
-
step: number;
|
|
16
|
-
/** i18n key for the localized error message */
|
|
17
|
-
message: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* User type option for first step.
|
|
22
|
-
* Either supply `label`/`description` directly (already translated) or
|
|
23
|
-
* supply `labelKey`/`descriptionKey` to be resolved by the consumer's i18n.
|
|
24
|
-
*/
|
|
25
|
-
export interface UserTypeOption {
|
|
26
|
-
/** Unique identifier */
|
|
27
|
-
id: string;
|
|
28
|
-
/** Display label (already-translated string) */
|
|
29
|
-
label?: string;
|
|
30
|
-
/** Description text (already-translated) */
|
|
31
|
-
description?: string;
|
|
32
|
-
/** i18n key for the label */
|
|
33
|
-
labelKey?: string;
|
|
34
|
-
/** i18n key for the description */
|
|
35
|
-
descriptionKey?: string;
|
|
36
|
-
/** Icon component (Lucide) */
|
|
37
|
-
icon?: LucideIcon;
|
|
38
|
-
/** Badge text */
|
|
39
|
-
badge?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Platform connection option.
|
|
44
|
-
* Icons must be Lucide components — emoji is not allowed.
|
|
45
|
-
*/
|
|
46
|
-
export interface PlatformOption {
|
|
47
|
-
/** Unique identifier */
|
|
48
|
-
id: string;
|
|
49
|
-
/** Display name */
|
|
50
|
-
name: string;
|
|
51
|
-
/** Lucide icon component */
|
|
52
|
-
icon: LucideIcon;
|
|
53
|
-
/** Brand color as a plain CSS color string (e.g. "#c026d3") */
|
|
54
|
-
color?: string;
|
|
55
|
-
/** Connection status */
|
|
56
|
-
connected?: boolean;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* App type option for the AppFocusStep.
|
|
61
|
-
* Same shape as PlatformOption (icon as component, not emoji).
|
|
62
|
-
*/
|
|
63
|
-
export interface AppTypeOption {
|
|
64
|
-
id: string;
|
|
65
|
-
name: string;
|
|
66
|
-
description: string;
|
|
67
|
-
icon: LucideIcon;
|
|
68
|
-
/**
|
|
69
|
-
* State field toggled by this option. When omitted, the field is
|
|
70
|
-
* derived from the id ("mobile" → hasMobileApp, "web" → hasWebApp);
|
|
71
|
-
* options that resolve to neither render inert.
|
|
72
|
-
*/
|
|
73
|
-
stateField?: "hasMobileApp" | "hasWebApp";
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Plan option for billing step
|
|
78
|
-
*/
|
|
79
|
-
export interface PlanOption {
|
|
80
|
-
/** Unique identifier */
|
|
81
|
-
id: string;
|
|
82
|
-
/** Plan name (already translated) */
|
|
83
|
-
name: string;
|
|
84
|
-
/** Badge text (already translated) — preferred for static labels */
|
|
85
|
-
badge?: string;
|
|
86
|
-
/** i18n key for the badge — resolved via `translate` in the consumer */
|
|
87
|
-
badgeKey?: string;
|
|
88
|
-
/** Semantic badge tone rendered by the stylesheet */
|
|
89
|
-
badgeTone?: "muted" | "primary" | "accent";
|
|
90
|
-
/** Description text */
|
|
91
|
-
description: string;
|
|
92
|
-
/** Monthly price */
|
|
93
|
-
price: number;
|
|
94
|
-
/** Features list */
|
|
95
|
-
features: (string | { text: string; bold?: boolean })[];
|
|
96
|
-
/** Highlight style */
|
|
97
|
-
highlight?: boolean;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Props for onboarding step components
|
|
102
|
-
*/
|
|
103
|
-
export interface OnboardingStepContentProps {
|
|
104
|
-
/** Current onboarding state */
|
|
105
|
-
state: OnboardingState;
|
|
106
|
-
/** Update state function */
|
|
107
|
-
updateState: (updates: Partial<OnboardingState>) => void;
|
|
108
|
-
/** Go to next step */
|
|
109
|
-
goToNext: () => void;
|
|
110
|
-
/** Go to previous step */
|
|
111
|
-
goToPrev: () => void;
|
|
112
|
-
/** Go to specific step */
|
|
113
|
-
goToStep: (step: number) => void;
|
|
114
|
-
/** Onboarding configuration */
|
|
115
|
-
config: OnboardingConfig;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Onboarding step configuration
|
|
120
|
-
*/
|
|
121
|
-
export interface OnboardingStep {
|
|
122
|
-
/** Step identifier */
|
|
123
|
-
id: string;
|
|
124
|
-
/** Step number */
|
|
125
|
-
order: number;
|
|
126
|
-
/** Step title */
|
|
127
|
-
title: string;
|
|
128
|
-
/** Step description */
|
|
129
|
-
description?: string;
|
|
130
|
-
/** Custom component - either a function component with props or a direct React node */
|
|
131
|
-
component?: ComponentType<OnboardingStepContentProps> | ReactElement;
|
|
132
|
-
/** Whether this step can be skipped */
|
|
133
|
-
skippable?: boolean;
|
|
134
|
-
/** Validation function */
|
|
135
|
-
validate?: (data: OnboardingState) => boolean;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Onboarding configuration
|
|
140
|
-
*/
|
|
141
|
-
export interface OnboardingConfig {
|
|
142
|
-
/** Brand/application name */
|
|
143
|
-
brandName: string;
|
|
144
|
-
/** Brand tagline */
|
|
145
|
-
brandTagline?: string;
|
|
146
|
-
/** Onboarding steps */
|
|
147
|
-
steps: OnboardingStep[];
|
|
148
|
-
/** Route to navigate after completion */
|
|
149
|
-
completeRoute: string;
|
|
150
|
-
/** Route to navigate on cancel */
|
|
151
|
-
cancelRoute?: string;
|
|
152
|
-
/** Allow skipping steps */
|
|
153
|
-
allowSkip?: boolean;
|
|
154
|
-
/** Allow canceling the wizard from the header */
|
|
155
|
-
allowCancel?: boolean;
|
|
156
|
-
/** Show progress indicator */
|
|
157
|
-
showProgress?: boolean;
|
|
158
|
-
/** Enable user menu in header */
|
|
159
|
-
showUserMenu?: boolean;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Onboarding state
|
|
164
|
-
*/
|
|
165
|
-
export interface OnboardingState extends Record<string, unknown> {
|
|
166
|
-
/** Current step number */
|
|
167
|
-
currentStep: number;
|
|
168
|
-
/** Selected user type */
|
|
169
|
-
selectedUserType?: string;
|
|
170
|
-
/** Has mobile app */
|
|
171
|
-
hasMobileApp?: boolean;
|
|
172
|
-
/** Has web app */
|
|
173
|
-
hasWebApp?: boolean;
|
|
174
|
-
/** Connected platform IDs */
|
|
175
|
-
connectedPlatforms: string[];
|
|
176
|
-
/** Selected plan ID */
|
|
177
|
-
selectedPlan?: string;
|
|
178
|
-
/** Billing cycle */
|
|
179
|
-
billingCycle: "monthly" | "yearly";
|
|
180
|
-
/** Additional step data */
|
|
181
|
-
stepData: Record<string, unknown>;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Onboarding actions
|
|
186
|
-
*/
|
|
187
|
-
export interface OnboardingActions {
|
|
188
|
-
/** Go to next step */
|
|
189
|
-
goToNext: () => void;
|
|
190
|
-
/** Go to previous step */
|
|
191
|
-
goToPrev: () => void;
|
|
192
|
-
/** Go to specific step */
|
|
193
|
-
goToStep: (step: number) => void;
|
|
194
|
-
/** Update state */
|
|
195
|
-
updateState: (updates: Partial<OnboardingState>) => void;
|
|
196
|
-
/** Complete onboarding */
|
|
197
|
-
complete: () => Promise<void>;
|
|
198
|
-
/** Cancel onboarding */
|
|
199
|
-
cancel: () => void;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Onboarding wizard props
|
|
204
|
-
*/
|
|
205
|
-
export interface OnboardingWizardProps {
|
|
206
|
-
/** Onboarding configuration */
|
|
207
|
-
config: OnboardingConfig;
|
|
208
|
-
/** Initial state */
|
|
209
|
-
initialState?: Partial<OnboardingState>;
|
|
210
|
-
/** Completion callback */
|
|
211
|
-
onComplete?: (data: OnboardingState) => Promise<void>;
|
|
212
|
-
/** Cancel callback */
|
|
213
|
-
onCancel?: () => void;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Step progress props
|
|
218
|
-
*/
|
|
219
|
-
export interface StepProgressProps {
|
|
220
|
-
/** Current step number */
|
|
221
|
-
currentStep: number;
|
|
222
|
-
/** Total number of steps */
|
|
223
|
-
totalSteps: number;
|
|
224
|
-
/** Completed steps */
|
|
225
|
-
completedSteps?: number[];
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Step navigation props
|
|
230
|
-
*/
|
|
231
|
-
export interface StepNavigationProps {
|
|
232
|
-
/** Current step number */
|
|
233
|
-
currentStep: number;
|
|
234
|
-
/** Total number of steps */
|
|
235
|
-
totalSteps: number;
|
|
236
|
-
/** Can proceed to next step */
|
|
237
|
-
canGoNext: boolean;
|
|
238
|
-
/** Is saving/completing */
|
|
239
|
-
isSaving?: boolean;
|
|
240
|
-
/** Next button label (overrides the i18n key) */
|
|
241
|
-
nextLabel?: string;
|
|
242
|
-
/** Previous button label (overrides the i18n key) */
|
|
243
|
-
prevLabel?: string;
|
|
244
|
-
/** On next */
|
|
245
|
-
onNext: () => void;
|
|
246
|
-
/** On previous */
|
|
247
|
-
onPrev: () => void;
|
|
248
|
-
/** Allow skipping */
|
|
249
|
-
allowSkip?: boolean;
|
|
250
|
-
/** On skip */
|
|
251
|
-
onSkip?: () => void;
|
|
252
|
-
/** Translation function */
|
|
253
|
-
translate: (key: string) => string;
|
|
254
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Onboarding Domain i18n Keys
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export const ONBOARDING_KEYS = {
|
|
6
|
-
// Wizard
|
|
7
|
-
wizard: {
|
|
8
|
-
cancel: 'onboarding.buttons.cancel',
|
|
9
|
-
stepNotConfigured: 'onboarding.errors.stepNotConfigured',
|
|
10
|
-
errors: {
|
|
11
|
-
completionFailed: 'onboarding.errors.completionFailed',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
// User type step
|
|
16
|
-
userType: {
|
|
17
|
-
title: 'onboarding.userType.title',
|
|
18
|
-
description: 'onboarding.userType.description',
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
// App focus step
|
|
22
|
-
appFocus: {
|
|
23
|
-
title: 'onboarding.appFocus.title',
|
|
24
|
-
description: 'onboarding.appFocus.description',
|
|
25
|
-
success: 'onboarding.appFocus.success',
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
// Platforms step
|
|
29
|
-
platforms: {
|
|
30
|
-
title: 'onboarding.platforms.title',
|
|
31
|
-
description: 'onboarding.platforms.description',
|
|
32
|
-
connect: 'onboarding.platforms.connect',
|
|
33
|
-
connected: 'onboarding.platforms.connected',
|
|
34
|
-
selected: 'onboarding.platforms.selected',
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
// Plan step
|
|
38
|
-
plan: {
|
|
39
|
-
title: 'onboarding.plan.title',
|
|
40
|
-
description: 'onboarding.plan.description',
|
|
41
|
-
monthly: 'onboarding.plan.monthly',
|
|
42
|
-
yearly: 'onboarding.plan.yearly',
|
|
43
|
-
monthlyShort: 'onboarding.plan.monthlyShort',
|
|
44
|
-
yearlyShort: 'onboarding.plan.yearlyShort',
|
|
45
|
-
save: 'onboarding.plan.save',
|
|
46
|
-
recommended: 'onboarding.plan.recommended',
|
|
47
|
-
selectedPlan: 'onboarding.plan.selectedPlan',
|
|
48
|
-
mostPopular: 'onboarding.plan.mostPopular',
|
|
49
|
-
bestValue: 'onboarding.plan.bestValue',
|
|
50
|
-
custom: 'onboarding.plan.custom',
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
// Steps (default data — keys can be overridden per consumer)
|
|
54
|
-
defaults: {
|
|
55
|
-
founder: 'onboarding.defaults.userType.founder',
|
|
56
|
-
founderDescription: 'onboarding.defaults.userType.founderDescription',
|
|
57
|
-
contentCreator: 'onboarding.defaults.userType.contentCreator',
|
|
58
|
-
contentCreatorDescription: 'onboarding.defaults.userType.contentCreatorDescription',
|
|
59
|
-
smallBusiness: 'onboarding.defaults.userType.smallBusiness',
|
|
60
|
-
smallBusinessDescription: 'onboarding.defaults.userType.smallBusinessDescription',
|
|
61
|
-
enterprise: 'onboarding.defaults.userType.enterprise',
|
|
62
|
-
enterpriseDescription: 'onboarding.defaults.userType.enterpriseDescription',
|
|
63
|
-
agency: 'onboarding.defaults.userType.agency',
|
|
64
|
-
agencyDescription: 'onboarding.defaults.userType.agencyDescription',
|
|
65
|
-
personal: 'onboarding.defaults.userType.personal',
|
|
66
|
-
personalDescription: 'onboarding.defaults.userType.personalDescription',
|
|
67
|
-
mobileApp: 'onboarding.defaults.appType.mobileApp',
|
|
68
|
-
mobileAppDescription: 'onboarding.defaults.appType.mobileAppDescription',
|
|
69
|
-
webApp: 'onboarding.defaults.appType.webApp',
|
|
70
|
-
webAppDescription: 'onboarding.defaults.appType.webAppDescription',
|
|
71
|
-
},
|
|
72
|
-
} as const;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Onboarding Utils Export
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
validateStep,
|
|
7
|
-
getStepTitle,
|
|
8
|
-
getStepDescription,
|
|
9
|
-
calculateProgress,
|
|
10
|
-
getCompletedSteps,
|
|
11
|
-
formatOnboardingData,
|
|
12
|
-
generateOnboardingEvent,
|
|
13
|
-
isValidEmail,
|
|
14
|
-
isValidPassword,
|
|
15
|
-
} from './onboarding';
|
|
16
|
-
|
|
17
|
-
export { ONBOARDING_KEYS } from './i18nKeys';
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Onboarding Utilities
|
|
3
|
-
*
|
|
4
|
-
* Utility functions for onboarding operations
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { OnboardingState, OnboardingConfig } from "../types/onboarding";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Validate onboarding step
|
|
11
|
-
*
|
|
12
|
-
* @param state - Current onboarding state
|
|
13
|
-
* @param stepNumber - Step number to validate
|
|
14
|
-
* @param config - Onboarding configuration
|
|
15
|
-
* @returns Whether the step is valid
|
|
16
|
-
*/
|
|
17
|
-
export function validateStep(
|
|
18
|
-
state: OnboardingState,
|
|
19
|
-
stepNumber: number,
|
|
20
|
-
config: OnboardingConfig
|
|
21
|
-
): boolean {
|
|
22
|
-
const stepConfig = config.steps[stepNumber - 1];
|
|
23
|
-
|
|
24
|
-
if (stepConfig?.validate) {
|
|
25
|
-
return stepConfig.validate(state);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Default validations
|
|
29
|
-
switch (stepNumber) {
|
|
30
|
-
case 1:
|
|
31
|
-
// User type step
|
|
32
|
-
return !!state.selectedUserType;
|
|
33
|
-
|
|
34
|
-
case 2:
|
|
35
|
-
// App focus step
|
|
36
|
-
return !!(state.hasMobileApp || state.hasWebApp);
|
|
37
|
-
|
|
38
|
-
case 3:
|
|
39
|
-
// Platforms step
|
|
40
|
-
return state.connectedPlatforms.length > 0;
|
|
41
|
-
|
|
42
|
-
case 4:
|
|
43
|
-
// Plan step
|
|
44
|
-
return !!state.selectedPlan;
|
|
45
|
-
|
|
46
|
-
default:
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Get step title
|
|
53
|
-
*
|
|
54
|
-
* @param stepNumber - Step number
|
|
55
|
-
* @param config - Onboarding configuration
|
|
56
|
-
* @returns Step title
|
|
57
|
-
*/
|
|
58
|
-
export function getStepTitle(stepNumber: number, config: OnboardingConfig): string {
|
|
59
|
-
const stepConfig = config.steps[stepNumber - 1];
|
|
60
|
-
return stepConfig?.title || `Step ${stepNumber}`;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Get step description
|
|
65
|
-
*
|
|
66
|
-
* @param stepNumber - Step number
|
|
67
|
-
* @param config - Onboarding configuration
|
|
68
|
-
* @returns Step description or undefined
|
|
69
|
-
*/
|
|
70
|
-
export function getStepDescription(stepNumber: number, config: OnboardingConfig): string | undefined {
|
|
71
|
-
const stepConfig = config.steps[stepNumber - 1];
|
|
72
|
-
return stepConfig?.description;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Calculate onboarding progress
|
|
77
|
-
*
|
|
78
|
-
* @param currentStep - Current step number
|
|
79
|
-
* @param totalSteps - Total number of steps
|
|
80
|
-
* @returns Progress percentage (0-100)
|
|
81
|
-
*/
|
|
82
|
-
export function calculateProgress(currentStep: number, totalSteps: number): number {
|
|
83
|
-
return Math.min((currentStep / totalSteps) * 100, 100);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Get completed steps
|
|
88
|
-
*
|
|
89
|
-
* @param currentStep - Current step number
|
|
90
|
-
* @returns Array of completed step numbers
|
|
91
|
-
*/
|
|
92
|
-
export function getCompletedSteps(currentStep: number): number[] {
|
|
93
|
-
return Array.from({ length: currentStep - 1 }, (_, i) => i + 1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Format onboarding data for API submission
|
|
98
|
-
*
|
|
99
|
-
* @param state - Onboarding state
|
|
100
|
-
* @param userId - User ID
|
|
101
|
-
* @returns Formatted data object
|
|
102
|
-
*/
|
|
103
|
-
export function formatOnboardingData(state: OnboardingState, userId?: string) {
|
|
104
|
-
return {
|
|
105
|
-
userId,
|
|
106
|
-
userType: state.selectedUserType,
|
|
107
|
-
hasMobileApp: state.hasMobileApp,
|
|
108
|
-
hasWebApp: state.hasWebApp,
|
|
109
|
-
connectedPlatforms: state.connectedPlatforms,
|
|
110
|
-
selectedPlan: state.selectedPlan,
|
|
111
|
-
billingCycle: state.billingCycle,
|
|
112
|
-
stepData: state.stepData,
|
|
113
|
-
completedAt: new Date().toISOString(),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Generate onboarding analytics event
|
|
119
|
-
*
|
|
120
|
-
* @param event - Event name
|
|
121
|
-
* @param state - Onboarding state
|
|
122
|
-
* @param additionalData - Additional event data
|
|
123
|
-
* @returns Analytics event object
|
|
124
|
-
*/
|
|
125
|
-
export function generateOnboardingEvent(
|
|
126
|
-
event: string,
|
|
127
|
-
state: OnboardingState,
|
|
128
|
-
additionalData?: Record<string, unknown>
|
|
129
|
-
) {
|
|
130
|
-
return {
|
|
131
|
-
event,
|
|
132
|
-
properties: {
|
|
133
|
-
currentStep: state.currentStep,
|
|
134
|
-
userType: state.selectedUserType,
|
|
135
|
-
hasMobileApp: state.hasMobileApp,
|
|
136
|
-
hasWebApp: state.hasWebApp,
|
|
137
|
-
platformCount: state.connectedPlatforms.length,
|
|
138
|
-
selectedPlan: state.selectedPlan,
|
|
139
|
-
billingCycle: state.billingCycle,
|
|
140
|
-
...additionalData,
|
|
141
|
-
},
|
|
142
|
-
timestamp: new Date().toISOString(),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Validate email format
|
|
148
|
-
*
|
|
149
|
-
* @param email - Email address
|
|
150
|
-
* @returns Whether email is valid
|
|
151
|
-
*/
|
|
152
|
-
export function isValidEmail(email: string): boolean {
|
|
153
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
154
|
-
return emailRegex.test(email);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Validate password strength
|
|
159
|
-
*
|
|
160
|
-
* @param password - Password
|
|
161
|
-
* @param minLength - Minimum length (default: 8)
|
|
162
|
-
* @returns Whether password meets requirements
|
|
163
|
-
*/
|
|
164
|
-
export function isValidPassword(password: string, minLength: number = 8): boolean {
|
|
165
|
-
return password.length >= minLength;
|
|
166
|
-
}
|