✨ 주요 개선사항: - PDF API 500 에러 수정 (한글 파일명 UTF-8 인코딩 처리) - PDF 뷰어 기능 완전 구현 (PDF.js 통합, 네비게이션, 확대/축소) - 서적별 문서 그룹화 UI 데본씽크 스타일로 개선 - PDF Manager 페이지 서적별 보기 기능 추가 - Alpine.js 로드 순서 최적화로 JavaScript 에러 해결 🎨 UI/UX 개선: - 확장/축소 가능한 아코디언 스타일 서적 목록 - 간결하고 직관적인 데본씽크 스타일 인터페이스 - PDF 상태 표시 (HTML 연결, 서적 분류) - 반응형 디자인 및 부드러운 애니메이션 🔧 기술적 개선: - PDF.js 워커 설정 및 토큰 인증 처리 - 서적별 PDF 자동 그룹화 로직 - Alpine.js 컴포넌트 초기화 최적화
161 lines
8.5 KiB
HTML
161 lines
8.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>서적 문서 목록 - Document Server</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
|
|
|
<style>
|
|
.line-clamp-2 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
.line-clamp-3 {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 3;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-50 min-h-screen" x-data="bookDocumentsApp()">
|
|
<!-- 헤더 -->
|
|
<div id="header-container"></div>
|
|
|
|
<!-- 메인 컨텐츠 -->
|
|
<main class="container mx-auto px-4 py-8">
|
|
<!-- 뒤로가기 및 서적 정보 -->
|
|
<div class="mb-6">
|
|
<!-- 네비게이션 -->
|
|
<div class="flex items-center justify-between mb-4">
|
|
<button @click="goBack()"
|
|
class="flex items-center px-3 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors">
|
|
<i class="fas fa-arrow-left mr-2"></i>
|
|
<span>뒤로</span>
|
|
</button>
|
|
|
|
<button @click="openBookEditor()"
|
|
class="flex items-center px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors text-sm">
|
|
<i class="fas fa-edit mr-2"></i>편집
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 서적 정보 (간결한 스타일) -->
|
|
<div class="bg-white rounded-lg border border-gray-200 p-4">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center space-x-3">
|
|
<div class="w-12 h-12 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-lg flex items-center justify-center">
|
|
<i class="fas fa-book text-white"></i>
|
|
</div>
|
|
<div>
|
|
<h1 class="text-xl font-semibold text-gray-900" x-text="bookInfo.title || '서적 미분류'"></h1>
|
|
<div class="flex items-center space-x-2 text-sm text-gray-500">
|
|
<span x-show="bookInfo.author" x-text="bookInfo.author"></span>
|
|
<span x-show="bookInfo.author" class="text-gray-300">•</span>
|
|
<span x-text="documents.length + '개 문서'"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 설명 (있을 때만 표시) -->
|
|
<div x-show="bookInfo.description" class="mt-3 pt-3 border-t border-gray-100">
|
|
<p class="text-sm text-gray-600" x-text="bookInfo.description"></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 문서 목록 -->
|
|
<div class="bg-white rounded-lg border border-gray-200">
|
|
<div class="px-4 py-3 border-b border-gray-100">
|
|
<h2 class="font-medium text-gray-900">문서 목록</h2>
|
|
</div>
|
|
|
|
<!-- 로딩 상태 -->
|
|
<div x-show="loading" class="p-8 text-center">
|
|
<i class="fas fa-spinner fa-spin text-2xl text-gray-400 mb-2"></i>
|
|
<p class="text-gray-500">문서를 불러오는 중...</p>
|
|
</div>
|
|
|
|
<!-- 문서 목록 (데본씽크 스타일) -->
|
|
<div x-show="!loading && documents.length > 0" class="divide-y divide-gray-100">
|
|
<template x-for="doc in documents" :key="doc.id">
|
|
<div class="p-4 hover:bg-gray-50 cursor-pointer transition-colors group"
|
|
@click="openDocument(doc.id)">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center space-x-3 flex-1">
|
|
<!-- 문서 타입 아이콘 -->
|
|
<div class="w-10 h-10 rounded-lg flex items-center justify-center"
|
|
:class="doc.pdf_path ? 'bg-red-100 text-red-600' : 'bg-blue-100 text-blue-600'">
|
|
<i :class="doc.pdf_path ? 'fas fa-file-pdf' : 'fas fa-file-alt'" class="text-sm"></i>
|
|
</div>
|
|
|
|
<!-- 문서 정보 -->
|
|
<div class="flex-1 min-w-0">
|
|
<div class="flex items-center space-x-2 mb-1">
|
|
<h3 class="font-medium text-gray-900 truncate" x-text="doc.title"></h3>
|
|
<!-- PDF 연결 상태 표시 -->
|
|
<span x-show="doc.pdf_path"
|
|
class="px-2 py-0.5 bg-red-100 text-red-700 text-xs rounded-full">
|
|
PDF
|
|
</span>
|
|
</div>
|
|
|
|
<p class="text-sm text-gray-500 truncate mb-1" x-text="doc.description || '설명이 없습니다'"></p>
|
|
|
|
<!-- 메타 정보 -->
|
|
<div class="flex items-center space-x-3 text-xs text-gray-400">
|
|
<span x-text="formatDate(doc.created_at)"></span>
|
|
<span x-show="doc.uploader_name" x-text="doc.uploader_name"></span>
|
|
<!-- 태그 표시 (간단하게) -->
|
|
<span x-show="doc.tags && doc.tags.length > 0"
|
|
class="flex items-center">
|
|
<i class="fas fa-tags mr-1"></i>
|
|
<span x-text="doc.tags.length + '개 태그'"></span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 액션 버튼들 -->
|
|
<div class="flex items-center space-x-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
<button @click.stop="editDocument(doc)"
|
|
class="p-2 text-gray-400 hover:text-blue-600 transition-colors rounded-md hover:bg-blue-50"
|
|
title="문서 수정">
|
|
<i class="fas fa-edit text-sm"></i>
|
|
</button>
|
|
<button x-show="currentUser && currentUser.is_admin"
|
|
@click.stop="deleteDocument(doc.id)"
|
|
class="p-2 text-gray-400 hover:text-red-600 transition-colors rounded-md hover:bg-red-50"
|
|
title="문서 삭제">
|
|
<i class="fas fa-trash text-sm"></i>
|
|
</button>
|
|
<i class="fas fa-chevron-right text-gray-300 ml-2"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<!-- 빈 상태 -->
|
|
<div x-show="!loading && documents.length === 0" class="p-8 text-center">
|
|
<i class="fas fa-file-alt text-gray-400 text-4xl mb-4"></i>
|
|
<h3 class="text-lg font-medium text-gray-900 mb-2">문서가 없습니다</h3>
|
|
<p class="text-gray-500">이 서적에 등록된 문서가 없습니다</p>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- JavaScript 파일들 -->
|
|
<script src="/static/js/api.js?v=2025012384"></script>
|
|
<script src="/static/js/auth.js?v=2025012351"></script>
|
|
<script src="/static/js/header-loader.js?v=2025012351"></script>
|
|
<script src="/static/js/book-documents.js?v=2025012401"></script>
|
|
</body>
|
|
</html>
|