Files
igny8/frontend/src/pages/Thinker/Dashboard.tsx
2025-11-14 04:43:02 +05:00

393 lines
16 KiB
TypeScript

import { useEffect, useState, lazy, Suspense } from "react";
import { Link, useNavigate } from "react-router";
import PageMeta from "../../components/common/PageMeta";
import ComponentCard from "../../components/common/ComponentCard";
import { ProgressBar } from "../../components/ui/progress";
import { ApexOptions } from "apexcharts";
import EnhancedMetricCard from "../../components/dashboard/EnhancedMetricCard";
import PageHeader from "../../components/common/PageHeader";
const Chart = lazy(() => import("react-apexcharts").then((mod) => ({ default: mod.default })));
import {
BoltIcon,
FileTextIcon,
UserIcon,
ShootingStarIcon,
CheckCircleIcon,
ArrowRightIcon,
PlusIcon,
PencilIcon,
ClockIcon,
PieChartIcon,
DocsIcon,
} from "../../icons";
import { useSiteStore } from "../../store/siteStore";
import { useSectorStore } from "../../store/sectorStore";
interface ThinkerStats {
totalPrompts: number;
activeProfiles: number;
strategies: number;
usageThisMonth: number;
}
export default function ThinkerDashboard() {
const navigate = useNavigate();
const { activeSite } = useSiteStore();
const { activeSector } = useSectorStore();
const [stats, setStats] = useState<ThinkerStats | null>(null);
const [loading, setLoading] = useState(true);
const [lastUpdated, setLastUpdated] = useState<Date>(new Date());
// Mock data for now - will be replaced with real API calls
useEffect(() => {
const fetchData = async () => {
setLoading(true);
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 500));
setStats({
totalPrompts: 24,
activeProfiles: 8,
strategies: 12,
usageThisMonth: 342,
});
setLastUpdated(new Date());
setLoading(false);
};
fetchData();
}, [activeSite, activeSector]);
const thinkerModules = [
{
title: "Prompt Library",
description: "Centralized prompt templates and AI instructions",
icon: FileTextIcon,
color: "from-[#ff7a00] to-[#cc5f00]",
path: "/thinker/prompts",
count: stats?.totalPrompts || 0,
status: "active",
},
{
title: "Author Profiles",
description: "Voice templates and writing style guides",
icon: UserIcon,
color: "from-[#0693e3] to-[#0472b8]",
path: "/thinker/profiles",
count: stats?.activeProfiles || 0,
status: "active",
},
{
title: "Content Strategies",
description: "Brand playbooks and content frameworks",
icon: ShootingStarIcon,
color: "from-[#5d4ae3] to-[#3a2f94]",
path: "/thinker/strategies",
count: stats?.strategies || 0,
status: "active",
},
{
title: "Governance",
description: "Track AI usage, compliance, and version control",
icon: PieChartIcon,
color: "from-[#0bbf87] to-[#08966b]",
path: "/thinker/governance",
count: 0,
status: "coming-soon",
},
];
const recentPrompts = [
{
id: 1,
name: "Long-form Article Template",
category: "Content Generation",
usage: 45,
lastUsed: "2 hours ago",
},
{
id: 2,
name: "SEO-Optimized Brief",
category: "Content Planning",
usage: 32,
lastUsed: "5 hours ago",
},
{
id: 3,
name: "Brand Voice - Technical",
category: "Author Profile",
usage: 28,
lastUsed: "1 day ago",
},
];
const chartOptions: ApexOptions = {
chart: {
type: "donut",
height: 300,
},
labels: ["Content Generation", "Content Planning", "Image Prompts", "Other"],
colors: ["#ff7a00", "#0693e3", "#5d4ae3", "#0bbf87"],
legend: {
position: "bottom",
labels: { colors: "#6b7280" },
},
dataLabels: {
enabled: true,
formatter: (val: number) => `${val}%`,
},
};
const chartSeries = [35, 28, 22, 15];
return (
<>
<PageMeta title="Thinker Dashboard - IGNY8" description="Strategic OS and thinking engine" />
<PageHeader title="Thinker Dashboard" />
<div className="space-y-6">
{/* Key Metrics */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<EnhancedMetricCard
title="Prompt Library"
value={stats?.totalPrompts || 0}
icon={DocumentTextIcon}
trend={{ value: 0, isPositive: true }}
color="from-[#ff7a00] to-[#cc5f00]"
loading={loading}
/>
<EnhancedMetricCard
title="Author Profiles"
value={stats?.activeProfiles || 0}
icon={UserIcon}
trend={{ value: 0, isPositive: true }}
color="from-[#0693e3] to-[#0472b8]"
loading={loading}
/>
<EnhancedMetricCard
title="Strategies"
value={stats?.strategies || 0}
icon={ShootingStarIcon}
trend={{ value: 0, isPositive: true }}
color="from-[#5d4ae3] to-[#3a2f94]"
loading={loading}
/>
<EnhancedMetricCard
title="Usage This Month"
value={stats?.usageThisMonth || 0}
icon={BoltIcon}
trend={{ value: 0, isPositive: true }}
color="from-[#0bbf87] to-[#08966b]"
loading={loading}
/>
</div>
{/* Thinker Modules */}
<ComponentCard title="Thinker Modules" desc="Manage prompts, profiles, and strategies">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{thinkerModules.map((module) => {
const Icon = module.icon;
return (
<Link
key={module.title}
to={module.path}
className="rounded-2xl border-2 border-slate-200 bg-white p-6 hover:shadow-xl hover:-translate-y-1 transition-all group"
>
<div className="flex items-start justify-between mb-4">
<div className={`inline-flex size-14 rounded-xl bg-gradient-to-br ${module.color} items-center justify-center text-white shadow-lg`}>
<Icon className="h-7 w-7" />
</div>
{module.status === "coming-soon" && (
<span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-semibold bg-slate-100 text-slate-600">
Soon
</span>
)}
</div>
<h3 className="text-lg font-bold text-slate-900 mb-2">{module.title}</h3>
<p className="text-sm text-slate-600 mb-4">{module.description}</p>
{module.count > 0 && (
<div className="flex items-center justify-between">
<span className="text-2xl font-bold text-slate-900">{module.count}</span>
<ArrowRightIcon className="h-5 w-5 text-slate-400 group-hover:text-[#0693e3] group-hover:translate-x-1 transition" />
</div>
)}
{module.status === "coming-soon" && (
<div className="mt-4 pt-4 border-t border-slate-200">
<span className="text-xs text-slate-500">Coming soon</span>
</div>
)}
</Link>
);
})}
</div>
</ComponentCard>
{/* Recent Activity & Usage Chart */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<ComponentCard title="Prompt Usage Distribution" desc="How your prompts are being used">
<Suspense fallback={<div className="h-[300px] flex items-center justify-center">Loading chart...</div>}>
<Chart options={chartOptions} series={chartSeries} type="donut" height={300} />
</Suspense>
</ComponentCard>
<ComponentCard title="Most Used Prompts" desc="Your top-performing prompt templates">
<div className="space-y-4">
{recentPrompts.map((prompt) => (
<div
key={prompt.id}
className="flex items-center gap-4 p-4 rounded-lg border border-slate-200 bg-white hover:shadow-md transition"
>
<div className="size-10 rounded-lg bg-gradient-to-br from-[#ff7a00] to-[#cc5f00] flex items-center justify-center text-white shadow-md">
<DocumentTextIcon className="h-5 w-5" />
</div>
<div className="flex-1">
<div className="flex items-center justify-between mb-1">
<h4 className="font-semibold text-slate-900">{prompt.name}</h4>
<span className="text-xs font-semibold text-[#0693e3]">{prompt.usage} uses</span>
</div>
<div className="flex items-center gap-3 text-xs text-slate-600">
<span>{prompt.category}</span>
<span></span>
<span>{prompt.lastUsed}</span>
</div>
</div>
</div>
))}
</div>
</ComponentCard>
</div>
{/* Quick Actions */}
<ComponentCard title="Quick Actions" desc="Create new prompts, profiles, or strategies">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<button
onClick={() => navigate("/thinker/prompts")}
className="flex items-center gap-4 p-6 rounded-xl border-2 border-slate-200 bg-white hover:border-[#ff7a00] hover:shadow-lg transition-all group"
>
<div className="size-12 rounded-xl bg-gradient-to-br from-[#ff7a00] to-[#cc5f00] flex items-center justify-center text-white shadow-lg">
<PlusIcon className="h-6 w-6" />
</div>
<div className="flex-1 text-left">
<h4 className="font-semibold text-slate-900 mb-1">New Prompt</h4>
<p className="text-sm text-slate-600">Create a reusable prompt template</p>
</div>
<ArrowRightIcon className="h-5 w-5 text-slate-400 group-hover:text-[#ff7a00] transition" />
</button>
<button
onClick={() => navigate("/thinker/profiles")}
className="flex items-center gap-4 p-6 rounded-xl border-2 border-slate-200 bg-white hover:border-[#0693e3] hover:shadow-lg transition-all group"
>
<div className="size-12 rounded-xl bg-gradient-to-br from-[#0693e3] to-[#0472b8] flex items-center justify-center text-white shadow-lg">
<PlusIcon className="h-6 w-6" />
</div>
<div className="flex-1 text-left">
<h4 className="font-semibold text-slate-900 mb-1">New Author Profile</h4>
<p className="text-sm text-slate-600">Define a writing voice and style</p>
</div>
<ArrowRightIcon className="h-5 w-5 text-slate-400 group-hover:text-[#0693e3] transition" />
</button>
<button
onClick={() => navigate("/thinker/strategies")}
className="flex items-center gap-4 p-6 rounded-xl border-2 border-slate-200 bg-white hover:border-[#5d4ae3] hover:shadow-lg transition-all group"
>
<div className="size-12 rounded-xl bg-gradient-to-br from-[#5d4ae3] to-[#3a2f94] flex items-center justify-center text-white shadow-lg">
<PlusIcon className="h-6 w-6" />
</div>
<div className="flex-1 text-left">
<h4 className="font-semibold text-slate-900 mb-1">New Strategy</h4>
<p className="text-sm text-slate-600">Build a content playbook</p>
</div>
<ArrowRightIcon className="h-5 w-5 text-slate-400 group-hover:text-[#5d4ae3] transition" />
</button>
</div>
</ComponentCard>
{/* Info Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<ComponentCard title="How Thinker Works" desc="Understanding the strategic OS">
<div className="space-y-4">
<div className="flex gap-4">
<div className="flex-shrink-0 size-10 rounded-lg bg-gradient-to-br from-[#ff7a00] to-[#cc5f00] flex items-center justify-center text-white shadow-md">
<BoltIcon className="h-5 w-5" />
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Centralized Control</h4>
<p className="text-sm text-slate-600">
Manage all AI prompts, author voices, and brand guidelines in one place. Changes sync automatically to all content generation.
</p>
</div>
</div>
<div className="flex gap-4">
<div className="flex-shrink-0 size-10 rounded-lg bg-gradient-to-br from-[#0693e3] to-[#0472b8] flex items-center justify-center text-white shadow-md">
<CheckCircleIcon className="h-5 w-5" />
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Version Control</h4>
<p className="text-sm text-slate-600">
Track changes to prompts and strategies with full version history. Roll back to previous versions when needed.
</p>
</div>
</div>
<div className="flex gap-4">
<div className="flex-shrink-0 size-10 rounded-lg bg-gradient-to-br from-[#0bbf87] to-[#08966b] flex items-center justify-center text-white shadow-md">
<ShootingStarIcon className="h-5 w-5" />
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Automated Enforcement</h4>
<p className="text-sm text-slate-600">
Every piece of content automatically uses your defined prompts, author profiles, and brand guidelines.
</p>
</div>
</div>
</div>
</ComponentCard>
<ComponentCard title="Getting Started" desc="Quick guide to using Thinker">
<div className="space-y-3">
<div className="flex items-start gap-3">
<div className="flex-shrink-0 size-8 rounded-full bg-[#0693e3] text-white flex items-center justify-center font-bold text-sm">
1
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Create Author Profiles</h4>
<p className="text-sm text-slate-600">
Define writing voices and styles that match your brand. Each profile can have unique tone, structure, and guidelines.
</p>
</div>
</div>
<div className="flex items-start gap-3">
<div className="flex-shrink-0 size-8 rounded-full bg-[#0bbf87] text-white flex items-center justify-center font-bold text-sm">
2
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Build Prompt Library</h4>
<p className="text-sm text-slate-600">
Create reusable prompt templates for different content types. Use variables to make prompts dynamic and flexible.
</p>
</div>
</div>
<div className="flex items-start gap-3">
<div className="flex-shrink-0 size-8 rounded-full bg-[#5d4ae3] text-white flex items-center justify-center font-bold text-sm">
3
</div>
<div>
<h4 className="font-semibold text-slate-900 mb-1">Define Strategies</h4>
<p className="text-sm text-slate-600">
Create content playbooks that combine prompts, profiles, and guidelines. Apply strategies to specific clusters or content types.
</p>
</div>
</div>
</div>
</ComponentCard>
</div>
</div>
</>
);
}