Spaces:
Sleeping
Sleeping
| "use client" | |
| import { useState } from "react" | |
| import { Input } from "@/components/ui/input" | |
| import { Button } from "@/components/ui/button" | |
| import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" | |
| import { AlertCircle, Download } from "lucide-react" | |
| import { processUrl } from "../app/actions" | |
| interface VideoInfo { | |
| platform: string | |
| title: string | |
| formats: Array<{ | |
| quality: string | |
| extension: string | |
| url: string | |
| }> | |
| } | |
| export default function VideoDownloader() { | |
| const [url, setUrl] = useState("") | |
| const [result, setResult] = useState<VideoInfo | null>(null) | |
| const [error, setError] = useState<string | null>(null) | |
| const handleSubmit = async (e: React.FormEvent) => { | |
| e.preventDefault() | |
| setError(null) | |
| setResult(null) | |
| try { | |
| const data = await processUrl(url) | |
| if ("error" in data) { | |
| setError(data.error) | |
| } else { | |
| setResult(data as VideoInfo) | |
| } | |
| } catch (err) { | |
| setError("Ocurrió un error al procesar la URL.") | |
| } | |
| } | |
| return ( | |
| <Card className="w-full max-w-md"> | |
| <CardHeader> | |
| <CardTitle className="text-2xl font-bold text-center">Descargador de Videos</CardTitle> | |
| </CardHeader> | |
| <CardContent> | |
| <form onSubmit={handleSubmit} className="space-y-4"> | |
| <Input | |
| type="url" | |
| placeholder="Ingrese la URL del video" | |
| value={url} | |
| onChange={(e) => setUrl(e.target.value)} | |
| required | |
| /> | |
| <Button type="submit" className="w-full"> | |
| Analizar URL | |
| </Button> | |
| </form> | |
| {error && ( | |
| <div className="mt-4 p-4 bg-red-100 text-red-700 rounded-md flex items-center"> | |
| <AlertCircle className="mr-2" /> | |
| <p>{error}</p> | |
| </div> | |
| )} | |
| {result && ( | |
| <div className="mt-4 space-y-4"> | |
| <h3 className="font-semibold">Opciones de descarga para {result.title}:</h3> | |
| {result.formats.map((format, index) => ( | |
| <Button | |
| key={index} | |
| variant="outline" | |
| className="w-full justify-between" | |
| onClick={() => window.open(format.url, "_blank")} | |
| > | |
| <span> | |
| {format.quality} - {format.extension} | |
| </span> | |
| <Download size={20} /> | |
| </Button> | |
| ))} | |
| </div> | |
| )} | |
| </CardContent> | |
| </Card> | |
| ) | |
| } | |