Spaces:
Build error
Build error
| "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> | |
| ); | |
| } | |