File size: 7,163 Bytes
666aab6
 
 
a20767f
 
5d62489
 
 
666aab6
a20767f
666aab6
5d62489
a20767f
 
5d62489
 
 
a20767f
 
660d02b
a20767f
666aab6
5d62489
a20767f
 
 
 
 
 
 
 
 
 
5d62489
 
 
 
 
666aab6
 
 
a20767f
666aab6
a20767f
666aab6
 
a20767f
 
666aab6
a20767f
 
 
 
 
 
 
 
 
666aab6
a20767f
 
 
 
5d62489
a20767f
5d62489
a20767f
 
 
 
 
5d62489
 
 
 
 
 
 
 
a20767f
666aab6
a20767f
 
 
666aab6
a20767f
 
 
 
5d62489
a20767f
5d62489
 
a20767f
5d62489
 
 
666aab6
a20767f
 
5d62489
a20767f
 
 
 
5d62489
 
a20767f
 
 
5d62489
 
 
 
 
a20767f
 
5d62489
a20767f
 
 
666aab6
a20767f
 
 
 
 
 
 
 
 
660d02b
a20767f
666aab6
 
a20767f
666aab6
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
'use client'

import { useAgentStore } from '@/hooks/useAgentStore'
import {
  MessageSquare, ListTodo, Brain, Clock, Plug, Terminal,
  Plus, Zap, Code2, Bug, Cpu,
  GitBranch, Workflow, Rocket, Palette, Bot, Globe, Folder,
  FlaskConical, Eye, Cpu as CpuIcon
} from 'lucide-react'
import type { ActivePanel, AgentName } from '@/hooks/useAgentStore'

const PANELS: { id: ActivePanel; icon: React.ElementType; labelEn: string; labelMy: string; badge?: string }[] = [
  { id: 'timeline',   icon: Clock,         labelEn: 'Timeline',    labelMy: 'α€‘α€α€»α€­α€”α€Ία€‡α€šα€¬α€Έ' },
  { id: 'tasks',      icon: ListTodo,       labelEn: 'Tasks',       labelMy: 'α€œα€―α€•α€Ία€„α€”α€Ία€Έα€™α€»α€¬α€Έ' },
  { id: 'sandbox',    icon: Terminal,       labelEn: 'Terminal',    labelMy: 'Terminal' },
  { id: 'files',      icon: Folder,         labelEn: 'Files',       labelMy: 'ဖိုင်များ',    badge: 'v7' },
  { id: 'browser',    icon: Globe,          labelEn: 'Browser',     labelMy: 'α€˜α€›α€±α€¬α€„α€Ία€‡α€¬',  badge: 'v7' },
  { id: 'memory',     icon: Brain,          labelEn: 'Memory',      labelMy: 'မှတ်ဉာဏ်' },
  { id: 'connectors', icon: Plug,           labelEn: 'Connectors',  labelMy: 'ချိတ်ဆက်မှု' },
  { id: 'ai_router',   icon: Cpu,            labelEn: 'AI Router',   labelMy: 'AI Router',    badge: 'v8' },
]

const AGENT_META: Record<string, { icon: React.ElementType; color: string; label: string; isNew?: boolean }> = {
  chat:      { icon: MessageSquare, color: '#22d3ee', label: 'Chat' },
  planner:   { icon: Zap,           color: '#a78bfa', label: 'Planner' },
  coding:    { icon: Code2,         color: '#34d399', label: 'Coding' },
  debug:     { icon: Bug,           color: '#f87171', label: 'Debug' },
  memory:    { icon: Brain,         color: '#fbbf24', label: 'Memory' },
  connector: { icon: Plug,          color: '#60a5fa', label: 'Connector' },
  deploy:    { icon: Rocket,        color: '#f472b6', label: 'Deploy' },
  workflow:  { icon: Workflow,      color: '#fb923c', label: 'Workflow' },
  sandbox:   { icon: Terminal,      color: '#4ade80', label: 'Sandbox' },
  ui:        { icon: Palette,       color: '#e879f9', label: 'UI' },
  browser:   { icon: Globe,         color: '#38bdf8', label: 'Browser',  isNew: true },
  file:      { icon: Folder,        color: '#fcd34d', label: 'File',     isNew: true },
  git:       { icon: GitBranch,     color: '#f97316', label: 'Git',      isNew: true },
  test:      { icon: FlaskConical,  color: '#a3e635', label: 'Test',     isNew: true },
  vision:    { icon: Eye,           color: '#c084fc', label: 'Vision',   isNew: true },
}

