modified: src/lib/templates.ts
This commit is contained in:
parent
0fdaefdc8d
commit
42a1e2c3e6
6 changed files with 129 additions and 156 deletions
206
src/App.tsx
206
src/App.tsx
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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%"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
Loading…
Reference in a new issue