carouselforge / src /components /input /FileUpload.tsx
CarouselForge Developer
fix: resolve TypeScript and test configuration issues for Phase 13
9a43362
'use client';
import { useRef, useState, DragEvent, ChangeEvent } from 'react';
interface FileUploadProps {
onFileContent: (text: string, fileName: string) => void;
}
export default function FileUpload({ onFileContent }: FileUploadProps): React.ReactElement {
const [isDragging, setIsDragging] = useState(false);
const [fileName, setFileName] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const inputRef = useRef<HTMLInputElement>(null);
function handleFile(file: File): void {
if (file.type !== 'application/pdf') {
setError('Only PDF files are supported');
return;
}
setError(null);
setFileName(file.name);
const reader = new FileReader();
reader.onload = () => {
onFileContent(reader.result as string, file.name);
};
reader.readAsDataURL(file);
}
function handleDrop(e: DragEvent<HTMLDivElement>): void {
e.preventDefault();
setIsDragging(false);
const file = e.dataTransfer.files[0];
if (file) handleFile(file);
}
function handleChange(e: ChangeEvent<HTMLInputElement>): void {
const file = e.target.files?.[0];
if (file) handleFile(file);
}
return (
<div className="space-y-2">
<label className="text-sm font-medium text-gray-700">Upload a PDF</label>
<div
onClick={() => inputRef.current?.click()}
onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
onDragLeave={() => setIsDragging(false)}
onDrop={handleDrop}
className={`border-2 border-dashed rounded-lg p-12 text-center cursor-pointer transition-colors ${
isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-gray-400'
}`}
>
<input
ref={inputRef}
type="file"
accept=".pdf"
className="hidden"
onChange={handleChange}
/>
{fileName ? (
<div>
<p className="text-sm font-medium text-gray-800">📄 {fileName}</p>
<p className="text-xs text-gray-400 mt-1">Click to replace</p>
</div>
) : (
<div>
<p className="text-gray-500 text-sm">Drag a PDF here, or click to browse</p>
<p className="text-xs text-gray-400 mt-1">PDF only</p>
</div>
)}
</div>
{error && <p className="text-xs text-red-500">{error}</p>}
</div>
);
}