import { useState, useRef, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Card } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { useLabTerminal } from "@/hooks/use-lab-terminal"; import { ChevronDown, Plus, X, Copy, Download, Settings, Play, Loader2 } from "lucide-react"; import { useLocation } from "wouter"; interface File { id: string; name: string; content: string; language: string; } export default function Lab() { const [files, setFiles] = useState([ { id: "1", name: "registry.ts", language: "typescript", content: `interface Architect { id: string; level: number; xp: number; verified: boolean; } class MetaverseRegistry { private architects: Map; constructor() { this.architects = new Map(); } registerArchitect(architect: Architect): void { this.architects.set(architect.id, architect); } getArchitect(id: string): Architect | undefined { return this.architects.get(id); } getAllArchitects(): Architect[] { return Array.from(this.architects.values()); } } `, }, { id: "2", name: "README.txt", language: "text", content: `The Lab - Code Editor & Registry Welcome to AeThex-OS Lab. This is where you can: - Write and edit code - Manage TypeScript interfaces and classes - Build the MetaverseRegistry - Compile and test your creations Get started by creating new files or editing existing ones. `, }, ]); const [activeFileId, setActiveFileId] = useState(files[0].id); const [newFileName, setNewFileName] = useState(""); const editorRef = useRef(null); const { executeCode, isExecuting, lastExecution } = useLabTerminal(); const [, setLocation] = useLocation(); const activeFile = files.find((f) => f.id === activeFileId); const handleCreateFile = () => { if (!newFileName.trim()) return; const newFile: File = { id: Date.now().toString(), name: newFileName, content: "", language: newFileName.endsWith(".ts") ? "typescript" : "text", }; setFiles([...files, newFile]); setActiveFileId(newFile.id); setNewFileName(""); }; const handleDeleteFile = (id: string) => { if (files.length === 1) return; const filtered = files.filter((f) => f.id !== id); setFiles(filtered); setActiveFileId(filtered[0].id); }; const handleUpdateContent = (content: string) => { setFiles( files.map((f) => f.id === activeFileId ? { ...f, content } : f ) ); }; const handleDownload = () => { if (!activeFile) return; const element = document.createElement("a"); element.setAttribute( "href", `data:text/plain;charset=utf-8,${encodeURIComponent(activeFile.content)}` ); element.setAttribute("download", activeFile.name); element.style.display = "none"; document.body.appendChild(element); element.click(); document.body.removeChild(element); }; const handleCopy = () => { if (!activeFile) return; navigator.clipboard.writeText(activeFile.content); }; const handleRun = async () => { if (!activeFile) return; await executeCode(activeFile.content, activeFile.language); // Open terminal to show results setLocation('/terminal'); }; return (
{/* Header */}
</>

The Lab

{/* File Explorer */}

FILES

setNewFileName(e.target.value)} onKeyPress={(e) => { if (e.key === "Enter") handleCreateFile(); }} className="h-8 text-xs bg-slate-800 border-slate-700" />
{files.map((file) => (
setActiveFileId(file.id)} className={`px-4 py-2 flex items-center justify-between cursor-pointer border-l-2 transition-colors ${ activeFileId === file.id ? "bg-slate-800 border-cyan-400 text-cyan-400" : "border-transparent text-slate-400 hover:bg-slate-800" }`} > {file.name} {files.length > 1 && ( )}
))}
{/* Editor */} {activeFile && (
{/* Tab Bar */}
{activeFile.name}
{activeFile.language.toUpperCase()} • UTF-8 • Spaces: 2
{/* Code Editor */}
{/* Line Numbers */}
{activeFile.content.split("\n").map((_, i) => (
{i + 1}
))}
{/* Editor Content */}