import { useState, useEffect } from 'react'; import { IoIosDownload } from 'react-icons/io'; import { Popup, PopupAction } from '../UiComponents/Popup/Popup'; import { useLanguage } from '../../providers/language/LanguageContext'; import { PdfRenderer, PdfJsRenderer, LoadingRenderer, ErrorRenderer } from './renderers'; import styles from './ContentPreview.module.css'; export interface UrlContentPreviewProps { isOpen: boolean; onClose: () => void; url: string; fileName: string; mimeType?: string; } export function UrlContentPreview({ isOpen, onClose, url, fileName, mimeType = 'application/pdf' }: UrlContentPreviewProps) { const { t } = useLanguage(); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [hasLoaded, setHasLoaded] = useState(false); const [warning, setWarning] = useState(null); const [showPdfAnyway, setShowPdfAnyway] = useState(false); const [usePdfJs, setUsePdfJs] = useState(false); // Reset state when modal opens/closes useEffect(() => { if (isOpen && url) { setIsLoading(true); setError(null); setWarning(null); setHasLoaded(false); setShowPdfAnyway(false); setUsePdfJs(false); // Start with iframe } else { setIsLoading(false); setError(null); setWarning(null); setHasLoaded(false); setShowPdfAnyway(false); setUsePdfJs(false); } }, [isOpen, url]); const handleDownload = () => { try { const link = document.createElement('a'); link.href = url; link.download = fileName; link.target = '_blank'; link.rel = 'noopener noreferrer'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } catch (err) { console.error('Failed to download file:', err); // Fallback: open in new tab window.open(url, '_blank', 'noopener,noreferrer'); } }; const handlePdfLoad = () => { setIsLoading(false); setHasLoaded(true); setError(null); }; const handlePdfError = () => { // Try PDF.js as fallback instead of showing error immediately if (!usePdfJs) { console.log('Iframe failed, switching to PDF.js fallback'); setUsePdfJs(true); setIsLoading(true); // Restart loading with PDF.js setError(null); setWarning(null); return; } // If PDF.js also fails, show error setIsLoading(false); setError('Failed to load PDF. This might be due to CORS restrictions. You can try downloading the file or opening it in a new tab.'); setShowPdfAnyway(true); }; const handleOpenInNewTab = () => { window.open(url, '_blank', 'noopener,noreferrer'); }; // Set up progressive timeout for loading (schnellerer Fallback) useEffect(() => { if (isOpen && isLoading && !hasLoaded) { // Schnellerer Timeout für externe PDFs: Warning after 3s, Error after 5s const QUICK_TIMEOUT = 5000; // 5 Sekunden const WARNING_TIMEOUT = 3000; // 3 Sekunden Warnung const warningTimeout = setTimeout(() => { if (isLoading && !hasLoaded) { setWarning('PDF lädt langsam. Sie können es auch direkt herunterladen oder in einem neuen Tab öffnen.'); // Don't set isLoading to false - let it continue } }, WARNING_TIMEOUT); const errorTimeout = setTimeout(() => { if (isLoading && !hasLoaded && !usePdfJs) { // Try PDF.js as fallback after 5 seconds console.log('PDF loading timeout, switching to PDF.js fallback'); setUsePdfJs(true); setIsLoading(true); // Restart loading with PDF.js setWarning('PDF lädt langsam. Versuche alternative Anzeigemethode...'); } else if (isLoading && !hasLoaded && usePdfJs) { // PDF.js also failed, show error setShowPdfAnyway(true); setError('PDF lädt langsam. Bitte verwenden Sie den Download-Button oder öffnen Sie es in einem neuen Tab.'); setIsLoading(false); } }, QUICK_TIMEOUT); return () => { clearTimeout(warningTimeout); clearTimeout(errorTimeout); }; } }, [isOpen, isLoading, hasLoaded, usePdfJs]); // Validate URL useEffect(() => { if (isOpen && url) { try { new URL(url); } catch (e) { setError('Invalid URL'); setIsLoading(false); } } }, [isOpen, url]); // Create action buttons for the popup header const actions: PopupAction[] = [ { label: String(''), icon: , onClick: handleDownload, disabled: false, variant: 'success' as const } ]; const renderPreview = () => { // Show warning but continue loading const showWarning = warning && !error; // For PDF files, always try to show PDF (even if there's an error) if (mimeType === 'application/pdf' && (hasLoaded || showPdfAnyway || !error)) { return (
{showWarning && (
⚠️ {warning}
)} {error && (
⚠️ {error}
)}
); } // Show error only if we're not showing PDF anyway if (error && !showPdfAnyway) { return (
⚠️

{error}

); } if (isLoading && !hasLoaded && !showPdfAnyway) { return (
{warning && (
⚠️ {warning}
)}
); } // For other file types, show unsupported message if (mimeType !== 'application/pdf') { return (
📄
{fileName}

Preview not supported for this file type. Please download the file to view it.

); } return null; }; return (
{renderPreview()}
); } export default UrlContentPreview;