sofia-cloud / src /components /dashboard /StorytellingTab.tsx
Gmagl
fix: correcciones críticas y refactorización de componentes
3eebcd0
Raw
History Blame Contribute Delete
5.51 kB
"use client";
import { useState } from "react";
import { Film, Sparkles, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Label } from "@/components/ui/label";
import { toast } from "sonner";
import { apiFetch, getStatusColor, type Story } from "./types";
interface Props { stories: Story[]; onCreated: () => void; }
export default function StorytellingTab({ stories, onCreated }: Props) {
const [storyPrompt, setStoryPrompt] = useState("");
const [storyGenre, setStoryGenre] = useState("lifestyle");
const [storyEpisodes, setStoryEpisodes] = useState(7);
const [storyLoading, setStoryLoading] = useState(false);
const handleCreateStory = async () => {
if (!storyPrompt.trim()) { toast.error("Describe tu historia"); return; }
setStoryLoading(true);
try {
const result = await apiFetch("/storytelling", {
method: "POST",
body: JSON.stringify({ prompt: storyPrompt, genre: storyGenre, totalEpisodes: storyEpisodes }),
});
if (result.success) {
toast.success(`Historia "${result.story?.title}" creada`);
setStoryPrompt("");
onCreated();
} else toast.error(result.error);
} catch { toast.error("Error"); }
finally { setStoryLoading(false); }
};
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card className="bg-slate-900/50 border-slate-800">
<CardHeader><CardTitle className="flex items-center gap-2"><Film className="h-5 w-5 text-purple-400" />Crear Historia</CardTitle></CardHeader>
<CardContent className="space-y-4">
<Textarea placeholder="Describe tu historia... Ej: Una historia de transformación fitness de 30 días..." value={storyPrompt} onChange={(e) => setStoryPrompt(e.target.value)} className="bg-slate-800 border-slate-700 min-h-24" />
<div className="grid grid-cols-2 gap-4">
<div>
<Label className="text-xs text-slate-400">Género</Label>
<Select value={storyGenre} onValueChange={setStoryGenre}>
<SelectTrigger className="bg-slate-800 border-slate-700 mt-1"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="lifestyle">Lifestyle</SelectItem>
<SelectItem value="fitness">Fitness</SelectItem>
<SelectItem value="romance">Romance</SelectItem>
<SelectItem value="drama">Drama</SelectItem>
<SelectItem value="comedy">Comedia</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<Label className="text-xs text-slate-400">Episodios</Label>
<Input type="number" value={storyEpisodes} onChange={(e) => setStoryEpisodes(parseInt(e.target.value) || 7)} className="bg-slate-800 border-slate-700 mt-1" />
</div>
</div>
<Button onClick={handleCreateStory} disabled={storyLoading} className="w-full bg-purple-600 hover:bg-purple-700">
{storyLoading ? <RefreshCw className="h-4 w-4 mr-2 animate-spin" /> : <Sparkles className="h-4 w-4 mr-2" />}Generar Historia
</Button>
</CardContent>
</Card>
<Card className="bg-slate-900/50 border-slate-800">
<CardHeader><CardTitle>Historias Creadas</CardTitle></CardHeader>
<CardContent>
<ScrollArea className="h-64">
{stories.length === 0 ? (
<p className="text-slate-400 text-center py-8">No hay historias</p>
) : (
<div className="space-y-2">
{stories.map((s) => (
<div key={s.id} className="p-3 rounded-lg bg-slate-800/50">
<div className="flex justify-between items-start">
<div>
<p className="font-medium">{s.title}</p>
<p className="text-xs text-slate-400">{s.totalEpisodes} episodios • {s.genre}</p>
</div>
<Badge className={getStatusColor(s.status)}>{s.status}</Badge>
</div>
</div>
))}
</div>
)}
</ScrollArea>
</CardContent>
</Card>
</div>
);
}