@@ -23,23 +23,34 @@ import { Input } from "@/components/ui/input";
2323import { Label } from "@/components/ui/label" ;
2424import { useToast } from "@/hooks/use-toast" ;
2525import { AppDispatch , RootState } from "@/store" ;
26- import { loadUser , updateProfile } from "@/store/slices/authSlice" ;
26+ import {
27+ changePassword ,
28+ loadUser ,
29+ updateProfile ,
30+ } from "@/store/slices/authSlice" ;
2731import { ProfileForm } from "@/types" ;
2832import { useEffect , useState } from "react" ;
2933import { FaRegTrashCan } from "react-icons/fa6" ;
3034import { useDispatch , useSelector } from "react-redux" ;
3135import { useNavigate } from "react-router" ;
36+ import { passwordFormValues , passwordSchema } from "@/schemas" ;
37+ import { FaEye , FaEyeSlash } from "react-icons/fa" ;
3238
3339const SettingPage = ( ) => {
3440 const { user, isAuthenticated, isLoading } = useSelector (
3541 ( state : RootState ) => state . auth
3642 ) ;
43+ const [ isShowCurrentPassword , setIsShowCurrentPassword ] =
44+ useState < boolean > ( false ) ;
45+ const [ isShowNewPassword , setIsShowNewPassword ] = useState < boolean > ( false ) ;
46+ const [ isShowConfirmPassword , setIsShowConfirmPassword ] =
47+ useState < boolean > ( false ) ;
3748 const [ profileForm , setProfileForm ] = useState < ProfileForm > ( {
3849 name : user ?. name ,
3950 email : user ?. email ,
4051 imageFile : null ,
4152 } ) ;
42- const [ passwordForm , setPasswordForm ] = useState ( {
53+ const [ passwordForm , setPasswordForm ] = useState < passwordFormValues > ( {
4354 currentPassword : "" ,
4455 newPassword : "" ,
4556 confirmPassword : "" ,
@@ -84,7 +95,10 @@ const SettingPage = () => {
8495 const profileFormChangeHandler = ( field : string , value : any ) => {
8596 setProfileForm ( ( prev ) => ( { ...prev , [ field ] : value } ) ) ;
8697 } ;
87- const passwordFormChangeHandler = ( field : string , value : string ) => {
98+ const passwordFormChangeHandler = (
99+ field : keyof passwordFormValues ,
100+ value : string
101+ ) => {
88102 setPasswordForm ( ( prev ) => ( { ...prev , [ field ] : value } ) ) ;
89103 } ;
90104
@@ -114,7 +128,30 @@ const SettingPage = () => {
114128 }
115129 } ;
116130
117- const updatePasswordHandler = ( ) => { } ;
131+ const updatePasswordHandler = async ( ) => {
132+ try {
133+ const validateData = passwordSchema . parse ( passwordForm ) ;
134+
135+ const formData = new FormData ( ) ;
136+ formData . append ( "currentPassword" , validateData . currentPassword ) ;
137+ formData . append ( "newPassword" , validateData . newPassword ) ;
138+
139+ const result = await dispatch ( changePassword ( formData ) ) ;
140+ if ( changePassword . fulfilled . match ( result ) ) {
141+ showToast ( "Password update successfully" , "success" ) ;
142+ } else {
143+ throw new Error ( result . payload as string ) ;
144+ }
145+ } catch ( error : any ) {
146+ let errorMessage ;
147+ if ( error . errors ) {
148+ errorMessage = error . errors [ 0 ] . message ;
149+ } else {
150+ errorMessage = error . message ;
151+ }
152+ showToast ( `${ errorMessage } ` || "Failed to updated Password" , "error" ) ;
153+ }
154+ } ;
118155
119156 if ( isLoading ) return < LoadingSnipper > Loading Settings...</ LoadingSnipper > ;
120157
@@ -232,35 +269,53 @@ const SettingPage = () => {
232269 </ CardHeader >
233270 < CardContent className = "space-y-6" >
234271 < div className = "grid sm:grid-cols-2 gap-4" >
235- < div className = "space-y-2" >
272+ < div className = "relative space-y-2" >
236273 < Label > Current Password</ Label >
237274 < Input
238- type = " password"
275+ type = { isShowCurrentPassword ? "text" : " password"}
239276 className = " border border-border"
240277 onChange = { ( e ) =>
241278 passwordFormChangeHandler ( "currentPassword" , e . target . value )
242279 }
243280 />
281+ < div
282+ className = { `absolute right-4 top-1/2 cursor-pointer` }
283+ onClick = { ( ) => setIsShowCurrentPassword ( ( prev ) => ! prev ) }
284+ >
285+ { isShowCurrentPassword ? < FaEyeSlash /> : < FaEye /> }
286+ </ div >
244287 </ div >
245- < div className = "space-y-2" >
288+ < div className = "space-y-2 relative " >
246289 < Label > New Password</ Label >
247290 < Input
248- type = " password"
291+ type = { isShowNewPassword ? "text" : " password"}
249292 className = " border border-border"
250293 onChange = { ( e ) =>
251294 passwordFormChangeHandler ( "newPassword" , e . target . value )
252295 }
253296 />
297+ < div
298+ className = { `absolute right-4 top-1/2 cursor-pointer` }
299+ onClick = { ( ) => setIsShowNewPassword ( ( prev ) => ! prev ) }
300+ >
301+ { isShowNewPassword ? < FaEyeSlash /> : < FaEye /> }
302+ </ div >
254303 </ div >
255- < div className = "space-y-2" >
304+ < div className = "space-y-2 relative " >
256305 < Label > Confirm New Password</ Label >
257306 < Input
258- type = " password"
307+ type = { isShowConfirmPassword ? "text" : " password"}
259308 className = " border border-border"
260309 onChange = { ( e ) =>
261310 passwordFormChangeHandler ( "confirmPassword" , e . target . value )
262311 }
263312 />
313+ < div
314+ className = { `absolute right-4 top-1/2 cursor-pointer` }
315+ onClick = { ( ) => setIsShowConfirmPassword ( ( prev ) => ! prev ) }
316+ >
317+ { isShowConfirmPassword ? < FaEyeSlash /> : < FaEye /> }
318+ </ div >
264319 </ div >
265320 </ div >
266321 < Button onClick = { updatePasswordHandler } > Update Password</ Button >
0 commit comments