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
+ })
})
};