Mayank2027 commited on
Commit
2e33a07
·
verified ·
1 Parent(s): f557300

Create frontend/src/App.tsx

Browse files
Files changed (1) hide show
  1. frontend/src/App.tsx +94 -0
frontend/src/App.tsx ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
3
+ import ChatPanel from './components/ChatPanel';
4
+ import AgentPanel from './components/AgentPanel';
5
+ import CodeEditor from './components/CodeEditor';
6
+ import TerminalTabs from './components/TerminalTabs';
7
+ import FileTree from './components/FileTree';
8
+ import ModelSelector from './components/ModelSelector';
9
+ import TopBar from './components/TopBar';
10
+ import StatusBar from './components/StatusBar';
11
+ import GitPanel from './components/GitPanel';
12
+ import BackgroundTasks from './components/BackgroundTasks';
13
+ import { FaComments, FaRobot, FaTerminal, FaCodeBranch, FaTasks } from 'react-icons/fa';
14
+
15
+ const App: React.FC = () => {
16
+ const [activeBottom, setActiveBottom] = useState('chat');
17
+ const [projectPath] = useState('/app/sandbox');
18
+ const [activeFile, setActiveFile] = useState<string | null>(null);
19
+ const [selectedModel, setSelectedModel] = useState('groq-llama-3.3-70b-versatile');
20
+ const [sidebarVisible, setSidebarVisible] = useState(true);
21
+
22
+ useEffect(() => {
23
+ const handleKeyDown = (e: KeyboardEvent) => {
24
+ const mod = e.ctrlKey || e.metaKey;
25
+ if (mod && e.key === 'b') { e.preventDefault(); setSidebarVisible(prev => !prev); }
26
+ else if (mod && e.key === '1') { e.preventDefault(); setActiveBottom('chat'); }
27
+ else if (mod && e.key === '2') { e.preventDefault(); setActiveBottom('agent'); }
28
+ else if (mod && e.key === '3') { e.preventDefault(); setActiveBottom('terminal'); }
29
+ else if (mod && e.key === '4') { e.preventDefault(); setActiveBottom('git'); }
30
+ else if (mod && e.key === '5') { e.preventDefault(); setActiveBottom('tasks'); }
31
+ };
32
+ window.addEventListener('keydown', handleKeyDown);
33
+ return () => window.removeEventListener('keydown', handleKeyDown);
34
+ }, []);
35
+
36
+ return (
37
+ <div style={{ display: 'flex', flexDirection: 'column', height: '100vh', background: 'var(--bg-primary)' }}>
38
+ <TopBar />
39
+ <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
40
+ {sidebarVisible && (
41
+ <div style={{ width: 280, background: 'var(--bg-secondary)', borderRight: '1px solid var(--border)', display: 'flex', flexDirection: 'column' }}>
42
+ <div style={{ padding: '8px 12px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
43
+ <span style={{ fontWeight: 600, fontSize: 13 }}>EXPLORER</span>
44
+ <span onClick={() => setSidebarVisible(false)} style={{ cursor: 'pointer', color: 'var(--text-secondary)' }}>×</span>
45
+ </div>
46
+ <ModelSelector selectedModel={selectedModel} onModelChange={setSelectedModel} />
47
+ <FileTree projectPath={projectPath} onFileSelect={setActiveFile} />
48
+ </div>
49
+ )}
50
+ {!sidebarVisible && (
51
+ <div style={{ width: 40, background: 'var(--bg-secondary)', borderRight: '1px solid var(--border)', display: 'flex', alignItems: 'flex-start', paddingTop: 10, justifyContent: 'center' }}>
52
+ <span onClick={() => setSidebarVisible(true)} style={{ cursor: 'pointer', color: 'var(--text-secondary)' }}>☰</span>
53
+ </div>
54
+ )}
55
+ <PanelGroup direction="vertical" style={{ flex: 1 }}>
56
+ <Panel defaultSize={65} minSize={20}>
57
+ <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
58
+ <div style={{ display: 'flex', background: 'var(--bg-tertiary)', borderBottom: '1px solid var(--border)', padding: '0 8px', overflowX: 'auto' }}>
59
+ {activeFile ? (
60
+ <div style={{ padding: '8px 12px', borderBottom: '2px solid var(--accent)', color: 'var(--accent)', fontSize: 13 }}>📄 {activeFile}</div>
61
+ ) : (
62
+ <div style={{ padding: '8px 12px', color: 'var(--text-secondary)', fontSize: 13 }}>No file selected</div>
63
+ )}
64
+ </div>
65
+ <CodeEditor filePath={activeFile} projectPath={projectPath} />
66
+ </div>
67
+ </Panel>
68
+ <PanelResizeHandle style={{ height: 4, background: 'var(--border)' }} />
69
+ <Panel defaultSize={35} minSize={15}>
70
+ <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg-primary)' }}>
71
+ <div style={{ display: 'flex', background: 'var(--bg-tertiary)', borderBottom: '1px solid var(--border)', padding: '0 8px' }}>
72
+ <button onClick={() => setActiveBottom('chat')} style={{ padding: '8px 16px', background: activeBottom === 'chat' ? 'var(--bg-primary)' : 'transparent', borderBottom: activeBottom === 'chat' ? '2px solid var(--accent)' : 'none', color: activeBottom === 'chat' ? 'var(--accent)' : 'var(--text-secondary)' }}><FaComments /> Chat (Ctrl+1)</button>
73
+ <button onClick={() => setActiveBottom('agent')} style={{ padding: '8px 16px', background: activeBottom === 'agent' ? 'var(--bg-primary)' : 'transparent', borderBottom: activeBottom === 'agent' ? '2px solid var(--accent)' : 'none', color: activeBottom === 'agent' ? 'var(--accent)' : 'var(--text-secondary)' }}><FaRobot /> Agent (Ctrl+2)</button>
74
+ <button onClick={() => setActiveBottom('terminal')} style={{ padding: '8px 16px', background: activeBottom === 'terminal' ? 'var(--bg-primary)' : 'transparent', borderBottom: activeBottom === 'terminal' ? '2px solid var(--accent)' : 'none', color: activeBottom === 'terminal' ? 'var(--accent)' : 'var(--text-secondary)' }}><FaTerminal /> Terminal (Ctrl+3)</button>
75
+ <button onClick={() => setActiveBottom('git')} style={{ padding: '8px 16px', background: activeBottom === 'git' ? 'var(--bg-primary)' : 'transparent', borderBottom: activeBottom === 'git' ? '2px solid var(--accent)' : 'none', color: activeBottom === 'git' ? 'var(--accent)' : 'var(--text-secondary)' }}><FaCodeBranch /> Git (Ctrl+4)</button>
76
+ <button onClick={() => setActiveBottom('tasks')} style={{ padding: '8px 16px', background: activeBottom === 'tasks' ? 'var(--bg-primary)' : 'transparent', borderBottom: activeBottom === 'tasks' ? '2px solid var(--accent)' : 'none', color: activeBottom === 'tasks' ? 'var(--accent)' : 'var(--text-secondary)' }}><FaTasks /> Tasks (Ctrl+5)</button>
77
+ </div>
78
+ <div style={{ flex: 1, overflow: 'hidden' }}>
79
+ {activeBottom === 'chat' && <ChatPanel projectPath={projectPath} model={selectedModel} />}
80
+ {activeBottom === 'agent' && <AgentPanel projectPath={projectPath} />}
81
+ {activeBottom === 'terminal' && <TerminalTabs />}
82
+ {activeBottom === 'git' && <GitPanel projectPath={projectPath} />}
83
+ {activeBottom === 'tasks' && <BackgroundTasks />}
84
+ </div>
85
+ </div>
86
+ </Panel>
87
+ </PanelGroup>
88
+ </div>
89
+ <StatusBar model={selectedModel} />
90
+ </div>
91
+ );
92
+ };
93
+
94
+ export default App;