diff --git a/frontend/admin.html b/frontend/admin.html index 7c9e994..1e5878d 100644 --- a/frontend/admin.html +++ b/frontend/admin.html @@ -305,10 +305,14 @@ // 사용자 목록 로드 async function loadUsers() { try { + // 백엔드 API에서 사용자 목록 로드 users = await AuthAPI.getUsers(); displayUsers(); } catch (error) { console.error('사용자 목록 로드 실패:', error); + // API 실패 시 빈 배열로 초기화 + users = []; + displayUsers(); } } @@ -339,18 +343,53 @@ - ${user.username !== 'hyungi' ? ` +
- ` : ''} + ${user.username !== 'hyungi' ? ` + + ` : ''} +
`).join(''); } + // 비밀번호 초기화 + async function resetPassword(username) { + if (!confirm(`${username} 사용자의 비밀번호를 "000000"으로 초기화하시겠습니까?`)) { + return; + } + + try { + // 사용자 ID 찾기 + const user = users.find(u => u.username === username); + if (!user) { + alert('사용자를 찾을 수 없습니다.'); + return; + } + + // 백엔드 API로 비밀번호 초기화 + await AuthAPI.resetPassword(user.id, '000000'); + + alert(`${username} 사용자의 비밀번호가 "000000"으로 초기화되었습니다.`); + + // 목록 새로고침 + await loadUsers(); + + } catch (error) { + alert('비밀번호 초기화에 실패했습니다: ' + error.message); + } + } + // 사용자 삭제 async function deleteUser(username) { if (!confirm(`정말 ${username} 사용자를 삭제하시겠습니까?`)) { diff --git a/frontend/index.html b/frontend/index.html index 713f16a..953b1a8 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -214,9 +214,9 @@ - @@ -500,6 +500,17 @@ } } + // 관리 버튼 클릭 처리 + function handleAdminClick() { + if (currentUser.role === 'admin') { + // 관리자: 사용자 관리 페이지로 이동 + window.location.href = 'admin.html'; + } else { + // 일반 사용자: 비밀번호 변경 모달 표시 + showPasswordChangeModal(); + } + } + // 섹션 전환 // URL 해시 처리 function handleUrlHash() { @@ -1414,6 +1425,125 @@ document.body.appendChild(modal); } + // 비밀번호 변경 모달 표시 + function showPasswordChangeModal() { + const modal = document.createElement('div'); + modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'; + modal.onclick = (e) => { + if (e.target === modal) modal.remove(); + }; + + modal.innerHTML = ` +
+
+

비밀번호 변경

+ +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ `; + + document.body.appendChild(modal); + + // 폼 제출 이벤트 처리 + document.getElementById('passwordChangeForm').addEventListener('submit', handlePasswordChange); + } + + // 비밀번호 변경 처리 + async function handlePasswordChange(e) { + e.preventDefault(); + + const currentPassword = document.getElementById('currentPassword').value; + const newPassword = document.getElementById('newPassword').value; + const confirmPassword = document.getElementById('confirmPassword').value; + + // 새 비밀번호 확인 + if (newPassword !== confirmPassword) { + alert('새 비밀번호가 일치하지 않습니다.'); + return; + } + + // 현재 비밀번호 확인 (localStorage 기반) + let users = JSON.parse(localStorage.getItem('work-report-users') || '[]'); + + // 기본 사용자가 없으면 생성 + if (users.length === 0) { + users = [ + { + username: 'hyungi', + full_name: '관리자', + password: 'djg3-jj34-X3Q3', + role: 'admin' + } + ]; + localStorage.setItem('work-report-users', JSON.stringify(users)); + } + + let user = users.find(u => u.username === currentUser.username); + + // 사용자가 없으면 기본값으로 생성 + if (!user) { + const username = currentUser.username; + user = { + username: username, + full_name: username === 'hyungi' ? '관리자' : username, + password: 'djg3-jj34-X3Q3', + role: username === 'hyungi' ? 'admin' : 'user' + }; + users.push(user); + localStorage.setItem('work-report-users', JSON.stringify(users)); + } + + if (user.password !== currentPassword) { + alert('현재 비밀번호가 올바르지 않습니다.'); + return; + } + + try { + // 비밀번호 변경 + user.password = newPassword; + localStorage.setItem('work-report-users', JSON.stringify(users)); + + // 현재 사용자 정보도 업데이트 + currentUser.password = newPassword; + localStorage.setItem('currentUser', JSON.stringify(currentUser)); + + showToastMessage('비밀번호가 성공적으로 변경되었습니다.'); + document.querySelector('.fixed').remove(); // 모달 닫기 + + } catch (error) { + alert('비밀번호 변경에 실패했습니다: ' + error.message); + } + } + // 토스트 메시지 표시 function showToastMessage(message, type = 'success') { const toast = document.createElement('div'); diff --git a/frontend/issue-view.html b/frontend/issue-view.html index bd090b9..945e03e 100644 --- a/frontend/issue-view.html +++ b/frontend/issue-view.html @@ -106,9 +106,9 @@ - @@ -599,6 +599,136 @@ return div; } + // 관리 버튼 클릭 처리 + function handleAdminClick() { + if (currentUser.role === 'admin') { + // 관리자: 사용자 관리 페이지로 이동 + window.location.href = 'admin.html'; + } else { + // 일반 사용자: 비밀번호 변경 모달 표시 + showPasswordChangeModal(); + } + } + + // 비밀번호 변경 모달 표시 + function showPasswordChangeModal() { + const modal = document.createElement('div'); + modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'; + modal.onclick = (e) => { + if (e.target === modal) modal.remove(); + }; + + modal.innerHTML = ` +
+
+

