import { Button, Empty, Spin } from 'antd'; import { useEffect, useState } from 'react'; import { ApiError } from '../../api/client'; import { fetchFileContent } from '../../services/api/files'; import { saveBlob } from '../../utils/download'; import PdfPages from './PdfPages'; type Loaded = { kind: 'pdf'; data: ArrayBuffer } | { kind: 'image'; url: string } | { kind: 'other'; blob: Blob; filename: string }; export function SourcePreview({ fileId }: { fileId: string }) { const [loaded, setLoaded] = useState(null); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; let objectUrl: string | null = null; setLoaded(null); setError(null); fetchFileContent(fileId) .then(async ({ blob, filename }) => { if (cancelled) { return; } if (blob.type === 'application/pdf') { const data = await blob.arrayBuffer(); if (!cancelled) { setLoaded({ kind: 'pdf', data }); } } else if (blob.type.startsWith('image/')) { objectUrl = URL.createObjectURL(blob); setLoaded({ kind: 'image', url: objectUrl }); } else { setLoaded({ kind: 'other', blob, filename: filename ?? 'исходный_файл' }); } }) .catch((e: unknown) => { if (!cancelled) { setError(e instanceof ApiError ? e.message : 'Не удалось получить исходный файл'); } }); return () => { cancelled = true; if (objectUrl) { URL.revokeObjectURL(objectUrl); } }; }, [fileId]); if (error) { return ; } if (!loaded) { return ; } if (loaded.kind === 'pdf') { return ; } if (loaded.kind === 'image') { return Исходный документ; } return ( ); }