diff --git a/chart.html b/chart.html
deleted file mode 100644
index ef7d45e..0000000
--- a/chart.html
+++ /dev/null
@@ -1,417 +0,0 @@
-
-
-
-
-
- M-Project - 차트
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
카테고리별 분포
-
-
-
-
-
-
최근 7일 추이
-
-
-
-
-
-
-
-
전체 갤러리
-
-
-
-
-
-
-
-
-
-
-
-
-
![]()
-
-
-
-
-
-
-
diff --git a/daily-work.html b/daily-work.html
deleted file mode 100644
index 983eb09..0000000
--- a/daily-work.html
+++ /dev/null
@@ -1,378 +0,0 @@
-
-
-
-
-
- 일일 공수 입력
-
-
-
-
-
-
-
-
-
-
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/chart.html b/frontend/chart.html
deleted file mode 100644
index ef7d45e..0000000
--- a/frontend/chart.html
+++ /dev/null
@@ -1,417 +0,0 @@
-
-
-
-
-
- M-Project - 차트
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
카테고리별 분포
-
-
-
-
-
-
최근 7일 추이
-
-
-
-
-
-
-
-
전체 갤러리
-
-
-
-
-
-
-
-
-
-
-
-
-
![]()
-
-
-
-
-
-
-
diff --git a/frontend/create-project-api.html b/frontend/create-project-api.html
deleted file mode 100644
index 9525173..0000000
--- a/frontend/create-project-api.html
+++ /dev/null
@@ -1,193 +0,0 @@
-
-
-
-
-
- API 프로젝트 생성 - M Project
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/debug-data.html b/frontend/debug-data.html
deleted file mode 100644
index e77f324..0000000
--- a/frontend/debug-data.html
+++ /dev/null
@@ -1,158 +0,0 @@
-
-
-
-
-
- 데이터 디버그 - M Project
-
-
-
-
-
-
-
-
- 데이터 디버그
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/fix-api-data.html b/frontend/fix-api-data.html
deleted file mode 100644
index d8c7ed8..0000000
--- a/frontend/fix-api-data.html
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
- API 데이터 수정 - M Project
-
-
-
-
-
-
-
-
- API 데이터 수정
-
-
-
-
-
⚠️ 주의사항
-
- 이 작업은 API 데이터베이스의 모든 부적합 사항에 TKR-25009R 프로젝트 정보를 추가합니다.
- 관리자(hyungi) 계정으로 로그인한 상태에서만 실행하세요.
-
-
-
-
-
-
-
-
-
-
- 디버그 도구로 이동
-
-
-
- 메인으로 돌아가기
-
-
-
-
-
-
-
-
diff --git a/frontend/fix-project-id.html b/frontend/fix-project-id.html
deleted file mode 100644
index 53acc1e..0000000
--- a/frontend/fix-project-id.html
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
-
-
-
- 프로젝트 ID 수정 - M Project
-
-
-
-
-
-
-
-
-
diff --git a/frontend/index.html b/frontend/index.html
index 61c3186..e75024a 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -214,9 +214,9 @@
프로젝트 관리
-
+
+
@@ -502,6 +502,17 @@
}
}
+ // 관리 버튼 클릭 처리
+ function handleAdminClick() {
+ if (currentUser.role === 'admin') {
+ // 관리자: 사용자 관리 페이지로 이동
+ window.location.href = 'admin.html';
+ } else {
+ // 일반 사용자: 비밀번호 변경 모달 표시
+ showPasswordChangeModal();
+ }
+ }
+
// 섹션 전환
// URL 해시 처리
function handleUrlHash() {
@@ -593,8 +604,6 @@
// 원본 파일 크기 확인
const originalSize = file.size;
- console.log(`원본 이미지 크기: ${ImageUtils.formatFileSize(originalSize)}`);
-
// 이미지 압축
const compressedImage = await ImageUtils.compressImage(file, {
maxWidth: 1280,
@@ -602,11 +611,6 @@
quality: 0.75
});
- // 압축된 크기 확인
- const compressedSize = ImageUtils.getBase64Size(compressedImage);
- console.log(`압축된 이미지 크기: ${ImageUtils.formatFileSize(compressedSize)}`);
- console.log(`압축률: ${Math.round((1 - compressedSize/originalSize) * 100)}%`);
-
currentPhotos.push(compressedImage);
updatePhotoPreview();
}
@@ -824,7 +828,6 @@
updateProgress(90);
updateLoadingMessage('완료 처리 중...', '거의 다 되었습니다');
- console.log(`업로드 완료: ${uploadTime}ms`);
updateProgress(100);
@@ -1453,6 +1456,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');
@@ -1517,7 +1639,6 @@
// localStorage의 프로젝트별 데이터 우선 사용 (프로젝트별 분리 지원)
const dailyWorkData = JSON.parse(localStorage.getItem('daily-work-data') || '[]');
-
if (selectedProjectId) {
// 선택된 프로젝트의 일일 공수만 합계
dailyWorkData.forEach(dayWork => {
diff --git a/frontend/issue-view.html b/frontend/issue-view.html
index 1176af6..0a702f1 100644
--- a/frontend/issue-view.html
+++ b/frontend/issue-view.html
@@ -106,9 +106,9 @@
프로젝트 관리
-
+
+
@@ -317,8 +317,6 @@
}
function filterIssues() {
- console.log('필터링 시작 - 전체 이슈:', issues.length);
-
// 필터 값 가져오기
const selectedProjectId = document.getElementById('projectFilter').value;
const reviewStatusFilter = document.getElementById('reviewStatusFilter').value;
@@ -332,7 +330,6 @@
const issueProjectId = issue.project_id || issue.projectId;
return issueProjectId && (issueProjectId == selectedProjectId || issueProjectId.toString() === selectedProjectId.toString());
});
- console.log('프로젝트 필터 후:', filteredIssues.length);
}
// 검토 상태 필터 적용
@@ -341,13 +338,11 @@
const isCompleted = isReviewCompleted(issue);
return reviewStatusFilter === 'completed' ? isCompleted : !isCompleted;
});
- console.log('검토 상태 필터 후:', filteredIssues.length);
}
// 날짜 필터 적용
if (dateFilter) {
filteredIssues = filterByDate(filteredIssues, dateFilter);
- console.log('날짜 필터 후:', filteredIssues.length);
}
// 전역 변수에 필터링된 결과 저장
@@ -599,6 +594,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/migrate-data.html b/frontend/migrate-data.html
deleted file mode 100644
index 3f61b23..0000000
--- a/frontend/migrate-data.html
+++ /dev/null
@@ -1,307 +0,0 @@
-
-
-
-
-
- 데이터 마이그레이션 - M Project
-
-
-
-
-
-
-
-
- 데이터 마이그레이션
-
-
-
-
-
⚠️ 주의사항
-
- 이 작업은 기존 데이터를 "M Project"로 마이그레이션합니다.
- 관리자(hyungi) 계정으로 로그인한 상태에서만 실행하세요.
-
-
-
-
-
-
-
-
-
-
- 메인으로 돌아가기
-
-
-
-
-
-
-
-
diff --git a/frontend/static/js/api.js b/frontend/static/js/api.js
index 40bba7e..1cae9a0 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
+ })
})
};
diff --git a/index.html b/index.html
deleted file mode 100644
index e5fb7bb..0000000
--- a/index.html
+++ /dev/null
@@ -1,671 +0,0 @@
-
-
-
-
-
- 작업보고서 시스템
-
-
-
-
-
-
-
-
-
-
-
작업보고서 시스템
-
부적합 사항 관리 및 공수 계산
-
-
-
-
-
-
-
-
-
-
-
-
-
- 작업보고서
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
부적합 사항 상세
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 시간
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
작업 보고서
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file