비밀번호 변경

+ +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ `; + + document.body.appendChild(modal); + + // 폼 제출 이벤트 처리 + document.getElementById('passwordChangeForm').addEventListener('submit', handlePasswordChange); + } + + // 비밀번호 변경 처리 + async function handlePasswordChange(e) { + e.preventDefault(); + + const currentPassword = document.getElementById('currentPassword').value; + const newPassword = document.getElementById('newPassword').value; + const confirmPassword = document.getElementById('confirmPassword').value; + + // 새 비밀번호 확인 + if (newPassword !== confirmPassword) { + alert('새 비밀번호가 일치하지 않습니다.'); + return; + } + + // 현재 비밀번호 확인 (localStorage 기반) + let users = JSON.parse(localStorage.getItem('work-report-users') || '[]'); + + // 기본 사용자가 없으면 생성 + if (users.length === 0) { + users = [ + { + username: 'hyungi', + full_name: '관리자', + password: 'djg3-jj34-X3Q3', + role: 'admin' + } + ]; + localStorage.setItem('work-report-users', JSON.stringify(users)); + } + + let user = users.find(u => u.username === currentUser.username); + + // 사용자가 없으면 기본값으로 생성 + if (!user) { + const username = currentUser.username; + user = { + username: username, + full_name: username === 'hyungi' ? '관리자' : username, + password: 'djg3-jj34-X3Q3', + role: username === 'hyungi' ? 'admin' : 'user' + }; + users.push(user); + localStorage.setItem('work-report-users', JSON.stringify(users)); + } + + if (user.password !== currentPassword) { + alert('현재 비밀번호가 올바르지 않습니다.'); + return; + } + + try { + // 비밀번호 변경 + user.password = newPassword; + localStorage.setItem('work-report-users', JSON.stringify(users)); + + // 현재 사용자 정보도 업데이트 + currentUser.password = newPassword; + localStorage.setItem('currentUser', JSON.stringify(currentUser)); + + alert('비밀번호가 성공적으로 변경되었습니다.'); + document.querySelector('.fixed').remove(); // 모달 닫기 + + } catch (error) { + alert('비밀번호 변경에 실패했습니다: ' + error.message); + } + } + // 로그아웃 함수 function logout() { localStorage.removeItem('currentUser'); diff --git a/frontend/static/js/api.js b/frontend/static/js/api.js index 844eb8b..b4678ec 100644 --- a/frontend/static/js/api.js +++ b/frontend/static/js/api.js @@ -125,6 +125,13 @@ const AuthAPI = { current_password: currentPassword, new_password: newPassword }) + }), + + resetPassword: (userId, newPassword = '000000') => apiRequest(`/auth/users/${userId}`, { + method: 'PUT', + body: JSON.stringify({ + password: newPassword + }) }) };