Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 01:24:15 +00:00
co-authored by renee-png
parent 28f74d83dd
commit 2ffce29fb7
+74
View File
@@ -380,6 +380,80 @@ export function CaseDocumentsTab({ caseId }: { caseId: string }) {
</CardContent>
</Card>
</div>
<Dialog open={!!previewDoc} onOpenChange={(o) => !o && closePreview()}>
<DialogContent className="max-w-5xl w-[95vw] h-[85vh] flex flex-col p-0 gap-0">
<DialogHeader className="px-4 py-3 border-b flex-row items-center justify-between space-y-0">
<DialogTitle className="truncate pr-4">{previewDoc?.name}</DialogTitle>
{previewUrl && (
<div className="flex items-center gap-1 mr-6">
<Button variant="ghost" size="sm" onClick={() => window.open(previewUrl, "_blank")}>
<ExternalLink className="h-4 w-4 mr-1.5" /> Open
</Button>
<Button variant="ghost" size="sm" onClick={() => previewDoc && download(previewDoc)}>
<Download className="h-4 w-4 mr-1.5" /> Download
</Button>
</div>
)}
</DialogHeader>
<div className="flex-1 min-h-0 bg-muted/30">
{previewLoading ? (
<div className="h-full flex items-center justify-center text-muted-foreground">
<Loader2 className="h-5 w-5 animate-spin mr-2" /> Loading preview…
</div>
) : previewUrl && previewDoc ? (
<PreviewBody url={previewUrl} doc={previewDoc} />
) : null}
</div>
</DialogContent>
</Dialog>
</div>
);
}
function PreviewBody({ url, doc }: { url: string; doc: any }) {
const mime = (doc.mime_type || "").toLowerCase();
const name = (doc.name || "").toLowerCase();
const isImage = mime.startsWith("image/") || /\.(png|jpe?g|gif|webp|svg|bmp)$/i.test(name);
const isPdf = mime === "application/pdf" || name.endsWith(".pdf");
const isText =
mime.startsWith("text/") ||
/\.(txt|md|csv|json|log|xml|yml|yaml)$/i.test(name);
const isAudio = mime.startsWith("audio/") || /\.(mp3|wav|m4a|ogg)$/i.test(name);
const isVideo = mime.startsWith("video/") || /\.(mp4|webm|mov)$/i.test(name);
if (isImage) {
return (
<div className="h-full w-full flex items-center justify-center overflow-auto p-4">
<img src={url} alt={doc.name} className="max-h-full max-w-full object-contain" />
</div>
);
}
if (isPdf || isText) {
return <iframe src={url} title={doc.name} className="h-full w-full border-0 bg-white" />;
}
if (isAudio) {
return (
<div className="h-full flex items-center justify-center p-4">
<audio controls src={url} className="w-full max-w-xl" />
</div>
);
}
if (isVideo) {
return (
<div className="h-full flex items-center justify-center p-4 bg-black">
<video controls src={url} className="max-h-full max-w-full" />
</div>
);
}
return (
<div className="h-full flex flex-col items-center justify-center text-center p-8 text-muted-foreground">
<FileText className="h-10 w-10 mb-3 opacity-60" />
<p className="mb-1">No inline preview available for this file type.</p>
<p className="text-xs mb-4">{doc.mime_type || "Unknown type"}</p>
<Button onClick={() => window.open(url, "_blank")}>
<ExternalLink className="h-4 w-4 mr-1.5" /> Open in new tab
</Button>
</div>
);
}