import React, { useState } from 'react'; import api from '../api'; import { reportError, logUserActionError } from '../utils/errorLogger'; const AccountSettingsPage = ({ onNavigate, user, onUserUpdate }) => { const [activeTab, setActiveTab] = useState('profile'); const [isLoading, setIsLoading] = useState(false); const [message, setMessage] = useState({ type: '', text: '' }); // 프로필 정보 상태 const [profileData, setProfileData] = useState({ name: user?.name || '', email: user?.email || '', department: user?.department || '', position: user?.position || '' }); // 비밀번호 변경 상태 const [passwordData, setPasswordData] = useState({ currentPassword: '', newPassword: '', confirmPassword: '' }); const [validationErrors, setValidationErrors] = useState({}); const handleProfileChange = (e) => { const { name, value } = e.target; setProfileData(prev => ({ ...prev, [name]: value })); // 에러 메시지 초기화 if (validationErrors[name]) { setValidationErrors(prev => ({ ...prev, [name]: '' })); } if (message.text) setMessage({ type: '', text: '' }); }; const handlePasswordChange = (e) => { const { name, value } = e.target; setPasswordData(prev => ({ ...prev, [name]: value })); // 에러 메시지 초기화 if (validationErrors[name]) { setValidationErrors(prev => ({ ...prev, [name]: '' })); } if (message.text) setMessage({ type: '', text: '' }); }; const validateProfileForm = () => { const errors = {}; if (!profileData.name.trim()) { errors.name = '이름을 입력해주세요'; } else if (profileData.name.length < 2 || profileData.name.length > 50) { errors.name = '이름은 2-50자여야 합니다'; } if (profileData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(profileData.email)) { errors.email = '올바른 이메일 형식을 입력해주세요'; } setValidationErrors(errors); return Object.keys(errors).length === 0; }; const validatePasswordForm = () => { const errors = {}; if (!passwordData.currentPassword) { errors.currentPassword = '현재 비밀번호를 입력해주세요'; } if (!passwordData.newPassword) { errors.newPassword = '새 비밀번호를 입력해주세요'; } else if (passwordData.newPassword.length < 8) { errors.newPassword = '새 비밀번호는 8자 이상이어야 합니다'; } if (!passwordData.confirmPassword) { errors.confirmPassword = '비밀번호 확인을 입력해주세요'; } else if (passwordData.newPassword !== passwordData.confirmPassword) { errors.confirmPassword = '새 비밀번호가 일치하지 않습니다'; } setValidationErrors(errors); return Object.keys(errors).length === 0; }; const handleProfileSubmit = async (e) => { e.preventDefault(); if (!validateProfileForm()) { return; } setIsLoading(true); setMessage({ type: '', text: '' }); try { const response = await api.put('/auth/profile', { name: profileData.name.trim(), email: profileData.email.trim() || null, department: profileData.department.trim() || null, position: profileData.position.trim() || null }); if (response.data.success) { const updatedUser = { ...user, ...response.data.user }; onUserUpdate(updatedUser); setMessage({ type: 'success', text: '프로필이 성공적으로 업데이트되었습니다' }); } else { setMessage({ type: 'error', text: response.data.message || '프로필 업데이트에 실패했습니다' }); } } catch (err) { console.error('Profile update error:', err); const errorMessage = err.response?.data?.detail || err.response?.data?.message || '프로필 업데이트 중 오류가 발생했습니다'; setMessage({ type: 'error', text: errorMessage }); logUserActionError('profile_update', err, { userId: user?.user_id }); } finally { setIsLoading(false); } }; const handlePasswordSubmit = async (e) => { e.preventDefault(); if (!validatePasswordForm()) { return; } setIsLoading(true); setMessage({ type: '', text: '' }); try { const response = await api.put('/auth/change-password', { current_password: passwordData.currentPassword, new_password: passwordData.newPassword }); if (response.data.success) { setPasswordData({ currentPassword: '', newPassword: '', confirmPassword: '' }); setMessage({ type: 'success', text: '비밀번호가 성공적으로 변경되었습니다' }); } else { setMessage({ type: 'error', text: response.data.message || '비밀번호 변경에 실패했습니다' }); } } catch (err) { console.error('Password change error:', err); const errorMessage = err.response?.data?.detail || err.response?.data?.message || '비밀번호 변경 중 오류가 발생했습니다'; setMessage({ type: 'error', text: errorMessage }); logUserActionError('password_change', err, { userId: user?.user_id }); } finally { setIsLoading(false); } }; return (
{/* 헤더 */}

⚙️ 계정 설정

프로필 정보 및 비밀번호를 관리하세요

{/* 탭 메뉴 */}
{/* 메시지 표시 */} {message.text && (
{message.text}
)} {/* 프로필 정보 탭 */} {activeTab === 'profile' && (

프로필 정보

{/* 사용자명 (읽기 전용) */}

사용자명은 변경할 수 없습니다

{/* 이름 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = validationErrors.name ? '#ef4444' : '#d1d5db'} /> {validationErrors.name && (

{validationErrors.name}

)}
{/* 이메일 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = validationErrors.email ? '#ef4444' : '#d1d5db'} /> {validationErrors.email && (

{validationErrors.email}

)}
{/* 부서 및 직책 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = '#d1d5db'} />
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = '#d1d5db'} />
{/* 역할 (읽기 전용) */}

역할은 시스템 관리자만 변경할 수 있습니다

)} {/* 비밀번호 변경 탭 */} {activeTab === 'password' && (

비밀번호 변경

{/* 현재 비밀번호 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = validationErrors.currentPassword ? '#ef4444' : '#d1d5db'} /> {validationErrors.currentPassword && (

{validationErrors.currentPassword}

)}
{/* 새 비밀번호 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = validationErrors.newPassword ? '#ef4444' : '#d1d5db'} /> {validationErrors.newPassword && (

{validationErrors.newPassword}

)}
{/* 새 비밀번호 확인 */}
e.target.style.borderColor = '#3b82f6'} onBlur={(e) => e.target.style.borderColor = validationErrors.confirmPassword ? '#ef4444' : '#d1d5db'} /> {validationErrors.confirmPassword && (

{validationErrors.confirmPassword}

)}
{/* 보안 안내 */}

🔐 보안 안내

  • 비밀번호는 8자 이상으로 설정해주세요
  • 영문, 숫자, 특수문자를 조합하여 사용하는 것을 권장합니다
  • 정기적으로 비밀번호를 변경해주세요
  • 다른 사이트와 동일한 비밀번호 사용을 피해주세요
)}
); }; export default AccountSettingsPage;