diff --git a/src/components/features/FilePreviewList.tsx b/src/components/features/FilePreviewList.tsx new file mode 100644 index 0000000..59d55ab --- /dev/null +++ b/src/components/features/FilePreviewList.tsx @@ -0,0 +1,147 @@ +'use client'; + +import { X, File, FileImage, FileText, FileSpreadsheet, FileCode, FileArchive, Loader2 } from 'lucide-react'; +import { cn } from '@/lib/utils'; +import { UploadFile, FileType, formatFileSize } from '@/types/file-upload'; +import Image from 'next/image'; + +interface FilePreviewListProps { + files: UploadFile[]; + onRemove: (fileId: string) => void; + className?: string; +} + +// 根据文件类型获取图标 +function getFileIcon(fileType: FileType) { + switch (fileType) { + case 'image': + return FileImage; + case 'pdf': + case 'document': + return FileText; + case 'spreadsheet': + return FileSpreadsheet; + case 'code': + case 'markdown': + return FileCode; + case 'archive': + return FileArchive; + default: + return File; + } +} + +// 根据文件类型获取颜色 +function getFileColor(fileType: FileType): string { + switch (fileType) { + case 'image': + return 'text-blue-500'; + case 'pdf': + return 'text-red-500'; + case 'document': + return 'text-blue-600'; + case 'spreadsheet': + return 'text-green-500'; + case 'code': + case 'markdown': + return 'text-purple-500'; + case 'archive': + return 'text-orange-500'; + default: + return 'text-gray-500'; + } +} + +interface FilePreviewItemProps { + file: UploadFile; + onRemove: (fileId: string) => void; +} + +function FilePreviewItem({ file, onRemove }: FilePreviewItemProps) { + const Icon = getFileIcon(file.type); + const colorClass = getFileColor(file.type); + + return ( +
+ {/* 文件预览/图标 */} +
+ {file.type === 'image' && file.previewUrl ? ( + {file.name} + ) : ( + + )} +
+ + {/* 文件信息 */} +
+

+ {file.name} +

+

+ {formatFileSize(file.size)} + {file.status === 'error' && file.error && ( + {file.error} + )} +

+
+ + {/* 状态指示器 */} + {file.status === 'uploading' && ( +
+ +
+ )} + + {/* 进度条 */} + {file.status === 'uploading' && ( +
+
+
+ )} + + {/* 删除按钮 */} + +
+ ); +} + +export function FilePreviewList({ files, onRemove, className }: FilePreviewListProps) { + if (files.length === 0) { + return null; + } + + return ( +
+ {files.map((file) => ( + + ))} +
+ ); +}