@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,208 @@
1
+ import { Check } from "lucide-react";
2
+ import { cn } from "@umituz/web-design-system/utils";
3
+ import type { OnboardingState, PlanOption } from "../types/onboarding";
4
+
5
+ interface PlanStepProps {
6
+ /** Current onboarding state */
7
+ state: OnboardingState;
8
+ /** Update state function */
9
+ updateState: (updates: Partial<OnboardingState>) => void;
10
+ /** Plan options */
11
+ plans?: PlanOption[];
12
+ }
13
+
14
+ /**
15
+ * Plan Selection Step
16
+ *
17
+ * Fourth step - select subscription plan
18
+ */
19
+ export const PlanStep = ({
20
+ state,
21
+ updateState,
22
+ plans,
23
+ }: PlanStepProps) => {
24
+ // Default plans
25
+ const defaultPlans: PlanOption[] = [
26
+ {
27
+ id: "standard",
28
+ name: "Standard",
29
+ badge: "Most Popular",
30
+ badgeColor: "bg-muted text-muted-foreground",
31
+ description: "Perfect for individuals and small businesses",
32
+ price: 12,
33
+ features: [
34
+ { text: "3 Social Accounts", bold: true },
35
+ "100 posts per month",
36
+ "Basic Analytics",
37
+ "Email Support",
38
+ ],
39
+ },
40
+ {
41
+ id: "pro",
42
+ name: "Pro",
43
+ badge: "Best Value",
44
+ badgeColor: "bg-primary text-primary-foreground",
45
+ description: "For growing businesses and teams",
46
+ price: 29,
47
+ features: [
48
+ { text: "15 Social Accounts", bold: true },
49
+ "Unlimited posts",
50
+ "Advanced Analytics",
51
+ "AI Caption Suggestions",
52
+ { text: "5 Team Members", bold: true },
53
+ "Priority Support",
54
+ ],
55
+ highlight: true,
56
+ },
57
+ {
58
+ id: "enterprise",
59
+ name: "Enterprise",
60
+ badge: "Custom",
61
+ badgeColor: "bg-purple-600 text-white",
62
+ description: "For large organizations with custom needs",
63
+ price: 99,
64
+ features: [
65
+ { text: "Unlimited Accounts", bold: true },
66
+ "Unlimited everything",
67
+ "Custom Integrations",
68
+ "Dedicated Account Manager",
69
+ "24/7 Phone Support",
70
+ "SLA Guarantee",
71
+ ],
72
+ },
73
+ ];
74
+
75
+ const planOptions = plans || defaultPlans;
76
+
77
+ // Calculate price with billing cycle discount
78
+ const getPlanPrice = (plan: PlanOption) => {
79
+ const basePrice = plan.price;
80
+ return state.billingCycle === "yearly" ? basePrice * 12 * 0.8 : basePrice; // 20% discount
81
+ };
82
+
83
+ return (
84
+ <div className="w-full max-w-5xl">
85
+ <div className="text-center mb-8">
86
+ <h1 className="text-3xl md:text-4xl font-extrabold text-foreground mb-3">
87
+ Choose your plan
88
+ </h1>
89
+ <p className="text-muted-foreground text-lg">
90
+ Start with a 14-day free trial - no credit card required
91
+ </p>
92
+ </div>
93
+
94
+ {/* Billing Cycle Toggle */}
95
+ <div className="flex items-center justify-center gap-2 mb-12">
96
+ <div className="flex bg-muted rounded-full p-1.5 border border-border">
97
+ <button
98
+ onClick={() => updateState({ billingCycle: "monthly" })}
99
+ className={cn(
100
+ "px-6 py-2 rounded-full text-sm font-bold transition-all",
101
+ state.billingCycle === "monthly"
102
+ ? "bg-primary text-primary-foreground shadow-lg shadow-primary/20"
103
+ : "text-muted-foreground hover:text-foreground"
104
+ )}
105
+ >
106
+ Monthly
107
+ </button>
108
+ <button
109
+ onClick={() => updateState({ billingCycle: "yearly" })}
110
+ className={cn(
111
+ "px-6 py-2 rounded-full text-sm font-bold transition-all flex items-center gap-2",
112
+ state.billingCycle === "yearly"
113
+ ? "bg-primary text-primary-foreground shadow-lg shadow-primary/20"
114
+ : "text-muted-foreground hover:text-foreground"
115
+ )}
116
+ >
117
+ Yearly
118
+ <span
119
+ className={cn(
120
+ "text-[10px] px-1.5 py-0.5 rounded-full transition-colors",
121
+ state.billingCycle === "yearly" ? "bg-white/20 text-white" : "bg-green-500/10 text-green-600"
122
+ )}
123
+ >
124
+ Save 20%
125
+ </span>
126
+ </button>
127
+ </div>
128
+ </div>
129
+
130
+ {/* Plans Grid */}
131
+ <div className="grid md:grid-cols-3 gap-8">
132
+ {planOptions.map((plan) => {
133
+ const isSelected = state.selectedPlan === plan.id;
134
+ const planPrice = getPlanPrice(plan);
135
+
136
+ return (
137
+ <button
138
+ key={plan.id}
139
+ onClick={() => updateState({ selectedPlan: plan.id })}
140
+ className={cn(
141
+ "bg-background border-2 rounded-[32px] p-8 text-left transition-all hover:translate-y-[-4px] relative",
142
+ isSelected
143
+ ? "border-primary ring-4 ring-primary/10"
144
+ : "border-border hover:border-primary/40",
145
+ plan.highlight && "shadow-xl"
146
+ )}
147
+ >
148
+ {plan.highlight && (
149
+ <div className="absolute -top-3 left-1/2 -translate-x-1/2 bg-gradient-to-r from-primary to-purple-600 text-white text-[10px] font-black uppercase tracking-widest px-4 py-1 rounded-full">
150
+ Recommended
151
+ </div>
152
+ )}
153
+
154
+ <div className="flex items-center justify-between mb-4">
155
+ <h3 className="text-2xl font-black text-foreground">{plan.name}</h3>
156
+ {plan.badge && (
157
+ <div
158
+ className={cn(
159
+ "text-[10px] font-black uppercase tracking-widest px-3 py-1 rounded-full",
160
+ plan.badgeColor
161
+ )}
162
+ >
163
+ {plan.badge}
164
+ </div>
165
+ )}
166
+ </div>
167
+
168
+ <p className="text-muted-foreground mb-8 font-medium">{plan.description}</p>
169
+
170
+ <div className="flex items-baseline gap-1 mb-8">
171
+ <span className="text-5xl font-black text-foreground">
172
+ ${Math.round(planPrice)}
173
+ </span>
174
+ <span className="text-lg font-bold text-muted-foreground">/mo</span>
175
+ </div>
176
+
177
+ <ul className="space-y-4">
178
+ {plan.features.map((feature, i) => {
179
+ const text = typeof feature === "string" ? feature : feature.text;
180
+ const bold = typeof feature !== "string" && feature.bold;
181
+
182
+ return (
183
+ <li key={i} className="flex items-start gap-3 text-sm font-medium">
184
+ <div className="w-5 h-5 rounded-full bg-primary/10 flex items-center justify-center shrink-0 mt-0.5">
185
+ <Check className="h-3 w-3 text-primary" />
186
+ </div>
187
+ <span className={cn("text-foreground/90", bold && "font-black")}>
188
+ {text}
189
+ </span>
190
+ </li>
191
+ );
192
+ })}
193
+ </ul>
194
+ </button>
195
+ );
196
+ })}
197
+ </div>
198
+
199
+ {state.selectedPlan && (
200
+ <p className="mt-8 text-center text-sm text-muted-foreground animate-in fade-in">
201
+ ✨ Great choice! You selected the {planOptions.find((p) => p.id === state.selectedPlan)?.name} plan
202
+ </p>
203
+ )}
204
+ </div>
205
+ );
206
+ };
207
+
208
+ export default PlanStep;
@@ -0,0 +1,109 @@
1
+ import { cn } from "@umituz/web-design-system/utils";
2
+ import type { OnboardingState } from "../types/onboarding";
3
+
4
+ interface PlatformsStepProps {
5
+ /** Current onboarding state */
6
+ state: OnboardingState;
7
+ /** Update state function */
8
+ updateState: (updates: Partial<OnboardingState>) => void;
9
+ /** Platform options */
10
+ platforms?: Array<{
11
+ id: string;
12
+ name: string;
13
+ icon: string;
14
+ color?: string;
15
+ }>;
16
+ }
17
+
18
+ /**
19
+ * Platform Selection Step
20
+ *
21
+ * Third step - select social media platforms to connect
22
+ */
23
+ export const PlatformsStep = ({
24
+ state,
25
+ updateState,
26
+ platforms,
27
+ }: PlatformsStepProps) => {
28
+ // Default platforms
29
+ const defaultPlatforms = [
30
+ { id: "instagram", name: "Instagram", icon: "📸", color: "bg-gradient-to-br from-purple-500 to-pink-500" },
31
+ { id: "twitter", name: "Twitter / X", icon: "🐦", color: "bg-black" },
32
+ { id: "facebook", name: "Facebook", icon: "👍", color: "bg-blue-600" },
33
+ { id: "linkedin", name: "LinkedIn", icon: "💼", color: "bg-blue-700" },
34
+ { id: "tiktok", name: "TikTok", icon: "🎵", color: "bg-black" },
35
+ { id: "youtube", name: "YouTube", icon: "📺", color: "bg-red-600" },
36
+ { id: "pinterest", name: "Pinterest", icon: "📌", color: "bg-red-700" },
37
+ { id: "threads", name: "Threads", icon: "🧵", color: "bg-black" },
38
+ ];
39
+
40
+ const platformOptions = platforms || defaultPlatforms;
41
+
42
+ const togglePlatform = (id: string) => {
43
+ const isConnected = state.connectedPlatforms.includes(id);
44
+ updateState({
45
+ connectedPlatforms: isConnected
46
+ ? state.connectedPlatforms.filter((p) => p !== id)
47
+ : [...state.connectedPlatforms, id],
48
+ });
49
+ };
50
+
51
+ return (
52
+ <div className="w-full max-w-4xl">
53
+ <div className="text-center mb-10">
54
+ <h1 className="text-3xl md:text-4xl font-extrabold text-foreground mb-3">
55
+ Connect your platforms
56
+ </h1>
57
+ <p className="text-muted-foreground">
58
+ Select the platforms you want to manage - you can add more later
59
+ </p>
60
+ </div>
61
+
62
+ <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4">
63
+ {platformOptions.map((platform) => {
64
+ const isConnected = state.connectedPlatforms.includes(platform.id);
65
+
66
+ return (
67
+ <button
68
+ key={platform.id}
69
+ onClick={() => togglePlatform(platform.id)}
70
+ className={cn(
71
+ "group bg-background border rounded-2xl p-6 flex flex-col items-center gap-4 transition-all hover:scale-[1.02]",
72
+ isConnected ? "border-primary ring-2 ring-primary/20 bg-primary/5" : "border-border hover:border-primary/40"
73
+ )}
74
+ >
75
+ <div
76
+ className={cn(
77
+ "w-12 h-12 rounded-2xl bg-muted flex items-center justify-center text-2xl group-hover:scale-110 transition-transform",
78
+ platform.color
79
+ )}
80
+ >
81
+ {platform.icon}
82
+ </div>
83
+
84
+ <div className="flex flex-col items-center">
85
+ <span className="font-bold text-foreground text-sm">{platform.name}</span>
86
+ <span
87
+ className={cn(
88
+ "text-[10px] font-bold uppercase tracking-wider mt-1 transition-colors",
89
+ isConnected ? "text-primary" : "text-muted-foreground"
90
+ )}
91
+ >
92
+ {isConnected ? "Connected" : "Connect"}
93
+ </span>
94
+ </div>
95
+ </button>
96
+ );
97
+ })}
98
+ </div>
99
+
100
+ {state.connectedPlatforms.length > 0 && (
101
+ <p className="mt-8 text-center text-sm text-muted-foreground animate-in fade-in">
102
+ ✨ {state.connectedPlatforms.length} platform{state.connectedPlatforms.length > 1 ? "s" : ""} selected
103
+ </p>
104
+ )}
105
+ </div>
106
+ );
107
+ };
108
+
109
+ export default PlatformsStep;
@@ -0,0 +1,135 @@
1
+ import { Check } from "lucide-react";
2
+ import { cn } from "@umituz/web-design-system/utils";
3
+ import type { OnboardingState } from "../types/onboarding";
4
+ import type { ComponentType } from "react";
5
+
6
+ interface UserTypeOption {
7
+ id: string;
8
+ label: string;
9
+ description: string;
10
+ icon?: ComponentType<{ className?: string }>;
11
+ badge?: string;
12
+ }
13
+
14
+ interface UserTypeStepProps {
15
+ /** Current onboarding state */
16
+ state: OnboardingState;
17
+ /** Update state function */
18
+ updateState: (updates: Partial<OnboardingState>) => void;
19
+ /** User type options */
20
+ options?: UserTypeOption[];
21
+ }
22
+
23
+ /**
24
+ * User Type Selection Step
25
+ *
26
+ * First step of onboarding - select user type/category
27
+ */
28
+ export const UserTypeStep = ({
29
+ state,
30
+ updateState,
31
+ options = [],
32
+ }: UserTypeStepProps) => {
33
+ // Default options if not provided
34
+ const defaultOptions: UserTypeOption[] = [
35
+ {
36
+ id: "founder",
37
+ label: "Founder",
38
+ description: "Building your own startup or business",
39
+ },
40
+ {
41
+ id: "creator",
42
+ label: "Content Creator",
43
+ description: "Creating content for social media and platforms",
44
+ },
45
+ {
46
+ id: "agency",
47
+ label: "Agency",
48
+ description: "Managing multiple client accounts",
49
+ },
50
+ {
51
+ id: "enterprise",
52
+ label: "Enterprise",
53
+ description: "Large scale organization with teams",
54
+ },
55
+ {
56
+ id: "small-business",
57
+ label: "Small Business",
58
+ description: "Local or niche business owner",
59
+ },
60
+ {
61
+ id: "personal",
62
+ label: "Personal",
63
+ description: "Individual looking to grow personal brand",
64
+ },
65
+ ];
66
+
67
+ const userTypeOptions = options.length > 0 ? options : defaultOptions;
68
+
69
+ return (
70
+ <div className="w-full max-w-xl">
71
+ <div className="text-center mb-10">
72
+ <h1 className="text-3xl md:text-4xl font-extrabold text-foreground mb-3">
73
+ What describes you best?
74
+ </h1>
75
+ <p className="text-muted-foreground">
76
+ Select the option that best describes your situation
77
+ </p>
78
+ </div>
79
+
80
+ <div className="grid grid-cols-1 gap-3">
81
+ {userTypeOptions.map((option) => {
82
+ const isSelected = state.selectedUserType === option.id;
83
+ const hasBadge = option.badge != null;
84
+ const hasIcon = option.icon != null;
85
+
86
+ return (
87
+ <button
88
+ key={option.id}
89
+ onClick={() => updateState({ selectedUserType: option.id })}
90
+ className={cn(
91
+ "w-full flex items-center gap-4 p-5 rounded-2xl border bg-background text-left transition-all group",
92
+ isSelected
93
+ ? "border-primary ring-2 ring-primary/20 bg-primary/5"
94
+ : "border-border hover:border-primary/40 hover:bg-muted/50"
95
+ )}
96
+ >
97
+ <div
98
+ className={cn(
99
+ "w-6 h-6 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
100
+ isSelected
101
+ ? "border-primary bg-primary text-white"
102
+ : "border-muted-foreground/30"
103
+ )}
104
+ >
105
+ {isSelected && <Check className="h-4 w-4" />}
106
+ </div>
107
+
108
+ <div className="flex-1">
109
+ <div className="flex items-center gap-2">
110
+ <p className="font-bold text-foreground">{option.label}</p>
111
+ {hasBadge && (
112
+ <span className="text-[10px] font-bold uppercase tracking-wider px-2 py-0.5 rounded-full bg-primary/10 text-primary">
113
+ {option.badge}
114
+ </span>
115
+ )}
116
+ </div>
117
+ <p className="text-sm text-muted-foreground mt-0.5">
118
+ {option.description}
119
+ </p>
120
+ </div>
121
+
122
+ {hasIcon && option.icon && (
123
+ <div className="w-10 h-10 rounded-xl bg-muted flex items-center justify-center shrink-0">
124
+ <option.icon className="h-5 w-5 text-muted-foreground" />
125
+ </div>
126
+ )}
127
+ </button>
128
+ );
129
+ })}
130
+ </div>
131
+ </div>
132
+ );
133
+ };
134
+
135
+ export default UserTypeStep;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Onboarding Components Export
3
+ */
4
+
5
+ export { OnboardingWizard } from './OnboardingWizard';
6
+ export { UserTypeStep } from './UserTypeStep';
7
+ export { AppFocusStep } from './AppFocusStep';
8
+ export { PlatformsStep } from './PlatformsStep';
9
+ export { PlanStep } from './PlanStep';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Onboarding Hooks Export
3
+ */
4
+
5
+ export { useOnboarding, useOnboardingStep } from './useOnboarding';
@@ -1,28 +1,53 @@
1
- "use client";
1
+ /**
2
+ * Onboarding Hooks
3
+ *
4
+ * Custom React hooks for onboarding functionality
5
+ */
2
6
 
