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

View file

@ -67,7 +67,7 @@ end)
}; };
return ( 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"> <div className="flex-1 min-h-0">
<Editor <Editor
height="100%" height="100%"

View file

@ -88,7 +88,7 @@ export function ConsolePanel({ collapsed, onToggle, currentCode = '', currentFil
if (collapsed) { if (collapsed) {
return ( 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"> <div className="flex items-center gap-2">
<Terminal size={16} /> <Terminal size={16} />
<span className="text-sm font-semibold">Console</span> <span className="text-sm font-semibold">Console</span>
@ -101,8 +101,8 @@ export function ConsolePanel({ collapsed, onToggle, currentCode = '', currentFil
} }
return ( return (
<div className="h-[200px] bg-card border-t border-border flex flex-col"> <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"> <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"> <div className="flex items-center gap-2">
<Terminal size={18} /> <Terminal size={18} />
<span className="text-sm font-semibold">Console</span> <span className="text-sm font-semibold">Console</span>

View file

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

View file

@ -36,7 +36,7 @@ function DialogOverlay({
<DialogPrimitive.Overlay <DialogPrimitive.Overlay
data-slot="dialog-overlay" data-slot="dialog-overlay"
className={cn( 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 className
)} )}
{...props} {...props}
@ -55,7 +55,7 @@ function DialogContent({
<DialogPrimitive.Content <DialogPrimitive.Content
data-slot="dialog-content" data-slot="dialog-content"
className={cn( 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 className
)} )}
{...props} {...props}

View file

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