1
+ "use client" ;
2
+
3
+ import { useAuth } from "@/components/auth/AuthContext" ;
4
+ import { Button } from "@/components/ui/button" ;
5
+ import { Form , FormControl , FormField , FormItem , FormLabel , FormMessage } from "@/components/ui/form" ;
6
+ import { Input } from "@/components/ui/input" ;
7
+ import { useForm } from "react-hook-form" ;
8
+ import { setGetProfile } from "@/api/user" ;
9
+ import { useEffect , useState } from "react" ;
10
+ import { User } from "@/types/user" ;
11
+ import { z } from "zod" ;
12
+ import { zodResolver } from "@hookform/resolvers/zod" ;
13
+ import Swal from "sweetalert2" ;
14
+
15
+ const formSchema = z . object ( {
16
+ username : z . string ( )
17
+ . min ( 5 , "Username must be at least 5 characters" ) ,
18
+ bio : z . string ( ) ,
19
+ linkedin : z . string ( )
20
+ . refine ( ( val ) => val . length == 0 || val . includes ( "linkedin.com/in/" ) ,
21
+ { message : "Invalid URL" } ) ,
22
+ github : z . string ( )
23
+ . refine ( ( val ) => val . length == 0 || val . includes ( "github.com/" ) ,
24
+ { message : "Invalid URL" } ) ,
25
+ } ) ;
26
+
27
+ const ProfilePage = ( ) => {
28
+ const { token } = useAuth ( ) ;
29
+ const [ user , setUser ] = useState < User > ( { } ) ;
30
+
31
+ const form = useForm < z . infer < typeof formSchema > > ( {
32
+ resolver : zodResolver ( formSchema ) ,
33
+ defaultValues : {
34
+ username : "" ,
35
+ bio : "" ,
36
+ linkedin : "" ,
37
+ github : "" ,
38
+ } ,
39
+ } ) ;
40
+
41
+ useEffect ( ( ) => {
42
+ setGetProfile ( token , { } ) . then ( ( data ) => {
43
+ setUser ( data ) ;
44
+ form . reset ( data ) ;
45
+ } ) . catch ( ( error ) => {
46
+ console . error ( "Profile Fetch Failed:" , error ) ;
47
+ Swal . fire ( {
48
+ icon : "error" ,
49
+ title : "Profile Fetch Failed" ,
50
+ text : "Please try again later" ,
51
+ } ) ;
52
+ } ) ;
53
+ } , [ token , form ] ) ;
54
+
55
+ const onSubmit = ( data : z . infer < typeof formSchema > ) => {
56
+ setGetProfile ( token , data ) . then ( ( data ) => {
57
+ setUser ( data ) ;
58
+ form . reset ( data ) ;
59
+ Swal . fire ( {
60
+ icon : "success" ,
61
+ title : "Profile Updated" ,
62
+ text : "Your profile has been updated successfully" ,
63
+ } ) ;
64
+ } ) . catch ( ( error ) => {
65
+ console . error ( "Profile Update Failed:" , error ) ;
66
+ Swal . fire ( {
67
+ icon : "error" ,
68
+ title : "Profile Update Failed" ,
69
+ text : "Please try again later" ,
70
+ } )
71
+ } ) ;
72
+ } ;
73
+
74
+ return (
75
+ < div className = "mx-auto max-w-xl my-10 p-4" >
76
+ < h1 className = "text-white font-extrabold text-h1" > Welcome, { user ?. username } !</ h1 >
77
+
78
+ < Form { ...form } >
79
+ < form className = "my-10 grid gap-4" onSubmit = { form . handleSubmit ( onSubmit ) } >
80
+ < FormField
81
+ control = { form . control }
82
+ name = "username"
83
+ render = { ( { field } ) => (
84
+ < FormItem >
85
+ < FormLabel className = "text-yellow-500 text-lg" > USERNAME</ FormLabel >
86
+ < FormControl >
87
+ < Input placeholder = "username" { ...field } className = "focus:border-yellow-500 text-white" />
88
+ </ FormControl >
89
+ { /* <FormDescription>This is your public display name.</FormDescription> */ }
90
+ < FormMessage />
91
+ </ FormItem >
92
+ ) }
93
+ />
94
+ < FormField
95
+ control = { form . control }
96
+ name = "bio"
97
+ render = { ( { field } ) => (
98
+ < FormItem >
99
+ < FormLabel className = "text-yellow-500 text-lg" > BIO</ FormLabel >
100
+ < FormControl >
101
+ < Input placeholder = "I am a..." { ...field } className = "focus:border-yellow-500 text-white" />
102
+ </ FormControl >
103
+ { /* <FormDescription>This is your public display name.</FormDescription> */ }
104
+ < FormMessage />
105
+ </ FormItem >
106
+ ) }
107
+ />
108
+ < FormField
109
+ control = { form . control }
110
+ name = "linkedin"
111
+ render = { ( { field } ) => (
112
+ < FormItem >
113
+ < FormLabel className = "text-yellow-500 text-lg" > LINKEDIN URL</ FormLabel >
114
+ < FormControl >
115
+ < Input placeholder = "https://www.linkedin.com/in/..." { ...field } className = "focus:border-yellow-500 text-white" />
116
+ </ FormControl >
117
+ { /* <FormDescription>This is your public display name.</FormDescription> */ }
118
+ < FormMessage />
119
+ </ FormItem >
120
+ ) }
121
+ />
122
+ < FormField
123
+ control = { form . control }
124
+ name = "github"
125
+ render = { ( { field } ) => (
126
+ < FormItem >
127
+ < FormLabel className = "text-yellow-500 text-lg" > GITHUB URL</ FormLabel >
128
+ < FormControl >
129
+ < Input placeholder = "https://github.com/..." { ...field } className = "focus:border-yellow-500 text-white" />
130
+ </ FormControl >
131
+ { /* <FormDescription>This is your public display name.</FormDescription> */ }
132
+ < FormMessage />
133
+ </ FormItem >
134
+ ) }
135
+ />
136
+ < Button type = "submit" className = "bg-yellow-500 hover:bg-yellow-300 px-4 py-2 my-2 rounded-md text-black" > Save Changes</ Button >
137
+ </ form >
138
+ </ Form >
139
+
140
+ </ div >
141
+ ) ;
142
+ }
143
+
144
+ export default ProfilePage ;
0 commit comments