1
+ import React , { useState , useEffect } from 'react' ;
2
+ import axios from 'axios' ;
3
+ import { Button } from '@/components/ui/button' ;
4
+ import { Input } from '@/components/ui/input' ;
5
+ import { Label } from '@/components/ui/label' ;
6
+ import { toast } from 'sonner' ;
7
+ import { Textarea } from '../ui/textarea' ;
8
+ import { Icons } from "@/components/ui/icons" ;
9
+
10
+ const backendUrl = import . meta. env . VITE_BACKEND_URL || 'http://localhost:5000' ;
11
+
12
+ interface ProfileData {
13
+ name : string ;
14
+ bio : string ;
15
+ githubUsername : string ;
16
+ leetcodeUsername : string ;
17
+ }
18
+
19
+ const UpdateProfile = ( ) => {
20
+ const [ username , setUsername ] = useState < string | null > ( null ) ;
21
+ const [ profileData , setProfileData ] = useState < ProfileData > ( {
22
+ name : '' ,
23
+ bio : '' ,
24
+ githubUsername : '' ,
25
+ leetcodeUsername : ''
26
+ } ) ;
27
+ const [ isLoading , setIsLoading ] = useState ( false ) ;
28
+
29
+
30
+ useEffect ( ( ) => {
31
+ const storedUsername = localStorage . getItem ( 'devhub_username' ) ;
32
+ setUsername ( storedUsername ) ;
33
+ } , [ ] ) ;
34
+
35
+ useEffect ( ( ) => {
36
+ const fetchProfile = async ( ) => {
37
+ if ( username ) {
38
+ try {
39
+ const response = await axios . get ( `${ backendUrl } /profile/${ username } ` ) ;
40
+ setProfileData ( response . data ) ;
41
+ } catch ( error ) {
42
+ console . error ( 'Failed to fetch profile data:' , error ) ;
43
+ }
44
+ }
45
+ } ;
46
+
47
+ fetchProfile ( ) ;
48
+ } , [ username ] ) ;
49
+
50
+ const handleChange = ( e : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) => {
51
+ const { name, value } = e . target ;
52
+ setProfileData ( ( prevData : ProfileData ) => ( {
53
+ ...prevData ,
54
+ [ name ] : value ,
55
+ } ) ) ;
56
+ } ;
57
+
58
+
59
+
60
+ const handleSubmit = async ( e : React . SyntheticEvent ) => {
61
+ e . preventDefault ( ) ;
62
+ if ( ! username ) return ;
63
+ setIsLoading ( true ) ;
64
+
65
+ try {
66
+ await axios . put ( `${ backendUrl } /profile/${ username } ` , profileData , {
67
+ withCredentials : true ,
68
+ } ) ;
69
+ toast . success ( 'Profile updated successfully' ) ;
70
+ } catch ( error ) {
71
+ console . error ( 'Failed to update profile:' , error ) ;
72
+ toast . error ( 'Failed to update profile' , {
73
+ description : 'Please check your details and try again.' ,
74
+ } ) ;
75
+ } finally {
76
+ setIsLoading ( false ) ;
77
+ }
78
+ } ;
79
+
80
+ return (
81
+ < div className = 'p-2 mt-4 h-full overflow-auto' >
82
+ < h2 className = 'text-xl font-semibold mb-4 dark:text-neutral-100' >
83
+ Update Profile
84
+ </ h2 >
85
+ < form onSubmit = { handleSubmit } className = 'grid gap-4' >
86
+ < div >
87
+ < Label htmlFor = 'name' className = 'dark:text-neutral-200' >
88
+ Name
89
+ </ Label >
90
+ < Input
91
+ id = 'name'
92
+ name = 'name'
93
+ value = { profileData . name || '' }
94
+ onChange = { handleChange }
95
+ disabled = { isLoading }
96
+ placeholder = 'Your name'
97
+ className = 'mt-2'
98
+ />
99
+ </ div >
100
+ < div >
101
+ < Label htmlFor = 'bio' className = 'dark:text-neutral-200' >
102
+ Bio
103
+ </ Label >
104
+ < Textarea
105
+ id = 'bio'
106
+ name = 'bio'
107
+ value = { profileData . bio || '' }
108
+ onChange = { handleChange }
109
+ disabled = { isLoading }
110
+ placeholder = 'Write something about yourself'
111
+ className = 'mt-2'
112
+ />
113
+ </ div >
114
+ < div className = 'grid grid-cols-1 sm:grid-cols-2 gap-6' >
115
+ < div >
116
+ < Label htmlFor = 'githubUsername' className = 'dark:text-neutral-200' >
117
+ GitHub Username
118
+ </ Label >
119
+ < Input
120
+ id = 'githubUsername'
121
+ name = 'githubUsername'
122
+ value = { profileData . githubUsername || '' }
123
+ onChange = { handleChange }
124
+ disabled = { isLoading }
125
+ placeholder = 'GitHub username'
126
+ className = 'mt-2'
127
+ />
128
+ </ div >
129
+ < div >
130
+ < Label htmlFor = 'leetcodeUsername' className = 'dark:text-neutral-200' >
131
+ Leetcode Username
132
+ </ Label >
133
+ < Input
134
+ id = 'leetcodeUsername'
135
+ name = 'leetcodeUsername'
136
+ value = { profileData . leetcodeUsername || '' }
137
+ onChange = { handleChange }
138
+ disabled = { isLoading }
139
+ placeholder = 'Leetcode username'
140
+ className = 'mt-2 '
141
+ />
142
+ </ div >
143
+ </ div >
144
+ < Button type = 'submit' disabled = { isLoading } className = 'w-full mt-4' >
145
+ { isLoading ? ( < > < Icons . spinner className = "mr-2 h-4 w-4 animate-spin" /> 'Updating...'
146
+ </ > ) : 'Update Profile' }
147
+ </ Button >
148
+ </ form >
149
+ </ div >
150
+ ) ;
151
+ } ;
152
+
153
+ export default UpdateProfile ;
0 commit comments