Files
sitemente/components/mission-control/MissionControlDashboard.tsx
T
2026-02-22 16:35:10 +00:00

565 lines
32 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect } from "react";
import { useMissionControl } from "@/lib/mission-control/store";
import { TaskStatus } from "@/lib/mission-control/types";
import HorusChat from "./HorusChat";
import MondayBoard from "./MondayBoard";
import { TaskCardsPanel } from "./TaskCardsPanel";
import { TaskHistoryPanel } from "./TaskHistoryPanel";
import { TradingPanel } from "./TradingPanel";
import AIManagement from "@/components/ai-management/AIManagement";
import Council from "@/components/council/Council";
interface SidebarItem {
id: string;
name: string;
icon: string;
color?: string;
category: string;
}
interface SidebarCategory {
id: string;
name: string;
icon: string;
items: SidebarItem[];
}
const sidebarCategories: SidebarCategory[] = [
{ id: "leads", name: "Leads", icon: "📈", items: [
{ id: "leads-crm", name: "CRM", icon: "📊", category: "leads" },
{ id: "dashboard", name: "Client Dashboard", icon: "🏢", category: "dashboard" },
]},
{ id: "projects", name: "Projects", icon: "🎯", items: [
{ id: "monday", name: "Monday Board", icon: "📊", category: "monday" },
{ id: "sitemente", name: "SiteMente", icon: "🌐", color: "#ff7bc0", category: "projects" },
{ id: "demos", name: "Demo Pages", icon: "🎨", category: "demos" },
{ id: "holacompi", name: "HolaCompi", icon: "🤝", color: "#6366f1", category: "projects" },
{ id: "arabredox", name: "Arabredox", icon: "💚", color: "#22c55e", category: "projects" },
{ id: "infrastructure", name: "Infra", icon: "⚙️", color: "#10b981", category: "projects" },
]},
{ id: "trading", name: "Trading", icon: "📈", items: [
{ id: "trading-research", name: "Deep Research", icon: "🔬", category: "trading" },
{ id: "trading-strategies", name: "Strategies", icon: "🎯", category: "trading" },
{ id: "trading-execution", name: "Execution", icon: "⚡", category: "trading" },
{ id: "trading-journal", name: "Journal", icon: "📔", category: "trading" },
]},
{ id: "tasks", name: "Tasks", icon: "✓", items: [
{ id: "task-cards", name: "Task Cards", icon: "☑️", category: "task-cards" },
{ id: "task-history", name: "History", icon: "📜", category: "task-history" },
]},
{ id: "chat", name: "Chat", icon: "💬", items: [
{ id: "voice", name: "Voice Chat", icon: "🎤", category: "chat" },
{ id: "horus-chat", name: "Horus Chat", icon: "👁️", category: "horus-chat" },
]},
{ id: "council", name: "Council", icon: "🏛️", items: [
{ id: "teams", name: "Agent Teams", icon: "👥", category: "council" },
{ id: "golden-notes", name: "Golden Notes", icon: "🔥", category: "golden-notes" },
{ id: "daily-feedback", name: "Daily Feedback", icon: "📝", category: "daily-feedback" },
{ id: "ai-settings", name: "AI Settings", icon: "🤖", category: "council-settings" },
]},
{ id: "calendar", name: "Calendar", icon: "📅", items: [
{ id: "brief", name: "Morning Brief", icon: "☀️", category: "calendar" },
]},
{ id: "memory", name: "Memory", icon: "🧠", items: [
{ id: "logs", name: "Session Logs", icon: "📝", category: "memory" },
]},
{ id: "docs", name: "Docs", icon: "📚", items: [
{ id: "docs-index", name: "Documentation", icon: "📚", category: "docs" },
]},
];
const statusConfig: Record<TaskStatus, { label: string; color: string }> = {
todo: { label: "To Do", color: "text-white/70" },
in_progress: { label: "In Progress", color: "text-yellow-400" },
done: { label: "Done", color: "text-green-400" },
blocked: { label: "Blocked", color: "text-red-400" },
paused: { label: "Paused", color: "text-gray-400" },
};
interface MissionControlDashboardProps {
onLogout?: () => void;
}
export default function MissionControlDashboard({ onLogout }: MissionControlDashboardProps) {
const { tasks, toggleTask, updateTaskStatus, addTask, getProjectProgress, getTasksByProject } = useMissionControl();
const [mounted, setMounted] = useState(false);
const [selectedItem, setSelectedItem] = useState<string>("sitemente");
const [filter, setFilter] = useState<TaskStatus | "all">("all");
const [expandedCategories, setExpandedCategories] = useState<string[]>(["projects"]);
const [searchQuery, setSearchQuery] = useState("");
const [showAddTask, setShowAddTask] = useState(false);
const [newTaskTitle, setNewTaskTitle] = useState("");
const [newTaskProject, setNewTaskProject] = useState("sitemente");
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "/" && !e.ctrlKey && !e.metaKey) {
const target = e.target as HTMLElement;
if (target.tagName !== "INPUT" && target.tagName !== "TEXTAREA") {
e.preventDefault();
document.getElementById("search-input")?.focus();
}
}
if (e.key === "n" && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
setShowAddTask(true);
}
if (e.key === "Escape") {
setShowAddTask(false);
setSearchQuery("");
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
let selectedCategory = sidebarCategories.find(c => c.items.some(i => i.id === selectedItem));
let currentItem = selectedCategory?.items.find(i => i.id === selectedItem);
const projectTasks = currentItem?.category === "projects" ? getTasksByProject(selectedItem as any) : tasks;
const filteredTasks = filter === "all" ? projectTasks : projectTasks.filter((t) => t.status === filter);
const searchedTasks = searchQuery ? filteredTasks.filter(t => t.title.toLowerCase().includes(searchQuery.toLowerCase())) : filteredTasks;
const progress = currentItem?.category === "projects" ? getProjectProgress(selectedItem as any) : 0;
const toggleCategory = (catId: string) => setExpandedCategories(prev => prev.includes(catId) ? prev.filter(id => id !== catId) : [...prev, catId]);
const collapseAll = () => setExpandedCategories([]);
const todayTasks = projectTasks.filter(t => t.priority === "critical" || t.status === "in_progress").slice(0, 3);
const exportTasks = () => {
const data = JSON.stringify(projectTasks, null, 2);
const blob = new Blob([data], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `tasks-${new Date().toISOString().split("T")[0]}.json`;
a.click();
};
const handleAddTask = () => {
if (!newTaskTitle.trim()) return;
addTask({ title: newTaskTitle, description: "", status: "todo", priority: "medium", project: newTaskProject as any });
setShowAddTask(false);
setNewTaskTitle("");
};
if (!mounted) {
return (
<div className="min-h-screen bg-[#1a1625] text-white flex items-center justify-center">
<div className="text-white/60">Loading...</div>
</div>
);
}
// Golden Notes - moved to Council tab
// Removed from home page per user request
return (
<div className="min-h-screen bg-[#1a1625] text-white flex">
<aside className="w-64 border-r border-white/10 bg-[#1a1625] p-4">
<div className="flex items-center gap-3 mb-6 pb-4 border-b border-white/10">
<div className="w-10 h-10 rounded-xl bg-brand-pink flex items-center justify-center text-xl">👁</div>
<div><h1 className="font-bold">Mission Control</h1><p className="text-xs text-white/50">Horus AI Assistant</p></div>
</div>
<nav className="space-y-1">
{sidebarCategories.map((category) => (
<div key={category.id}>
<button onClick={() => toggleCategory(category.id)} className="w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm font-medium text-white/70 hover:bg-white/5 hover:text-white transition">
<span className="flex items-center gap-2"><span>{category.icon}</span><span>{category.name}</span></span>
<span className={`transition ${expandedCategories.includes(category.id) ? "rotate-90" : ""}`}></span>
</button>
{expandedCategories.includes(category.id) && (
<div className="ml-4 mt-1 space-y-1">
{category.items.map((item) => (
<button key={item.id} onClick={() => setSelectedItem(item.id)} className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm transition ${selectedItem === item.id ? "bg-white/10 text-white border border-white/20" : "text-white/60 hover:bg-white/5 hover:text-white"}`}>
<span>{item.icon}</span><span>{item.name}</span>
</button>
))}
</div>
)}
</div>
))}
</nav>
<div className="mt-6 pt-4 border-t border-white/10">
<p className="text-xs text-white/40 uppercase mb-2 px-3">Quick</p>
<a href="/" className="flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-white/60 hover:bg-white/5 hover:text-white transition">🏠 SiteMente Site</a>
<button onClick={collapseAll} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-white/60 hover:bg-white/5 hover:text-white transition"> Collapse All</button>
{onLogout && (
<button onClick={onLogout} className="w-full flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-red-400 hover:bg-red-500/10 transition">🚪 Logout</button>
)}
</div>
</aside>
<main className="flex-1 p-6 overflow-y-auto">
<header className="flex items-center justify-between mb-6 pb-4 border-b border-white/10">
<div className="flex items-center gap-4">
<button onClick={() => { setSelectedItem("sitemente"); setExpandedCategories(["projects"]); }} className="w-10 h-10 rounded-xl bg-brand-pink flex items-center justify-center text-xl hover:bg-[#ff7bc0] transition">👁</button>
<div>
<h2 className="text-xl font-bold flex items-center gap-2"><span>{currentItem?.icon}</span><span>{currentItem?.name}</span></h2>
<p className="text-sm text-white/50">{currentItem?.category === "projects" ? `${progress}% complete` : `${tasks.length} total tasks`}</p>
</div>
</div>
{currentItem?.category === "projects" && (
<div className="h-12 w-12 rounded-full border-4 border-brand-pink bg-white/10">
<svg className="h-full w-full -rotate-90" viewBox="0 0 36 36">
<circle cx="18" cy="18" r="16" fill="none" stroke="currentColor" strokeWidth="3" className="text-white/20" />
<circle cx="18" cy="18" r="16" fill="none" stroke="currentColor" strokeWidth="3" strokeDasharray={`${progress}, 100`} className="text-brand-pink" />
</svg>
</div>
)}
</header>
{currentItem?.category === "chat" && <div className="rounded-xl border border-white/10 bg-white/5 p-6"><HorusChat /></div>}
{currentItem?.category === "horus-chat" && (
<div className="h-full">
<HorusChat />
</div>
)}
{currentItem?.category === "monday" && <div className="h-full"><MondayBoard /></div>}
{currentItem?.category === "council" && currentItem?.id === "teams" && <div className="rounded-xl border border-white/10 bg-white/5 p-6"><Council /></div>}
{currentItem?.category === "council-settings" && <div className="rounded-xl border border-white/10 bg-white/5 p-6"><AIManagement /></div>}
{currentItem?.category === "golden-notes" && (
<div className="rounded-xl border border-amber-500/30 bg-gradient-to-br from-[#1a1625] to-[#2d1f3d] p-6">
<div className="flex items-center gap-2 mb-4">
<span className="text-amber-400 text-2xl">🔥</span>
<h3 className="font-bold text-amber-400 text-xl">Golden Notes</h3>
</div>
<p className="text-white/60 mb-6">Insights and wisdom from the agent council</p>
<div className="space-y-4">
<div className="p-4 rounded-lg bg-white/5 border border-amber-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-amber-400">👁</span>
<span className="font-semibold text-amber-400">HORUS</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li> Your frame: "safe" should be "leading"</li>
<li> Own the Egyptian-Scandinavian contrast</li>
<li> Fun first, lead often, let go</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-blue-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-blue-400">👁</span>
<span className="font-semibold text-blue-400">THOTH (Strategy)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li> Stop tracking "case notes" creates attachment</li>
<li> Signal intent early: comfort curiosity desire</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-green-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-green-400">🏗</span>
<span className="font-semibold text-green-400">PTAH (Builder)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li> You're over-engineering. Strip it down.</li>
<li>• Friendzone = too much comfort before desire</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-yellow-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-yellow-400">📜</span>
<span className="font-semibold text-yellow-400">SESHAT (Records)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li>• Delete case notes entirely</li>
<li>• Write forward, analyze backward less</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-purple-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-purple-400">🐺</span>
<span className="font-semibold text-purple-400">ANUBIS (Connector)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li>• Calm + leading = attractive | Calm + passive = friend</li>
<li>• Make small demands, create reasons to meet</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-cyan-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-cyan-400">📈</span>
<span className="font-semibold text-cyan-400">THOTH TRADING (Observer)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li>• You're in accumulation, need breakout</li>
<li> Introduce escalation every 7-10 messages</li>
</ul>
</div>
<div className="p-4 rounded-lg bg-white/5 border border-red-500/20">
<div className="flex items-center gap-2 mb-2">
<span className="text-red-400"></span>
<span className="font-semibold text-red-400">SEKHMET (Action)</span>
</div>
<ul className="text-sm text-white/80 space-y-1">
<li> You're too nice in approach</li>
<li>• Tease more, challenge more, lead more</li>
</ul>
</div>
</div>
</div>
)}
{currentItem?.category === "daily-feedback" && (
<div className="rounded-xl border border-blue-500/30 bg-gradient-to-br from-[#1a1625] to-[#1a2a3d] p-6">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2">
<span className="text-blue-400 text-2xl">📝</span>
<h3 className="font-bold text-blue-400 text-xl">Daily Feedback</h3>
</div>
<span className="text-xs text-white/50">{new Date().toLocaleDateString()}</span>
</div>
<p className="text-white/60 mb-4">End-of-day insights from all agents. Select notes to promote to Golden.</p>
<div className="space-y-4 mb-6">
<div className="p-4 rounded-lg bg-white/5 border border-blue-500/20">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<span className="text-amber-400">👁️</span>
<span className="font-semibold">HORUS</span>
</div>
<label className="flex items-center gap-2 text-xs cursor-pointer">
<input type="checkbox" className="w-4 h-4 rounded accent-brand-pink" />
<span className="text-white/60">Promote to Golden</span>
</label>
</div>
<textarea className="w-full bg-white/5 border border-white/10 rounded-lg p-3 text-sm text-white/80 resize-none" rows={3} placeholder="What did you learn today?" />
</div>
<div className="p-4 rounded-lg bg-white/5 border border-blue-500/20">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<span className="text-blue-400">👁️</span>
<span className="font-semibold">THOTH</span>
</div>
<label className="flex items-center gap-2 text-xs cursor-pointer">
<input type="checkbox" className="w-4 h-4 rounded accent-brand-pink" />
<span className="text-white/60">Promote to Golden</span>
</label>
</div>
<textarea className="w-full bg-white/5 border border-white/10 rounded-lg p-3 text-sm text-white/80 resize-none" rows={3} placeholder="What did you learn today?" />
</div>
<div className="p-4 rounded-lg bg-white/5 border border-blue-500/20">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<span className="text-green-400">🏗️</span>
<span className="font-semibold">PTAH</span>
</div>
<label className="flex items-center gap-2 text-xs cursor-pointer">
<input type="checkbox" className="w-4 h-4 rounded accent-brand-pink" />
<span className="text-white/60">Promote to Golden</span>
</label>
</div>
<textarea className="w-full bg-white/5 border border-white/10 rounded-lg p-3 text-sm text-white/80 resize-none" rows={3} placeholder="What did you learn today?" />
</div>
<div className="p-4 rounded-lg bg-white/5 border border-blue-500/20">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<span className="text-purple-400">🐺</span>
<span className="font-semibold">ANUBIS</span>
</div>
<label className="flex items-center gap-2 text-xs cursor-pointer">
<input type="checkbox" className="w-4 h-4 rounded accent-brand-pink" />
<span className="text-white/60">Promote to Golden</span>
</label>
</div>
<textarea className="w-full bg-white/5 border border-white/10 rounded-lg p-3 text-sm text-white/80 resize-none" rows={3} placeholder="What did you learn today?" />
</div>
</div>
<button className="w-full py-3 bg-brand-pink hover:bg-[#ff7bc0] rounded-lg font-medium transition">
💾 Save & Promote Selected
</button>
<p className="text-xs text-white/40 mt-4 text-center">
Feedback auto-generates at 9pm CET. Edit and promote what matters.
</p>
</div>
)}
{currentItem?.category === "trading" && <TradingPanel />}
{currentItem?.category === "calendar" && (
<div className="space-y-4">
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<h3 className="text-lg font-semibold mb-4">📅 Morning Brief</h3>
<p className="text-white/60 mb-4">Daily intelligence at 6am CET</p>
<a href="/morning-brief" className="inline-flex items-center gap-2 px-4 py-2 bg-brand-pink rounded-lg text-sm font-medium hover:bg-[#ff7bc0] transition">☀️ Open Calendar</a>
</div>
<HorusChat />
</div>
)}
{currentItem?.category === "memory" && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<h3 className="text-lg font-semibold mb-4">🧠 Memory & Logs</h3>
<p className="text-white/60 mb-4">Session history and daily logs</p>
<div className="space-y-2 text-sm text-white/70"><p>Memory is stored in:</p><ul className="text-white/50 space-y-1"><li>• localStorage (browser)</li><li>• GitHub repo (daily commits)</li><li>• MEMORY.md (curated)</li></ul></div>
</div>
)}
{currentItem?.category === "docs" && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<h3 className="text-lg font-semibold mb-4">📚 Documentation</h3>
<p className="text-white/60 mb-4">Long-term docs and guides</p>
<div className="space-y-3">
<a href="/mission-control/docs" target="_blank" className="flex items-center gap-3 p-3 rounded-lg bg-white/5 hover:bg-white/10 transition">
<span className="text-2xl">📖</span>
<div><p className="font-medium">Docs Index</p><p className="text-xs text-white/50">All documentation</p></div>
</a>
<a href="https://github.com/HaithamEKhalifa/SiteMente" target="_blank" className="flex items-center gap-3 p-3 rounded-lg bg-white/5 hover:bg-white/10 transition">
<span className="text-2xl">🐙</span>
<div><p className="font-medium">GitHub Repo</p><p className="text-xs text-white/50">Source code & issues</p></div>
</a>
<a href="https://sitemente.com" target="_blank" className="flex items-center gap-3 p-3 rounded-lg bg-white/5 hover:bg-white/10 transition">
<span className="text-2xl">🌐</span>
<div><p className="font-medium">Live Site</p><p className="text-xs text-white/50">sitemente.com</p></div>
</a>
</div>
</div>
)}
{/* Task Cards View */}
{currentItem?.category === "task-cards" && (
<TaskCardsPanel tasks={tasks} toggleTask={toggleTask} />
)}
{/* Task History View */}
{currentItem?.category === "task-history" && (
<TaskHistoryPanel />
)}
{currentItem?.category === "demos" && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<div className="text-center py-8">
<div className="text-5xl mb-4">🎨</div>
<h3 className="text-xl font-bold mb-2">Demo Pages</h3>
<p className="text-white/60 mb-6">Vertical demo pages for SiteMente</p>
<div className="flex flex-wrap justify-center gap-3">
<a href="/demos" target="_blank" className="px-4 py-2 bg-brand-pink rounded-lg text-sm font-medium hover:bg-[#ff7bc0] transition">🌐 All Demos</a>
<a href="/demos?vertical=real-estate" target="_blank" className="px-4 py-2 bg-green-500/20 border border-green-500/30 rounded-lg text-sm hover:bg-green-500/30 transition">🏠 Real Estate</a>
<a href="/demos?vertical=restaurant" target="_blank" className="px-4 py-2 bg-yellow-500/20 border border-yellow-500/30 rounded-lg text-sm hover:bg-yellow-500/30 transition">🍽️ Restaurant</a>
<a href="/demos?vertical=clinic" target="_blank" className="px-4 py-2 bg-cyan-500/20 border border-cyan-500/30 rounded-lg text-sm hover:bg-cyan-500/30 transition">⚕️ Clinic</a>
<a href="/demos?vertical=home-services" target="_blank" className="px-4 py-2 bg-purple-500/20 border border-purple-500/30 rounded-lg text-sm hover:bg-purple-500/30 transition">🔧 Home Services</a>
</div>
</div>
</div>
)}
{currentItem?.category === "leads" && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<div className="text-center py-8">
<div className="text-5xl mb-4">📈</div>
<h3 className="text-xl font-bold mb-2">Leads CRM</h3>
<p className="text-white/60 mb-6">Track and manage your leads</p>
<div className="flex flex-wrap justify-center gap-3">
<a href="/leads" target="_blank" className="px-4 py-2 bg-brand-pink rounded-lg text-sm font-medium hover:bg-[#ff7bc0] transition">📈 Open Leads CRM</a>
</div>
</div>
</div>
)}
{currentItem?.category === "dashboard" && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<div className="text-center py-8">
<div className="text-5xl mb-4">🏢</div>
<h3 className="text-xl font-bold mb-2">Client Dashboard</h3>
<p className="text-white/60 mb-6">Where your clients see bookings & leads</p>
<div className="flex flex-wrap justify-center gap-3">
<a href="/dashboard" target="_blank" className="px-4 py-2 bg-brand-pink rounded-lg text-sm font-medium hover:bg-[#ff7bc0] transition">🏢 Open Dashboard Demo</a>
</div>
</div>
</div>
)}
{currentItem?.category === "projects" && (
<>
{todayTasks.length > 0 && (
<div className="mb-6 p-4 rounded-xl border border-brand-pink/30 bg-brand-pink/10">
<p className="text-xs text-brand-pink font-medium mb-2">🎯 TODAY'S FOCUS</p>
<div className="space-y-2">{todayTasks.map(task => (
<div key={task.id} className="flex items-center gap-2 text-sm">
<span className={`w-2 h-2 rounded-full ${task.status === "in_progress" ? "bg-yellow-400" : "bg-red-400"}`} />
<span className="truncate">{task.title}</span>
</div>
))}</div>
</div>
)}
<div className="flex items-center gap-3 mb-4">
<div className="flex-1 relative">
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-white/40">🔍</span>
<input id="search-input" type="text" value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="Search tasks... (press /)" className="w-full bg-white/10 border border-white/20 rounded-lg pl-9 pr-4 py-2 text-sm placeholder:text-white/40 focus:outline-none focus:border-brand-pink" />
</div>
<button onClick={() => setShowAddTask(!showAddTask)} className="px-4 py-2 bg-brand-pink rounded-lg text-sm font-medium hover:bg-[#ff7bc0] transition">+ Add</button>
<button onClick={exportTasks} className="px-3 py-2 bg-white/10 rounded-lg text-sm hover:bg-white/20 transition">📥</button>
</div>
{showAddTask && (
<div className="mb-4 p-4 rounded-xl border border-brand-pink/30 bg-brand-pink/5">
<input type="text" value={newTaskTitle} onChange={(e) => setNewTaskTitle(e.target.value)} placeholder="New task title..." className="w-full bg-white/10 border border-white/20 rounded-lg px-4 py-2 text-sm placeholder:text-white/40 focus:outline-none focus:border-brand-pink mb-3" autoFocus onKeyDown={(e) => e.key === "Enter" && handleAddTask()} />
<div className="flex items-center gap-2">
<select value={newTaskProject} onChange={(e) => setNewTaskProject(e.target.value)} className="bg-white/10 border border-white/20 rounded-lg px-3 py-1.5 text-sm">
<option value="sitemente">SiteMente</option>
<option value="holacompi">HolaCompi</option>
<option value="arabredox">Arabredox</option>
<option value="infrastructure">Infrastructure</option>
</select>
<button onClick={handleAddTask} className="px-4 py-1.5 bg-brand-pink rounded-lg text-sm font-medium">Add Task</button>
<button onClick={() => setShowAddTask(false)} className="px-3 py-1.5 text-sm text-white/60 hover:text-white">Cancel</button>
</div>
</div>
)}
<div className="mb-4 grid grid-cols-4 gap-3">
{(["todo", "in_progress", "done", "blocked"] as TaskStatus[]).map((status) => {
const count = projectTasks.filter((t) => t.status === status).length;
const config = statusConfig[status];
return (
<button key={status} onClick={() => setFilter(filter === status ? "all" : status)} className={`rounded-xl border p-3 text-center transition ${filter === status ? "border-white/40 bg-white/10" : "border-white/10 bg-white/5 hover:border-white/20"}`}>
<p className={`text-xl font-bold ${config.color}`}>{count}</p>
<p className="text-xs text-white/50">{config.label}</p>
</button>
);
})}
</div>
<div className="rounded-xl border border-white/10 bg-white/5">
<div className="border-b border-white/10 px-4 py-3">
<div className="flex items-center justify-between">
<h2 className="font-semibold">{currentItem?.name}{searchQuery && <span className="ml-2 text-white/50 text-sm">({searchedTasks.length} results)</span>}</h2>
<p className="text-sm text-white/50">{filteredTasks.filter((t) => t.status === "done").length} / {filteredTasks.length} done</p>
</div>
</div>
<div className="divide-y divide-white/5 max-h-[500px] overflow-y-auto">
{searchedTasks.map((task) => (
<div key={task.id} className={`flex items-center gap-3 px-4 py-3 transition hover:bg-white/5 ${task.status === "done" ? "opacity-50" : ""}`}>
<button onClick={() => toggleTask(task.id)} className={`flex-shrink-0 w-5 h-5 rounded-full border-2 flex items-center justify-center transition ${task.status === "done" ? "border-green-500 bg-green-500 text-white" : "border-white/30 hover:border-white/50"}`}>
{task.status === "done" && <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" /></svg>}
</button>
<div className="flex-1 min-w-0"><p className={`text-sm font-medium truncate ${task.status === "done" ? "line-through text-white/50" : ""}`}>{task.title}</p></div>
{task.priority === "critical" && <span className="px-2 py-0.5 rounded-full bg-red-500/20 text-red-400 text-xs">CRITICAL</span>}
<select value={task.status} onChange={(e) => updateTaskStatus(task.id, e.target.value as TaskStatus)} className="text-xs bg-transparent border border-white/20 rounded px-2 py-1">
<option value="todo">To Do</option><option value="in_progress">In Progress</option><option value="done">Done</option><option value="blocked">Blocked</option>
</select>
</div>
))}
</div>
{searchedTasks.length === 0 && <div className="px-4 py-8 text-center text-white/50 text-sm">No tasks match.</div>}
</div>
</>
)}
</main>
</div>
);
}