From cc2cd469a9f489b0ba7b79027e8d7bdce8faf08d Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 28 Apr 2025 10:38:34 +0700 Subject: [PATCH] update profile --- .../AccountUserProfileContent.tsx | 3 + .../home/user-profile/blocks/PinCode.tsx | 200 ++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 src/pages/account/home/user-profile/blocks/PinCode.tsx diff --git a/src/pages/account/home/user-profile/AccountUserProfileContent.tsx b/src/pages/account/home/user-profile/AccountUserProfileContent.tsx index 06e35be..76cc820 100644 --- a/src/pages/account/home/user-profile/AccountUserProfileContent.tsx +++ b/src/pages/account/home/user-profile/AccountUserProfileContent.tsx @@ -1,4 +1,5 @@ import { BasicSettings, Password } from './blocks'; +import { PinCode } from './blocks/PinCode'; import { AccountUserProfileContextProvider } from './hooks'; const AccountUserProfileContent = () => { @@ -7,6 +8,8 @@ const AccountUserProfileContent = () => { + + {/* Uncomment the line below to enable the Delete Account feature */} {/* */} diff --git a/src/pages/account/home/user-profile/blocks/PinCode.tsx b/src/pages/account/home/user-profile/blocks/PinCode.tsx new file mode 100644 index 0000000..da647ca --- /dev/null +++ b/src/pages/account/home/user-profile/blocks/PinCode.tsx @@ -0,0 +1,200 @@ +import { useState, useContext, useEffect, useCallback, MouseEvent } from 'react'; +import { AccountUserProfileContext } from '../hooks'; +import { toast } from 'sonner'; +import { useAuthContext } from '@/auth'; +import { KeenIcon } from '@/components'; +import clsx from 'clsx'; + +type PasswordType = 'password' | 'retype_password' | 'current_password'; +const PinCode = () => { + const { setPassword } = useContext(AccountUserProfileContext); + const { getUser } = useAuthContext(); + + const [newPassword, setNewPassword] = useState(''); + const [currentPassword, setCurrentPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [messagePassword, setMessagePassword] = useState(true); + const [showPassword, setShowPassword] = useState({ + current_password: false, + password: false, + retype_password: false + }); + + const [passwordErrors, setPasswordErrors] = useState([]); + + const validatePassword = (password: string) => { + const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password); + const hasCapitalLetter = /[A-Z]/.test(password); + const hasNumber = /[0-9]/.test(password); + return hasSpecialChar && hasCapitalLetter && hasNumber; + }; + + useEffect(() => { + const passwordsMatch = newPassword === confirmPassword; + const isPasswordValid = validatePassword(newPassword); + setMessagePassword(passwordsMatch && isPasswordValid); + + const errors: string[] = []; + if (newPassword) { + if (!/[A-Z]/.test(newPassword)) { + errors.push('Password must contain at least one capital letter'); + } + if (!/[0-9]/.test(newPassword)) { + errors.push('Password must contain at least one number'); + } + if (!/[!@#$%^&*(),.?":{}|<>]/.test(newPassword)) { + errors.push('Password must contain at least one special character'); + } + if (newPassword !== confirmPassword) { + errors.push('Passwords do not match'); + } + } + setPasswordErrors(errors); + }, [newPassword, confirmPassword]); + + const handleResetPassword = useCallback(async () => { + const user: any = await getUser(); + + if (!messagePassword) { + toast.error('Passwords do not match!'); + return; + } + + setIsSubmitting(true); + + try { + await setPassword({ + current_password: currentPassword, + password: newPassword, + retype_password: confirmPassword, + username: user.data.username ?? '' + }); + + setNewPassword(''); + setConfirmPassword(''); + setCurrentPassword(''); + } catch (error: any) { + const errorMessage = + error?.response?.data?.message || + error?.message || + 'An error occurred while resetting the password.'; + toast.error(errorMessage); + } finally { + setIsSubmitting(false); + } + }, [currentPassword, newPassword, newPassword, messagePassword, getUser]); + + const isButtonDisabled = isSubmitting || !newPassword || !confirmPassword || !messagePassword; + + const togglePassword = useCallback((event: MouseEvent, key: string) => { + event.preventDefault(); + setShowPassword((prev) => ({ ...prev, [key]: !prev[key as PasswordType] })); + }, []); + + return ( +
+
+

Pin Code

+
+
+
+ +
+ setCurrentPassword(e.target.value)} + disabled={isSubmitting} + /> + +
+
+
+ +
+ setNewPassword(e.target.value)} + disabled={isSubmitting} + type={showPassword.password ? 'text' : 'password'} + /> + +
+
+
+
+ +
+ setConfirmPassword(e.target.value)} + disabled={isSubmitting} + /> + +
+
+
+ + {passwordErrors.length > 0 && ( +
+ {passwordErrors.map((error, index) => ( +

{error}

+ ))} +
+ )} +
+
+ +
+ +
+
+
+ ); +}; + +export { PinCode };