@@ -16,16 +16,23 @@ import { LoadingButton } from '@/components/form/LoadingButton';
1616import { AuthLayout } from '@/components/layout/AuthLayout' ;
1717import { useAuth } from '../context/AuthContext' ;
1818import { PageLoader } from '@/components/PageLoader' ;
19+ import { Switch } from '@/components/ui/switch' ;
20+ import { useTelemetryConsent } from '../hooks/useTelemetryConsent' ;
1921
2022export default function OnboardingPage ( ) {
2123 const { register, isLoading, isAuthenticated, setupRequired } = useAuth ( ) ;
24+ const { saveTelemetryConsent, isLoading : isSavingConsent } = useTelemetryConsent ( ) ;
2225 const [ currentStep , setCurrentStep ] = useState ( 1 ) ;
2326 const [ formData , setFormData ] = useState ( {
2427 username : '' ,
2528 email : '' ,
2629 password : '' ,
2730 confirmPassword : ''
2831 } ) ;
32+ const [ telemetryConsent , setTelemetryConsent ] = useState ( {
33+ errorDiagnostics : true , // Default ON
34+ usageAnalytics : true // Default ON
35+ } ) ;
2936 const [ error , setError ] = useState ( '' ) ;
3037 const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
3138
@@ -86,6 +93,7 @@ export default function OnboardingPage() {
8693 }
8794 return true ;
8895
96+
8997 default :
9098 return true ;
9199 }
@@ -109,8 +117,13 @@ export default function OnboardingPage() {
109117 setError ( '' ) ;
110118
111119 try {
120+ // Register the user
112121 await register ( formData ) ;
113- // Navigation handled by auth context change
122+
123+ // Save telemetry consent preferences after successful registration
124+ await saveTelemetryConsent ( telemetryConsent ) ;
125+
126+ // Navigation will be handled by auth context change (redirect to dashboard)
114127 } catch ( err ) {
115128 const errorMessage = err instanceof Error ? err . message : 'Registration failed' ;
116129 try {
@@ -158,6 +171,56 @@ export default function OnboardingPage() {
158171 />
159172 </ Stack >
160173
174+ { /* Telemetry Consent Section */ }
175+ < VStack gap = { 4 } w = "full" align = "start" p = { 4 } bg = "gray.50" rounded = "md" >
176+ < Box >
177+ < Text fontSize = "md" fontWeight = "medium" color = "gray.800" mb = { 1 } >
178+ Help improve ThingConnect Pulse? (Optional)
179+ </ Text >
180+ < Text fontSize = "sm" color = "gray.600" >
181+ Enable anonymous diagnostics to help us fix crashes faster and improve features.
182+ </ Text >
183+ </ Box >
184+
185+ < Stack gap = { 3 } w = "full" >
186+ < Flex justify = "space-between" align = "center" >
187+ < VStack align = "start" gap = { 0 } flex = "1" >
188+ < Text fontSize = "sm" fontWeight = "medium" color = "gray.800" >
189+ Send sanitized error diagnostics
190+ </ Text >
191+ < Text fontSize = "xs" color = "gray.600" >
192+ Exception types, stack traces (no sensitive data)
193+ </ Text >
194+ </ VStack >
195+ < Switch
196+ checked = { telemetryConsent . errorDiagnostics }
197+ onCheckedChange = { ( details ) => setTelemetryConsent ( prev => ( { ...prev , errorDiagnostics : details . checked } ) ) }
198+ colorPalette = "blue"
199+ size = "sm"
200+ disabled = { isSubmitting }
201+ />
202+ </ Flex >
203+
204+ < Flex justify = "space-between" align = "center" >
205+ < VStack align = "start" gap = { 0 } flex = "1" >
206+ < Text fontSize = "sm" fontWeight = "medium" color = "gray.800" >
207+ Send anonymous usage analytics
208+ </ Text >
209+ < Text fontSize = "xs" color = "gray.600" >
210+ Feature usage counts (no personal information)
211+ </ Text >
212+ </ VStack >
213+ < Switch
214+ checked = { telemetryConsent . usageAnalytics }
215+ onCheckedChange = { ( details ) => setTelemetryConsent ( prev => ( { ...prev , usageAnalytics : details . checked } ) ) }
216+ colorPalette = "blue"
217+ size = "sm"
218+ disabled = { isSubmitting }
219+ />
220+ </ Flex >
221+ </ Stack >
222+ </ VStack >
223+
161224 < LoadingButton
162225 size = "lg"
163226 w = "full"
@@ -230,38 +293,6 @@ export default function OnboardingPage() {
230293 </ VStack >
231294 ) ;
232295
233- const renderStep3 = ( ) => (
234- < VStack gap = { 6 } >
235- < Box textAlign = "center" >
236- < Heading size = "lg" mb = { 2 } color = "#076bb3" fontWeight = "bold" >
237- Setup Complete!
238- </ Heading >
239- < Text color = "gray.600" fontSize = "lg" fontWeight = "medium" >
240- Your ThingConnect Pulse system is ready to use
241- </ Text >
242- </ Box >
243-
244- < VStack gap = { 4 } align = "start" maxW = "md" w = "full" >
245- < Flex align = "center" gap = { 3 } >
246- < Box w = { 2 } h = { 2 } bg = "#076bb3" rounded = "full" />
247- < Text color = "gray.800" fontWeight = "medium" > Administrator account created</ Text >
248- </ Flex >
249- < Flex align = "center" gap = { 3 } >
250- < Box w = { 2 } h = { 2 } bg = "#076bb3" rounded = "full" />
251- < Text color = "gray.800" fontWeight = "medium" > System authentication configured</ Text >
252- </ Flex >
253- < Flex align = "center" gap = { 3 } >
254- < Box w = { 2 } h = { 2 } bg = "#076bb3" rounded = "full" />
255- < Text color = "gray.800" fontWeight = "medium" > Ready to monitor your network</ Text >
256- </ Flex >
257- </ VStack >
258-
259- < Text fontSize = "sm" color = "gray.600" fontWeight = "medium" textAlign = "center" >
260- You will be automatically logged in and redirected to the dashboard
261- </ Text >
262- </ VStack >
263- ) ;
264-
265296
266297 return (
267298 < AuthLayout >
@@ -292,7 +323,6 @@ export default function OnboardingPage() {
292323
293324 { currentStep === 1 && renderStep1 ( ) }
294325 { currentStep === 2 && renderStep2 ( ) }
295- { currentStep === 3 && renderStep3 ( ) }
296326 </ VStack >
297327 </ AuthLayout >
298328 ) ;
0 commit comments