import { HTMLAttributes, useMemo } from 'react'; import { SharedData } from '@/types/global'; import { usePage } from '@inertiajs/react'; import { AlertCircle, Download, ExternalLink } from 'lucide-react'; interface Props extends HTMLAttributes { src: string; fileName?: string; } type DocumentType = 'pdf' | 'office' | 'image' | 'text' | 'unsupported'; const DocumentViewer = ({ src, fileName, className, ...props }: Props) => { const { props: pageProps } = usePage(); const { translate } = pageProps; const { frontend } = translate; const documentInfo = useMemo(() => { const getFileExtension = (url: string): string => { const urlWithoutQuery = url.split('?')[0]; const extension = urlWithoutQuery.split('.').pop()?.toLowerCase() || ''; return extension; }; const getDocumentType = (extension: string): DocumentType => { const pdfFormats = ['pdf']; const officeFormats = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'ods', 'odp']; const imageFormats = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']; const textFormats = ['txt', 'rtf', 'csv']; if (pdfFormats.includes(extension)) return 'pdf'; if (officeFormats.includes(extension)) return 'office'; if (imageFormats.includes(extension)) return 'image'; if (textFormats.includes(extension)) return 'text'; return 'unsupported'; }; const extension = getFileExtension(src); const type = getDocumentType(extension); return { extension, type }; }, [src]); const renderDocument = () => { const baseClassName = "h-full max-h-[calc(100vh-60px)] min-h-[80vh] w-full"; switch (documentInfo.type) { case 'pdf': return ( ); case 'office': { // Use Microsoft Office Online Viewer for office documents const officeViewerUrl = `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(src)}`; return ( { // Fallback to Google Docs Viewer if Office Online fails const googleViewerUrl = `https://docs.google.com/gview?url=${encodeURIComponent(src)}&embedded=true`; const iframe = document.querySelector('iframe[src*="officeapps.live.com"]') as HTMLIFrameElement; if (iframe) { iframe.src = googleViewerUrl; } }} /> ); } case 'image': return ( ); case 'text': return ( ); default: return ( {frontend.unsupported_document_format} {frontend.document_format_cannot_be_previewed.replace('{extension}', documentInfo.extension)} {frontend.open_in_new_tab_button} {frontend.download} ); } }; return ( {renderDocument()} ); }; export default DocumentViewer;
{frontend.document_format_cannot_be_previewed.replace('{extension}', documentInfo.extension)}