1- import { useEffect } from 'react' ;
1+ import { useEffect , useState } from 'react' ;
22
33import { Outlet } from '@tanstack/react-router' ;
44
55import { ErrorBoundary } from '@/components/ErrorBoundary' ;
66import { useAuth } from '@/hooks/useAuth' ;
7+ import { useGetUserDetailsMutation , useUpdateUser } from '@/hooks/useUsers' ;
78import Header from '@/layouts/header' ;
89import { Logger } from '@/lib/services/logger' ;
10+ import { type User } from '@/lib/types' ;
11+ import { useAppStore } from '@/store/store' ;
912
1013export function App ( ) {
11- const { isAuthenticated, isLoading, loginWithRedirect } = useAuth ( ) ;
14+ const { user, isAuthenticated, isLoading, loginWithRedirect } = useAuth ( ) ;
15+ const { mutate : fetchUserDetails , isPending : isFetchingUserDetails } =
16+ useGetUserDetailsMutation ( ) ;
17+ const updateUserMutation = useUpdateUser ( ) ;
18+ const { setUserDetail } = useAppStore ( ) ;
19+
20+ const [ userDetailsFetched , setUserDetailsFetched ] = useState ( false ) ;
21+ const [ fetchInitiated , setFetchInitiated ] = useState ( false ) ;
22+
1223 useEffect ( ( ) => {
1324 Logger . logEvent ( 'AppStarted' , {
1425 startTime : new Date ( ) . toISOString ( ) ,
@@ -41,6 +52,7 @@ export function App() {
4152 window . removeEventListener ( 'unhandledrejection' , handleUnhandledRejection ) ;
4253 } ;
4354 } , [ ] ) ;
55+
4456 // Handle authentication redirect
4557 useEffect ( ( ) => {
4658 if ( ! isLoading && ! isAuthenticated ) {
@@ -56,41 +68,104 @@ export function App() {
5668 returnTo : window . location . pathname + window . location . search ,
5769 } ,
5870 } ) ;
71+ } else if ( isAuthenticated && user ?. email && ! fetchInitiated ) {
72+ // Log successful authentication
73+ Logger . logEvent ( 'UserAuthenticated' , {
74+ userId : user . sub ,
75+ userEmail : user . email ,
76+ timestamp : new Date ( ) . toISOString ( ) ,
77+ } ) ;
78+
79+ setFetchInitiated ( true ) ;
80+
81+ // Fetch user details
82+ fetchUserDetails ( user . email , {
83+ onSuccess : userDetails => {
84+ void ( async ( ) => {
85+ if ( userDetails . status !== 'verified' && user . email_verified ) {
86+ userDetails . status = 'verified' ;
87+ await updateUserMutation . mutateAsync ( {
88+ userData : userDetails as User ,
89+ email : userDetails . email ,
90+ } ) ;
91+ }
92+ setUserDetail ( {
93+ id : userDetails . id ,
94+ email : userDetails . email ,
95+ username : userDetails . username ,
96+ role : userDetails . role ,
97+ organization : userDetails . organization ,
98+ firstName : userDetails . firstName ,
99+ lastName : userDetails . lastName ,
100+ status : userDetails . status ,
101+ } ) ;
102+ setUserDetailsFetched ( true ) ;
103+ } ) ( ) ;
104+ } ,
105+ onError : error => {
106+ // Log the error
107+ Logger . logException ( error instanceof Error ? error : new Error ( String ( error ) ) , {
108+ source : 'FetchUserDetails' ,
109+ userEmail : user . email ,
110+ } ) ;
111+
112+ // Reset states
113+ setFetchInitiated ( false ) ;
114+ setUserDetailsFetched ( false ) ;
115+
116+ // Redirect to login
117+ void loginWithRedirect ( {
118+ appState : {
119+ returnTo : window . location . pathname + window . location . search ,
120+ } ,
121+ } ) ;
122+ } ,
123+ } ) ;
59124 }
60- } , [ isAuthenticated , isLoading , loginWithRedirect ] ) ;
125+ } , [
126+ isAuthenticated ,
127+ isLoading ,
128+ loginWithRedirect ,
129+ user ,
130+ fetchUserDetails ,
131+ setUserDetail ,
132+ fetchInitiated ,
133+ updateUserMutation ,
134+ ] ) ;
61135
62136 if ( isLoading ) {
63- return (
64- < ErrorBoundary >
65- < div className = 'flex min-h-screen items-center justify-center bg-gray-50' >
66- < div className = 'text-center' >
67- < div className = 'mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-blue-600' > </ div >
68- < p className = 'text-lg text-gray-600' > Loading...</ p >
69- </ div >
70- </ div >
71- </ ErrorBoundary >
72- ) ;
137+ return LoadingScreen ( 'Loading...' ) ;
73138 }
74139
75140 if ( ! isAuthenticated ) {
76- return (
77- < ErrorBoundary >
78- < div className = 'flex min-h-screen items-center justify-center bg-gray-50' >
79- < div className = 'text-center' >
80- < div className = 'mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-blue-600' > </ div >
81- < p className = 'text-lg text-gray-600' > Redirecting to login...</ p >
82- </ div >
83- </ div >
84- </ ErrorBoundary >
85- ) ;
141+ return LoadingScreen ( 'Redirecting to login...' ) ;
142+ }
143+
144+ if ( isFetchingUserDetails || ! userDetailsFetched ) {
145+ return LoadingScreen ( 'Loading user details...' ) ;
86146 }
87147
88148 return (
89149 < ErrorBoundary >
90- < Header />
91- < main className = 'p-4' >
92- < Outlet />
93- </ main >
150+ < div className = 'flex h-screen flex-col overflow-hidden' >
151+ < Header />
152+ < main className = 'flex-1 overflow-hidden p-4' >
153+ < Outlet />
154+ </ main >
155+ </ div >
156+ </ ErrorBoundary >
157+ ) ;
158+ }
159+
160+ function LoadingScreen ( message : string ) {
161+ return (
162+ < ErrorBoundary >
163+ < div className = 'flex h-screen items-center justify-center bg-gray-50' >
164+ < div className = 'text-center' >
165+ < div className = 'mx-auto mb-4 h-12 w-12 animate-spin rounded-full border-b-2 border-blue-600' > </ div >
166+ < p className = 'text-lg text-gray-600' > { message } </ p >
167+ </ div >
168+ </ div >
94169 </ ErrorBoundary >
95170 ) ;
96171}
0 commit comments