"use client"; import { useCallback, useState } from "react"; import { useRouter } from "next/navigation"; import { Film, Loader2, Upload } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn, formatFileSize } from "@/lib/utils"; const MAX_SIZE = 500 * 1024 * 1024; const ACCEPTED = ["video/mp4", "video/quicktime", "video/webm"]; export function VideoUpload() { const router = useRouter(); const [dragging, setDragging] = useState(false); const [uploading, setUploading] = useState(false); const [error, setError] = useState(null); const uploadFile = useCallback(async (file: File) => { setError(null); if (!ACCEPTED.includes(file.type) && !file.name.match(/\.(mp4|mov|webm)$/i)) { setError("Please upload MP4, MOV, or WebM."); return; } if (file.size > MAX_SIZE) { setError(`File too large (${formatFileSize(file.size)}). Max 500MB.`); return; } setUploading(true); try { const formData = new FormData(); formData.append("video", file); const res = await fetch("/api/upload", { method: "POST", body: formData }); const data = await res.json(); if (!res.ok) throw new Error(data.error || "Upload failed"); router.push(`/editor?id=${data.id}`); } catch (err) { setError(err instanceof Error ? err.message : "Upload failed"); } finally { setUploading(false); } }, [router]); const onDrop = (e: React.DragEvent) => { e.preventDefault(); setDragging(false); const file = e.dataTransfer.files?.[0]; if (file) void uploadFile(file); }; return (
{ e.preventDefault(); setDragging(true); }} onDragLeave={() => setDragging(false)} onDrop={onDrop} className={cn( "flex min-h-[320px] cursor-pointer flex-col items-center justify-center rounded-2xl border-2 border-dashed p-10 transition-colors", dragging ? "border-zinc-900 bg-zinc-50" : "border-zinc-300 bg-white hover:border-zinc-400", )} onClick={() => document.getElementById("video-input")?.click()} > { const file = e.target.files?.[0]; if (file) void uploadFile(file); }} /> {uploading ? ( ) : ( )}

Drop video here

or click to browse

MP4, MOV, WebM • Max 500MB • 5 min

{error && (
{error}
)}
Upload a short vertical video to add viral-style captions
); }