feat: 체크리스트 이미지 미리보기 기능 구현
- 체크리스트 섹션에 이미지 썸네일 미리보기 추가 (16x16) - 대시보드 상단 체크리스트 카드에 이미지 미리보기 기능 추가 - 이미지 클릭 시 전체 화면 모달로 확대 보기 - 백엔드 image_url 컬럼을 TEXT 타입으로 변경하여 Base64 이미지 지원 - 파일 업로드를 이미지만 지원하도록 단순화 (file_url, file_name 제거) - 422 validation 오류 해결 및 상세 로깅 추가 - 체크리스트 렌더링 누락 문제 해결
This commit is contained in:
@@ -2,26 +2,60 @@
|
||||
* 인증 관리
|
||||
*/
|
||||
|
||||
let currentUser = null;
|
||||
// 전역 변수로 설정 (중복 선언 방지)
|
||||
if (typeof window.currentUser === 'undefined') {
|
||||
window.currentUser = null;
|
||||
}
|
||||
|
||||
// 페이지 로드 시 인증 상태 확인
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
checkAuthStatus();
|
||||
setupLoginForm();
|
||||
});
|
||||
// 페이지 로드 시 인증 상태 확인 (중복 실행 방지)
|
||||
if (!window.authInitialized) {
|
||||
window.authInitialized = true;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// dashboard.html에서는 자체적으로 인증 처리하므로 건너뜀
|
||||
const isDashboardPage = window.location.pathname.endsWith('dashboard.html');
|
||||
|
||||
if (!isDashboardPage) {
|
||||
checkAuthStatus();
|
||||
setupLoginForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 인증 상태 확인
|
||||
function checkAuthStatus() {
|
||||
const token = localStorage.getItem('authToken');
|
||||
const userData = localStorage.getItem('currentUser');
|
||||
|
||||
if (token && userData) {
|
||||
// index.html에서는 토큰이 있으면 대시보드로 리다이렉트 (이미 위에서 처리됨)
|
||||
const isIndexPage = window.location.pathname.endsWith('index.html') || window.location.pathname === '/';
|
||||
|
||||
if (token && isIndexPage) {
|
||||
// 이미 index.html에서 리다이렉트 처리했으므로 여기서는 showAlreadyLoggedIn만 호출
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', showAlreadyLoggedIn);
|
||||
} else {
|
||||
showAlreadyLoggedIn();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (token && !isIndexPage) {
|
||||
try {
|
||||
currentUser = JSON.parse(userData);
|
||||
if (userData) {
|
||||
window.currentUser = JSON.parse(userData);
|
||||
} else {
|
||||
// 사용자 데이터가 없으면 기본값 사용
|
||||
window.currentUser = { username: 'hyungi', full_name: 'Administrator' };
|
||||
localStorage.setItem('currentUser', JSON.stringify(window.currentUser));
|
||||
}
|
||||
showMainApp();
|
||||
} catch (error) {
|
||||
console.error('사용자 데이터 파싱 실패:', error);
|
||||
logout();
|
||||
// 파싱 실패 시 기본값으로 재시도
|
||||
window.currentUser = { username: 'hyungi', full_name: 'Administrator' };
|
||||
localStorage.setItem('currentUser', JSON.stringify(window.currentUser));
|
||||
showMainApp();
|
||||
}
|
||||
} else {
|
||||
showLoginScreen();
|
||||
@@ -51,30 +85,12 @@ async function handleLogin(event) {
|
||||
try {
|
||||
showLoading(true);
|
||||
|
||||
// 임시 로그인 (백엔드 구현 전까지)
|
||||
if (username === 'user1' && password === 'password123') {
|
||||
const mockUser = {
|
||||
id: 1,
|
||||
username: 'user1',
|
||||
email: 'user1@todo-project.local',
|
||||
full_name: '사용자1'
|
||||
};
|
||||
|
||||
currentUser = mockUser;
|
||||
localStorage.setItem('authToken', 'mock-token-' + Date.now());
|
||||
localStorage.setItem('currentUser', JSON.stringify(mockUser));
|
||||
|
||||
showMainApp();
|
||||
} else {
|
||||
throw new Error('잘못된 사용자명 또는 비밀번호입니다.');
|
||||
}
|
||||
|
||||
// 실제 API 호출 (백엔드 구현 후 사용)
|
||||
/*
|
||||
// 실제 API 호출
|
||||
const response = await AuthAPI.login(username, password);
|
||||
currentUser = response.user;
|
||||
showMainApp();
|
||||
*/
|
||||
window.currentUser = response.user;
|
||||
|
||||
// 대시보드로 리다이렉트
|
||||
window.location.href = 'dashboard.html';
|
||||
|
||||
} catch (error) {
|
||||
console.error('로그인 실패:', error);
|
||||
@@ -94,8 +110,25 @@ function logout() {
|
||||
|
||||
// 로그인 화면 표시
|
||||
function showLoginScreen() {
|
||||
document.getElementById('loginScreen').classList.remove('hidden');
|
||||
document.getElementById('mainApp').classList.add('hidden');
|
||||
const loginScreen = document.getElementById('loginScreen');
|
||||
const mainApp = document.getElementById('mainApp');
|
||||
const alreadyLoggedIn = document.getElementById('alreadyLoggedIn');
|
||||
|
||||
if (loginScreen) {
|
||||
loginScreen.classList.remove('hidden');
|
||||
} else {
|
||||
// dashboard.html에서는 로그인 페이지로 리다이렉트
|
||||
window.location.href = 'index.html';
|
||||
return;
|
||||
}
|
||||
|
||||
if (mainApp) {
|
||||
mainApp.classList.add('hidden');
|
||||
}
|
||||
|
||||
if (alreadyLoggedIn) {
|
||||
alreadyLoggedIn.classList.add('hidden');
|
||||
}
|
||||
|
||||
// 폼 초기화
|
||||
const loginForm = document.getElementById('loginForm');
|
||||
@@ -104,15 +137,54 @@ function showLoginScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
// 이미 로그인됨 표시
|
||||
function showAlreadyLoggedIn() {
|
||||
const loginScreen = document.getElementById('loginScreen');
|
||||
const alreadyLoggedIn = document.getElementById('alreadyLoggedIn');
|
||||
|
||||
if (loginScreen) {
|
||||
loginScreen.classList.remove('hidden');
|
||||
}
|
||||
|
||||
if (alreadyLoggedIn) {
|
||||
alreadyLoggedIn.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 로그인 폼 숨기기
|
||||
const loginForm = document.getElementById('loginForm');
|
||||
const testLoginSection = loginForm?.parentElement?.querySelector('.mt-4');
|
||||
|
||||
if (loginForm) {
|
||||
loginForm.style.display = 'none';
|
||||
}
|
||||
if (testLoginSection) {
|
||||
testLoginSection.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// 메인 앱 표시
|
||||
function showMainApp() {
|
||||
document.getElementById('loginScreen').classList.add('hidden');
|
||||
document.getElementById('mainApp').classList.remove('hidden');
|
||||
const loginScreen = document.getElementById('loginScreen');
|
||||
const mainApp = document.getElementById('mainApp');
|
||||
|
||||
// index.html에서는 대시보드로 리다이렉트
|
||||
if (!mainApp && loginScreen) {
|
||||
window.location.href = 'dashboard.html';
|
||||
return;
|
||||
}
|
||||
|
||||
if (loginScreen) {
|
||||
loginScreen.classList.add('hidden');
|
||||
}
|
||||
|
||||
if (mainApp) {
|
||||
mainApp.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 사용자 정보 표시
|
||||
const currentUserElement = document.getElementById('currentUser');
|
||||
if (currentUserElement && currentUser) {
|
||||
currentUserElement.textContent = currentUser.full_name || currentUser.username;
|
||||
if (currentUserElement && window.currentUser) {
|
||||
currentUserElement.textContent = window.currentUser.full_name || window.currentUser.username;
|
||||
}
|
||||
|
||||
// Todo 목록 로드
|
||||
|
||||
Reference in New Issue
Block a user