aethex-studio/components/AIAssistant.tsx

203 lines
7.4 KiB
TypeScript

"use client";
import React from 'react';
import { Send, Sparkles, Code, MessageSquare, TestTube, RefreshCw, Lock, Search } from 'lucide-react';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
interface Message {
id: string;
role: 'user' | 'assistant';
content: string;
code?: {
language: string;
code: string;
};
}
export function AIAssistant() {
const [messages, setMessages] = React.useState<Message[]>([
{
id: '1',
role: 'assistant',
content: 'Hello! I\'m your AeThex AI Assistant. I can help you with cross-platform development, Nexus Engine integration, Passport authentication, and more. How can I help you today?',
},
]);
const [input, setInput] = React.useState('');
const [model, setModel] = React.useState('gemini-pro');
const scrollRef = React.useRef<HTMLDivElement>(null);
const quickActions = [
{ icon: <Search className="w-4 h-4" />, label: 'Explain Code', color: 'bg-blue-500/10 text-blue-400' },
{ icon: <MessageSquare className="w-4 h-4" />, label: 'Add Comments', color: 'bg-purple-500/10 text-purple-400' },
{ icon: <TestTube className="w-4 h-4" />, label: 'Generate Tests', color: 'bg-green-500/10 text-green-400' },
{ icon: <RefreshCw className="w-4 h-4" />, label: 'Cross-Platform Convert', color: 'bg-cyan-500/10 text-cyan-400' },
{ icon: <Lock className="w-4 h-4" />, label: 'Add Nexus Sync', color: 'bg-orange-500/10 text-orange-400' },
{ icon: <Lock className="w-4 h-4" />, label: 'Setup Passport Auth', color: 'bg-pink-500/10 text-pink-400' },
];
const prebuiltPrompts = [
"Set up cross-platform player movement",
"Add Nexus Engine state sync for [variable]",
"Create Passport login flow",
"Generate GameForge anti-cheat rules",
"Build multiplayer matchmaking system",
];
const sendMessage = () => {
if (!input.trim()) return;
const userMessage: Message = {
id: Date.now().toString(),
role: 'user',
content: input,
};
setMessages(prev => [...prev, userMessage]);
setInput('');
// Simulate AI response
setTimeout(() => {
const aiMessage: Message = {
id: (Date.now() + 1).toString(),
role: 'assistant',
content: 'I can help you with that! Here\'s a code example:',
code: {
language: 'typescript',
code: `// Example cross-platform code\nexport class PlayerController {\n move(x: number, y: number) {\n // Update position\n nexusEngine.setState('playerX', x);\n nexusEngine.setState('playerY', y);\n }\n}`,
},
};
setMessages(prev => [...prev, aiMessage]);
}, 1000);
};
React.useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [messages]);
return (
<div className="h-full flex flex-col bg-gray-900">
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-800">
<div className="flex items-center gap-2">
<Sparkles className="w-5 h-5 text-primary" />
<span className="font-semibold text-white">AI Assistant</span>
</div>
<Select value={model} onValueChange={setModel}>
<SelectTrigger className="w-32 h-8 text-xs border-gray-700 bg-surface">
<SelectValue />
</SelectTrigger>
<SelectContent className="bg-surface border-gray-700">
<SelectItem value="gemini-pro">Gemini Pro</SelectItem>
<SelectItem value="claude-3">Claude 3</SelectItem>
<SelectItem value="gpt-4">GPT-4</SelectItem>
</SelectContent>
</Select>
</div>
{/* Quick Actions */}
<div className="p-3 border-b border-gray-800">
<div className="grid grid-cols-2 gap-2">
{quickActions.map((action, i) => (
<button
key={i}
className={`flex items-center gap-2 px-3 py-2 rounded-lg text-xs font-medium transition-colors ${action.color} hover:opacity-80`}
>
{action.icon}
{action.label}
</button>
))}
</div>
</div>
{/* Messages */}
<ScrollArea ref={scrollRef} className="flex-1 p-4">
<div className="space-y-4">
{messages.map((message) => (
<div
key={message.id}
className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
>
<div
className={`max-w-[85%] rounded-lg px-4 py-2 ${
message.role === 'user'
? 'bg-blue-600 text-white'
: 'bg-primary/20 text-white'
}`}
>
<p className="text-sm whitespace-pre-wrap">{message.content}</p>
{message.code && (
<div className="mt-2 bg-background rounded-lg p-3 font-mono text-xs">
<div className="flex items-center justify-between mb-2">
<span className="text-gray-400">{message.code.language}</span>
<div className="flex gap-2">
<button className="text-xs text-primary hover:text-primary-light">
Copy
</button>
<button className="text-xs text-green-400 hover:text-green-300">
Insert into editor
</button>
</div>
</div>
<pre className="text-gray-200">{message.code.code}</pre>
</div>
)}
</div>
</div>
))}
</div>
</ScrollArea>
{/* Prebuilt Prompts */}
<div className="px-3 py-2 border-t border-gray-800">
<ScrollArea className="max-h-20">
<div className="flex flex-wrap gap-1">
{prebuiltPrompts.map((prompt, i) => (
<button
key={i}
onClick={() => setInput(prompt)}
className="text-xs px-2 py-1 bg-surface hover:bg-surface/70 rounded text-gray-300 transition-colors whitespace-nowrap"
>
{prompt}
</button>
))}
</div>
</ScrollArea>
</div>
{/* Input */}
<div className="p-3 border-t border-gray-800">
<div className="flex gap-2">
<Textarea
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
}}
placeholder="Ask anything..."
className="resize-none bg-surface border-gray-700 text-white placeholder:text-gray-500"
rows={2}
/>
<Button
onClick={sendMessage}
disabled={!input.trim()}
className="px-4 bg-primary hover:bg-primary-light"
>
<Send className="w-4 h-4" />
</Button>
</div>
<div className="mt-2 flex items-center justify-between text-xs text-gray-400">
<span>Press Enter to send, Shift+Enter for new line</span>
<span>450K / 500K tokens used</span>
</div>
</div>
</div>
);
}