From f4e6651724f85df8aaf77c87607bd12e55c6fd0d Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Jan 2026 22:58:04 +0000 Subject: [PATCH] Complete Phase 2: Full integration of multi-platform system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- src/App.tsx | 24 ++++++++++++++++++++++-- src/components/CodeEditor.tsx | 16 +++++++++++++--- src/components/TemplatesDrawer.tsx | 24 ++++++++++++++++-------- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index cb68f94..a1f1fb1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,6 +20,8 @@ import { initPostHog, captureEvent } from './lib/posthog'; import { initSentry, captureError } from './lib/sentry'; import { LoadingSpinner } from './components/ui/loading-spinner'; +import { PlatformId } from './lib/platforms'; + // Lazy load heavy/modal components for code splitting and better initial load const TemplatesDrawer = lazy(() => import('./components/TemplatesDrawer').then(m => ({ default: m.TemplatesDrawer }))); const WelcomeDialog = lazy(() => import('./components/WelcomeDialog').then(m => ({ default: m.WelcomeDialog }))); @@ -27,6 +29,7 @@ const PreviewModal = lazy(() => import('./components/PreviewModal').then(m => ({ const NewProjectModal = lazy(() => import('./components/NewProjectModal').then(m => ({ default: m.NewProjectModal }))); const EducationPanel = lazy(() => import('./components/EducationPanel').then(m => ({ default: m.EducationPanel }))); const PassportLogin = lazy(() => import('./components/PassportLogin').then(m => ({ default: m.PassportLogin }))); +const TranslationPanel = lazy(() => import('./components/TranslationPanel').then(m => ({ default: m.TranslationPanel }))); function App() { const [currentCode, setCurrentCode] = useState(''); @@ -36,7 +39,9 @@ function App() { const [showFileSearch, setShowFileSearch] = useState(false); const [showCommandPalette, setShowCommandPalette] = useState(false); const [showSearchInFiles, setShowSearchInFiles] = useState(false); + const [showTranslation, setShowTranslation] = useState(false); const [code, setCode] = useState(''); + const [currentPlatform, setCurrentPlatform] = useState('roblox'); const isMobile = useIsMobile(); const [showPassportLogin, setShowPassportLogin] = useState(false); @@ -457,6 +462,9 @@ end)`,
setShowTranslation(true)} onTemplatesClick={() => setShowTemplates(true)} onPreviewClick={() => setShowPreview(true)} onNewProjectClick={() => setShowNewProject(true)} @@ -490,7 +498,7 @@ end)`, onFileClose={handleFileClose} />
- +
@@ -529,7 +537,7 @@ end)`, onFileClose={handleFileClose} />
- +
@@ -572,6 +580,7 @@ end)`, setShowTemplates(false)} + currentPlatform={currentPlatform} /> )} @@ -592,6 +601,17 @@ end)`, /> + + {showTranslation && ( + setShowTranslation(false)} + currentCode={currentCode} + currentPlatform={currentPlatform} + /> + )} + + diff --git a/src/components/CodeEditor.tsx b/src/components/CodeEditor.tsx index a5cdd9b..e4f315a 100644 --- a/src/components/CodeEditor.tsx +++ b/src/components/CodeEditor.tsx @@ -1,14 +1,24 @@ import Editor from '@monaco-editor/react'; import { useKV } from '@github/spark/hooks'; -import { useEffect } from 'react'; +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 }: CodeEditorProps) { +export function CodeEditor({ onCodeChange, platform = 'roblox' }: CodeEditorProps) { + const languageMap: Record = 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 @@ -61,7 +71,7 @@ end)
void; onClose: () => void; + currentPlatform: PlatformId; } -export function TemplatesDrawer({ onSelectTemplate, onClose }: TemplatesDrawerProps) { +export function TemplatesDrawer({ onSelectTemplate, onClose, currentPlatform }: TemplatesDrawerProps) { + const platform = getPlatform(currentPlatform); + const platformTemplates = getTemplatesForPlatform(currentPlatform); + const categories = { - beginner: templates.filter(t => t.category === 'beginner'), - gameplay: templates.filter(t => t.category === 'gameplay'), - ui: templates.filter(t => t.category === 'ui'), - tools: templates.filter(t => t.category === 'tools'), + beginner: platformTemplates.filter(t => t.category === 'beginner'), + gameplay: platformTemplates.filter(t => t.category === 'gameplay'), + ui: platformTemplates.filter(t => t.category === 'ui'), + tools: platformTemplates.filter(t => t.category === 'tools'), }; const handleTemplateClick = (template: ScriptTemplate) => { @@ -29,9 +34,12 @@ export function TemplatesDrawer({ onSelectTemplate, onClose }: TemplatesDrawerPr
-

Script Templates

+

+ {platform.icon} + {platform.displayName} Templates +

- Choose a template to get started quickly + {platformTemplates.length} templates available • Choose one to get started