3
- // src/domains/onboarding/hooks/useOnboarding.ts
4
7
  import { useState, useCallback } from "react";
5
- function useOnboarding(config, initialState) {
6
- const [state, setState] = useState({
8
+ import type { OnboardingState, OnboardingConfig } from "../types/onboarding";
9
+
10
+ /**
11
+ * Use Onboarding Hook
12
+ *
13
+ * Manages onboarding state and actions
14
+ *
15
+ * @param config - Onboarding configuration
16
+ * @param initialState - Initial state
17
+ * @returns Onboarding state and actions
18
+ */
19
+ export function useOnboarding(
20
+ config: OnboardingConfig,
21
+ initialState?: Partial<OnboardingState>
22
+ ) {
23
+ const [state, setState] = useState<OnboardingState>({
7
24
  currentStep: 1,
8
25
  connectedPlatforms: [],
9
26
  billingCycle: "monthly",
10
27
  stepData: {},
11
- ...initialState
28
+ ...initialState,
12
29
  });
30
+
13
31
  const totalSteps = config.steps.length;
32
+
33
+ // Navigation actions
14
34
  const goToNext = useCallback(() => {
15
35
  const currentStepConfig = config.steps[state.currentStep - 1];
36
+
37
+ // Validate if needed
16
38
  if (currentStepConfig?.validate) {
17
39
  const isValid = currentStepConfig.validate(state);
18
40
  if (!isValid) return false;
19
41
  }
42
+
20
43
  if (state.currentStep < totalSteps) {
21
44
  setState((prev) => ({ ...prev, currentStep: prev.currentStep + 1 }));
22
45
  return true;
23
46
  }
47
+
24
48
  return false;
25
49
  }, [config.steps, state, totalSteps]);
50
+
26
51
  const goToPrev = useCallback(() => {
27
52
  if (state.currentStep > 1) {
28
53
  setState((prev) => ({ ...prev, currentStep: prev.currentStep - 1 }));
@@ -30,14 +55,19 @@ function useOnboarding(config, initialState) {
30
55
  }
31
56
  return false;
32
57
  }, [state.currentStep]);
33
- const goToStep = useCallback((step) => {
58
+
59
+ const goToStep = useCallback((step: number) => {
34
60
  if (step >= 1 && step <= totalSteps) {
35
61
  setState((prev) => ({ ...prev, currentStep: step }));
36
62
  }
37
63
  }, [totalSteps]);
38
- const updateState = useCallback((updates) => {
64
+
65
+ // State update action
66
+ const updateState = useCallback((updates: Partial<OnboardingState>) => {
39
67
  setState((prev) => ({ ...prev, ...updates }));
40
68
  }, []);
69
+
70
+ // Validation helper
41
71
  const canGoNext = useCallback(() => {
42
72
  const currentStepConfig = config.steps[state.currentStep - 1];
43
73
  if (currentStepConfig?.validate) {
@@ -45,11 +75,18 @@ function useOnboarding(config, initialState) {
45
75
  }
46
76
  return true;
47
77
  }, [config.steps, state]);
78
+
79
+ // Progress calculation
48
80
  const getProgress = useCallback(() => {
49
- return state.currentStep / totalSteps * 100;
81
+ return (state.currentStep / totalSteps) * 100;
50
82
  }, [state.currentStep, totalSteps]);
83
+
84
+ // Is first step
51
85
  const isFirstStep = state.currentStep === 1;
86
+
87
+ // Is last step
52
88
  const isLastStep = state.currentStep === totalSteps;
89
+
53
90
  return {
54
91
  // State
55
92
  state,
@@ -58,43 +95,52 @@ function useOnboarding(config, initialState) {
58
95
  isFirstStep,
59
96
  isLastStep,
60
97
  progress: getProgress(),
98
+
61
99
  // Actions
62
100
  goToNext,
63
101
  goToPrev,
64
102
  goToStep,
65
103
  updateState,
66
- canGoNext
104
+ canGoNext,
67
105
  };
68
106
  }
69
- function useOnboardingStep(stepId) {
70
- const [data, setData] = useState({});
107
+
108
+ /**
109
+ * Use Onboarding Step Hook
110
+ *
111
+ * Hook for managing individual step state
112
+ *
113
+ * @param stepId - Step identifier
114
+ * @returns Step state and actions
115
+ */
116
+ export function useOnboardingStep(stepId: string) {
117
+ const [data, setData] = useState<Record<string, unknown>>({});
71
118
  const [isValid, setIsValid] = useState(false);
72
119
  const [isTouched, setIsTouched] = useState(false);
73
- const updateData = useCallback((updates) => {
120
+
121
+ const updateData = useCallback((updates: Record<string, unknown>) => {
74
122
  setData((prev) => ({ ...prev, ...updates }));
75
123
  setIsTouched(true);
76
124
  }, []);
77
- const validate = useCallback((validator) => {
125
+
126
+ const validate = useCallback((validator: (data: Record<string, unknown>) => boolean) => {
78
127
  const valid = validator(data);
79
128
  setIsValid(valid);
80
129
  return valid;
81
130
  }, []);
131
+
82
132
  const reset = useCallback(() => {
83
133
  setData({});
84
134
  setIsValid(false);
85
135
  setIsTouched(false);
86
136
  }, []);
137
+
87
138
  return {
88
139
  data,
89
140
  isValid,
90
141
  isTouched,
91
142
  updateData,
92
143
  validate,
93
- reset
144
+ reset,
94
145
  };
95
146
  }
96
- export {
97
- useOnboarding,
98
- useOnboardingStep
99
- };
100
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @umituz/web-dashboard - Onboarding Domain
3
+ *
4
+ * Config-driven Onboarding System
5
+ */
6
+
7
+ export { OnboardingWizard } from './components';
8
+ export { UserTypeStep } from './components';
9
+ export { AppFocusStep } from './components';
10
+ export { PlatformsStep } from './components';
11
+ export { PlanStep } from './components';
12
+ export { useOnboarding, useOnboardingStep } from './hooks';
13
+ export {
14
+ validateStep,
15
+ getStepTitle,
16
+ getStepDescription,
17
+ calculateProgress,
18
+ getCompletedSteps,
19
+ formatOnboardingData,
20
+ generateOnboardingEvent,
21
+ isValidEmail,
22
+ isValidPassword,
23
+ } from './utils';
24
+ export type {
25
+ UserTypeOption,
26
+ PlatformOption,
27
+ PlanOption,
28
+ OnboardingStep,
29
+ OnboardingConfig,
30
+ OnboardingState,
31
+ OnboardingActions,
32
+ OnboardingWizardProps,
33
+ StepProgressProps,
34
+ StepNavigationProps,
35
+ } from './types';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Onboarding Types Export
3
+ */
4
+
5
+ export type {
6
+ UserTypeOption,
7
+ PlatformOption,
8
+ PlanOption,
9
+ OnboardingStep,
10
+ OnboardingConfig,
11
+ OnboardingState,
12
+ OnboardingActions,
13
+ OnboardingWizardProps,
14
+ StepProgressProps,
15
+ StepNavigationProps,
16
+ } from './onboarding';