Screen-VLA / components /VideoUploader.tsx
Gemini
VLA Data Generator - Complete TypeScript/React app with backend
256cef9
import React, { useState, useCallback, useRef } from 'react';
import { FileVideo } from './Icons';
interface VideoUploaderProps {
onVideoSelect: (file: File) => void;
}
export const VideoUploader: React.FC<VideoUploaderProps> = ({ onVideoSelect }) => {
const [isDragging, setIsDragging] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleDrag = useCallback((e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
}, []);
const handleDragIn = useCallback((e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
setIsDragging(true);
}
}, []);
const handleDragOut = useCallback((e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
setIsDragging(false);
}, []);
const handleDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
setIsDragging(false);
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
onVideoSelect(e.dataTransfer.files[0]);
e.dataTransfer.clearData();
}
}, [onVideoSelect]);
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files.length > 0) {
onVideoSelect(e.target.files[0]);
}
};
const onButtonClick = () => {
fileInputRef.current?.click();
};
return (
<div
onDragEnter={handleDragIn}
onDragLeave={handleDragOut}
onDragOver={handleDrag}
onDrop={handleDrop}
onClick={onButtonClick}
className={`w-full h-full p-4 flex flex-col items-center justify-center border-4 border-dashed rounded-xl transition-all duration-300 cursor-pointer
${isDragging ? 'border-indigo-500 bg-slate-700/50' : 'border-slate-600 hover:border-indigo-600 hover:bg-slate-700/30'}`}
>
<input
ref={fileInputRef}
type="file"
accept="video/*"
onChange={handleFileChange}
className="hidden"
/>
<div className="text-center pointer-events-none">
<FileVideo className="w-16 h-16 mx-auto text-slate-500 mb-4" />
<p className="text-lg font-semibold text-slate-300">Drag & Drop Video File</p>
<p className="text-slate-400">or click to select a file</p>
</div>
</div>
);
};