File size: 4,685 Bytes
cce8120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
'use client';

import React, { useState, useEffect } from 'react';
import FileExplorer from './explorer/FileExplorer';
import AIChatPanel from './chat/AIChatPanel';
import CodeEditor from './editor/CodeEditor';
import TerminalPanel from './terminal/TerminalPanel';
import AgentMonitor from './dashboards/AgentMonitor';
import { api } from '../services/api';

export default function WorkspaceLayout() {
  const [activeFile, setActiveFile] = useState('');
  const [fileContent, setFileContent] = useState('');
  const [sessionId, setSessionId] = useState(null);
  const [activeTab, setActiveTab] = useState('editor'); // 'editor' | 'preview' | 'monitor'
  const [showTerminal, setShowTerminal] = useState(true);

  useEffect(() => {
    api.createSession('.')
      .then((data) => setSessionId(data.session_id))
      .catch((err) => console.error('Failed to initialize workspace session:', err));
  }, []);

  const handleSelectFile = async (filepath) => {
    setActiveFile(filepath);
    try {
      const content = await api.getFileContent(filepath);
      setFileContent(content);
    } catch (err) {
      setFileContent(`// Error reading file: ${filepath}`);
    }
  };

  const handleSaveFile = async () => {
    if (!activeFile) return;
    try {
      await api.saveFile(activeFile, fileContent);
      alert(`Successfully saved ${activeFile}`);
    } catch (err) {
      alert(`Failed to save ${activeFile}`);
    }
  };

  return (
    <div className="flex h-screen bg-slate-950 font-sans text-white overflow-hidden select-none">
      {/* 1. File Explorer Sidebar */}
      <FileExplorer onSelectFile={handleSelectFile} activeFile={activeFile} />

      {/* 2. Main Workstation Center Area */}
      <div className="flex-1 flex flex-col h-full border-r border-slate-800">
        {/* Workspace Top Navigation Bar */}
        <div className="h-10 bg-slate-900 border-b border-slate-800 flex items-center justify-between px-4">
          <div className="flex gap-1 text-xs">
            <button
              onClick={() => setActiveTab('editor')}
              className={`px-3 py-1 rounded transition-colors ${
                activeTab === 'editor' ? 'bg-slate-800 text-blue-400 font-semibold' : 'text-slate-400 hover:text-white'
              }`}
            >
              💻 Editor {activeFile && `(${activeFile.split('/').pop()})`}
            </button>
            <button
              onClick={() => setActiveTab('preview')}
              className={`px-3 py-1 rounded transition-colors ${
                activeTab === 'preview' ? 'bg-slate-800 text-blue-400 font-semibold' : 'text-slate-400 hover:text-white'
              }`}
            >
              👁️ Device Preview
            </button>
            <button
              onClick={() => setActiveTab('monitor')}
              className={`px-3 py-1 rounded transition-colors ${
                activeTab === 'monitor' ? 'bg-slate-800 text-blue-400 font-semibold' : 'text-slate-400 hover:text-white'
              }`}
            >
              🚀 Build Center
            </button>
          </div>

          <div className="flex items-center gap-2">
            <button
              onClick={() => setShowTerminal(!showTerminal)}
              className="text-xs px-2.5 py-1 bg-slate-800 hover:bg-slate-700 text-slate-300 rounded transition-colors"
            >
              {showTerminal ? 'Terminal ▼' : 'Terminal ▲'}
            </button>

            {activeFile && (
              <button
                onClick={handleSaveFile}
                className="bg-blue-600 hover:bg-blue-500 text-white text-xs px-3 py-1 rounded font-medium transition-colors"
              >
                Save
              </button>
            )}
          </div>
        </div>

        {/* Viewport Content Panel */}
        <div className="flex-1 overflow-hidden p-2 bg-slate-950">
          {activeTab === 'editor' && (
            <CodeEditor
              filename={activeFile}
              value={fileContent}
              onChange={setFileContent}
              onSave={handleSaveFile}
            />
          )}

          {activeTab === 'preview' && (
            <div className="w-full h-full bg-white rounded-lg overflow-hidden border border-slate-800">
              <iframe title="preview-viewport" src="http://localhost:8000/docs" className="w-full h-full border-none" />
            </div>
          )}

          {activeTab === 'monitor' && <AgentMonitor />}
        </div>

        {/* Bottom Terminal Drawer */}
        {showTerminal && <TerminalPanel />}
      </div>

      {/* 3. AI Assistant Right Drawer */}
      <AIChatPanel sessionId={sessionId} />
    </div>
  );
}