2026-01-07 09:31:02 +00:00
|
|
|
import React from 'react';
|
|
|
|
|
import { Card } from '../ui/card';
|
|
|
|
|
import { UploadProgressBar } from './UploadProgressBar';
|
2026-01-13 18:47:57 +00:00
|
|
|
import {
|
|
|
|
|
FileAudio,
|
|
|
|
|
FileImage,
|
|
|
|
|
FolderArchive,
|
|
|
|
|
File,
|
|
|
|
|
CheckCircle,
|
|
|
|
|
AlertCircle,
|
|
|
|
|
} from 'lucide-react';
|
2026-01-07 09:31:02 +00:00
|
|
|
|
|
|
|
|
export interface UploadFile {
|
|
|
|
|
id: string;
|
|
|
|
|
file: File;
|
|
|
|
|
progress: number;
|
|
|
|
|
status: 'uploading' | 'paused' | 'completed' | 'error' | 'processing';
|
|
|
|
|
previewUrl?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface FilePreviewCardProps {
|
|
|
|
|
fileData: UploadFile;
|
|
|
|
|
onPause: () => void;
|
|
|
|
|
onResume: () => void;
|
|
|
|
|
onCancel: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
export const FilePreviewCard: React.FC<FilePreviewCardProps> = ({
|
|
|
|
|
fileData,
|
|
|
|
|
onPause,
|
|
|
|
|
onResume,
|
|
|
|
|
onCancel,
|
2026-01-07 09:31:02 +00:00
|
|
|
}) => {
|
|
|
|
|
const { file, progress, status, previewUrl } = fileData;
|
|
|
|
|
|
|
|
|
|
const formatSize = (bytes: number) => {
|
|
|
|
|
if (bytes === 0) return '0 B';
|
|
|
|
|
const k = 1024;
|
|
|
|
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
2026-01-13 18:47:57 +00:00
|
|
|
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
|
2026-01-07 09:31:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getIcon = () => {
|
2026-01-13 18:47:57 +00:00
|
|
|
if (file.type.startsWith('image/'))
|
|
|
|
|
return <FileImage className="w-6 h-6 text-kodo-magenta" />;
|
|
|
|
|
if (file.type.startsWith('audio/'))
|
|
|
|
|
return <FileAudio className="w-6 h-6 text-kodo-cyan" />;
|
|
|
|
|
if (file.type.includes('zip') || file.type.includes('compressed'))
|
|
|
|
|
return <FolderArchive className="w-6 h-6 text-kodo-gold" />;
|
2026-01-07 09:31:02 +00:00
|
|
|
return <File className="w-6 h-6 text-gray-400" />;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
2026-01-13 18:47:57 +00:00
|
|
|
<Card
|
|
|
|
|
variant="gaming"
|
|
|
|
|
className="p-3 flex items-center gap-4 border-l-4 border-l-kodo-slate hover:border-l-kodo-cyan transition-all"
|
|
|
|
|
>
|
2026-01-07 09:31:02 +00:00
|
|
|
{/* Thumbnail / Icon */}
|
|
|
|
|
<div className="w-12 h-12 rounded-lg bg-black/40 flex items-center justify-center overflow-hidden flex-shrink-0 border border-white/5">
|
|
|
|
|
{previewUrl && file.type.startsWith('image/') ? (
|
2026-01-13 18:47:57 +00:00
|
|
|
<img
|
|
|
|
|
src={previewUrl}
|
|
|
|
|
alt="Preview"
|
|
|
|
|
className="w-full h-full object-cover"
|
|
|
|
|
/>
|
2026-01-07 09:31:02 +00:00
|
|
|
) : (
|
|
|
|
|
getIcon()
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Info & Progress */}
|
|
|
|
|
<div className="flex-1 min-w-0">
|
|
|
|
|
<div className="flex justify-between items-start mb-1">
|
2026-01-13 18:47:57 +00:00
|
|
|
<h4
|
|
|
|
|
className="font-bold text-white text-sm truncate pr-2"
|
|
|
|
|
title={file.name}
|
|
|
|
|
>
|
|
|
|
|
{file.name}
|
|
|
|
|
</h4>
|
|
|
|
|
<span className="text-[10px] text-gray-500 font-mono flex-shrink-0">
|
|
|
|
|
{formatSize(file.size)}
|
|
|
|
|
</span>
|
2026-01-07 09:31:02 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
|
2026-01-07 09:31:02 +00:00
|
|
|
{status === 'completed' ? (
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="flex items-center gap-2 text-xs text-kodo-lime font-bold">
|
|
|
|
|
<CheckCircle className="w-3 h-3" /> Ready
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
) : status === 'error' ? (
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="flex items-center gap-2 text-xs text-kodo-red font-bold">
|
|
|
|
|
<AlertCircle className="w-3 h-3" /> Failed
|
|
|
|
|
</div>
|
2026-01-07 09:31:02 +00:00
|
|
|
) : (
|
2026-01-13 18:47:57 +00:00
|
|
|
<UploadProgressBar
|
|
|
|
|
progress={progress}
|
|
|
|
|
status={status}
|
|
|
|
|
onPause={onPause}
|
|
|
|
|
onResume={onResume}
|
|
|
|
|
onCancel={onCancel}
|
|
|
|
|
/>
|
2026-01-07 09:31:02 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</Card>
|
|
|
|
|
);
|
2026-01-13 18:47:57 +00:00
|
|
|
};
|