Files
Pennyzo-webapp-frontend/src/components/AgentPanel.tsx

131 lines
6.3 KiB
TypeScript

import React, { useMemo } from 'react';
export type Agent = {
id: string;
name: string;
color: string; // tailwind gradient colors
emoji: string;
};
interface AgentPanelProps {
agents: Agent[];
activeAgentId: string;
onChangeAgent: (id: string) => void;
}
const AgentPanel: React.FC<AgentPanelProps> = ({ agents, activeAgentId, onChangeAgent }) => {
const active = useMemo(() => agents.find(a => a.id === activeAgentId) || agents[0], [agents, activeAgentId]);
// 8 diverse agents for the 3D carousel
const carouselAgents = useMemo(() => [
{ id: 'hr', name: 'HR Command', emoji: '👥', color: 'from-luxury-gold/30 to-brass/30' },
{ id: 'finance', name: 'Finance Sage', emoji: '💰', color: 'from-bronze/30 to-luxury-gold/30' },
{ id: 'project', name: 'Project Sensei', emoji: '📊', color: 'from-brass/30 to-bronze/30' },
{ id: 'marketing', name: 'Marketing Genius', emoji: '🎯', color: 'from-luxury-gold/30 to-cream/30' },
{ id: 'analytics', name: 'Data Wizard', emoji: '📈', color: 'from-bronze/30 to-brass/30' },
{ id: 'security', name: 'Security Guard', emoji: '🛡️', color: 'from-deep-forest/40 to-luxury-gold/30' },
{ id: 'support', name: 'Support Hero', emoji: '🎧', color: 'from-brass/30 to-rich-brown/30' },
{ id: 'research', name: 'Research Bot', emoji: '🔍', color: 'from-luxury-gold/30 to-bronze/30' }
], []);
return (
<div className="h-full w-full rounded-xl bg-deep-forest/60 backdrop-blur-xl overflow-hidden flex flex-col shadow-inner">
{/* Removed heading & static active name per user request */}
<div className="relative flex-1">
<div className={`absolute inset-0 opacity-35 bg-gradient-to-br ${active.color}`} />
{/* Creative Orbital Agent Display */}
<div className="absolute inset-0 grid place-items-center">
{/* Central Hub */}
<div className="relative">
{/* Outer orbital ring */}
<div className="w-72 h-72 rounded-full border border-luxury-gold/15 relative">
{/* Orbital path indicator */}
<div className="absolute inset-4 rounded-full border border-luxury-gold/10"></div>
<div className="absolute inset-8 rounded-full border border-luxury-gold/5"></div>
{/* Rotating agents on the orbit */}
{carouselAgents.map((agent, index) => {
const angle = (index * 360) / carouselAgents.length;
const isActive = agent.id === activeAgentId;
const radian = (angle * Math.PI) / 180;
const radius = 130;
const x = Math.cos(radian) * radius;
const y = Math.sin(radian) * radius;
return (
<div key={agent.id} className="contents">
<button
onClick={() => onChangeAgent(agent.id)}
className={`absolute w-12 h-12 rounded-xl transition-all duration-300 hover:scale-125 focus:outline-none group ${
isActive
? 'bg-gradient-to-br from-luxury-gold/60 to-brass/60 border-2 border-luxury-gold shadow-[0_0_25px_rgba(197,157,89,0.8)] scale-110 z-10'
: 'bg-deep-forest/70 border border-luxury-gold/30 hover:border-luxury-gold/60 hover:bg-deep-forest/80'
}`}
style={{
left: '50%',
top: '50%',
transform: `translate(${x - 24}px, ${y - 24}px)`,
}}
title={agent.name}
>
<div className="flex flex-col items-center justify-center h-full">
<span className={`text-lg transition-all duration-300 ${isActive ? 'text-deep-forest' : 'text-cream'}`}>
{agent.emoji}
</span>
</div>
{/* Connection line to center for active agent */}
{isActive && (
<div
className="absolute w-0.5 bg-gradient-to-r from-luxury-gold to-transparent opacity-60"
style={{
height: `${radius - 20}px`,
left: '50%',
top: '50%',
transformOrigin: 'top center',
transform: `translateX(-50%) rotate(${180 + angle}deg)`
}}
/>
)}
</button>
{/* Tooltip positioned outside rotating container */}
<div
className="absolute z-50 pointer-events-none"
style={{
left: '50%',
top: '50%',
transform: `translate(${x - 24}px, ${y + 40}px)`,
}}
>
<div className="opacity-0 group-hover:opacity-100 transition-opacity duration-150 bg-deep-forest/95 text-cream/90 text-[11px] px-2 py-1 rounded-md border border-luxury-gold/30 whitespace-nowrap font-montserrat font-medium shadow-[0_2px_4px_rgba(0,0,0,0.4)] -translate-x-1/2">
{agent.name}
</div>
</div>
</div>
);
})}
</div>
{/* Central Control Hub */}
<div className="absolute top-1/2 left-1/2 w-16 h-16 -translate-x-1/2 -translate-y-1/2 z-20">
<div className="w-full h-full rounded-full bg-gradient-to-br from-deep-forest/80 to-rich-brown/60 border border-luxury-gold/30 flex items-center justify-center group cursor-pointer">
<div className="text-center">
<div className="text-xl mb-0.5">🤖</div>
<div className="text-[10px] text-cream/80 font-montserrat font-medium">HUB</div>
</div>
</div>
{/* Removed pulsing rings for a calmer static display */}
</div>
</div>
</div>
{/* Removed floating particle animations */}
</div>
</div>
);
};
export default AgentPanel;