import { useState, useRef, useEffect, ChangeEvent } from 'react'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { HeaderType } from '@/entities/common/model/types'; import { useSetHeaderTitle, useSetHeaderType, useSetFooterMode, useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { useUserChangeCancelPasswordMutation } from '@/entities/user/api/use-user-change-cancel-password-mutation'; import { useStore } from '@/shared/model/store'; import { XKeypad, XKeypadManager, createPasswordKeypad } from '@/utils/xkeypad'; export const PasswordModifyCancelPasswordPage = () => { const { navigate } = useNavigate(); const midOptions = useStore.getState().UserStore.selectOptionsMids; const userMid = useStore.getState().UserStore.mid; const [mid, setMid] = useState(userMid); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [isKeypadLoaded, setIsKeypadLoaded] = useState(false); // Input refs for xkeypad const passwordInputRef = useRef(null); const confirmPasswordInputRef = useRef(null); // XKeypad instances const passwordKeypadRef = useRef(null); const confirmPasswordKeypadRef = useRef(null); // RSA Keys (실제 프로덕션에서는 서버에서 받아와야 함) const RSA_MODULUS = "C4F7B39E2E93DB19C016C7A0C1C05B028A1D57CB9B91E13F5B7353F8FB5AC6CE6BE31ABEB8E8F7AD18B90C08F4EBC011A6A8FCE614EA879ED5B96296B969CE92923BC9BAD6FD87F00E08F529F93010EA77E40937BDAC1C866E79ACE2F2822A3ECD982F90532D5301CF90D9BF89E953A0593AB6C5F31E99B690DD582FB85F85A9"; const RSA_EXPONENT = "10001"; const changeCancelPasswordMutation = useUserChangeCancelPasswordMutation({ onSuccess: () => { // snackBar('비밀번호가 성공적으로 변경되었습니다.'); // Clear form and keypads setPassword(''); setConfirmPassword(''); if (passwordKeypadRef.current) passwordKeypadRef.current.clear(); if (confirmPasswordKeypadRef.current) confirmPasswordKeypadRef.current.clear(); if (passwordInputRef.current) passwordInputRef.current.value = ''; if (confirmPasswordInputRef.current) confirmPasswordInputRef.current.value = ''; // Navigate back navigate(PATHS.account.password.manage); }, onError: (error) => { // snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); } }); // Initialize XKeypad useEffect(() => { const initializeKeypad = async () => { try { const manager = XKeypadManager.getInstance({ modulus: RSA_MODULUS, exponent: RSA_EXPONENT }); await manager.loadScripts(); // RSA 키 설정을 명시적으로 다시 한번 수행 manager.setRSAPublicKey(RSA_MODULUS, RSA_EXPONENT); setIsKeypadLoaded(true); } catch (error) { console.error('Failed to load XKeypad:', error); } }; initializeKeypad(); return () => { // Cleanup keypads on unmount if (passwordKeypadRef.current) { passwordKeypadRef.current.destroy(); } if (confirmPasswordKeypadRef.current) { confirmPasswordKeypadRef.current.destroy(); } }; }, []); useSetHeaderTitle('거래취소 비밀번호 변경'); useSetHeaderType(HeaderType.LeftArrow); useSetFooterMode(false); useSetOnBack(() => { navigate(PATHS.account.password.manage); }); // 저장 버튼 활성화 조건 체크 const isFormValid = () => { return ( password.length >= 8 && confirmPassword.length >= 8 && password === confirmPassword ); }; // Handle password keypad const handlePasswordKeypad = async () => { if (!passwordInputRef.current || !isKeypadLoaded) return; // Close other keypad if open if (confirmPasswordKeypadRef.current) { confirmPasswordKeypadRef.current.close(); } // Create or initialize password keypad if (!passwordKeypadRef.current) { passwordKeypadRef.current = createPasswordKeypad(passwordInputRef.current, { keyType: 'qwertysmart', viewType: 'half', maxInputSize: 16, useOverlay: true, useModal: false, hasPressEffect: true, isE2E: false, // E2E 모드 비활성화 onInputChange: (length: number) => { // Update password state as typing if (passwordKeypadRef.current) { const plainText = passwordKeypadRef.current.getPlainText(); console.log('passwordKeypadRef:', plainText, passwordInputRef.current?.value); setPassword(plainText); } }, onKeypadClose: () => { // Final update when keypad closes if (passwordKeypadRef.current) { const plainText = passwordKeypadRef.current.getPlainText(); setPassword(plainText); } } }); } const result = await passwordKeypadRef.current.initialize(passwordInputRef.current); if (result !== 0) { console.error('Failed to initialize password keypad'); } }; // Handle confirm password keypad const handleConfirmPasswordKeypad = async () => { if (!confirmPasswordInputRef.current || !isKeypadLoaded) return; // Close other keypad if open if (passwordKeypadRef.current) { passwordKeypadRef.current.close(); } // Create or initialize confirm password keypad if (!confirmPasswordKeypadRef.current) { confirmPasswordKeypadRef.current = createPasswordKeypad(confirmPasswordInputRef.current, { keyType: 'qwertysmart', viewType: 'half', maxInputSize: 16, useOverlay: true, useModal: false, hasPressEffect: true, isE2E: false, // E2E 모드 비활성화 onInputChange: (length: number) => { // Update confirm password state as typing if (confirmPasswordKeypadRef.current) { const plainText = confirmPasswordKeypadRef.current.getPlainText(); console.log('confirmPasswordKeypadRef:', plainText, confirmPasswordInputRef.current?.value); setConfirmPassword(plainText); } }, onKeypadClose: () => { // Final update when keypad closes if (confirmPasswordKeypadRef.current) { const plainText = confirmPasswordKeypadRef.current.getPlainText(); setConfirmPassword(plainText); } } }); } const result = await confirmPasswordKeypadRef.current.initialize(confirmPasswordInputRef.current); if (result !== 0) { console.error('Failed to initialize confirm password keypad'); } }; // 저장 버튼 클릭 핸들러 const handleSave = () => { if (!isFormValid()) return; // 평문 비밀번호 사용 (E2E 모드가 꺼져있으므로) changeCancelPasswordMutation.mutate({ mid, password: password }); }; return ( <>
가맹점 *
변경 비밀번호 *
변경 비밀번호 재입력 *
{confirmPassword && password !== confirmPassword && (
입력 정보 불일치
)}
); };