@@ -76,10 +76,10 @@ const skillsList = [
7676
7777const MainDashboard : React . FC = ( ) => {
7878 const theme = useTheme ( )
79- const [ aboutMe , setAboutMe ] = useState ( ( ) => localStorage . getItem ( "aboutMe" ) || "" )
80- const [ skills , setSkills ] = useState < string [ ] > ( ( ) => JSON . parse ( localStorage . getItem ( "skills" ) || "[]" ) )
79+ const [ aboutMe , setAboutMe ] = useState ( "" )
80+ const [ skills , setSkills ] = useState < string [ ] > ( [ ] )
8181 const [ newSkill , setNewSkill ] = useState ( "" )
82- const [ selectedRole , setSelectedRole ] = useState ( ( ) => localStorage . getItem ( "selectedRole ") || "" )
82+ const [ selectedRole , setSelectedRole ] = useState ( " ")
8383 const [ repos , setRepos ] = useState < { id : number ; name : string ; html_url : string } [ ] > ( [ ] )
8484 const [ useOAuth , setUseOAuth ] = useState ( true )
8585 const [ showAuthOptions , setShowAuthOptions ] = useState ( false )
@@ -114,17 +114,6 @@ const MainDashboard: React.FC = () => {
114114 setShowJobRecommendations ( ! showJobRecommendations )
115115 }
116116
117- // Persist to localStorage
118- useEffect ( ( ) => {
119- localStorage . setItem ( "aboutMe" , aboutMe )
120- } , [ aboutMe ] )
121- useEffect ( ( ) => {
122- localStorage . setItem ( "skills" , JSON . stringify ( skills ) )
123- } , [ skills ] )
124- useEffect ( ( ) => {
125- localStorage . setItem ( "selectedRole" , selectedRole )
126- } , [ selectedRole ] )
127-
128117 // Handle GitHub OAuth callback
129118 useEffect ( ( ) => {
130119 const code = new URLSearchParams ( window . location . search ) . get ( "code" )
@@ -146,6 +135,13 @@ const MainDashboard: React.FC = () => {
146135 useEffect ( ( ) => {
147136 const fetchResumeData = async ( ) => {
148137 try {
138+ const user_data = await api . get ( "/user/" + getUserAuth ( ) . userId ) ;
139+ if ( user_data . data . aboutMe ) {
140+ setAboutMe ( user_data . data . aboutMe || "" )
141+ setSkills ( user_data . data . skills || [ ] )
142+ setSelectedRole ( user_data . data . selectedRole || "" )
143+ }
144+
149145 const response = await api . get ( "/resume" )
150146 if ( response . data && response . data . parsedData ) {
151147 const parsedData = response . data . parsedData
@@ -184,11 +180,13 @@ const MainDashboard: React.FC = () => {
184180 const trimmed = skill . trim ( )
185181 if ( ! trimmed || skills . includes ( trimmed ) ) return
186182 setSkills ( ( prev ) => [ trimmed , ...prev ] )
183+ setIsProfileDirty ( true ) ;
187184 setNewSkill ( "" )
188185 }
189186
190187 const handleDeleteSkill = ( skillToDelete : string ) => {
191188 setSkills ( ( prev ) => prev . filter ( ( s ) => s !== skillToDelete ) )
189+ setIsProfileDirty ( true ) ;
192190 }
193191
194192 const handleGitHubConnect = async ( ) => {
@@ -256,6 +254,7 @@ const MainDashboard: React.FC = () => {
256254 setResumeExperience ( aiExp )
257255 setCurrentResumeId ( uploadedResume )
258256 localStorage . setItem ( "lastResumeId" , uploadedResume )
257+ updateUserProfile ( aiAbout , aiSkills , aiRole ) ;
259258 setHasResumeChanged ( false )
260259 } catch ( err ) {
261260 console . error ( err )
@@ -282,6 +281,7 @@ const MainDashboard: React.FC = () => {
282281 setResumeExperience ( aiExp )
283282 localStorage . setItem ( "lastResumeId" , currentResumeId )
284283 setHasResumeChanged ( false )
284+ updateUserProfile ( aiAbout , aiSkills , aiRole ) ;
285285 } catch ( err ) {
286286 console . error ( err )
287287 alert ( "Failed to sync with resume." )
@@ -333,8 +333,52 @@ const MainDashboard: React.FC = () => {
333333
334334 const handleRemoveAllSkills = ( ) => {
335335 setSkills ( [ ] )
336+ setIsProfileDirty ( true ) ;
336337 }
337338
339+ const [ isProfileDirty , setIsProfileDirty ] = useState ( false ) ;
340+ const [ isSaving , setIsSaving ] = useState ( false ) ;
341+
342+
343+ useEffect ( ( ) => {
344+ setIsProfileDirty ( true ) ;
345+ } , [ aboutMe , skills , selectedRole ] ) ;
346+
347+ const handleAboutMeChange = ( e : React . ChangeEvent < HTMLInputElement > ) => {
348+ setAboutMe ( e . target . value ) ;
349+ setIsProfileDirty ( true ) ;
350+ } ;
351+
352+ const handleSelectedRoleChange = ( _ : any , val : string | null ) => {
353+ setSelectedRole ( val || "" ) ;
354+ setIsProfileDirty ( true ) ;
355+ } ;
356+
357+ const updateUserProfile = async ( newAboutMe ?: string , newSkills ?: string , newSelectedRole ?: string ) => {
358+ setIsSaving ( true ) ;
359+ try {
360+ await api . put ( `/user/${ getUserAuth ( ) . userId } ` , {
361+ aboutMe : newAboutMe ? newAboutMe : aboutMe ,
362+ skills : newSkills ? newSkills : skills ,
363+ selectedRole : newSelectedRole ? newSelectedRole : selectedRole ,
364+ } , {
365+ headers : {
366+ Authorization : `Bearer ${ getUserAuth ( ) . accessToken } ` ,
367+ } ,
368+ } ) ;
369+ // // Optionally, update localStorage or context with new values
370+ // localStorage.setItem("aboutMe", aboutMe);
371+ // localStorage.setItem("skills", JSON.stringify(skills));
372+ // localStorage.setItem("selectedRole", selectedRole);
373+ // setIsProfileDirty(false);
374+ } catch ( error ) {
375+ console . error ( "Failed to update profile:" , error ) ;
376+ alert ( "Failed to update profile. Please try again." ) ;
377+ } finally {
378+ setIsSaving ( false ) ;
379+ }
380+ } ;
381+
338382 return (
339383 < Box sx = { { minHeight : "100vh" , py : 4 } } >
340384 < Container maxWidth = "xl" >
@@ -560,7 +604,7 @@ const MainDashboard: React.FC = () => {
560604 variant = "outlined"
561605 placeholder = "Describe your background, experience, and career aspirations..."
562606 value = { aboutMe }
563- onChange = { ( e ) => setAboutMe ( e . target . value ) }
607+ onChange = { handleAboutMeChange }
564608 sx = { {
565609 "& .MuiOutlinedInput-root" : {
566610 borderRadius : 3 ,
@@ -756,7 +800,7 @@ const MainDashboard: React.FC = () => {
756800 freeSolo
757801 options = { roles }
758802 value = { selectedRole }
759- onInputChange = { ( _ , val ) => setSelectedRole ( val ) }
803+ onInputChange = { handleSelectedRoleChange }
760804 renderInput = { ( params ) => (
761805 < TextField
762806 { ...params }
@@ -1090,6 +1134,17 @@ const MainDashboard: React.FC = () => {
10901134 </ Stack >
10911135 </ Grid >
10921136 </ Grid >
1137+ { isProfileDirty && (
1138+ < Button
1139+ variant = "contained"
1140+ color = "primary"
1141+ onClick = { updateUserProfile }
1142+ disabled = { isSaving }
1143+ sx = { { mt : 2 } }
1144+ >
1145+ { isSaving ? < CircularProgress size = { 24 } /> : "Save Changes" }
1146+ </ Button >
1147+ ) }
10931148 </ Container >
10941149 </ Box >
10951150 )
0 commit comments