99 CircularProgress ,
1010} from "@mui/material" ;
1111import axios from "axios" ;
12+ import { Colors } from "design/theme" ;
1213import React , { useState , useEffect } from "react" ;
1314import { useNavigate , useSearchParams } from "react-router-dom" ;
1415
@@ -25,6 +26,7 @@ const CompleteProfile: React.FC = () => {
2526 } ) ;
2627 const [ loading , setLoading ] = useState ( false ) ;
2728 const [ error , setError ] = useState ( "" ) ;
29+ const [ tokenExpired , setTokenExpired ] = useState ( false ) ;
2830
2931 useEffect ( ( ) => {
3032 if ( ! token ) {
@@ -55,21 +57,36 @@ const CompleteProfile: React.FC = () => {
5557 const handleSubmit = async ( e : React . FormEvent < HTMLFormElement > ) => {
5658 e . preventDefault ( ) ;
5759 setError ( "" ) ;
60+ setTokenExpired ( false ) ;
5861 setLoading ( true ) ;
5962
6063 try {
61- await axios . post ( "/api/v1/auth/complete-profile" , {
62- token,
63- ...formData ,
64- } ) ;
64+ await axios . post (
65+ `${
66+ process . env . REACT_APP_API_URL || "http://localhost:5000"
67+ } /api/v1/auth/complete-profile`,
68+ {
69+ token,
70+ ...formData ,
71+ }
72+ ) ;
6573
6674 // Profile completed successfully, redirect to home
6775 navigate ( "/?auth=success" ) ;
6876 window . location . reload ( ) ; // Reload to update auth state
6977 } catch ( err : unknown ) {
7078 // setError(err.response?.data?.message || 'Failed to complete profile');
7179 if ( axios . isAxiosError ( err ) ) {
72- setError ( err . response ?. data ?. message || "Failed to complete profile" ) ;
80+ const errorMessage =
81+ err . response ?. data ?. message || "Failed to complete profile" ;
82+ setError ( errorMessage ) ;
83+ // ← NEW: Check if token expired
84+ if (
85+ errorMessage . toLowerCase ( ) . includes ( "expired" ) ||
86+ errorMessage . toLowerCase ( ) . includes ( "invalid" )
87+ ) {
88+ setTokenExpired ( true ) ;
89+ }
7390 } else {
7491 setError ( "Failed to complete profile" ) ;
7592 }
@@ -98,83 +115,154 @@ const CompleteProfile: React.FC = () => {
98115 </ Alert >
99116 ) }
100117
101- < Box component = "form" onSubmit = { handleSubmit } >
102- < TextField
103- fullWidth
104- label = "First Name"
105- name = "firstName"
106- value = { formData . firstName }
107- onChange = { handleChange }
108- required
109- margin = "normal"
110- disabled = { loading }
111- autoFocus
112- />
113-
114- < TextField
115- fullWidth
116- label = "Last Name"
117- name = "lastName"
118- value = { formData . lastName }
119- onChange = { handleChange }
120- required
121- margin = "normal"
122- disabled = { loading }
123- />
124-
125- < TextField
126- fullWidth
127- label = "Company/Institution"
128- name = "company"
129- value = { formData . company }
130- onChange = { handleChange }
131- required
132- margin = "normal"
133- helperText = "Your university, research institution, or company"
134- disabled = { loading }
135- placeholder = "e.g., MIT, Harvard Medical School, Google Research"
136- />
137-
138- < TextField
139- fullWidth
140- label = "Research Interests (Optional)"
141- name = "interests"
142- value = { formData . interests }
143- onChange = { handleChange }
144- margin = "normal"
145- multiline
146- rows = { 3 }
147- helperText = "e.g., fMRI, EEG, Machine Learning, Neuroimaging"
148- disabled = { loading }
149- placeholder = "What areas of neuroscience research are you interested in?"
150- />
151-
152- < Typography
153- variant = "caption"
154- color = "text.secondary"
155- sx = { { mt : 2 , display : "block" } }
156- >
157- ⏱️ Take your time - this session is valid for 1 hour
158- </ Typography >
159-
160- < Button
161- type = "submit"
162- fullWidth
163- variant = "contained"
164- size = "large"
165- disabled = { loading }
166- sx = { { mt : 3 } }
167- >
168- { loading ? (
169- < >
170- < CircularProgress size = { 24 } sx = { { mr : 1 , color : "white" } } />
171- Completing Profile...
172- </ >
173- ) : (
174- "Complete Profile & Continue"
175- ) }
176- </ Button >
177- </ Box >
118+ { tokenExpired ? (
119+ < Box sx = { { textAlign : "center" , mt : 3 } } >
120+ < Typography variant = "body1" color = "text.secondary" sx = { { mb : 3 } } >
121+ Your session has expired. Please return to the home page and sign
122+ in again to continue.
123+ </ Typography >
124+ < Button
125+ variant = "outlined"
126+ size = "large"
127+ onClick = { ( ) => navigate ( "/" ) }
128+ sx = { {
129+ backgroundColor : Colors . purple ,
130+ color : Colors . white ,
131+ "&:hover" : {
132+ backgroundColor : Colors . secondaryPurple ,
133+ color : Colors . white ,
134+ } ,
135+ } }
136+ >
137+ Go to Home Page
138+ </ Button >
139+ </ Box >
140+ ) : (
141+ < Box component = "form" onSubmit = { handleSubmit } >
142+ < TextField
143+ fullWidth
144+ label = "First Name"
145+ name = "firstName"
146+ value = { formData . firstName }
147+ onChange = { handleChange }
148+ required
149+ margin = "normal"
150+ disabled = { loading }
151+ autoFocus
152+ sx = { {
153+ "& .MuiOutlinedInput-root" : {
154+ "&.Mui-focused fieldset" : {
155+ borderColor : Colors . purple ,
156+ } ,
157+ } ,
158+ "& .MuiInputLabel-root.Mui-focused" : {
159+ color : Colors . purple ,
160+ } ,
161+ } }
162+ />
163+
164+ < TextField
165+ fullWidth
166+ label = "Last Name"
167+ name = "lastName"
168+ value = { formData . lastName }
169+ onChange = { handleChange }
170+ required
171+ margin = "normal"
172+ disabled = { loading }
173+ sx = { {
174+ "& .MuiOutlinedInput-root" : {
175+ "&.Mui-focused fieldset" : {
176+ borderColor : Colors . purple ,
177+ } ,
178+ } ,
179+ "& .MuiInputLabel-root.Mui-focused" : {
180+ color : Colors . purple ,
181+ } ,
182+ } }
183+ />
184+
185+ < TextField
186+ fullWidth
187+ label = "Company/Institute"
188+ name = "company"
189+ value = { formData . company }
190+ onChange = { handleChange }
191+ required
192+ margin = "normal"
193+ helperText = "Your university, research institution, or company"
194+ disabled = { loading }
195+ sx = { {
196+ "& .MuiOutlinedInput-root" : {
197+ "&.Mui-focused fieldset" : {
198+ borderColor : Colors . purple ,
199+ } ,
200+ } ,
201+ "& .MuiInputLabel-root.Mui-focused" : {
202+ color : Colors . purple ,
203+ } ,
204+ } }
205+ />
206+
207+ < TextField
208+ fullWidth
209+ label = "Research Interests (Optional)"
210+ name = "interests"
211+ value = { formData . interests }
212+ onChange = { handleChange }
213+ margin = "normal"
214+ multiline
215+ rows = { 3 }
216+ helperText = "e.g., fMRI, EEG, fNIRS, Neuroimaging"
217+ disabled = { loading }
218+ placeholder = "What areas of neuroscience research are you interested in?"
219+ sx = { {
220+ "& .MuiOutlinedInput-root" : {
221+ "&.Mui-focused fieldset" : {
222+ borderColor : Colors . purple ,
223+ } ,
224+ } ,
225+ "& .MuiInputLabel-root.Mui-focused" : {
226+ color : Colors . purple ,
227+ } ,
228+ } }
229+ />
230+
231+ < Typography
232+ variant = "caption"
233+ color = "text.secondary"
234+ sx = { { mt : 2 , display : "block" } }
235+ >
236+ ⏱️ Take your time - this session is valid for 1 hour
237+ </ Typography >
238+
239+ < Button
240+ type = "submit"
241+ fullWidth
242+ variant = "contained"
243+ size = "large"
244+ disabled = { loading }
245+ sx = { {
246+ mt : 3 ,
247+ backgroundColor : Colors . purple ,
248+ color : Colors . white ,
249+ "&:hover" : {
250+ backgroundColor : Colors . secondaryPurple ,
251+ color : Colors . white ,
252+ } ,
253+ } }
254+ >
255+ { loading ? (
256+ < >
257+ < CircularProgress size = { 24 } sx = { { mr : 1 , color : "white" } } />
258+ Completing Profile...
259+ </ >
260+ ) : (
261+ "Complete Profile & Continue"
262+ ) }
263+ </ Button >
264+ </ Box >
265+ ) }
178266 </ Paper >
179267 </ Container >
180268 ) ;
0 commit comments