import React, { useState, useCallback, useEffect } from 'react'
import mcpService from '../../services/mcpService'
import MCPStatusBanner from '../../components/MCPStatusBanner'
import LaunchControls from '../../components/LaunchControls'
// Resonite integration data
const resoniteData = {
connected: true,
user: {
username: 'RoboticsLab',
userId: 'U-RoboticsLab',
rank: 'Builder',
reputation: 2847
},
world: {
name: 'Robotics Research Lab',
worldId: 'W-RoboticsLab-001',
description: 'Advanced robotics simulation and testing environment',
visitors: 12,
maxVisitors: 50,
category: 'Educational',
tags: ['Robotics', 'Simulation', 'Research', 'Education']
},
sessions: [
{ id: 'session_001', name: 'Robot Testing Session', users: 8, startTime: '14:30', duration: '2h 15m' },
{ id: 'session_002', name: 'Collaborative Design', users: 5, startTime: '16:00', duration: '1h 45m' }
],
uix: {
activeInterfaces: 3,
customComponents: 12,
interactions: 45,
accessibility: 'Full'
},
networking: {
protocol: 'Resonite Networking',
compression: 'LZ4',
encryption: 'AES-256',
latency: 45,
packetLoss: 0.1
},
assets: {
models: 234,
textures: 456,
audio: 89,
scripts: 67,
worlds: 12
},
social: {
friends: 28,
contacts: 156,
groups: 5,
messages: 12
}
}
export default function ResonitePage() {
console.log('Resonite Integration loading...')
const [resonite, setResonite] = useState(resoniteData)
const [activeTab, setActiveTab] = useState('world')
const [selectedSession, setSelectedSession] = useState('')
const [mcpConnected, setMcpConnected] = useState(false)
const [usingMockData, setUsingMockData] = useState(true)
const [chatMessages, setChatMessages] = useState([
{ user: 'System', message: 'Welcome to Robotics Research Lab', time: '14:25' },
{ user: 'Alice', message: 'Starting robot calibration...', time: '14:26' },
{ user: 'Bob', message: 'Sensor data looks good', time: '14:27' }
])
const sendChatMessage = useCallback((message: string) => {
const newMessage = {
user: resonite.user.username,
message,
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}
setChatMessages(prev => [...prev, newMessage])
}, [resonite.user.username])
const createSession = useCallback(() => {
const newSession = {
id: `session_${Date.now()}`,
name: 'New Robotics Session',
users: 1,
startTime: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
duration: '0m'
}
setResonite(prev => ({
...prev,
sessions: [...prev.sessions, newSession]
}))
}, [])
const spawnRobot = useCallback(async (type: string) => {
if (mcpConnected) {
try {
const result = await mcpService.resoniteCallTool('spawn_object', {
object_type: type,
world_id: resonite.world.worldId
})
if (result.success) {
sendChatMessage(`Spawned ${type} robot in world (via MCP)`)
} else {
sendChatMessage(`Failed to spawn ${type}: ${result.error}`)
}
} catch (error) {
console.error('Error spawning robot via MCP:', error)
sendChatMessage(`Spawned ${type} robot (MOCK - MCP unavailable)`)
}
} else {
console.log(`Spawning ${type} robot (MOCK)`)
sendChatMessage(`Spawned ${type} robot in world`)
}
}, [sendChatMessage, mcpConnected, resonite.world.worldId])
return (
<div style={{
minHeight: '100vh',
backgroundColor: '#0f172a',
color: '#f8fafc',
padding: '24px',
fontFamily: 'system-ui, -apple-system, sans-serif'
}}>
<div style={{ maxWidth: '1400px', margin: '0 auto' }}>
{/* MCP Status Banner */}
<MCPStatusBanner serverName="resonite" displayName="Resonite" />
{/* Header */}
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '32px',
padding: '24px',
backgroundColor: '#1e293b',
borderRadius: '16px',
border: '1px solid #334155'
}}>
<div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
<div style={{
width: '64px',
height: '64px',
backgroundColor: '#6366f1',
borderRadius: '16px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '32px'
}}>
π
</div>
<div>
<h1 style={{
fontSize: '32px',
fontWeight: 'bold',
color: '#f8fafc',
marginBottom: '4px'
}}>Resonite Integration</h1>
<p style={{ color: '#94a3b8' }}>Metaverse robotics simulation and collaborative environment</p>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<div style={{
padding: '8px 16px',
backgroundColor: resonite.connected ? '#10b981' : '#dc2626',
color: 'white',
borderRadius: '20px',
fontSize: '12px',
fontWeight: '500'
}}>
π {resonite.connected ? 'Connected' : 'Disconnected'}
</div>
<div style={{ textAlign: 'right' }}>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>{resonite.user.username}</div>
<div style={{ fontSize: '10px', color: '#64748b' }}>Rank: {resonite.user.rank}</div>
</div>
</div>
</div>
{/* Tab Navigation */}
<div style={{
display: 'flex',
borderBottom: '1px solid #334155',
marginBottom: '24px'
}}>
{[
{ id: 'world', label: 'π World', icon: 'π' },
{ id: 'sessions', label: 'π₯ Sessions', icon: 'π₯' },
{ id: 'uix', label: 'π₯οΈ UIX', icon: 'π₯οΈ' },
{ id: 'social', label: 'π¬ Social', icon: 'π¬' }
].map(tab => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
style={{
padding: '12px 24px',
backgroundColor: 'transparent',
color: activeTab === tab.id ? '#3b82f6' : '#94a3b8',
border: 'none',
borderBottom: activeTab === tab.id ? '2px solid #3b82f6' : '2px solid transparent',
fontSize: '14px',
fontWeight: '500',
cursor: 'pointer',
transition: 'all 0.2s'
}}
>
{tab.label}
</button>
))}
</div>
{/* Tab Content */}
{activeTab === 'world' && (
<div style={{
display: 'grid',
gridTemplateColumns: '1fr 350px',
gap: '24px'
}}>
{/* World Viewer */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px',
height: '500px'
}}>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: '16px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc' }}>
π World View - {resonite.world.name}
</h3>
<div style={{ display: 'flex', gap: '8px' }}>
<button style={{
padding: '6px 12px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>βΆοΈ Start</button>
<button style={{
padding: '6px 12px',
backgroundColor: '#6b7280',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}>π· Capture</button>
</div>
</div>
{/* Resonite World Placeholder */}
<div style={{
height: '350px',
backgroundColor: '#0f172a',
borderRadius: '8px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
border: '2px dashed #475569'
}}>
<div style={{ textAlign: 'center', color: '#94a3b8' }}>
<div style={{ fontSize: '64px', marginBottom: '16px' }}>π</div>
<div style={{ fontSize: '18px', fontWeight: '500', marginBottom: '8px' }}>
Resonite World Active
</div>
<div style={{ fontSize: '14px' }}>
{resonite.world.visitors}/{resonite.world.maxVisitors} visitors β’ {resonite.world.category}
</div>
<div style={{ fontSize: '12px', marginTop: '8px', color: '#64748b' }}>
World ID: {resonite.world.worldId}
</div>
</div>
</div>
{/* Quick Spawn */}
<div style={{
marginTop: '16px',
display: 'flex',
gap: '8px',
flexWrap: 'wrap'
}}>
<button
onClick={() => spawnRobot('Quadruped Robot')}
style={{
padding: '6px 12px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}
>
π€ Spawn Robot
</button>
<button
onClick={() => spawnRobot('Sensor Platform')}
style={{
padding: '6px 12px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}
>
π‘ Spawn Sensors
</button>
<button
onClick={() => spawnRobot('Test Object')}
style={{
padding: '6px 12px',
backgroundColor: '#f59e0b',
color: 'white',
border: 'none',
borderRadius: '4px',
fontSize: '11px',
cursor: 'pointer'
}}
>
π§ͺ Spawn Test
</button>
</div>
</div>
{/* World Info & Controls */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
{/* World Stats */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
π World Statistics
</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '14px' }}>Visitors</span>
<span style={{ color: '#f8fafc', fontSize: '14px', fontWeight: '500' }}>
{resonite.world.visitors}/{resonite.world.maxVisitors}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '14px' }}>Category</span>
<span style={{ color: '#f8fafc', fontSize: '14px', fontWeight: '500' }}>
{resonite.world.category}
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '14px' }}>Network</span>
<span style={{
color: resonite.networking.latency < 50 ? '#10b981' : '#f59e0b',
fontSize: '14px',
fontWeight: '500'
}}>
{resonite.networking.latency}ms
</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '14px' }}>Packet Loss</span>
<span style={{ color: '#f8fafc', fontSize: '14px', fontWeight: '500' }}>
{resonite.networking.packetLoss}%
</span>
</div>
</div>
</div>
{/* UIX Components */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
π₯οΈ Active UIX Components
</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Interfaces</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.uix.activeInterfaces}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Components</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.uix.customComponents}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Interactions</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.uix.interactions}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Accessibility</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.uix.accessibility}</span>
</div>
</div>
</div>
{/* Asset Library */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
π¦ Asset Library
</h3>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#3b82f6' }}>
{resonite.assets.models}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Models</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#10b981' }}>
{resonite.assets.textures}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Textures</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#f59e0b' }}>
{resonite.assets.audio}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Audio</div>
</div>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#8b5cf6' }}>
{resonite.assets.worlds}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Worlds</div>
</div>
</div>
</div>
</div>
</div>
)}
{activeTab === 'sessions' && (
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}}>
<h3 style={{ fontSize: '20px', fontWeight: '600', color: '#f8fafc' }}>Active Sessions</h3>
<button
onClick={createSession}
style={{
padding: '8px 16px',
backgroundColor: '#10b981',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '14px',
cursor: 'pointer'
}}
>
β New Session
</button>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '16px' }}>
{resonite.sessions.map(session => (
<div key={session.id} style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '8px' }}>
{session.name}
</h4>
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px', fontSize: '12px', color: '#94a3b8' }}>
<div>π₯ {session.users} users</div>
<div>π Started: {session.startTime}</div>
<div>β±οΈ Duration: {session.duration}</div>
</div>
</div>
))}
</div>
</div>
)}
{activeTab === 'uix' && (
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
<h3 style={{ fontSize: '20px', fontWeight: '600', color: '#f8fafc' }}>User Interface Experience (UIX)</h3>
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
gap: '16px'
}}>
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
ποΈ Active Interfaces
</h4>
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#3b82f6', marginBottom: '4px' }}>
{resonite.uix.activeInterfaces}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>Interactive UI elements</div>
</div>
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
π§© Custom Components
</h4>
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#10b981', marginBottom: '4px' }}>
{resonite.uix.customComponents}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>User-created components</div>
</div>
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
π Interactions
</h4>
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#f59e0b', marginBottom: '4px' }}>
{resonite.uix.interactions}
</div>
<div style={{ fontSize: '12px', color: '#94a3b8' }}>User interactions tracked</div>
</div>
</div>
</div>
)}
{activeTab === 'social' && (
<div style={{
display: 'grid',
gridTemplateColumns: '1fr 300px',
gap: '24px'
}}>
{/* Social Feed */}
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '24px'
}}>
<h3 style={{ fontSize: '18px', fontWeight: '600', color: '#f8fafc', marginBottom: '16px' }}>
π¬ Social Feed
</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', maxHeight: '400px', overflowY: 'auto' }}>
{chatMessages.map((msg, index) => (
<div key={index} style={{
padding: '12px',
backgroundColor: '#0f172a',
borderRadius: '8px'
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px' }}>
<span style={{ fontSize: '12px', fontWeight: '600', color: '#3b82f6' }}>{msg.user}</span>
<span style={{ fontSize: '10px', color: '#64748b' }}>{msg.time}</span>
</div>
<div style={{ color: '#f8fafc', fontSize: '14px' }}>{msg.message}</div>
</div>
))}
</div>
<div style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
<input
type="text"
placeholder="Type a message..."
style={{
flex: 1,
padding: '8px 12px',
backgroundColor: '#0f172a',
border: '1px solid #334155',
borderRadius: '6px',
color: '#f8fafc',
fontSize: '14px'
}}
onKeyPress={(e) => {
if (e.key === 'Enter' && e.currentTarget.value.trim()) {
sendChatMessage(e.currentTarget.value.trim())
e.currentTarget.value = ''
}
}}
/>
<button
onClick={() => {
const input = document.querySelector('input[placeholder="Type a message..."]') as HTMLInputElement
if (input && input.value.trim()) {
sendChatMessage(input.value.trim())
input.value = ''
}
}}
style={{
padding: '8px 16px',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '6px',
fontSize: '14px',
cursor: 'pointer'
}}
>
Send
</button>
</div>
</div>
{/* Social Stats */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
{/* Launch Controls */}
<LaunchControls
appId="resonite"
appName="Resonite"
onStatusChange={(running) => {
// Update UI based on app status if needed
}}
/>
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
π₯ Social Network
</h4>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Friends</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.social.friends}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Contacts</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.social.contacts}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Groups</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.social.groups}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Messages</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.social.messages}</span>
</div>
</div>
</div>
<div style={{
backgroundColor: '#1e293b',
borderRadius: '12px',
border: '1px solid #334155',
padding: '20px'
}}>
<h4 style={{ fontSize: '16px', fontWeight: '600', color: '#f8fafc', marginBottom: '12px' }}>
π User Profile
</h4>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Username</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.user.username}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Rank</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.user.rank}</span>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: '#94a3b8', fontSize: '12px' }}>Reputation</span>
<span style={{ color: '#f8fafc', fontSize: '12px' }}>{resonite.user.reputation.toLocaleString()}</span>
</div>
</div>
</div>
</div>
</div>
)}
</div>
</div>
)
}