diff --git a/DASHBOARD_REDESIGN_PLAN.md b/DASHBOARD_REDESIGN_PLAN.md new file mode 100644 index 00000000..3070e643 --- /dev/null +++ b/DASHBOARD_REDESIGN_PLAN.md @@ -0,0 +1,73 @@ +# Dashboard Redesign Plan + +## Overview +Transform the main Dashboard into a comprehensive, marketing-focused page that serves as the "face" of the application. + +## Structure + +### 1. Hero Section (Marketing-Focused) +- **Purpose**: Explain what IGNY8 is and how it works +- **Content**: + - Compelling headline: "AI-Powered Content Creation Workflow" + - Brief description of the system + - Visual workflow diagram (simplified) + - Key value propositions + +### 2. App-Wide Insights +- **Purpose**: Show aggregated metrics across the entire application +- **Metrics** (NOT duplicating planner/writer dashboards): + - Total Keywords across all sites + - Total Content Pieces created + - Total Images generated + - Overall workflow completion rate + - Recent activity feed + - System health indicators + +### 3. Workflow Explainer (5-7 Steps) +- **Visual Steps**: + 1. **Discover Keywords** → Find high-volume keywords from global database + 2. **Cluster Keywords** → Group related keywords into clusters + 3. **Generate Ideas** → AI creates content ideas from clusters + 4. **Create Tasks** → Convert ideas into actionable writing tasks + 5. **Write Content** → AI generates full content pieces + 6. **Generate Images** → Create featured and in-article images + 7. **Publish** → Content ready for publication + +- **Design**: Interactive step-by-step visual with icons and brief descriptions +- **Action**: Each step can link to relevant page + +### 4. Automation Setup +- **Purpose**: Configure automation settings +- **Sections**: + - **Keywords Automation**: + - How many keywords to take per cycle + - Auto-cluster enabled/disabled + - Cluster settings (max keywords per cluster) + + - **Ideas Automation**: + - Auto-generate ideas from clusters + - Ideas per cluster limit + + - **Content Automation**: + - Auto-create tasks from ideas + - Auto-generate content from tasks + + - **Image Automation**: + - Auto-generate images for content + - Image generation settings + +- **Note**: These are placeholders/settings that will link to Schedules page or have inline configuration + +## Design Principles +- **Marketing-Focused**: Should be impressive enough for marketing screenshots +- **Clear & Simple**: Easy to understand the system at a glance +- **Actionable**: Quick access to key actions +- **Visual**: Heavy use of icons, colors, and visual elements +- **Responsive**: Works on all screen sizes + +## Implementation Notes +- Use existing components where possible (EnhancedMetricCard, WorkflowPipeline, etc.) +- Create new components for workflow explainer +- Automation section can be expandable/collapsible cards +- Consider adding "Quick Actions" section for one-click workflows + diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c1e44265..9e8c4f53 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -49,7 +49,6 @@ const SeedKeywords = lazy(() => import("./pages/Reference/SeedKeywords")); const ReferenceIndustries = lazy(() => import("./pages/Reference/Industries")); // Other Pages - Lazy loaded -const Analytics = lazy(() => import("./pages/Analytics")); const Schedules = lazy(() => import("./pages/Schedules")); // Settings - Lazy loaded @@ -253,11 +252,6 @@ export default function App() { } /> {/* Other Pages */} - - - - } /> diff --git a/frontend/src/config/routes.config.ts b/frontend/src/config/routes.config.ts index 52d97ee1..ae26feec 100644 --- a/frontend/src/config/routes.config.ts +++ b/frontend/src/config/routes.config.ts @@ -51,11 +51,6 @@ export const routes: RouteConfig[] = [ { path: '/thinker/profile', label: 'Profile', breadcrumb: 'Profile' }, ], }, - { - path: '/analytics', - label: 'Analytics', - icon: 'Analytics', - }, { path: '/schedules', label: 'Schedules', diff --git a/frontend/src/layout/AppSidebar.tsx b/frontend/src/layout/AppSidebar.tsx index 02c9d790..a041e8b4 100644 --- a/frontend/src/layout/AppSidebar.tsx +++ b/frontend/src/layout/AppSidebar.tsx @@ -68,11 +68,6 @@ const AppSidebar: React.FC = () => { name: "Dashboard", path: "/", }, - { - icon: , - name: "Analytics", - path: "/analytics", - }, { icon: , name: "Industry / Sectors", diff --git a/frontend/src/pages/Dashboard/Home.tsx b/frontend/src/pages/Dashboard/Home.tsx index 0b9ab28e..2a3e1b63 100644 --- a/frontend/src/pages/Dashboard/Home.tsx +++ b/frontend/src/pages/Dashboard/Home.tsx @@ -1,14 +1,546 @@ +import { useEffect, useState } from "react"; +import { Link } from "react-router"; import PageMeta from "../../components/common/PageMeta"; import CreditBalanceWidget from "../../components/dashboard/CreditBalanceWidget"; import UsageChartWidget from "../../components/dashboard/UsageChartWidget"; +import EnhancedMetricCard from "../../components/dashboard/EnhancedMetricCard"; +import { Card } from "../../components/ui/card"; +import Badge from "../../components/ui/badge/Badge"; +import { + ListIcon, + FileIcon, + FileTextIcon, + BoltIcon, + GroupIcon, + CheckCircleIcon, + ArrowRightIcon, + PlugInIcon +} from "../../icons"; +import { + fetchKeywords, + fetchClusters, + fetchContentIdeas, + fetchTasks, + fetchContent, + fetchContentImages +} from "../../services/api"; +import { useSiteStore } from "../../store/siteStore"; +import { useSectorStore } from "../../store/sectorStore"; +import { useToast } from "../../components/ui/toast/ToastContainer"; + +interface AppInsights { + totalKeywords: number; + totalClusters: number; + totalIdeas: number; + totalTasks: number; + totalContent: number; + totalImages: number; + publishedContent: number; + workflowCompletionRate: number; +} + +const workflowSteps = [ + { + id: 1, + title: "Discover Keywords", + description: "Find high-volume keywords from our global database", + icon: , + color: "blue", + path: "/planner/keyword-opportunities" + }, + { + id: 2, + title: "Cluster Keywords", + description: "Group related keywords into strategic clusters", + icon: , + color: "purple", + path: "/planner/clusters" + }, + { + id: 3, + title: "Generate Ideas", + description: "AI creates content ideas from keyword clusters", + icon: , + color: "orange", + path: "/planner/ideas" + }, + { + id: 4, + title: "Create Tasks", + description: "Convert ideas into actionable writing tasks", + icon: , + color: "indigo", + path: "/writer/tasks" + }, + { + id: 5, + title: "Write Content", + description: "AI generates full content pieces automatically", + icon: , + color: "green", + path: "/writer/content" + }, + { + id: 6, + title: "Generate Images", + description: "Create featured and in-article images", + icon: , + color: "pink", + path: "/writer/images" + }, + { + id: 7, + title: "Publish", + description: "Content ready for publication", + icon: , + color: "success", + path: "/writer/published" + } +]; export default function Home() { + const toast = useToast(); + const { activeSite } = useSiteStore(); + const { activeSector } = useSectorStore(); + + const [insights, setInsights] = useState(null); + const [loading, setLoading] = useState(true); + + // Automation settings state (placeholders) + const [automationSettings, setAutomationSettings] = useState({ + keywords: { + enabled: false, + keywordsPerCycle: 50, + autoCluster: true, + maxKeywordsPerCluster: 10 + }, + ideas: { + enabled: false, + autoGenerate: true, + ideasPerCluster: 3 + }, + content: { + enabled: false, + autoCreateTasks: true, + autoGenerateContent: false + }, + images: { + enabled: false, + autoGenerate: false + } + }); + + const fetchAppInsights = async () => { + try { + setLoading(true); + + // Fetch all data in parallel (without site/sector filters for app-wide view) + const [keywordsRes, clustersRes, ideasRes, tasksRes, contentRes, imagesRes] = await Promise.all([ + fetchKeywords({ page_size: 1 }), // Just get count + fetchClusters({ page_size: 1 }), + fetchContentIdeas({ page_size: 1 }), + fetchTasks({ page_size: 1 }), + fetchContent({ page_size: 1 }), + fetchContentImages({ page_size: 1 }) + ]); + + const totalKeywords = keywordsRes.count || 0; + const totalClusters = clustersRes.count || 0; + const totalIdeas = ideasRes.count || 0; + const totalTasks = tasksRes.count || 0; + const totalContent = contentRes.count || 0; + const totalImages = imagesRes.count || 0; + + // Calculate published content (would need status filter in real implementation) + const publishedContent = 0; // Placeholder + + // Calculate workflow completion rate + const workflowCompletionRate = totalKeywords > 0 + ? Math.round((publishedContent / totalKeywords) * 100) + : 0; + + setInsights({ + totalKeywords, + totalClusters, + totalIdeas, + totalTasks, + totalContent, + totalImages, + publishedContent, + workflowCompletionRate + }); + } catch (error: any) { + console.error('Error fetching insights:', error); + toast.error(`Failed to load insights: ${error.message}`); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchAppInsights(); + }, [activeSite, activeSector]); + + const stepColors = { + blue: "bg-blue-100 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400", + purple: "bg-purple-100 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400", + orange: "bg-orange-100 dark:bg-orange-900/20 text-orange-600 dark:text-orange-400", + indigo: "bg-indigo-100 dark:bg-indigo-900/20 text-indigo-600 dark:text-indigo-400", + green: "bg-green-100 dark:bg-green-900/20 text-green-600 dark:text-green-400", + pink: "bg-pink-100 dark:bg-pink-900/20 text-pink-600 dark:text-pink-400", + success: "bg-green-100 dark:bg-green-900/20 text-green-600 dark:text-green-400" + }; + return ( <> + + {/* Hero Section */} +
+
+
+
+

