modified: src/lib/templates.ts

This commit is contained in:
Anderson 2026-01-18 04:59:27 +00:00 committed by GitHub
parent 0fdaefdc8d
commit 42a1e2c3e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 129 additions and 156 deletions

View file

@ -460,122 +460,101 @@ end)`,
email: 'demo@aethex.com',
};
return (
<div className="h-screen flex flex-col bg-background text-foreground">
<Toolbar
code={currentCode}
currentPlatform={currentPlatform}
onPlatformChange={setCurrentPlatform}
onTranslateClick={() => setShowTranslation(true)}
onTemplatesClick={() => setShowTemplates(true)}
onPreviewClick={() => setShowPreview(true)}
onNewProjectClick={() => setShowNewProject(true)}
/>
<div className="h-screen w-screen flex flex-col bg-background text-foreground">
{/* Top Bar */}
<div className="flex items-center h-12 px-4 bg-card border-b border-border shadow-sm z-20">
<span className="text-xl font-bold tracking-tight select-none">
Ae<span className="text-accent">Thex</span>
</span>
<span className="ml-2 text-sm text-muted-foreground font-medium select-none">Studio</span>
<div className="flex-1" />
<Toolbar
code={currentCode}
currentPlatform={currentPlatform}
onPlatformChange={setCurrentPlatform}
onTranslateClick={() => setShowTranslation(true)}
onTemplatesClick={() => setShowTemplates(true)}
onPreviewClick={() => setShowPreview(true)}
onNewProjectClick={() => setShowNewProject(true)}
/>
</div>
<div className="flex-1 overflow-hidden flex flex-col">
{isMobile ? (
<Tabs defaultValue="editor" className="h-full flex flex-col">
<TabsList className="w-full rounded-none border-b border-border">
<TabsTrigger value="files" className="flex-1">Files</TabsTrigger>
<TabsTrigger value="editor" className="flex-1">Editor</TabsTrigger>
<TabsTrigger value="ai" className="flex-1">AI</TabsTrigger>
<TabsTrigger value="education" className="flex-1">Learn</TabsTrigger>
</TabsList>
<TabsContent value="files" className="flex-1 m-0">
<FileTree
files={files || []}
onFileSelect={handleFileSelect}
onFileCreate={handleFileCreate}
onFileRename={handleFileRename}
onFileDelete={handleFileDelete}
onFileMove={handleFileMove}
selectedFileId={activeFileId}
/>
</TabsContent>
<TabsContent value="editor" className="flex-1 m-0 flex flex-col">
<FileTabs
openFiles={openFiles || []}
activeFileId={activeFileId}
onFileSelect={handleFileSelect}
onFileClose={handleFileClose}
/>
<div className="flex-1">
<CodeEditor onCodeChange={handleCodeChange} platform={currentPlatform} />
</div>
</TabsContent>
<TabsContent value="ai" className="flex-1 m-0">
<AIChat currentCode={currentCode} />
</TabsContent>
<TabsContent value="education" className="flex-1 m-0">
<Suspense fallback={<div className="flex items-center justify-center h-full"><LoadingSpinner /></div>}>
<EducationPanel />
</Suspense>
</TabsContent>
</Tabs>
) : (
<>
<div className="flex-1 overflow-hidden">
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize={15} minSize={10} maxSize={25}>
<FileTree
files={files || []}
{/* Main Content Area */}
<div className="flex flex-1 min-h-0 min-w-0 overflow-hidden">
{/* Activity Bar */}
<div className="flex flex-col items-center w-12 bg-muted border-r border-border py-2 gap-2 z-10">
{/* Example activity icons, replace with real navigation/actions */}
<button className="w-8 h-8 rounded flex items-center justify-center hover:bg-accent/20 text-accent" title="Files">
<svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path d="M4 4h16v16H4z" /></svg>
</button>
<button className="w-8 h-8 rounded flex items-center justify-center hover:bg-accent/20 text-accent" title="AI">
<svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" /></svg>
</button>
<button className="w-8 h-8 rounded flex items-center justify-center hover:bg-accent/20 text-accent" title="Learn">
<svg width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" /></svg>
</button>
</div>
{/* Main Panels */}
<div className="flex-1 flex flex-col min-h-0 min-w-0">
<div className="flex-1 min-h-0 min-w-0 overflow-hidden">
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize={16} minSize={10} maxSize={25}>
<FileTree
files={files || []}
onFileSelect={handleFileSelect}
onFileCreate={handleFileCreate}
onFileRename={handleFileRename}
onFileDelete={handleFileDelete}
onFileMove={handleFileMove}
selectedFileId={activeFileId}
/>
</ResizablePanel>
<ResizableHandle className="w-1 bg-border hover:bg-accent transition-colors" />
<ResizablePanel defaultSize={54} minSize={30}>
<div className="h-full flex flex-col">
<FileTabs
openFiles={openFiles || []}
activeFileId={activeFileId}
onFileSelect={handleFileSelect}
onFileCreate={handleFileCreate}
onFileRename={handleFileRename}
onFileDelete={handleFileDelete}
onFileMove={handleFileMove}
selectedFileId={activeFileId}
onFileClose={handleFileClose}
/>
</ResizablePanel>
<ResizableHandle className="w-1 bg-border hover:bg-accent transition-colors" />
<ResizablePanel defaultSize={55} minSize={30}>
<div className="h-full flex flex-col">
<FileTabs
openFiles={openFiles || []}
activeFileId={activeFileId}
onFileSelect={handleFileSelect}
onFileClose={handleFileClose}
/>
<div className="flex-1">
<CodeEditor onCodeChange={setCurrentCode} platform={currentPlatform} />
</div>
<div className="flex-1">
<CodeEditor onCodeChange={setCurrentCode} platform={currentPlatform} />
</div>
</ResizablePanel>
<ResizableHandle className="w-1 bg-border hover:bg-accent transition-colors" />
<ResizablePanel defaultSize={20} minSize={15}>
<EducationPanel />
</ResizablePanel>
<ResizablePanel defaultSize={15} minSize={10}>
<AIChat currentCode={currentCode} />
</ResizablePanel>
</ResizablePanelGroup>
</div>
<ConsolePanel
collapsed={consoleCollapsed}
onToggle={() => setConsoleCollapsed(!consoleCollapsed)}
currentCode={currentCode}
currentFile={activeFileId ? (openFiles || []).find(f => f.id === activeFileId)?.name : undefined}
files={files || []}
onCodeChange={setCurrentCode}
/>
<SearchInFilesPanel
files={files || []}
onFileSelect={handleFileSelect}
isOpen={showSearchInFiles}
onClose={() => setShowSearchInFiles(false)}
/>
</>
)}
{/* Unified feature tabs for all major panels */}
<div className="w-full border-t border-border mt-4">
<ExtraTabs user={demoUser} />
</div>
</ResizablePanel>
<ResizableHandle className="w-1 bg-border hover:bg-accent transition-colors" />
<ResizablePanel defaultSize={15} minSize={10}>
<AIChat currentCode={currentCode} />
</ResizablePanel>
<ResizableHandle className="w-1 bg-border hover:bg-accent transition-colors" />
<ResizablePanel defaultSize={15} minSize={10}>
<EducationPanel />
</ResizablePanel>
</ResizablePanelGroup>
</div>
<ConsolePanel
collapsed={consoleCollapsed}
onToggle={() => setConsoleCollapsed(!consoleCollapsed)}
currentCode={currentCode}
currentFile={activeFileId ? (openFiles || []).find(f => f.id === activeFileId)?.name : undefined}
files={files || []}
onCodeChange={setCurrentCode}
/>
<SearchInFilesPanel
files={files || []}
onFileSelect={handleFileSelect}
isOpen={showSearchInFiles}
onClose={() => setShowSearchInFiles(false)}
/>
<div className="w-full border-t border-border mt-2">
<ExtraTabs user={demoUser} />
</div>
</div>
</div>
{/* Modals and overlays */}
<Suspense fallback={null}>
{showTemplates && (
<TemplatesDrawer
@ -585,7 +564,6 @@ end)`,
/>
)}
</Suspense>
<Suspense fallback={null}>
<PreviewModal
open={showPreview}
@ -593,7 +571,6 @@ end)`,
code={currentCode}
/>
</Suspense>
<Suspense fallback={null}>
<NewProjectModal
open={showNewProject}
@ -601,7 +578,6 @@ end)`,
onCreateProject={handleCreateProject}
/>
</Suspense>
<Suspense fallback={null}>
{showTranslation && (
<TranslationPanel
@ -612,20 +588,15 @@ end)`,
/>
)}
</Suspense>
<Suspense fallback={null}>
<WelcomeDialog />
</Suspense>
{/* File Search Modal (Cmd/Ctrl+P) */}
<FileSearchModal
open={showFileSearch}
onClose={() => setShowFileSearch(false)}
files={files || []}
onFileSelect={handleFileSelect}
/>
{/* Command Palette (Cmd/Ctrl+K) */}
<CommandPalette
open={showCommandPalette}
onClose={() => setShowCommandPalette(false)}
@ -655,7 +626,6 @@ end)`,
},
})}
/>
{!user && (
<Button
variant="secondary"

View file

@ -67,7 +67,7 @@ end)
};
return (
<div className="h-full w-full bg-background border-l border-border flex flex-col">
<div className="h-full w-full bg-background border border-border shadow-md rounded-md flex flex-col">
<div className="flex-1 min-h-0">
<Editor
height="100%"

View file

@ -88,7 +88,7 @@ export function ConsolePanel({ collapsed, onToggle, currentCode = '', currentFil
if (collapsed) {
return (
<div className="h-8 bg-card border-t border-border flex items-center justify-between px-4 cursor-pointer" onClick={onToggle}>
<div className="h-8 bg-card border-t border-border flex items-center justify-between px-4 cursor-pointer shadow-sm" onClick={onToggle}>
<div className="flex items-center gap-2">
<Terminal size={16} />
<span className="text-sm font-semibold">Console</span>
@ -101,8 +101,8 @@ export function ConsolePanel({ collapsed, onToggle, currentCode = '', currentFil
}
return (
<div className="h-[200px] bg-card border-t border-border flex flex-col">
<div className="flex items-center justify-between px-4 py-2 border-b border-border">
<div className="h-[200px] bg-card border-t border-border flex flex-col shadow-lg rounded-t-md">
<div className="flex items-center justify-between px-4 py-2 border-b border-border bg-muted/40 rounded-t-md">
<div className="flex items-center gap-2">
<Terminal size={18} />
<span className="text-sm font-semibold">Console</span>

View file

@ -58,38 +58,38 @@ export function FileTree({
if (next.has(id)) {
next.delete(id);
} else {
next.add(id);
}
return next;
});
}, []);
const startRename = useCallback((file: FileNode) => {
setEditingId(file.id);
setEditingName(file.name);
}, []);
const finishRename = useCallback((id: string) => {
if (editingName.trim() && editingName !== '') {
onFileRename(id, editingName.trim());
toast.success('File renamed');
}
setEditingId(null);
setEditingName('');
}, [editingName, onFileRename]);
const handleDelete = useCallback((file: FileNode) => {
if (confirm(`Delete ${file.name}?`)) {
onFileDelete(file.id);
toast.success('File deleted');
}
}, [onFileDelete]);
const handleDragStart = useCallback((e: React.DragEvent, node: FileNode) => {
e.stopPropagation();
setDraggedId(node.id);
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', node.id);
return (
<ScrollArea className="flex-1 bg-muted/40 border-r border-border min-w-[180px] max-w-[260px]">
<div className="p-2">
{files.map((node) => (
<FileNodeComponent
key={node.id}
node={node}
expandedFolders={expandedFolders}
toggleFolder={toggleFolder}
onFileSelect={onFileSelect}
onFileCreate={onFileCreate}
onFileRename={onFileRename}
onFileDelete={onFileDelete}
onFileMove={onFileMove}
selectedFileId={selectedFileId}
startRename={startRename}
finishRename={finishRename}
editingId={editingId}
editingName={editingName}
setEditingName={setEditingName}
handleDelete={handleDelete}
handleDragStart={handleDragStart}
handleDragOver={handleDragOver}
handleDragLeave={handleDragLeave}
handleDrop={handleDrop}
draggedId={draggedId}
dropTargetId={dropTargetId}
/>
))}
</div>
</ScrollArea>
);
}, []);
const handleDragOver = useCallback((e: React.DragEvent, node: FileNode) => {

View file

@ -36,7 +36,7 @@ function DialogOverlay({
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/70 backdrop-blur-sm",
className
)}
{...props}
@ -55,7 +55,7 @@ function DialogContent({
<DialogPrimitive.Content
data-slot="dialog-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-2xl border-2 border-accent/60 p-8 shadow-2xl duration-200 sm:max-w-lg",
className
)}
{...props}

View file

@ -1,6 +1,9 @@
export function getTemplatesForPlatform(platform: PlatformId): ScriptTemplate[] {
return templates.filter(t => t.platform === platform);
}
export function getTemplatesForPlatform(platform: PlatformId): ScriptTemplate[] {
return templates.filter(t => t.platform === platform);
}
import { PlatformId } from './platforms';
import { uefnTemplates } from './templates-uefn';
import { spatialTemplates } from './templates-spatial';