import { useEffect, useState } from 'react'; import { useFileService } from '../hooks/useFileService'; import { generateFilePreview } from '../utils/filePreview'; import type { FileServiceConfig, FileMetadata, FilePreview } from '../types'; interface FileViewerProps { fileId: string; config?: FileServiceConfig; className?: string; showPreview?: boolean; } export function FileViewer({ fileId, config, className = '', showPreview = true }: FileViewerProps) { const { getFileMetadata, getFile, loading, error } = useFileService(config); const [fileUrl, setFileUrl] = useState(null); const [fileBlob, setFileBlob] = useState(null); const [fileMetadata, setFileMetadata] = useState(null); const [preview, setPreview] = useState(null); useEffect(() => { const loadFile = async () => { try { const metadata = await getFileMetadata(fileId); if (metadata) { setFileMetadata(metadata); // Backend returns presigned URL in storagePath field if (metadata.storagePath && metadata.storagePath.startsWith('http')) { // Use presigned URL directly for preview setFileUrl(metadata.storagePath); // Try to get blob for preview metadata generation if (showPreview) { try { const blob = await getFile(fileId); if (blob) { setFileBlob(blob); const file = new File([blob], metadata.fileName, { type: `application/${metadata.fileExtension.replace('.', '')}`, }); const previewData = await generateFilePreview(file); setPreview(previewData); } } catch (blobError) { // If blob download fails, still show preview using presigned URL console.warn('Could not generate preview metadata:', blobError); } } } else { // Fallback: try to get blob if presigned URL not available const blob = await getFile(fileId); if (blob) { const objectUrl = URL.createObjectURL(blob); setFileUrl(objectUrl); if (showPreview) { const file = new File([blob], metadata.fileName, { type: `application/${metadata.fileExtension.replace('.', '')}`, }); const previewData = await generateFilePreview(file); setPreview(previewData); } } } } } catch (error) { console.error('Error loading file:', error); } }; if (fileId) { loadFile(); } return () => { if (fileUrl && fileUrl.startsWith('blob:')) { URL.revokeObjectURL(fileUrl); } }; }, [fileId, getFileMetadata, getFile, showPreview]); if (loading) { return
Loading file...
; } if (error) { return
Error: {error}
; } if (!fileUrl || !fileMetadata) { return
No file to display
; } const fileExtension = fileMetadata.fileExtension.toLowerCase(); const isPdf = fileExtension === '.pdf'; const isImage = fileMetadata.fileExtension.match(/\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i); const isText = fileMetadata.fileExtension.match(/\.(txt|md|json|xml|html|css|js|ts|tsx|jsx)$/i); const isWord = fileExtension.match(/\.(doc|docx)$/i); const isExcel = fileExtension.match(/\.(xls|xlsx)$/i); const isCsv = fileExtension === '.csv'; return (

{fileMetadata.fileName}

Size: {(fileMetadata.size / 1024).toFixed(2)} KB Type: {fileMetadata.fileExtension} {preview?.pages && Pages: {preview.pages}} {preview?.sheets && preview.sheets.length > 0 && ( Sheets: {preview.sheets.join(', ')} )}
{isPdf && fileUrl && (