+ AI-Powered Content Creation Workflow +

+

+ Transform keywords into published content with intelligent automation. + From discovery to publication, IGNY8 streamlines your entire content creation process. +

+
+ + Get Started + + + + Configure Automation + + +
+
+
+
+ + {/* App-Wide Insights */} +
+

+ App-Wide Insights +

+ {loading ? ( +
+ {[1, 2, 3, 4].map((i) => ( +
+ ))} +
+ ) : insights ? ( +
+ } + accentColor="blue" + href="/planner/keywords" + /> + } + accentColor="green" + href="/writer/content" + /> + } + accentColor="purple" + href="/writer/images" + /> + } + accentColor="success" + /> +
+ ) : null} +
+ + {/* Workflow Explainer */} +
+

+ How It Works +

+
+ {workflowSteps.map((step, index) => ( + + +
+
+
+ {step.icon} +
+
+
+ Step {step.id} +
+

+ {step.title} +

+

+ {step.description} +

+ {index < workflowSteps.length - 1 && ( +
+ +
+ )} +
+
+ + ))} +
+
+ + {/* Automation Setup */} +
+
+

+ Automation Setup +

+ + Advanced Settings + + +
+ +
+ {/* Keywords Automation */} + +
+
+
+ +
+

+ Keywords Automation +

