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)
90 lines
3.8 KiB
TypeScript
90 lines
3.8 KiB
TypeScript
import { Button } from '@/components/ui/button';
|
|
import { Card } from '@/components/ui/card';
|
|
import { ScrollArea } from '@/components/ui/scroll-area';
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { X } from '@phosphor-icons/react';
|
|
import { templates, type ScriptTemplate, getTemplatesForPlatform } from '@/lib/templates';
|
|
import { PlatformId, getPlatform } from '@/lib/platforms';
|
|
|
|
interface TemplatesDrawerProps {
|
|
onSelectTemplate: (code: string) => void;
|
|
onClose: () => void;
|
|
currentPlatform: PlatformId;
|
|
}
|
|
|
|
export function TemplatesDrawer({ onSelectTemplate, onClose, currentPlatform }: TemplatesDrawerProps) {
|
|
const platform = getPlatform(currentPlatform);
|
|
const platformTemplates = getTemplatesForPlatform(currentPlatform);
|
|
|
|
const categories = {
|
|
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) => {
|
|
onSelectTemplate(template.code);
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<div className="fixed inset-0 bg-background/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
|
|
<Card className="w-full max-w-4xl max-h-[80vh] flex flex-col bg-card border-border">
|
|
<div className="flex items-center justify-between p-4 border-b border-border">
|
|
<div>
|
|
<h2 className="text-2xl font-bold flex items-center gap-2">
|
|
<span>{platform.icon}</span>
|
|
{platform.displayName} Templates
|
|
</h2>
|
|
<p className="text-sm text-muted-foreground mt-1">
|
|
{platformTemplates.length} templates available • Choose one to get started
|
|
</p>
|
|
</div>
|
|
<Button variant="ghost" size="icon" onClick={onClose}>
|
|
<X />
|
|
</Button>
|
|
</div>
|
|
|
|
<Tabs defaultValue="beginner" className="flex-1 flex flex-col">
|
|
<TabsList className="mx-4 mt-4">
|
|
<TabsTrigger value="beginner">Beginner</TabsTrigger>
|
|
<TabsTrigger value="gameplay">Gameplay</TabsTrigger>
|
|
<TabsTrigger value="ui">UI</TabsTrigger>
|
|
<TabsTrigger value="tools">Tools</TabsTrigger>
|
|
</TabsList>
|
|
|
|
{Object.entries(categories).map(([category, items]) => (
|
|
<TabsContent key={category} value={category} className="flex-1 m-0">
|
|
<ScrollArea className="h-[calc(80vh-180px)]">
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 p-4">
|
|
{items.map((template) => (
|
|
<Card
|
|
key={template.id}
|
|
className="p-4 cursor-pointer hover:border-accent transition-colors"
|
|
onClick={() => handleTemplateClick(template)}
|
|
>
|
|
<div className="flex items-start justify-between mb-2">
|
|
<h3 className="font-semibold">{template.name}</h3>
|
|
<Badge variant="secondary" className="text-xs">
|
|
{template.category}
|
|
</Badge>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground mb-3">
|
|
{template.description}
|
|
</p>
|
|
<pre className="text-xs bg-background p-2 rounded overflow-x-auto">
|
|
<code>{template.code.split('\n').slice(0, 3).join('\n')}...</code>
|
|
</pre>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
</TabsContent>
|
|
))}
|
|
</Tabs>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|