import { useEffect, useMemo, useRef, useState } from 'react'; import { renderAsync } from 'docx-preview'; import { useLanguage } from '../../../providers/language/LanguageContext'; import styles from '../ContentPreview.module.css'; interface WordRendererProps { blob: Blob; fileName: string; mimeType?: string; onError: (message: string) => void; } const SUPPORTED_MIME_TYPES = new Set([ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', ]); export function isWordMimeType(mimeType?: string, fileName?: string): boolean { if (mimeType && SUPPORTED_MIME_TYPES.has(mimeType)) return true; if (fileName && /\.docx$/i.test(fileName)) return true; return false; } export function WordRenderer({ blob, fileName, mimeType, onError }: WordRendererProps) { const { t } = useLanguage(); const bodyRef = useRef(null); const styleRef = useRef(null); const [loading, setLoading] = useState(true); const [localError, setLocalError] = useState(null); const isLegacyDoc = useMemo( () => mimeType === 'application/msword' || /\.doc$/i.test(fileName), [mimeType, fileName], ); useEffect(() => { let cancelled = false; if (isLegacyDoc) { const msg = t( 'Das alte Word-Format (.doc) wird nicht unterstützt. Bitte konvertiere die Datei in .docx.', ); setLocalError(msg); setLoading(false); onError(msg); return; } const body = bodyRef.current; const styleContainer = styleRef.current; if (!body || !styleContainer) return; body.innerHTML = ''; styleContainer.innerHTML = ''; setLoading(true); setLocalError(null); renderAsync(blob, body, styleContainer, { className: 'docx-preview', inWrapper: true, ignoreWidth: false, ignoreHeight: false, ignoreFonts: false, breakPages: true, experimental: true, trimXmlDeclaration: true, useBase64URL: true, renderHeaders: true, renderFooters: true, renderFootnotes: true, renderEndnotes: true, }) .then(() => { if (cancelled) return; setLoading(false); }) .catch(err => { if (cancelled) return; const msg = err?.message ?? t('Word-Dokument konnte nicht gerendert werden.'); setLocalError(msg); setLoading(false); onError(msg); }); return () => { cancelled = true; }; }, [blob, isLegacyDoc, onError, t]); if (localError) { return (
{fileName}
{localError}
); } return (
{loading && (
{t('Word-Dokument wird geladen...')}
)}
); }