Major UI overhaul and upload system improvements

- Removed hierarchy view and integrated functionality into index.html
- Added book-based document grouping with dedicated book-documents.html page
- Implemented comprehensive multi-file upload system with drag-and-drop reordering
- Added HTML-PDF matching functionality with download capability
- Enhanced upload workflow with 3-step process (File Selection, Book Settings, Order & Match)
- Added book conflict resolution (existing book vs new edition)
- Improved document order adjustment with one-click sort options
- Added modular header component system
- Updated API connectivity for Docker environment
- Enhanced viewer.html with PDF download functionality
- Fixed browser caching issues with version management
- Improved mobile responsiveness and modern UI design
This commit is contained in:
Hyungi Ahn
2025-08-25 15:58:30 +09:00
parent f95f67364a
commit 4038040faa
21 changed files with 3875 additions and 2603 deletions

View File

@@ -3,6 +3,8 @@ window.documentApp = () => ({
// 상태 관리
documents: [],
filteredDocuments: [],
groupedDocuments: [],
expandedBooks: [],
loading: false,
error: '',
@@ -17,20 +19,34 @@ window.documentApp = () => ({
availableTags: [],
// UI 상태
viewMode: 'grid', // 'grid' 또는 'list'
viewMode: 'grid', // 'grid' 또는 'books'
user: null, // currentUser의 별칭
tags: [], // availableTags의 별칭
// 모달 상태
showUploadModal: false,
// 로그인 관련 함수들
openLoginModal() {
this.showLoginModal = true;
},
// 초기화
async init() {
await this.checkAuthStatus();
if (this.isAuthenticated) {
await this.loadDocuments();
} else {
// 로그인하지 않은 경우에도 빈 배열로 초기화
this.groupedDocuments = [];
}
this.setupEventListeners();
// 커스텀 이벤트 리스너 등록
document.addEventListener('open-login-modal', () => {
console.log('📨 open-login-modal 이벤트 수신 (index.html)');
this.openLoginModal();
});
},
// 인증 상태 확인
@@ -162,6 +178,7 @@ window.documentApp = () => ({
}
this.filteredDocuments = filtered;
this.groupDocumentsByBook();
},
// 검색어 변경 시
@@ -169,6 +186,59 @@ window.documentApp = () => ({
this.filterDocuments();
},
// 필터 초기화
clearFilters() {
this.searchQuery = '';
this.selectedTag = '';
this.filterDocuments();
},
// 서적별 그룹화
groupDocumentsByBook() {
if (!this.filteredDocuments || this.filteredDocuments.length === 0) {
this.groupedDocuments = [];
return;
}
const grouped = {};
this.filteredDocuments.forEach(doc => {
const bookKey = doc.book_id || 'no-book';
if (!grouped[bookKey]) {
grouped[bookKey] = {
book: doc.book_id ? {
id: doc.book_id,
title: doc.book_title,
author: doc.book_author
} : null,
documents: []
};
}
grouped[bookKey].documents.push(doc);
});
// 배열로 변환하고 정렬 (서적 있는 것 먼저, 그 다음 서적명 순)
this.groupedDocuments = Object.values(grouped).sort((a, b) => {
if (!a.book && b.book) return 1;
if (a.book && !b.book) return -1;
if (!a.book && !b.book) return 0;
return a.book.title.localeCompare(b.book.title);
});
// 기본적으로 모든 서적을 펼친 상태로 설정
this.expandedBooks = this.groupedDocuments.map(group => group.book?.id || 'no-book');
},
// 서적 펼침/접힘 토글
toggleBookExpansion(bookId) {
const index = this.expandedBooks.indexOf(bookId);
if (index > -1) {
this.expandedBooks.splice(index, 1);
} else {
this.expandedBooks.push(bookId);
}
},
// 문서 검색 (HTML에서 사용)
searchDocuments() {
this.filterDocuments();
@@ -204,7 +274,29 @@ window.documentApp = () => ({
// 문서 보기
viewDocument(documentId) {
window.open(`/viewer.html?id=${documentId}`, '_blank');
// 현재 페이지 정보를 세션 스토리지에 저장
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
sessionStorage.setItem('previousPage', currentPage);
// from 파라미터 추가
const fromParam = currentPage === 'hierarchy.html' ? 'hierarchy' : 'index';
window.open(`/viewer.html?id=${documentId}&from=${fromParam}`, '_blank');
},
// 서적의 문서들 보기
openBookDocuments(book) {
if (book && book.id) {
// 서적 ID를 URL 파라미터로 전달하여 해당 서적의 문서들만 표시
window.location.href = `book-documents.html?bookId=${book.id}`;
} else {
// 서적 미분류 문서들 보기
window.location.href = `book-documents.html?bookId=none`;
}
},
// 업로드 페이지 열기
openUploadPage() {
window.location.href = 'upload.html';
},
// 문서 열기 (HTML에서 사용)