klawdyoss's picture
salvando
969b550
import { useRef, useState } from "react";
import { editor } from "monaco-editor";
import { useMount, useLocalStorage } from "react-use";
import { toast } from "react-toastify";
import Sidebar, { View } from "./sidebar/Sidebar";
import EditorPanel from "./panels/EditorPanel";
import FilesPanel from "./panels/FilesPanel";
import PreviewPanel from "./panels/PreviewPanel";
import APIKeysConfig from "./panels/APIKeysConfig";
import AgentConfig from "./panels/AgentConfig";
import SystemPromptConfig from "./panels/SystemPromptConfig";
import AskAI from "./ask-ai/ask-ai";
import agents from "../../agents.json";
import { defaultHTML } from "../../utils/consts";
function App() {
const [htmlStorage, , removeHtmlStorage] =
useLocalStorage<string>("html_content", "");
const [html, setHtml] = useState<string>(htmlStorage || defaultHTML);
const [error, setError] = useState(false);
const [isAiWorking, setIsAiWorking] = useState(false);
const [selectedAgent, setSelectedAgent] = useLocalStorage<string>(
"selectedAgent",
agents[0].id
);
const agentId = selectedAgent || agents[0].id; // ← nunca undefined
const [activePanel, setActivePanel] = useState<View>("editor");
const [prompts, setPrompts] = useState<string[]>([]);
const [activeViewer, setActiveViewer] = useState<string>("viewer1");
const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null);
useMount(() => {
if (htmlStorage) {
removeHtmlStorage();
toast.warn("Conteúdo HTML restaurado do storage.");
}
});
return (
<div className="h-screen flex overflow-hidden bg-gray-950 text-gray-200">
{/* Team/Agentes - Barra lateral esquerda */}
<div className="w-20 bg-gray-900 border-r border-gray-800 flex flex-col items-center py-4">
<div className="mb-6">
<img src="/logo.svg" alt="Logo" className="w-10 h-10" />
</div>
<div className="flex flex-col items-center space-y-6">
{agents.slice(0, 5).map((agent) => (
<div
key={agent.id}
className={`w-12 h-12 rounded-full flex items-center justify-center cursor-pointer transition-all
${selectedAgent === agent.id ? 'bg-indigo-600' : 'bg-gray-800 hover:bg-gray-700'}`}
onClick={() => setSelectedAgent(agent.id)}
title={agent.name}
>
<span className="text-lg font-bold">{agent.name.charAt(0)}</span>
</div>
))}
</div>
</div>
{/* Chat / agentes */}
<div className="w-[320px] bg-gray-900 border-r border-gray-800 flex flex-col">
<div className="p-4 border-b border-gray-800">
<h2 className="text-xl font-semibold">Agentes IA</h2>
<p className="text-sm text-gray-400 mt-1">Selecione um agente para ajudar no seu projeto</p>
</div>
<AskAI
agentId={agentId}
html={html}
setHtml={setHtml}
isAiWorking={isAiWorking}
setisAiWorking={setIsAiWorking}
onNewPrompt={(p) => setPrompts((ps) => [...ps, p])}
onScrollToBottom={() => {
editorRef.current?.revealLine(
editorRef.current?.getModel()?.getLineCount() ?? 0
);
}}
/>
</div>
{/* Painéis principais */}
<div className="flex flex-1 flex-col">
<div className="h-14 bg-gray-900 border-b border-gray-800 flex items-center px-4">
<div className="flex space-x-2">
<button
className={`px-4 py-2 rounded ${activeViewer === 'viewer1' ? 'bg-indigo-600' : 'bg-gray-800 hover:bg-gray-700'}`}
onClick={() => setActiveViewer('viewer1')}
>
Viewer 1
</button>
<button
className={`px-4 py-2 rounded ${activeViewer === 'viewer2' ? 'bg-indigo-600' : 'bg-gray-800 hover:bg-gray-700'}`}
onClick={() => setActiveViewer('viewer2')}
>
Viewer 2
</button>
</div>
</div>
<div className="flex flex-1">
<Sidebar view={activePanel} onSelect={setActivePanel} />
<div className="flex-1 overflow-auto bg-gray-900 p-4">
{activePanel === "editor" && (
<EditorPanel
html={html}
setHtml={setHtml}
isAiWorking={isAiWorking}
setError={setError}
editorRef={editorRef}
/>
)}
{activePanel === "files" && <FilesPanel />}
{activePanel === "preview" && <PreviewPanel html={html} />}
{activePanel === "apikeys" && <APIKeysConfig />}
{activePanel === "agents" && <AgentConfig />}
{activePanel === "system" && <SystemPromptConfig />}
</div>
</div>
</div>
</div>
);
}
export default App;