Spaces:
Build error
Build error
| "use client"; | |
| import { useState, useEffect, useCallback } from "react"; | |
| import { Menu, X, RefreshCw } from "lucide-react"; | |
| import { Button } from "@/components/ui/button"; | |
| import { toast } from "sonner"; | |
| import { | |
| DashboardSidebar, | |
| PromptEngineerTab, | |
| ImagesTab, | |
| VideosTab, | |
| MonetizationTab, | |
| PostsTab, | |
| StorytellingTab, | |
| AutomationTab, | |
| InfluencersTab, | |
| PetsTab, | |
| TrendsTab, | |
| ContentTab, | |
| } from "@/components/dashboard"; | |
| import { apiFetch, type Content, type Platform, type Post, type Story, type Automation, type Pet } from "@/components/dashboard/types"; | |
| export default function Dashboard() { | |
| const [sidebarOpen, setSidebarOpen] = useState(true); | |
| const [activeTab, setActiveTab] = useState("prompt-engineer"); | |
| const [loading, setLoading] = useState(false); | |
| // Shared state loaded at dashboard level | |
| const [contents, setContents] = useState<Content[]>([]); | |
| const [platforms, setPlatforms] = useState<Platform[]>([]); | |
| const [posts, setPosts] = useState<Post[]>([]); | |
| const [stories, setStories] = useState<Story[]>([]); | |
| const [automations, setAutomations] = useState<Automation[]>([]); | |
| const [pets, setPets] = useState<Pet[]>([]); | |
| const [includePetInContent, setIncludePetInContent] = useState(false); | |
| const [stats, setStats] = useState({ images: 0, videos: 0, stories: 0, automations: 0, pets: 0 }); | |
| const loadData = useCallback(async () => { | |
| setLoading(true); | |
| try { | |
| const [contentRes, platformsRes, postsRes, storiesRes, automationRes, petsRes] = await Promise.all([ | |
| apiFetch("/content"), | |
| apiFetch("/monetization"), | |
| apiFetch("/posts"), | |
| apiFetch("/storytelling"), | |
| apiFetch("/automation"), | |
| apiFetch("/pets"), | |
| ]); | |
| if (contentRes.success) { | |
| setContents(contentRes.contents); | |
| setStats({ | |
| images: contentRes.stats?.images || 0, | |
| videos: contentRes.stats?.videos || 0, | |
| stories: storiesRes?.total || 0, | |
| automations: automationRes?.stats?.total || 0, | |
| pets: petsRes?.total || 0, | |
| }); | |
| } | |
| if (platformsRes.success) setPlatforms(platformsRes.userPlatforms); | |
| if (postsRes.success) setPosts(postsRes.posts); | |
| if (storiesRes.success) setStories(storiesRes.stories); | |
| if (automationRes.success) setAutomations(automationRes.automations); | |
| if (petsRes.success) setPets(petsRes.pets); | |
| } catch { | |
| toast.error("Error al cargar datos"); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }, []); | |
| useEffect(() => { loadData(); }, [loadData]); | |
| const renderActiveTab = () => { | |
| switch (activeTab) { | |
| case "prompt-engineer": | |
| return <PromptEngineerTab pets={pets} includePetInContent={includePetInContent} setIncludePetInContent={setIncludePetInContent} onImageGenerated={loadData} />; | |
| case "images": | |
| return <ImagesTab pets={pets} includePetInContent={includePetInContent} setIncludePetInContent={setIncludePetInContent} onGenerated={loadData} />; | |
| case "videos": | |
| return <VideosTab onGenerated={loadData} />; | |
| case "monetization": | |
| return <MonetizationTab />; | |
| case "posts": | |
| return <PostsTab posts={posts} onCreated={loadData} />; | |
| case "storytelling": | |
| return <StorytellingTab stories={stories} onCreated={loadData} />; | |
| case "automation": | |
| return <AutomationTab automations={automations} onCreated={loadData} />; | |
| case "influencers": | |
| return <InfluencersTab />; | |
| case "pets": | |
| return <PetsTab pets={pets} onCreated={loadData} />; | |
| case "trends": | |
| return <TrendsTab />; | |
| case "content": | |
| return <ContentTab contents={contents} />; | |
| default: | |
| return null; | |
| } | |
| }; | |
| return ( | |
| <div className="min-h-screen bg-gradient-to-b from-slate-950 via-slate-900 to-slate-950 text-white"> | |
| <DashboardSidebar sidebarOpen={sidebarOpen} activeTab={activeTab} setActiveTab={setActiveTab} stats={stats} /> | |
| <div className={`transition-all duration-300 ${sidebarOpen ? "ml-64" : "ml-0"}`}> | |
| {/* Header */} | |
| <header className="sticky top-0 bg-slate-900/80 backdrop-blur-xl border-b border-slate-800 z-40"> | |
| <div className="flex items-center justify-between px-6 py-3"> | |
| <div className="flex items-center gap-3"> | |
| <Button variant="ghost" size="icon" onClick={() => setSidebarOpen(!sidebarOpen)}> | |
| {sidebarOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />} | |
| </Button> | |
| <h2 className="text-lg font-semibold capitalize">{activeTab.replace(/-/g, " ")}</h2> | |
| </div> | |
| <Button variant="ghost" size="sm" onClick={loadData} disabled={loading}> | |
| <RefreshCw className={`h-4 w-4 mr-2 ${loading ? "animate-spin" : ""}`} />Actualizar | |
| </Button> | |
| </div> | |
| </header> | |
| {/* Main Content */} | |
| <main className="p-6"> | |
| {renderActiveTab()} | |
| </main> | |
| </div> | |
| </div> | |
| ); | |
| } | |