'use client' /** * FullscreenViewer - Enhanced PDF viewer with fullscreen, zoom, and page navigation * Features: Keyboard shortcuts, zoom controls, similar documents panel */ import { useState, useEffect, useCallback } from 'react' import { X, Download, ZoomIn, ZoomOut, Maximize2, Minimize2, ChevronLeft, ChevronRight, RotateCw, FileText, Search, BookOpen, Calendar, Layers, ExternalLink, Plus } from 'lucide-react' import type { AbiturDokument } from '@/lib/education/abitur-docs-types' import { formatFileSize, formatDocumentTitle, FAECHER, NIVEAUS } from '@/lib/education/abitur-docs-types' import { ZOOM_LEVELS, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP } from '@/lib/education/abitur-archiv-types' import { AehnlicheDokumente } from './AehnlicheDokumente' interface FullscreenViewerProps { document: AbiturDokument | null onClose: () => void onAddToKlausur?: (doc: AbiturDokument) => void backendUrl?: string } export function FullscreenViewer({ document, onClose, onAddToKlausur, backendUrl = '' }: FullscreenViewerProps) { const [isFullscreen, setIsFullscreen] = useState(false) const [zoom, setZoom] = useState(100) const [currentPage, setCurrentPage] = useState(1) const [totalPages, setTotalPages] = useState(1) const [showSidebar, setShowSidebar] = useState(true) const [activeTab, setActiveTab] = useState<'details' | 'similar'>('details') // Reset state when document changes useEffect(() => { setZoom(100) setCurrentPage(1) setIsFullscreen(false) }, [document?.id]) // Keyboard shortcuts useEffect(() => { if (!document) return const handleKeyDown = (e: KeyboardEvent) => { // Ignore if typing in an input if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) { return } switch (e.key) { case 'Escape': if (isFullscreen) { setIsFullscreen(false) } else { onClose() } break case 'f': case 'F11': e.preventDefault() setIsFullscreen(prev => !prev) break case '+': case '=': e.preventDefault() setZoom(z => Math.min(MAX_ZOOM, z + ZOOM_STEP)) break case '-': e.preventDefault() setZoom(z => Math.max(MIN_ZOOM, z - ZOOM_STEP)) break case '0': e.preventDefault() setZoom(100) break case 'ArrowLeft': e.preventDefault() setCurrentPage(p => Math.max(1, p - 1)) break case 'ArrowRight': e.preventDefault() setCurrentPage(p => Math.min(totalPages, p + 1)) break case 's': if (e.ctrlKey || e.metaKey) { e.preventDefault() handleDownload() } break } } window.addEventListener('keydown', handleKeyDown) return () => window.removeEventListener('keydown', handleKeyDown) }, [document, isFullscreen, totalPages, onClose]) // Handle native fullscreen changes useEffect(() => { const handleFullscreenChange = () => { setIsFullscreen(!!window.document.fullscreenElement) } window.document.addEventListener('fullscreenchange', handleFullscreenChange) return () => window.document.removeEventListener('fullscreenchange', handleFullscreenChange) }, []) const handleDownload = useCallback(() => { if (!document) return const link = window.document.createElement('a') link.href = pdfUrl link.download = document.dateiname link.click() }, [document]) const handleSearchInRAG = () => { if (!document) return window.location.href = `/education/edu-search?doc=${document.id}&search=1` } const handleAddToKlausur = () => { if (!document || !onAddToKlausur) return onAddToKlausur(document) } if (!document) return null const fachLabel = FAECHER.find(f => f.id === document.fach)?.label || document.fach const niveauLabel = NIVEAUS.find(n => n.id === document.niveau)?.label || document.niveau // Build PDF URL const pdfUrl = backendUrl ? `${backendUrl}/api/abitur-docs/${document.id}/file` : document.file_path return (
{/* Modal Container */}
{/* Header */}

{formatDocumentTitle(document)}

{document.dateiname}

{/* Toolbar */}
{/* Zoom Controls */}
{zoom}%
{/* Page Navigation */} {totalPages > 1 && (
{currentPage} / {totalPages}
)}
{/* Action Buttons */} {onAddToKlausur && ( )}
{/* Content */}
{/* PDF Viewer */}
100 ? 'none' : '100%' }} >