socks22's picture
first
f3f6f5d
import { useCallback, useRef, useState } from 'preact/hooks';
interface UploadProps {
onFile: (file: File) => void;
disabled?: boolean;
}
export function Upload({ onFile, disabled }: UploadProps) {
const [dragOver, setDragOver] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const handleFile = useCallback(
(file: File | undefined) => {
if (file && (file.type === 'image/jpeg' || file.type === 'image/png')) {
onFile(file);
}
},
[onFile]
);
const onDrop = useCallback(
(e: DragEvent) => {
e.preventDefault();
setDragOver(false);
handleFile(e.dataTransfer?.files[0]);
},
[handleFile]
);
const onDragOver = useCallback((e: DragEvent) => {
e.preventDefault();
setDragOver(true);
}, []);
const onDragLeave = useCallback(() => setDragOver(false), []);
const onChange = useCallback(
(e: Event) => {
const input = e.target as HTMLInputElement;
handleFile(input.files?.[0]);
},
[handleFile]
);
return (
<div
class={`upload-zone ${dragOver ? 'drag-over' : ''} ${disabled ? 'disabled' : ''}`}
onDrop={onDrop}
onDragOver={onDragOver}
onDragLeave={onDragLeave}
onClick={() => !disabled && inputRef.current?.click()}
>
<input
ref={inputRef}
type="file"
accept="image/jpeg,image/png"
onChange={onChange}
hidden
/>
<p class="upload-icon">+</p>
<p>Drag & drop an aerial image here, or click to browse</p>
<p class="upload-hint">JPEG or PNG</p>
</div>
);
}