modcomms/frontend/components/ProofPreview.tsx
2025-12-18 16:51:27 +00:00

84 lines
No EOL
2.8 KiB
TypeScript
Executable file

import React from 'react';
import { DocumentIcon } from './icons/DocumentIcon';
interface ProofPreviewProps {
file?: File | null;
previewUrl: string | null;
fileName?: string;
}
export const ProofPreview: React.FC<ProofPreviewProps> = ({ file, previewUrl, fileName }) => {
if (!previewUrl) {
return null;
}
const getMimeType = (): string => {
if (file?.type) return file.type;
if (previewUrl.startsWith('data:')) {
const match = previewUrl.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+);/);
if (match && match[1]) {
return match[1];
}
}
return 'application/octet-stream'; // Fallback
};
const fileType = getMimeType();
const displayName = fileName || file?.name || 'Proof Preview';
const renderPreview = () => {
if (fileType.startsWith('image/')) {
return (
<img
src={previewUrl}
alt={displayName}
className="w-full rounded-lg shadow-2xl object-contain border border-gray-200 bg-white p-2"
style={{ maxHeight: 'calc(100vh - 9rem)' }}
/>
);
}
if (fileType === 'video/mp4') {
return (
<video
src={previewUrl}
controls
className="w-full rounded-lg shadow-2xl object-contain border border-gray-200 bg-white p-2"
style={{ maxHeight: 'calc(100vh - 9rem)' }}
>
Your browser does not support the video tag.
</video>
);
}
if (fileType === 'application/pdf') {
return (
<iframe
src={`${previewUrl}#view=fitH`}
title={displayName}
className="w-full h-[calc(100vh-9rem)] rounded-lg shadow-2xl border border-gray-200 bg-white"
/>
);
}
// Fallback for other file types
return (
<div
className="w-full rounded-lg shadow-2xl border border-gray-200 bg-white p-8 flex flex-col items-center justify-center text-center"
style={{ minHeight: '300px', maxHeight: 'calc(100vh - 9rem)' }}
>
<DocumentIcon className="h-20 w-20 text-gray-400 mb-4" />
<p className="text-lg font-semibold text-brand-dark-blue break-all">{displayName}</p>
<p className="text-sm text-gray-500">{fileType}</p>
<p className="text-sm text-gray-500 mt-2">No preview available for this file type.</p>
</div>
);
};
return (
<div className="sticky top-8">
{renderPreview()}
</div>
);
};