+
+ +
+ {automationSettings.keywords.enabled && ( +
+
+ + setAutomationSettings(prev => ({ + ...prev, + keywords: { ...prev.keywords, keywordsPerCycle: parseInt(e.target.value) || 0 } + }))} + className="mt-1 w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800" + /> +
+
+ setAutomationSettings(prev => ({ + ...prev, + keywords: { ...prev.keywords, autoCluster: e.target.checked } + }))} + className="rounded" + /> + +
+
+ )} +
+ + {/* Ideas Automation */} + +
+
+
+ +
+

+ Ideas Automation +

+
+ +
+ {automationSettings.ideas.enabled && ( +
+
+ setAutomationSettings(prev => ({ + ...prev, + ideas: { ...prev.ideas, autoGenerate: e.target.checked } + }))} + className="rounded" + /> + +
+
+ )} +
+ + {/* Content Automation */} + +
+
+
+ +
+

+ Content Automation +

+
+ +
+ {automationSettings.content.enabled && ( +
+
+ setAutomationSettings(prev => ({ + ...prev, + content: { ...prev.content, autoCreateTasks: e.target.checked } + }))} + className="rounded" + /> + +
+
+ setAutomationSettings(prev => ({ + ...prev, + content: { ...prev.content, autoGenerateContent: e.target.checked } + }))} + className="rounded" + /> + +
+
+ )} +
+ + {/* Images Automation */} + +
+
+
+ +
+

+ Images Automation +

+
+ +
+ {automationSettings.images.enabled && ( +
+
+ setAutomationSettings(prev => ({ + ...prev, + images: { ...prev.images, autoGenerate: e.target.checked } + }))} + className="rounded" + /> + +
+
+ )} +
+
+
+ + {/* Credit Balance & Usage (Existing Widgets) */}