Quizify / frontend /src /components /DropZone.jsx
hetsheta's picture
fix: resolve mobile file upload click issues by making native input overlay capture taps directly
7aa7fb2
Raw
History Blame Contribute Delete
1.91 kB
import { useState, useRef } from 'react';
const ACCEPTED = '.pdf,.docx,.pptx,.txt,.md';
const fmtSize = (bytes) => {
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
};
export default function DropZone({ onFile, disabled }) {
const [dragging, setDragging] = useState(false);
const [chosen, setChosen] = useState(null);
const inputRef = useRef(null);
const handleFile = (file) => {
if (!file) return;
setChosen(file);
onFile(file);
};
const onDragOver = (e) => { e.preventDefault(); setDragging(true); };
const onDragLeave = () => setDragging(false);
const onDrop = (e) => {
e.preventDefault();
setDragging(false);
const file = e.dataTransfer.files[0];
if (file) handleFile(file);
};
const onChange = (e) => handleFile(e.target.files[0]);
return (
<div>
<div
className={`drop-zone${dragging ? ' dragging' : ''}`}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
onDrop={onDrop}
style={disabled ? { pointerEvents: 'none', opacity: .5 } : {}}
>
<input
ref={inputRef}
type="file"
accept={ACCEPTED}
onChange={onChange}
disabled={disabled}
id="file-input"
/>
<div className="drop-icon">馃搫</div>
<div className="drop-title">
{dragging ? 'Drop it here!' : 'Click or drag file here'}
</div>
<div className="drop-sub">PDF 路 DOCX 路 PPTX 路 TXT 路 MD</div>
</div>
{chosen && (
<div className="file-chosen">
<span className="file-chosen-icon">馃搸</span>
<span className="file-chosen-name">{chosen.name}</span>
<span className="file-chosen-size">{fmtSize(chosen.size)}</span>
</div>
)}
</div>
);
}