63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import type {
|
|
ChangeEventHandler,
|
|
DragEventHandler,
|
|
MouseEventHandler,
|
|
RefObject,
|
|
} from 'react';
|
|
import { RotateCcw, Upload } from 'lucide-react';
|
|
|
|
interface UploadDropzoneProps {
|
|
inputRef: RefObject<HTMLInputElement | null>;
|
|
file: File | null;
|
|
uploading: boolean;
|
|
dragOver: boolean;
|
|
onClick: MouseEventHandler<HTMLElement>;
|
|
onDragOver: DragEventHandler<HTMLElement>;
|
|
onDragLeave: DragEventHandler<HTMLElement>;
|
|
onDrop: DragEventHandler<HTMLElement>;
|
|
onInputChange: ChangeEventHandler<HTMLInputElement>;
|
|
}
|
|
|
|
export function UploadDropzone({
|
|
inputRef,
|
|
file,
|
|
uploading,
|
|
dragOver,
|
|
onClick,
|
|
onDragOver,
|
|
onDragLeave,
|
|
onDrop,
|
|
onInputChange,
|
|
}: UploadDropzoneProps) {
|
|
return (
|
|
<section
|
|
onDragOver={onDragOver}
|
|
onDragLeave={onDragLeave}
|
|
onDrop={onDrop}
|
|
onClick={onClick}
|
|
className={`bg-white rounded-2xl border-2 border-dashed shadow-sm cursor-pointer transition-all ${
|
|
dragOver ? 'border-blue-400 bg-blue-50/40' : uploading ? 'border-slate-200' : 'border-slate-200 hover:border-blue-300'
|
|
}`}
|
|
>
|
|
<input
|
|
ref={inputRef}
|
|
type="file"
|
|
accept=".xlsx,.xls"
|
|
className="hidden"
|
|
onChange={onInputChange}
|
|
/>
|
|
<div className="px-6 py-10 flex flex-col items-center text-center">
|
|
<div className="w-14 h-14 rounded-2xl bg-blue-50 flex items-center justify-center mb-3">
|
|
{uploading ? <RotateCcw size={22} className="text-blue-500 animate-spin" /> : <Upload size={22} className="text-blue-500" />}
|
|
</div>
|
|
<div className="text-sm font-bold text-slate-700 mb-1">
|
|
{uploading ? '正在解析...' : file ? file.name : '点击或拖拽 xlsx 文件到此处'}
|
|
</div>
|
|
<div className="text-[11px] text-slate-400 max-w-md leading-relaxed">
|
|
支持「充电成功记录明细」格式;订单编号已存在的会自动跳过
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|