Files
document-server/frontend/pdf-manager.html
Hyungi Ahn f221a5611c 전체 페이지 헤더 여백 통일 및 z-index 충돌 해결
주요 변경사항:
- story-reader.html: pt-4 → pt-20
- pdf-manager.html: py-8 → pt-20 pb-8
- upload.html: py-8 → pt-20 pb-8
- index.html: py-8 → pt-20 pb-8
- search.html: py-8 → pt-20 pb-8
- memo-tree.html: pt-16 → pt-20
- notebooks.html: py-8 → pt-20 pb-8
- notes.html: py-8 → pt-20 pb-8

헤더(h-16, z-50)와의 충돌을 방지하기 위해 모든 페이지의 상단 여백을 pt-20(80px)으로 통일
2025-09-04 10:25:57 +09:00

317 lines
18 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF 파일 관리 - 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;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen" x-data="pdfManagerApp()">
<!-- 헤더 -->
<div id="header-container"></div>
<!-- 메인 컨텐츠 -->
<main class="container mx-auto px-4 pt-20 pb-8">
<!-- 페이지 헤더 -->
<div class="mb-8">
<div class="flex items-center justify-between mb-4">
<div>
<h1 class="text-3xl font-bold text-gray-900">PDF 파일 관리</h1>
<p class="text-gray-600 mt-2">업로드된 PDF 파일들을 관리하고 삭제할 수 있습니다</p>
</div>
<button @click="refreshPDFs()"
:disabled="loading"
class="flex items-center px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white rounded-lg transition-colors">
<i class="fas fa-sync-alt mr-2" :class="{'fa-spin': loading}"></i>
<span>새로고침</span>
</button>
</div>
</div>
<!-- 통계 카드 -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="bg-white rounded-lg shadow-sm border p-6">
<div class="flex items-center">
<div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-file-pdf text-red-600 text-xl"></i>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-900">전체 PDF</h3>
<p class="text-2xl font-bold text-red-600" x-text="pdfDocuments.length"></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border p-6">
<div class="flex items-center">
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-book text-blue-600 text-xl"></i>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-900">서적 포함</h3>
<p class="text-2xl font-bold text-blue-600" x-text="bookPDFs"></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border p-6">
<div class="flex items-center">
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-link text-green-600 text-xl"></i>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-900">HTML 연결</h3>
<p class="text-2xl font-bold text-green-600" x-text="linkedPDFs"></p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border p-6">
<div class="flex items-center">
<div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-unlink text-yellow-600 text-xl"></i>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-900">독립 파일</h3>
<p class="text-2xl font-bold text-yellow-600" x-text="standalonePDFs"></p>
</div>
</div>
</div>
</div>
<!-- PDF 목록 -->
<div class="bg-white rounded-lg shadow-sm border">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold text-gray-900">PDF 파일 목록</h2>
<!-- 필터 버튼 -->
<div class="flex flex-wrap gap-2">
<button @click="filterType = 'all'"
:class="filterType === 'all' ? 'bg-gray-600 text-white' : 'bg-gray-200 text-gray-700'"
class="px-3 py-1.5 rounded-lg text-sm transition-colors">
전체
</button>
<button @click="filterType = 'book'"
:class="filterType === 'book' ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-700'"
class="px-3 py-1.5 rounded-lg text-sm transition-colors">
서적 포함
</button>
<button @click="filterType = 'linked'"
:class="filterType === 'linked' ? 'bg-green-600 text-white' : 'bg-gray-200 text-gray-700'"
class="px-3 py-1.5 rounded-lg text-sm transition-colors">
HTML 연결
</button>
<button @click="filterType = 'standalone'"
:class="filterType === 'standalone' ? 'bg-yellow-600 text-white' : 'bg-gray-200 text-gray-700'"
class="px-3 py-1.5 rounded-lg text-sm transition-colors">
독립 파일
</button>
</div>
</div>
</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">PDF 파일을 불러오는 중...</p>
</div>
<!-- PDF 목록 -->
<div x-show="!loading && filteredPDFs.length > 0" class="divide-y divide-gray-200">
<template x-for="pdf in filteredPDFs" :key="pdf.id">
<div class="p-6 hover:bg-gray-50 transition-colors">
<div class="flex items-start justify-between">
<div class="flex items-start space-x-4 flex-1">
<!-- PDF 아이콘 -->
<div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center flex-shrink-0">
<i class="fas fa-file-pdf text-red-600 text-xl"></i>
</div>
<!-- PDF 정보 -->
<div class="flex-1 min-w-0">
<h3 class="text-lg font-semibold text-gray-900 mb-1" x-text="pdf.title"></h3>
<p class="text-sm text-gray-500 mb-2" x-text="pdf.original_filename"></p>
<p class="text-sm text-gray-600 line-clamp-2" x-text="pdf.description || '설명이 없습니다'"></p>
<!-- 서적 정보 및 연결 상태 -->
<div class="mt-3 space-y-2">
<!-- 서적 정보 -->
<div x-show="pdf.book_title" class="flex items-center space-x-2">
<span class="inline-flex items-center px-3 py-1 bg-blue-100 text-blue-800 text-sm rounded-full">
<i class="fas fa-book mr-1"></i>
<span x-text="pdf.book_title"></span>
</span>
<span x-show="pdf.isLinked" class="inline-flex items-center px-2 py-1 bg-green-100 text-green-800 text-xs rounded-full">
<i class="fas fa-link mr-1"></i>
HTML 연결됨
</span>
</div>
<!-- 서적 없는 경우 -->
<div x-show="!pdf.book_title" class="flex items-center space-x-2">
<span class="inline-flex items-center px-3 py-1 bg-gray-100 text-gray-600 text-sm rounded-full">
<i class="fas fa-file mr-1"></i>
서적 미분류
</span>
<span x-show="pdf.isLinked" class="inline-flex items-center px-2 py-1 bg-green-100 text-green-800 text-xs rounded-full">
<i class="fas fa-link mr-1"></i>
HTML 연결됨
</span>
<span x-show="!pdf.isLinked" class="inline-flex items-center px-2 py-1 bg-yellow-100 text-yellow-800 text-xs rounded-full">
<i class="fas fa-unlink mr-1"></i>
독립 파일
</span>
</div>
<!-- 업로드 날짜 -->
<div class="flex items-center space-x-4">
<span class="text-sm text-gray-500">
<i class="fas fa-calendar mr-1"></i>
<span x-text="formatDate(pdf.created_at)"></span>
</span>
<span x-show="pdf.uploaded_by" class="text-sm text-gray-500">
<i class="fas fa-user mr-1"></i>
<span x-text="pdf.uploaded_by"></span>
</span>
</div>
</div>
</div>
</div>
<!-- 액션 버튼 -->
<div class="flex items-center space-x-2 ml-4">
<button @click="previewPDF(pdf)"
class="p-2 text-gray-400 hover:text-green-600 transition-colors"
title="PDF 미리보기">
<i class="fas fa-eye"></i>
</button>
<button @click="downloadPDF(pdf)"
class="p-2 text-gray-400 hover:text-blue-600 transition-colors"
title="PDF 다운로드">
<i class="fas fa-download"></i>
</button>
<button x-show="currentUser && currentUser.is_admin"
@click="deletePDF(pdf)"
class="p-2 text-gray-400 hover:text-red-600 transition-colors"
title="PDF 삭제">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
</template>
</div>
<!-- 빈 상태 -->
<div x-show="!loading && filteredPDFs.length === 0" class="p-8 text-center">
<i class="fas fa-file-pdf text-gray-400 text-4xl mb-4"></i>
<h3 class="text-lg font-medium text-gray-900 mb-2">PDF 파일이 없습니다</h3>
<p class="text-gray-500">
<span x-show="filterType === 'all'">업로드된 PDF 파일이 없습니다</span>
<span x-show="filterType === 'book'">서적에 포함된 PDF 파일이 없습니다</span>
<span x-show="filterType === 'linked'">HTML과 연결된 PDF 파일이 없습니다</span>
<span x-show="filterType === 'standalone'">독립 PDF 파일이 없습니다</span>
</p>
</div>
</div>
</main>
<!-- PDF 미리보기 모달 -->
<div x-show="showPreviewModal"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
@click.self="closePreview()">
<div class="bg-white rounded-2xl shadow-2xl max-w-6xl w-full max-h-[90vh] overflow-hidden">
<!-- 헤더 -->
<div class="flex items-center justify-between p-6 border-b border-gray-200">
<div class="flex items-center space-x-3">
<i class="fas fa-file-pdf text-red-600 text-xl"></i>
<div>
<h3 class="text-xl font-bold text-gray-900" x-text="previewPdf?.title"></h3>
<p class="text-sm text-gray-500" x-text="previewPdf?.original_filename"></p>
</div>
</div>
<div class="flex items-center space-x-2">
<button @click="downloadPDF(previewPdf)"
class="px-3 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center space-x-2">
<i class="fas fa-download"></i>
<span>다운로드</span>
</button>
<button @click="closePreview()"
class="text-gray-400 hover:text-gray-600 transition-colors">
<i class="fas fa-times text-xl"></i>
</button>
</div>
</div>
<!-- PDF 뷰어 -->
<div class="p-6 overflow-y-auto" style="max-height: calc(90vh - 120px);">
<!-- PDF 미리보기 -->
<div x-show="previewPdf" class="mb-4">
<!-- PDF 뷰어 컨테이너 -->
<div class="border rounded-lg overflow-hidden bg-gray-100 relative" style="height: 600px;">
<!-- PDF iframe 뷰어 -->
<iframe x-show="!pdfPreviewError && !pdfPreviewLoading && pdfPreviewSrc"
class="w-full h-full border-0"
:src="pdfPreviewSrc"
@load="pdfPreviewLoaded = true"
@error="handlePdfPreviewError()">
</iframe>
<!-- PDF 로딩 상태 -->
<div x-show="pdfPreviewLoading" class="flex items-center justify-center h-full">
<div class="text-center">
<i class="fas fa-spinner fa-spin text-3xl text-gray-500 mb-4"></i>
<p class="text-gray-600 text-lg">PDF를 로드하는 중...</p>
</div>
</div>
<!-- PDF 에러 상태 -->
<div x-show="pdfPreviewError" class="flex items-center justify-center h-full text-gray-500">
<div class="text-center">
<i class="fas fa-exclamation-triangle text-3xl mb-4 text-red-500"></i>
<p class="text-lg mb-4">PDF를 로드할 수 없습니다</p>
<button @click="retryPdfPreview()"
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 mr-2">
다시 시도
</button>
<button @click="downloadPDF(previewPdf)"
class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700">
파일 다운로드
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 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/pdf-manager.js?v=2025012627"></script>
</body>
</html>