Files
sitemente/components/council/Council.tsx
T
2026-02-27 18:46:52 +01:00

121 lines
4.3 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 { AgentTeam, defaultTeams } from "@/lib/council/types";
import AgentModal from "./AgentModal";
const STORAGE_KEY = "horus:council";
export default function Council() {
const [teams, setTeams] = useState<AgentTeam[]>(defaultTeams);
const [selectedTeam, setSelectedTeam] = useState<string | null>(null);
const [selectedAgent, setSelectedAgent] = useState<string | null>(null);
useEffect(() => {
if (typeof window === "undefined") return;
const saved = localStorage.getItem(STORAGE_KEY);
if (saved) {
try {
setTeams(JSON.parse(saved));
} catch {}
}
}, []);
useEffect(() => {
if (typeof window === "undefined") return;
localStorage.setItem(STORAGE_KEY, JSON.stringify(teams));
}, [teams]);
const getStatusColor = (status: string) => {
switch (status) {
case "working": return "text-yellow-400 bg-yellow-400/20";
case "completed": return "text-green-400 bg-green-400/20";
case "error": return "text-red-400 bg-red-400/20";
default: return "text-white/50 bg-white/10";
}
};
const currentTeam = teams.find(t => t.id === selectedTeam);
return (
<div className="space-y-6">
{/* Header */}
<div>
<h2 className="text-2xl font-bold flex items-center gap-2">
🏛 Council
</h2>
<p className="text-white/60 mt-1">
Manage AI agent teams for each project. I'm the boss I delegate tasks and oversee execution.
</p>
</div>
{/* Team Grid */}
<div className="grid gap-4 md:grid-cols-3">
{teams.map((team) => (
<button
key={team.id}
onClick={() => setSelectedTeam(team.id)}
className={`p-4 rounded-xl border text-left transition ${
selectedTeam === team.id
? "border-brand-pink bg-brand-pink/10"
: "border-white/10 bg-white/5 hover:border-white/30"
}`}
>
<div className="flex items-center gap-3 mb-2">
<span className="text-2xl">{team.icon}</span>
<div>
<p className="font-semibold">{team.name}</p>
<p className="text-xs text-white/50">{team.agents.length} agents</p>
</div>
</div>
<p className="text-sm text-white/60">{team.description}</p>
</button>
))}
</div>
{/* Selected Team Detail */}
{currentTeam && (
<div className="rounded-xl border border-white/10 bg-white/5 p-6">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<span className="text-2xl">{currentTeam.icon}</span>
<div>
<h3 className="font-semibold">{currentTeam.name}</h3>
<p className="text-sm text-white/50">{currentTeam.description}</p>
</div>
</div>
<button onClick={() => setSelectedTeam(null)} className="text-white/50 hover:text-white"></button>
</div>
{/* Agents - Grid Layout */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
{currentTeam.agents.map((agent) => (
<button
key={agent.id}
onClick={() => setSelectedAgent(agent.id)}
className="p-4 rounded-lg border border-white/10 bg-white/5 hover:bg-white/10 hover:border-brand-pink/50 transition text-left"
>
<div className="flex items-center gap-2 mb-2">
<span className={`px-2 py-0.5 rounded text-xs font-medium ${getStatusColor(agent.status)}`}>
{agent.status.toUpperCase()}
</span>
</div>
<p className="font-medium">{agent.name}</p>
<p className="text-xs text-white/50">{agent.role}</p>
<div className="mt-3 pt-2 border-t border-white/10">
<span className="text-xs text-brand-pink">🧑💼 Open </span>
</div>
</button>
))}
</div>
</div>
)}
{/* Agent Modal */}
{selectedAgent && (
<AgentModal agentId={selectedAgent} onClose={() => setSelectedAgent(null)} />
)}
</div>
);
}