export default function Sidebar() {
  const { sidebarOpen, activePanel, setActivePanel, locale, messages, clearMessages, agents } = useAgentStore()

  if (!sidebarOpen) return null

  return (
    <aside className="w-52 flex-shrink-0 flex flex-col border-r hidden md:flex"
      style={{ background: 'var(--bg-2)', borderColor: 'var(--border)' }}>

      {/* New Chat */}
      <div className="p-3 border-b" style={{ borderColor: 'var(--border)' }}>
        <button onClick={clearMessages}
          className="w-full flex items-center gap-2 px-3 py-2 rounded-xl text-sm font-medium transition-all hover:opacity-90 active:scale-95"
          style={{ background: 'var(--brand)', color: '#fff' }}>
          <Plus size={14} />
          {locale === 'my' ? 'α€…α€€α€¬α€Έα€•α€Όα€±α€¬α€žα€…α€Ί' : 'New Chat'}
        </button>
      </div>

      {/* Navigation */}
      <nav className="p-2 border-b" style={{ borderColor: 'var(--border)' }}>
        <p className="text-[10px] uppercase tracking-wider px-2 mb-1.5"
          style={{ color: 'var(--text-muted)' }}>Views</p>
        {PANELS.map(({ id, icon: Icon, labelEn, labelMy, badge }) => (
          <button key={id} onClick={() => setActivePanel(id)}
            className={`w-full flex items-center gap-2.5 px-2.5 py-1.5 rounded-lg text-xs font-medium transition-all mb-0.5`}
            style={{
              background: activePanel === id ? 'var(--brand)' : 'transparent',
              color: activePanel === id ? '#fff' : 'var(--text-secondary)',
            }}>
            <Icon size={13} />
            <span className="flex-1 text-left">{locale === 'my' ? labelMy : labelEn}</span>
            {badge && (
              <span className="text-[8px] px-1 py-0.5 rounded font-bold"
                style={{
                  background: activePanel === id ? 'rgba(255,255,255,0.2)' : 'rgba(99,102,241,0.2)',
                  color: activePanel === id ? '#fff' : '#a5b4fc',
                }}>
                {badge}
              </span>
            )}
          </button>
        ))}
      </nav>

      {/* Agent Status */}
      <div className="p-2 flex-1 overflow-y-auto">
        <p className="text-[10px] uppercase tracking-wider px-2 mb-1.5"
          style={{ color: 'var(--text-muted)' }}>
          Agents ({Object.keys(AGENT_META).length})
        </p>
        {Object.entries(AGENT_META).map(([name, meta]) => {
          const agent = (agents as any)[name]
          const Icon = meta.icon
          const isActive = agent?.status === 'executing' || agent?.status === 'thinking'
          const isComplete = agent?.status === 'complete'
          const isError = agent?.status === 'error'

          return (
            <div key={name}
              className="flex items-center gap-2 px-2 py-1 rounded-lg mb-0.5 transition-all"
              style={{
                background: isActive ? `${meta.color}10` : 'transparent',
                border: isActive ? `1px solid ${meta.color}30` : '1px solid transparent',
              }}>
              <Icon size={11} style={{ color: meta.color, flexShrink: 0 }} />
              <span className="text-[11px] flex-1 truncate capitalize"
                style={{ color: isActive ? 'var(--text-primary)' : 'var(--text-muted)' }}>
                {meta.label}
              </span>
              {meta.isNew && !isActive && (
                <span className="text-[8px] px-1 rounded" style={{ background: 'rgba(99,102,241,0.15)', color: '#a5b4fc' }}>
                  new
                </span>
              )}
              <div className={`w-1.5 h-1.5 rounded-full flex-shrink-0 ${isActive ? 'animate-pulse' : ''}`}
                style={{
                  background: isActive ? meta.color : isComplete ? '#22c55e' : isError ? '#ef4444' : 'var(--border)',
                  boxShadow: isActive ? `0 0 6px ${meta.color}` : 'none',
                }}
              />
            </div>
          )
        })}
      </div>

      {/* Footer */}
      <div className="p-3 border-t" style={{ borderColor: 'var(--border)' }}>
        <div className="flex items-center gap-2 px-2 py-1.5 rounded-lg text-[10px]"
          style={{ background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)' }}>
          <Bot size={10} className="text-indigo-400" />
          <span style={{ color: 'var(--text-muted)' }}>God Agent OS v8.0</span>
          <div className="ml-auto w-1.5 h-1.5 rounded-full bg-green-400 animate-pulse" />
        </div>
      </div>
    </aside>
  )
}