Layout: Top navbar: AeThex logo (left), project name (center), user menu with avatar (right) Left sidebar (250px): File tree navigator with folders/files, "New File" and "New Folder" buttons Center: Code editor area (use Monaco Editor component if available, or textarea with syntax highlighting) Right sidebar (300px, collapsible): AI Assistant chat panel with message history Bottom panel (200px, collapsible): Console output and terminal Features: File tree supports create/rename/delete operations Tabs for multiple open files Syntax highlighting for Lua, JavaScript, TypeScript Dark theme with purple/cyan accent colors (futuristic gaming aesthetic) Split panes are resizable Auto-save indicator in navbar Use TypeScript and proper state management. Make it feel like VS Code but purpose-built for game development. Create a unified game development workspace that shows the same game running on three platforms simultaneously: Left panel: Roblox viewport (embed mockup) Center panel: Web browser viewport with game canvas Right panel: Mobile device mockup with game Include: Shared state indicator showing synced variables (player position, score, inventory) Platform-specific code tabs that show Lua (Roblox), JavaScript (Web), and React Native (Mobile) "Deploy to Platform" buttons for each Sync status indicator (green = synced, yellow = syncing, red = conflict) Console output panel at bottom showing platform-specific logs Use a dark IDE-like theme. Make it feel like a professional developer tool. Add a "New Project" modal to the AeThex Studio IDE: Modal triggered by "New Project" button in navbar: Step 1: Choose template (card grid layout) Roblox Game Starter Cross-Platform Multiplayer Transmedia Story Project Blank Project Each card shows icon, title, description, and "Popular" badge where applicable Step 2: Project configuration form Project name input Platform checkboxes (Roblox, Web, Mobile) Enable Nexus Engine toggle (with tooltip explaining state sync) Enable Passport Auth toggle (with tooltip explaining unified identity) Step 3: Review summary and "Create Project" button After creation, populate file tree with template structure and open main file in editor. Use a stepper UI component to show progress. Modern, clean design. Build the AI Assistant chat panel for the right sidebar: UI Components: Header: "AeThex AI Assistant" with model selector dropdown (Claude Sonnet, GPT-4o) Chat message history (scrollable, auto-scroll to bottom) Messages alternate left (user) and right (AI) with avatars Code blocks in messages with syntax highlighting and copy button Input textarea at bottom with "Send" button Token usage indicator (shows X / 500K tokens used this month) Quick Actions (buttons above input): "Explain selected code" "Add comments" "Convert to cross-platform" "Generate tests" Message Types: User messages: blue background AI messages: dark gray background with purple border System messages: small, centered, gray text (e.g., "Code inserted into editor") Features: When AI generates code, show "Insert into editor" button Track conversation context (include current file, project structure) Show typing indicator when AI is responding Make the UX smooth and polished. Create a preview panel modal that opens when user clicks "Preview" in navbar: Layout (fullscreen modal with dark backdrop): Close button (top right) Tab navigation: "Roblox" | "Web" | "Mobile" | "All Platforms" "All Platforms" tab shows three columns: Left: Roblox viewport (iframe placeholder with Roblox logo) Center: Web browser viewport (iframe with game canvas) Right: Mobile device mockup (iPhone frame with game view) Shared State Indicator (floating panel at bottom): Shows synced variables in real-time table: Variable | Roblox | Web | Mobile | Status playerX | 120 | 120 | 120 | ✓ Synced health | 100 | 98 | 100 | ⚠ Syncing Color coded: Green (synced), Yellow (syncing), Red (conflict) Controls: "Refresh All" button Individual "Deploy to [Platform]" buttons Latency simulator slider (0-500ms) Use glassmorphism UI style with blur effects. This should look futuristic and impressive. Add user authentication and workspace management: Login page: AeThex logo and tagline "Sign in with AeThex Passport" button (purple gradient) "Sign in with Google" button "Sign in with GitHub" button Illustration of cross-platform game development Dashboard (after login, before opening project): Header: "My Workspaces" with "New Workspace" button Grid of workspace cards showing: Project name Last modified timestamp Platform badges (Roblox, Web, Mobile icons) Thumbnail/preview image Three-dot menu (Rename, Delete, Share) Empty state if no workspaces: "Create your first game" CTA with template previews Each workspace card is clickable and opens the IDE with that project loaded. Use modern card design with hover effects. Show loading skeletons while fetching data.
207 lines
9.4 KiB
TypeScript
207 lines
9.4 KiB
TypeScript
import { useState } from 'react';
|
|
import { Dialog, DialogContent } from '@/components/ui/dialog';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
import { Card } from '@/components/ui/card';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { X, ArrowsClockwise } from '@phosphor-icons/react';
|
|
|
|
interface PreviewModalProps {
|
|
open: boolean;
|
|
onClose: () => void;
|
|
code: string;
|
|
}
|
|
|
|
interface SharedState {
|
|
variable: string;
|
|
roblox: string;
|
|
web: string;
|
|
mobile: string;
|
|
status: 'synced' | 'syncing' | 'conflict';
|
|
}
|
|
|
|
export function PreviewModal({ open, onClose, code }: PreviewModalProps) {
|
|
const [sharedState] = useState<SharedState[]>([
|
|
{ variable: 'playerX', roblox: '120', web: '120', mobile: '120', status: 'synced' },
|
|
{ variable: 'playerY', roblox: '50', web: '50', mobile: '50', status: 'synced' },
|
|
{ variable: 'health', roblox: '100', web: '98', mobile: '100', status: 'syncing' },
|
|
{ variable: 'score', roblox: '450', web: '450', mobile: '450', status: 'synced' },
|
|
]);
|
|
|
|
const getStatusColor = (status: SharedState['status']) => {
|
|
switch (status) {
|
|
case 'synced':
|
|
return 'text-green-500';
|
|
case 'syncing':
|
|
return 'text-yellow-500';
|
|
case 'conflict':
|
|
return 'text-red-500';
|
|
}
|
|
};
|
|
|
|
const getStatusIcon = (status: SharedState['status']) => {
|
|
switch (status) {
|
|
case 'synced':
|
|
return '✓';
|
|
case 'syncing':
|
|
return '⚠';
|
|
case 'conflict':
|
|
return '✗';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onClose}>
|
|
<DialogContent className="max-w-[95vw] h-[90vh] p-0 gap-0">
|
|
<div className="flex flex-col h-full">
|
|
<div className="flex items-center justify-between p-4 border-b border-border">
|
|
<h2 className="text-xl font-bold">Preview - All Platforms</h2>
|
|
<div className="flex items-center gap-2">
|
|
<Button variant="outline" size="sm">
|
|
<ArrowsClockwise className="mr-2" />
|
|
Refresh All
|
|
</Button>
|
|
<Button variant="ghost" size="icon" onClick={onClose}>
|
|
<X />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<Tabs defaultValue="all" className="flex-1 flex flex-col">
|
|
<TabsList className="mx-4 mt-4 w-fit">
|
|
<TabsTrigger value="all">All Platforms</TabsTrigger>
|
|
<TabsTrigger value="roblox">Roblox</TabsTrigger>
|
|
<TabsTrigger value="web">Web</TabsTrigger>
|
|
<TabsTrigger value="mobile">Mobile</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="all" className="flex-1 flex flex-col p-4 gap-4 m-0">
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4 flex-1">
|
|
<Card className="p-4 flex flex-col">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-semibold">Roblox</h3>
|
|
<Button size="sm" variant="outline">Deploy</Button>
|
|
</div>
|
|
<div className="flex-1 bg-muted/30 rounded flex items-center justify-center border-2 border-dashed border-border">
|
|
<div className="text-center p-8">
|
|
<div className="text-6xl mb-4">🎮</div>
|
|
<p className="text-sm text-muted-foreground">Roblox Viewport</p>
|
|
<p className="text-xs text-muted-foreground mt-1">Studio integration</p>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
|
|
<Card className="p-4 flex flex-col">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-semibold">Web Browser</h3>
|
|
<Button size="sm" variant="outline">Deploy</Button>
|
|
</div>
|
|
<div className="flex-1 bg-muted/30 rounded flex items-center justify-center border-2 border-dashed border-border">
|
|
<div className="text-center p-8">
|
|
<div className="text-6xl mb-4">🌐</div>
|
|
<p className="text-sm text-muted-foreground">Web Canvas</p>
|
|
<p className="text-xs text-muted-foreground mt-1">Browser preview</p>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
|
|
<Card className="p-4 flex flex-col">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-semibold">Mobile</h3>
|
|
<Button size="sm" variant="outline">Deploy</Button>
|
|
</div>
|
|
<div className="flex-1 bg-muted/30 rounded flex items-center justify-center border-2 border-dashed border-border">
|
|
<div className="w-[200px] h-full bg-background rounded-3xl border-4 border-foreground/20 p-2 flex flex-col">
|
|
<div className="w-1/3 h-6 bg-foreground/10 rounded-full mx-auto mb-2" />
|
|
<div className="flex-1 bg-muted/30 rounded-2xl flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-4xl mb-2">📱</div>
|
|
<p className="text-xs text-muted-foreground">Mobile View</p>
|
|
</div>
|
|
</div>
|
|
<div className="h-6 w-1/2 bg-foreground/10 rounded-full mx-auto mt-2" />
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
|
|
<Card className="p-4">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-semibold">Shared State Sync</h3>
|
|
<Badge variant="outline" className="text-green-500 border-green-500">
|
|
Live Sync Enabled
|
|
</Badge>
|
|
</div>
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-sm">
|
|
<thead className="border-b border-border">
|
|
<tr className="text-left">
|
|
<th className="pb-2 font-semibold">Variable</th>
|
|
<th className="pb-2 font-semibold">Roblox</th>
|
|
<th className="pb-2 font-semibold">Web</th>
|
|
<th className="pb-2 font-semibold">Mobile</th>
|
|
<th className="pb-2 font-semibold">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{sharedState.map((state, idx) => (
|
|
<tr key={idx} className="border-b border-border/50">
|
|
<td className="py-2 font-mono text-accent">{state.variable}</td>
|
|
<td className="py-2 font-mono">{state.roblox}</td>
|
|
<td className="py-2 font-mono">{state.web}</td>
|
|
<td className="py-2 font-mono">{state.mobile}</td>
|
|
<td className="py-2">
|
|
<span className={getStatusColor(state.status)}>
|
|
{getStatusIcon(state.status)} {state.status}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</Card>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="roblox" className="flex-1 p-4 m-0">
|
|
<Card className="h-full p-8 flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-8xl mb-4">🎮</div>
|
|
<h3 className="text-2xl font-bold mb-2">Roblox Preview</h3>
|
|
<p className="text-muted-foreground mb-4">Full-screen Roblox viewport</p>
|
|
<Button>Deploy to Roblox</Button>
|
|
</div>
|
|
</Card>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="web" className="flex-1 p-4 m-0">
|
|
<Card className="h-full p-8 flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-8xl mb-4">🌐</div>
|
|
<h3 className="text-2xl font-bold mb-2">Web Preview</h3>
|
|
<p className="text-muted-foreground mb-4">Browser-based game preview</p>
|
|
<Button>Deploy to Web</Button>
|
|
</div>
|
|
</Card>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="mobile" className="flex-1 p-4 m-0 flex items-center justify-center">
|
|
<div className="w-[300px] h-[600px] bg-background rounded-3xl border-8 border-foreground/20 p-4 flex flex-col shadow-2xl">
|
|
<div className="w-1/2 h-8 bg-foreground/10 rounded-full mx-auto mb-4" />
|
|
<Card className="flex-1 flex items-center justify-center">
|
|
<div className="text-center">
|
|
<div className="text-6xl mb-4">📱</div>
|
|
<h3 className="text-xl font-bold mb-2">Mobile Preview</h3>
|
|
<p className="text-sm text-muted-foreground mb-4">iOS/Android view</p>
|
|
<Button size="sm">Deploy to Mobile</Button>
|
|
</div>
|
|
</Card>
|
|
<div className="h-8 w-1/2 bg-foreground/10 rounded-full mx-auto mt-4" />
|
|
</div>
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|