Skip to content

Commit ac47f74

Browse files
committed
feat: Implement Universal Document Preview (Google Docs Viewer Fallback)
1 parent 7b1da6f commit ac47f74

2 files changed

Lines changed: 36 additions & 29 deletions

File tree

src/components/common/FilePreviewModal.tsx

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,20 @@ export default function FilePreviewModal({ isOpen, onClose, fileUrl, fileName, f
1717
const isImage = fileType.includes("image");
1818
const isVideo = fileType.includes("video");
1919
const isPDF = fileType.includes("pdf");
20-
// Simple check for office files based on type or extension if needed,
21-
// but usually these have specific mime types or we can imply from extension in name.
22-
// Common Office Mime Types:
23-
// application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document
24-
// application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
25-
// application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation
26-
const isOffice =
27-
fileType.includes("word") ||
28-
fileType.includes("excel") ||
29-
fileType.includes("spreadsheet") ||
30-
fileType.includes("powerpoint") ||
31-
fileType.includes("presentation") ||
32-
fileName.endsWith(".doc") || fileName.endsWith(".docx") ||
33-
fileName.endsWith(".xls") || fileName.endsWith(".xlsx") ||
34-
fileName.endsWith(".ppt") || fileName.endsWith(".pptx");
20+
21+
// Generic check for any document that isn't media or PDF
22+
// Google Viewer supports many formats including .ai, .psd, .dxf, .svg, .eps, .ps, .ttf, .xps, .zip, .rar
23+
const isGoogleDocSupported =
24+
!isImage &&
25+
!isVideo &&
26+
!isPDF &&
27+
(
28+
fileType.includes("application/") ||
29+
fileType.includes("text/") ||
30+
fileName.match(/\.(doc|docx|xls|xlsx|ppt|pptx|txt|rtf|csv|odt|ods|odp|ai|psd|dxf|eps|ps|xps|ttf|pages|numbers|key)$/i)
31+
);
32+
33+
const showGoogleViewer = isGoogleDocSupported;
3534

3635
return (
3736
<div style={{
@@ -76,14 +75,15 @@ export default function FilePreviewModal({ isOpen, onClose, fileUrl, fileName, f
7675
<PDFViewer fileUrl={fileUrl} fileName={fileName} />
7776
)}
7877

79-
{isOffice && (
78+
{showGoogleViewer && (
8079
<iframe
81-
src={`https://docs.google.com/gview?url=${encodeURIComponent(fileUrl)}&embedded=true`}
80+
src={`https://docs.google.com/viewer?url=${encodeURIComponent(fileUrl)}&embedded=true`}
8281
style={{ width: "100%", height: "100%", border: "none" }}
82+
title="Document Preview"
8383
/>
8484
)}
8585

86-
{!isImage && !isVideo && !isPDF && !isOffice && (
86+
{!isImage && !isVideo && !isPDF && !showGoogleViewer && (
8787
<div style={{ textAlign: "center", color: "#64748b" }}>
8888
<p style={{ marginBottom: "1rem" }}>Preview not available for this file type.</p>
8989
<a href={fileUrl} download className="btn btn-primary" style={{ display: "inline-flex", alignItems: "center", gap: "0.5rem", padding: "0.5rem 1rem", background: "#2563eb", color: "white", borderRadius: "6px", textDecoration: "none" }}>

src/components/public/FilePreviewModal.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,19 @@ export default function FilePreviewModal({ file, onClose }: FilePreviewModalProp
174174
const isImage = file.fileType.startsWith("image/");
175175
const isVideo = file.fileType.startsWith("video/");
176176
const isPdf = file.fileType.includes("pdf");
177-
const isOfficeDoc =
178-
file.fileType.includes("msword") ||
179-
file.fileType.includes("wordprocessingml") ||
180-
file.fileType.includes("ms-excel") ||
181-
file.fileType.includes("spreadsheetml") ||
182-
file.fileType.includes("ms-powerpoint") ||
183-
file.fileType.includes("presentationml");
177+
178+
// Expanded support for Google Drive Viewer (Docs, Sheets, Slides, Text, Code, etc)
179+
const isGoogleDocSupported =
180+
!isImage &&
181+
!isVideo &&
182+
!isPdf &&
183+
(
184+
file.title.match(/\.(doc|docx|xls|xlsx|ppt|pptx|txt|rtf|csv|odt|ods|odp|ai|psd|dxf|eps|ps|xps|ttf|pages|numbers|key)$/i) ||
185+
file.fileType.includes("application/") ||
186+
file.fileType.includes("text/")
187+
);
188+
189+
const showGoogleViewer = isGoogleDocSupported;
184190

185191
return (
186192
<div
@@ -313,7 +319,7 @@ export default function FilePreviewModal({ file, onClose }: FilePreviewModalProp
313319
</div>
314320
)}
315321

316-
{isOfficeDoc && (
322+
{showGoogleViewer && (
317323
<iframe
318324
src={`https://docs.google.com/viewer?url=${encodeURIComponent(file.fileUrl)}&embedded=true`}
319325
style={{
@@ -324,24 +330,25 @@ export default function FilePreviewModal({ file, onClose }: FilePreviewModalProp
324330
borderRadius: "8px",
325331
boxShadow: "0 20px 50px rgba(0,0,0,0.5)"
326332
}}
333+
title="Document Preview"
327334
/>
328335
)}
329336

330-
{!isImage && !isVideo && !isPdf && !isOfficeDoc && (
337+
{!isImage && !isVideo && !isPdf && !showGoogleViewer && (
331338
<div style={{
332339
background: "var(--surface)",
333340
padding: "3rem",
334341
borderRadius: "12px",
335342
textAlign: "center",
336343
color: "var(--text-main)"
337344
}}>
338-
<FileText size={64} style={{ marginBottom: "1rem", color: "var(--primary)" }} />
345+
<FileText size={64} style={{ marginBottom: "1rem" }} />
339346
<h3 style={{ marginBottom: "0.5rem" }}>Preview not available</h3>
340347
<p style={{ color: "var(--text-muted)", marginBottom: "2rem" }}>
341348
This file type cannot be previewed directly.
342349
</p>
343350
<button onClick={handleDownload} className="btn btn-primary">
344-
Download File
351+
<Download size={18} style={{ marginRight: "0.5rem" }} /> Download
345352
</button>
346353
</div>
347354
)}

0 commit comments

Comments
 (0)