feat(T05): Dateiablage pro Fahrzeug + File UI with thumbnails and gallery
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
'use client';
|
||||
|
||||
import { Modal } from '@/components/ui/Modal';
|
||||
import { isImageMime, formatFileSize, type FileResponse } from '@/lib/files';
|
||||
|
||||
interface FilePreviewProps {
|
||||
file: FileResponse | null;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function FilePreview({ file, open, onClose }: FilePreviewProps) {
|
||||
if (!file) return null;
|
||||
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api/v1';
|
||||
const downloadUrl = `${API_BASE_URL}/vehicles/${file.vehicle_id}/files/${file.id}`;
|
||||
const isImg = isImageMime(file.mime_type);
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={onClose} title={file.original_filename}>
|
||||
<div data-testid="file-preview" className="space-y-4">
|
||||
{/* Preview content */}
|
||||
{isImg ? (
|
||||
<div className="flex justify-center">
|
||||
<img
|
||||
src={downloadUrl}
|
||||
alt={file.original_filename}
|
||||
className="max-w-full max-h-[60vh] rounded-lg"
|
||||
data-testid="preview-image"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-center gap-4 py-8">
|
||||
<svg className="h-16 w-16 text-text-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
<p className="text-text-muted">Preview not available for this file type</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* File metadata */}
|
||||
<div className="space-y-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-text-muted">File type:</span>
|
||||
<span className="text-text">{file.mime_type}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-text-muted">Size:</span>
|
||||
<span className="text-text">{formatFileSize(file.file_size)}</span>
|
||||
</div>
|
||||
{file.created_at && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-text-muted">Uploaded:</span>
|
||||
<span className="text-text">
|
||||
{new Date(file.created_at).toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Download button */}
|
||||
<div className="flex justify-end">
|
||||
<a
|
||||
href={downloadUrl}
|
||||
download={file.original_filename}
|
||||
className="inline-flex items-center px-4 py-2 rounded-lg bg-primary text-white hover:bg-primary-hover transition-colors"
|
||||
data-testid="preview-download-btn"
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user