File size: 5,014 Bytes
333c51a
 
 
3eebcd0
333c51a
 
 
3eebcd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
 
 
 
3eebcd0
 
333c51a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3eebcd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333c51a
 
 
3eebcd0
 
333c51a
 
3eebcd0
 
333c51a
 
3eebcd0
333c51a
 
3eebcd0
333c51a
3eebcd0
333c51a
 
 
 
 
3eebcd0
333c51a
3eebcd0
333c51a
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"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>
  );
}