aethex-studio/src/components/CodeEditor.tsx
Claude f4e6651724
Complete Phase 2: Full integration of multi-platform system
This completes the integration of the cross-platform translation engine
into the main application, making it fully functional.

App.tsx Changes:
- Added platform state management (currentPlatform: PlatformId)
- Added translation panel state (showTranslation)
- Integrated TranslationPanel component with lazy loading
- Updated Toolbar with platform selector and translate button
- Passed platform prop to TemplatesDrawer and CodeEditor
- Connected all state management for seamless platform switching

TemplatesDrawer Changes:
- Now accepts currentPlatform prop
- Filters templates by selected platform using getTemplatesForPlatform()
- Shows platform icon and name in header
- Displays template count for current platform
- Ready for UEFN/Spatial/Core templates

CodeEditor Changes:
- Accepts optional platform prop (defaults to 'roblox')
- Dynamically sets Monaco editor language based on platform:
  * roblox → lua
  * uefn → plaintext (Verse not yet in Monaco)
  * spatial → typescript
  * core → lua
- Maintains backward compatibility with existing code

Functional Features:
 Platform switching in toolbar
 Templates filter by platform automatically
 Editor language changes with platform
 Translation panel opens with "Translate" button
 Side-by-side code comparison
 Mock translation working
 All state connected and reactive

Next: Phase 3 (Create UEFN templates) or Phase 4 (Claude API integration)
2026-01-17 22:58:04 +00:00

105 lines
3 KiB
TypeScript

import Editor from '@monaco-editor/react';
import { useKV } from '@github/spark/hooks';
import { useEffect, useMemo } from 'react';
import { LoadingSpinner } from './ui/loading-spinner';
import { toast } from 'sonner';
import { PlatformId } from '@/lib/platforms';
interface CodeEditorProps {
onCodeChange?: (code: string) => void;
platform?: PlatformId;
}
export function CodeEditor({ onCodeChange, platform = 'roblox' }: CodeEditorProps) {
const languageMap: Record<PlatformId, string> = useMemo(() => ({
roblox: 'lua',
uefn: 'plaintext', // Verse not yet supported by Monaco, use plaintext
spatial: 'typescript',
core: 'lua',
}), []);
const editorLanguage = languageMap[platform];
const [code, setCode] = useKV('aethex-current-code', `-- Welcome to AeThex Studio!
-- Write your Roblox Lua code here
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
print(player.Name .. " joined the game!")
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Value = 0
coins.Parent = leaderstats
end)
`);
useEffect(() => {
try {
if (onCodeChange && code) {
onCodeChange(code);
}
} catch (error) {
console.error('Failed to update code:', error);
}
}, [code, onCodeChange]);
const handleEditorChange = (value: string | undefined) => {
try {
setCode(value || '');
} catch (error) {
console.error('Failed to save code:', error);
toast.error('Failed to save changes. Please try again.');
}
};
const handleEditorMount = () => {
console.log('Monaco editor mounted successfully');
};
const handleEditorError = (error: Error) => {
console.error('Monaco editor error:', error);
toast.error('Editor failed to load. Please refresh the page.');
};
return (
<div className="h-full w-full bg-background border-l border-border flex flex-col">
<div className="flex-1 min-h-0">
<Editor
height="100%"
language={editorLanguage}
theme="vs-dark"
value={code}
onChange={handleEditorChange}
onMount={handleEditorMount}
loading={
<div className="h-full flex items-center justify-center">
<LoadingSpinner />
</div>
}
options={{
minimap: { enabled: typeof window !== 'undefined' && window.innerWidth >= 768 },
fontSize: 13,
lineNumbers: 'on',
automaticLayout: true,
scrollBeyondLastLine: false,
wordWrap: 'on',
fontFamily: 'JetBrains Mono, monospace',
fontLigatures: true,
cursorBlinking: 'smooth',
smoothScrolling: true,
padding: { top: 8, bottom: 8 },
scrollbar: {
verticalScrollbarSize: 6,
horizontalScrollbarSize: 6,
},
}}
/>
</div>
</div>
);
}