124 lines
5.6 KiB
TypeScript
124 lines
5.6 KiB
TypeScript
"use client";
|
||
|
||
import React from 'react';
|
||
import { Trash2 } from 'lucide-react';
|
||
import { useAppStore } from '@/store/app-store';
|
||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||
import { Button } from '@/components/ui/button';
|
||
import { formatTimestamp, getPlatformColor } from '@/lib/utils';
|
||
|
||
export function ConsolePanel() {
|
||
const { consoleMessages, clearConsole, bottomPanelTab, setBottomPanelTab } = useAppStore();
|
||
const scrollRef = React.useRef<HTMLDivElement>(null);
|
||
|
||
React.useEffect(() => {
|
||
if (scrollRef.current) {
|
||
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
||
}
|
||
}, [consoleMessages]);
|
||
|
||
return (
|
||
<div className="h-full flex flex-col bg-surface">
|
||
<Tabs value={bottomPanelTab} onValueChange={(v) => setBottomPanelTab(v as any)} className="flex-1 flex flex-col">
|
||
<div className="flex items-center justify-between border-b border-gray-800">
|
||
<TabsList className="bg-transparent border-none h-auto p-0">
|
||
<TabsTrigger
|
||
value="console"
|
||
className="data-[state=active]:bg-background data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-4 py-2"
|
||
>
|
||
Console
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="terminal"
|
||
className="data-[state=active]:bg-background data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-4 py-2"
|
||
>
|
||
Terminal
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="nexus"
|
||
className="data-[state=active]:bg-background data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-4 py-2"
|
||
>
|
||
Nexus Sync
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="deploy"
|
||
className="data-[state=active]:bg-background data-[state=active]:border-b-2 data-[state=active]:border-primary rounded-none px-4 py-2"
|
||
>
|
||
Deploy Logs
|
||
</TabsTrigger>
|
||
</TabsList>
|
||
|
||
{bottomPanelTab === 'console' && (
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={clearConsole}
|
||
className="mr-2 text-gray-400 hover:text-white"
|
||
>
|
||
<Trash2 className="w-4 h-4 mr-2" />
|
||
Clear
|
||
</Button>
|
||
)}
|
||
</div>
|
||
|
||
<TabsContent value="console" className="flex-1 m-0 overflow-hidden">
|
||
<ScrollArea ref={scrollRef} className="h-full">
|
||
<div className="p-2 font-mono text-xs space-y-0.5">
|
||
{consoleMessages.map((msg: any) => (
|
||
<div key={msg.id} className="flex gap-2 py-1 hover:bg-background/50">
|
||
<span className="text-gray-500 shrink-0">{formatTimestamp(msg.timestamp)}</span>
|
||
<span className={`font-semibold shrink-0 ${getPlatformColor(msg.platform)}`}>
|
||
[{msg.platform.toUpperCase()}]
|
||
</span>
|
||
<span className="text-gray-200">{msg.message}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</ScrollArea>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="terminal" className="flex-1 m-0 overflow-hidden bg-background">
|
||
<ScrollArea className="h-full">
|
||
<div className="p-4 font-mono text-sm text-gray-300">
|
||
<div className="mb-2">$ npm run dev</div>
|
||
<div className="text-green-400">✓ Starting development server...</div>
|
||
<div className="text-cyan-400">Local: http://localhost:3000</div>
|
||
<div className="mt-4">
|
||
<span className="text-primary">❯</span>
|
||
<span className="ml-2 animate-pulse">_</span>
|
||
</div>
|
||
</div>
|
||
</ScrollArea>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="nexus" className="flex-1 m-0 overflow-hidden">
|
||
<ScrollArea className="h-full">
|
||
<div className="p-4 font-mono text-xs space-y-1">
|
||
<div className="text-blue-400">14:30:45.123 [Roblox→All] Player_001.position updated</div>
|
||
<div className="text-gray-400">14:30:45.124 [Web] Ack received (12ms latency)</div>
|
||
<div className="text-gray-400">14:30:45.126 [Mobile] Ack received (14ms latency)</div>
|
||
<div className="text-gray-400">14:30:45.140 [Desktop] Ack received (28ms latency)</div>
|
||
<div className="text-blue-400">14:30:46.001 [Web→All] Player_002.health changed: 100→95</div>
|
||
<div className="text-yellow-400">14:30:46.015 [Conflict] Player_001.inventory - resolving...</div>
|
||
<div className="text-green-400">14:30:46.020 [Resolved] Server authority applied</div>
|
||
</div>
|
||
</ScrollArea>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="deploy" className="flex-1 m-0 overflow-hidden">
|
||
<ScrollArea className="h-full">
|
||
<div className="p-4 font-mono text-xs space-y-1">
|
||
<div className="text-cyan-400">[Deploy] Starting deployment to Roblox...</div>
|
||
<div className="text-gray-300">[Build] Compiling Lua scripts...</div>
|
||
<div className="text-green-400">[Build] ✓ Compilation successful</div>
|
||
<div className="text-cyan-400">[Upload] Uploading to Roblox Cloud...</div>
|
||
<div className="text-green-400">[Deploy] ✓ Deployment complete!</div>
|
||
<div className="text-gray-400">[Info] Universe ID: 123456789</div>
|
||
</div>
|
||
</ScrollArea>
|
||
</TabsContent>
|
||
</Tabs>
|
||
</div>
|
||
);
|
||
}
|