@@ -15,18 +15,22 @@ import { getInitials } from '@/lib/utils';
1515import { useState } from 'react' ;
1616import { useRouter } from 'next/navigation' ;
1717import { TokenInfoCard } from '@/components/profile/token-info-card' ;
18-
19- const profileSchema = z . object ( {
20- nickname : z . string ( ) . min ( 1 , 'Nickname is required' ) . max ( 50 ) ,
21- signature : z . string ( ) . max ( 100 ) . optional ( ) ,
22- } ) ;
18+ import { useTranslations } from 'next-intl' ; // Import useTranslations
2319
2420export default function ProfilePage ( ) {
21+ const t = useTranslations ( 'Profile' ) ; // Initialize translations
2522 const { user, isLoading, logout } = useAuth ( ) ;
2623 const { toast } = useToast ( ) ;
2724 const router = useRouter ( ) ;
2825 const [ isUploading , setIsUploading ] = useState ( false ) ;
2926
27+ // Schema definition must be inside the component or outside, but using t() inside requires it to be inside
28+ // or passed as a function argument, let's redefine it here to use t() for error messages.
29+ const profileSchema = z . object ( {
30+ nickname : z . string ( ) . min ( 1 , t ( 'form.nicknameRequired' ) ) . max ( 50 ) ,
31+ signature : z . string ( ) . max ( 100 ) . optional ( ) ,
32+ } ) ;
33+
3034 const form = useForm < z . infer < typeof profileSchema > > ( {
3135 resolver : zodResolver ( profileSchema ) ,
3236 values : {
@@ -47,14 +51,14 @@ export default function ProfilePage() {
4751 await api . post ( '/user/avatar' , formData , {
4852 headers : { 'Content-Type' : 'multipart/form-data' } ,
4953 } ) ;
50- toast ( { title : 'Avatar updated successfully!' } ) ;
54+ toast ( { title : t ( 'avatar.uploadSuccess' ) } ) ;
5155 // Forcing a reload to get the new user profile with updated avatar URL
5256 window . location . reload ( ) ;
5357 } catch ( error : any ) {
5458 toast ( {
5559 variant : 'destructive' ,
56- title : 'Upload failed' ,
57- description : error . response ?. data ?. message || 'Could not upload avatar.' ,
60+ title : t ( 'avatar.uploadFailTitle' ) ,
61+ description : error . response ?. data ?. message || t ( ' avatar.uploadFailDescription' ) ,
5862 } ) ;
5963 } finally {
6064 setIsUploading ( false ) ;
@@ -64,14 +68,14 @@ export default function ProfilePage() {
6468 const onSubmit = async ( values : z . infer < typeof profileSchema > ) => {
6569 try {
6670 await api . patch ( '/user/profile' , values ) ;
67- toast ( { title : 'Profile updated successfully!' } ) ;
71+ toast ( { title : t ( 'form.updateSuccess' ) } ) ;
6872 // Forcing a reload to get the new user profile
6973 window . location . reload ( ) ;
7074 } catch ( error : any ) {
7175 toast ( {
7276 variant : 'destructive' ,
73- title : 'Update failed' ,
74- description : error . response ?. data ?. message || 'Could not update profile.' ,
77+ title : t ( 'form.updateFailTitle' ) ,
78+ description : error . response ?. data ?. message || t ( 'form.updateFailDescription' ) ,
7579 } ) ;
7680 }
7781 } ;
@@ -85,12 +89,14 @@ export default function ProfilePage() {
8589 return < Skeleton className = "w-full h-96" /> ;
8690 }
8791
92+ const isSubmitting = form . formState . isSubmitting ;
93+
8894 return (
8995 < div className = "grid auto-rows-min gap-6 lg:grid-cols-3" >
9096 < Card >
9197 < CardHeader >
92- < CardTitle > Avatar </ CardTitle >
93- < CardDescription > Update your profile picture. </ CardDescription >
98+ < CardTitle > { t ( 'avatar.title' ) } </ CardTitle >
99+ < CardDescription > { t ( 'avatar.description' ) } </ CardDescription >
94100 </ CardHeader >
95101 < CardContent className = "flex flex-col items-center gap-4" >
96102 < Avatar className = "h-32 w-32" >
@@ -99,31 +105,31 @@ export default function ProfilePage() {
99105 </ Avatar >
100106 < Input id = "avatar-upload" type = "file" accept = "image/*" onChange = { handleAvatarUpload } className = "hidden" />
101107 < Button asChild variant = "outline" >
102- < label htmlFor = "avatar-upload" > { isUploading ? "Uploading..." : "Change Avatar" } </ label >
108+ < label htmlFor = "avatar-upload" > { isUploading ? t ( 'avatar.uploading' ) : t ( 'avatar.change' ) } </ label >
103109 </ Button >
104110 </ CardContent >
105111 </ Card >
106112
107113 < Card className = "lg:col-span-2 lg:row-span-2 flex flex-col" >
108114 < CardHeader >
109- < CardTitle > Profile Information </ CardTitle >
110- < CardDescription > Update your account details. Username cannot be changed. </ CardDescription >
115+ < CardTitle > { t ( 'form.title' ) } </ CardTitle >
116+ < CardDescription > { t ( 'form.description' ) } </ CardDescription >
111117 </ CardHeader >
112118 < CardContent className = "flex flex-1 flex-col justify-between" >
113119 < Form { ...form } >
114120 < form onSubmit = { form . handleSubmit ( onSubmit ) } className = "space-y-4" >
115121 < FormItem >
116- < FormLabel > Username </ FormLabel >
122+ < FormLabel > { t ( 'form.username' ) } </ FormLabel >
117123 < Input disabled value = { user . username } />
118124 </ FormItem >
119125 < FormField
120126 control = { form . control }
121127 name = "nickname"
122128 render = { ( { field } ) => (
123129 < FormItem >
124- < FormLabel > Nickname </ FormLabel >
130+ < FormLabel > { t ( 'form.nickname' ) } </ FormLabel >
125131 < FormControl >
126- < Input placeholder = "Your display name" { ...field } />
132+ < Input placeholder = { t ( 'form.nicknamePlaceholder' ) } { ...field } />
127133 </ FormControl >
128134 < FormMessage />
129135 </ FormItem >
@@ -134,21 +140,21 @@ export default function ProfilePage() {
134140 name = "signature"
135141 render = { ( { field } ) => (
136142 < FormItem >
137- < FormLabel > Signature </ FormLabel >
143+ < FormLabel > { t ( 'form.signature' ) } </ FormLabel >
138144 < FormControl >
139- < Input placeholder = "A short bio" { ...field } />
145+ < Input placeholder = { t ( 'form.signaturePlaceholder' ) } { ...field } />
140146 </ FormControl >
141147 < FormMessage />
142148 </ FormItem >
143149 ) }
144150 />
145- < Button type = "submit" disabled = { form . formState . isSubmitting } >
146- { form . formState . isSubmitting ? 'Saving...' : 'Save Changes' }
151+ < Button type = "submit" disabled = { isSubmitting } >
152+ { isSubmitting ? t ( 'form.saving' ) : t ( 'form.saveChanges' ) }
147153 </ Button >
148154 </ form >
149155 </ Form >
150156 < div className = "border-t pt-6 mt-6" >
151- < Button variant = "destructive" onClick = { handleLogout } > Log Out </ Button >
157+ < Button variant = "destructive" onClick = { handleLogout } > { t ( 'logout' ) } </ Button >
152158 </ div >
153159 </ CardContent >
154160 </ Card >
0 commit comments