78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import SvgIcon from "@/components/svg-icon";
|
|
import { useTranslation } from "react-i18next";
|
|
import { DEFAULT_ALLOWED_FILE_TYPES, DEFAULT_MAX_FILE_SIZE } from "./file-uploader";
|
|
|
|
interface UploadDropzoneProps {
|
|
onClick: () => void;
|
|
disabled?: boolean;
|
|
allowedFileTypes?: string[];
|
|
maxFileSize?: number;
|
|
}
|
|
|
|
/**
|
|
* 上传区域组件 - 用于显示文件拖放和选择区域
|
|
*/
|
|
export default function UploadDropzone({
|
|
onClick,
|
|
disabled = false,
|
|
allowedFileTypes = DEFAULT_ALLOWED_FILE_TYPES,
|
|
maxFileSize = DEFAULT_MAX_FILE_SIZE
|
|
}: UploadDropzoneProps) {
|
|
const { t } = useTranslation();
|
|
|
|
// 格式化文件类型显示
|
|
const formatFileTypes = (types: string[]): string => {
|
|
return types.map(type => {
|
|
// 从 MIME 类型提取文件扩展名
|
|
const extensions: Record<string, string> = {
|
|
'video/mp4': 'MP4',
|
|
'video/quicktime': 'MOV',
|
|
'video/x-msvideo': 'AVI',
|
|
'video/x-matroska': 'MKV',
|
|
'image/jpeg': 'JPG',
|
|
'image/png': 'PNG',
|
|
'image/gif': 'GIF',
|
|
'image/webp': 'WEBP'
|
|
};
|
|
return extensions[type] || type.split('/')[1]?.toUpperCase() || type;
|
|
}).join(', ');
|
|
};
|
|
|
|
// 格式化文件大小显示
|
|
const formatFileSize = (bytes: number): string => {
|
|
if (bytes < 1024) return bytes + ' B';
|
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-all
|
|
${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-primary/50'} h-full`}
|
|
onClick={disabled ? undefined : onClick}
|
|
>
|
|
<div className="flex flex-col items-center justify-center gap-3 h-full">
|
|
<div className="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center">
|
|
<SvgIcon name="upload" className="h-6 w-6 text-gray-500" />
|
|
</div>
|
|
|
|
<div>
|
|
<h3 className="text-base font-medium text-gray-900">
|
|
{t('fileUploader.dragAndDropFiles')}
|
|
</h3>
|
|
<p className="mt-1 text-sm text-gray-500">
|
|
{t('fileUploader.orClickToUpload')}
|
|
</p>
|
|
<p className="mt-1 text-xs text-gray-500">
|
|
{t('fileUploader.supportedFormats')}: {formatFileTypes(allowedFileTypes)}
|
|
</p>
|
|
<p className="text-xs text-gray-500">
|
|
{t('fileUploader.maxFileSize')}: {formatFileSize(maxFileSize)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|