feat(agent-office): add SidePanel container with 4-tab layout
This commit is contained in:
73
src/pages/agent-office/components/SidePanel.jsx
Normal file
73
src/pages/agent-office/components/SidePanel.jsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// src/pages/agent-office/components/SidePanel.jsx
|
||||||
|
import { useState } from 'react';
|
||||||
|
import CommandTab from './CommandTab.jsx';
|
||||||
|
import TaskTab from './TaskTab.jsx';
|
||||||
|
import TokenTab from './TokenTab.jsx';
|
||||||
|
import LogTab from './LogTab.jsx';
|
||||||
|
|
||||||
|
const AGENT_META = {
|
||||||
|
stock: { displayName: '주식 트레이더', emoji: '📈', color: '#4488cc' },
|
||||||
|
music: { displayName: '음악 프로듀서', emoji: '🎵', color: '#44aa88' },
|
||||||
|
blog: { displayName: '블로그 마케터', emoji: '✍️', color: '#d97706' },
|
||||||
|
realestate: { displayName: '청약 애널리스트', emoji: '🏢', color: '#c026d3' },
|
||||||
|
lotto: { displayName: '로또 큐레이터', emoji: '🎱', color: '#ef4444' }
|
||||||
|
};
|
||||||
|
|
||||||
|
const TABS = ['Commands', 'Tasks', 'Tokens', 'Logs'];
|
||||||
|
|
||||||
|
export default function SidePanel({ agentId, agentState, pendingTask, onClose, refreshTrigger }) {
|
||||||
|
const [activeTab, setActiveTab] = useState('Commands');
|
||||||
|
const meta = AGENT_META[agentId];
|
||||||
|
if (!meta) return null;
|
||||||
|
|
||||||
|
const stateText = agentState?.detail
|
||||||
|
? `${agentState.state} - ${agentState.detail}`
|
||||||
|
: agentState?.state || 'unknown';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ao-sidepanel">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="ao-sidepanel-header">
|
||||||
|
<div className="ao-sidepanel-agent">
|
||||||
|
<div className="ao-sidepanel-icon" style={{ background: meta.color }}>
|
||||||
|
{meta.emoji}
|
||||||
|
</div>
|
||||||
|
<div className="ao-sidepanel-info">
|
||||||
|
<div className="ao-sidepanel-name">{meta.displayName}</div>
|
||||||
|
<div className="ao-sidepanel-state">● {stateText}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button className="ao-sidepanel-close" onClick={onClose}>×</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tabs */}
|
||||||
|
<div className="ao-sidepanel-tabs">
|
||||||
|
{TABS.map(tab => (
|
||||||
|
<button
|
||||||
|
key={tab}
|
||||||
|
className={`ao-sidepanel-tab ${activeTab === tab ? 'active' : ''}`}
|
||||||
|
onClick={() => setActiveTab(tab)}
|
||||||
|
>
|
||||||
|
{tab}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tab Content */}
|
||||||
|
<div className="ao-sidepanel-content">
|
||||||
|
{activeTab === 'Commands' && (
|
||||||
|
<CommandTab agentId={agentId} agentState={agentState?.state} pendingTask={pendingTask} />
|
||||||
|
)}
|
||||||
|
{activeTab === 'Tasks' && (
|
||||||
|
<TaskTab agentId={agentId} refreshTrigger={refreshTrigger} />
|
||||||
|
)}
|
||||||
|
{activeTab === 'Tokens' && (
|
||||||
|
<TokenTab agentId={agentId} />
|
||||||
|
)}
|
||||||
|
{activeTab === 'Logs' && (
|
||||||
|
<LogTab agentId={agentId} refreshTrigger={refreshTrigger} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user