165 lines
3.7 KiB
JavaScript
165 lines
3.7 KiB
JavaScript
import { useState, useEffect } from 'react'
|
|
import { useApp } from '../context/AppContext'
|
|
import Window from './Window'
|
|
import StartMenu from './StartMenu'
|
|
import {
|
|
Menu,
|
|
LayoutGrid,
|
|
ShoppingBag,
|
|
Clock,
|
|
BookOpen,
|
|
Wifi,
|
|
Shield,
|
|
Power
|
|
} from 'lucide-react'
|
|
|
|
const APPS = [
|
|
{
|
|
id: 'kanban',
|
|
title: 'Collective Kanban',
|
|
icon: LayoutGrid,
|
|
defaultWidth: 900,
|
|
defaultHeight: 600
|
|
},
|
|
{
|
|
id: 'clawhub',
|
|
title: 'ClawHub Marketplace',
|
|
icon: ShoppingBag,
|
|
defaultWidth: 1000,
|
|
defaultHeight: 700
|
|
},
|
|
{
|
|
id: 'session',
|
|
title: 'Session Tracker',
|
|
icon: Clock,
|
|
defaultWidth: 500,
|
|
defaultHeight: 400
|
|
},
|
|
{
|
|
id: 'wiki',
|
|
title: 'Agent Wiki',
|
|
icon: BookOpen,
|
|
defaultWidth: 800,
|
|
defaultHeight: 600
|
|
}
|
|
]
|
|
|
|
function Desktop() {
|
|
const {
|
|
windows,
|
|
activeWindow,
|
|
startMenuOpen,
|
|
setStartMenuOpen,
|
|
openWindow,
|
|
restoreWindow,
|
|
focusWindow,
|
|
sessionActive
|
|
} = useApp()
|
|
|
|
const [currentTime, setCurrentTime] = useState(new Date())
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => setCurrentTime(new Date()), 1000)
|
|
return () => clearInterval(timer)
|
|
}, [])
|
|
|
|
return (
|
|
<div className="desktop" onClick={() => setStartMenuOpen(false)}>
|
|
{/* Desktop Icons */}
|
|
<div className="desktop-icons" onClick={(e) => e.stopPropagation()}>
|
|
{APPS.map(app => (
|
|
<div
|
|
key={app.id}
|
|
className="desktop-icon"
|
|
onClick={() => openWindow(app)}
|
|
>
|
|
<app.icon />
|
|
<span>{app.title}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Windows */}
|
|
{windows.map(window => (
|
|
!window.minimized && (
|
|
<Window
|
|
key={window.id}
|
|
window={window}
|
|
isActive={activeWindow === window.id}
|
|
app={APPS.find(a => a.id === window.app)}
|
|
/>
|
|
)
|
|
))}
|
|
|
|
{/* Start Menu */}
|
|
{startMenuOpen && (
|
|
<StartMenu
|
|
apps={APPS}
|
|
onAppClick={openWindow}
|
|
/>
|
|
)}
|
|
|
|
{/* Taskbar */}
|
|
<div className="taskbar">
|
|
<button
|
|
className="start-btn"
|
|
onClick={(e) => {
|
|
e.stopPropagation()
|
|
setStartMenuOpen(!startMenuOpen)
|
|
}}
|
|
>
|
|
<Menu size={20} />
|
|
<span>Start</span>
|
|
</button>
|
|
|
|
<div className="taskbar-icons">
|
|
{windows.map(window => (
|
|
<div
|
|
key={window.id}
|
|
className={`taskbar-icon ${activeWindow === window.id ? 'active' : ''}`}
|
|
onClick={() => {
|
|
if (window.minimized || activeWindow !== window.id) {
|
|
restoreWindow(window.id)
|
|
} else {
|
|
focusWindow(window.id)
|
|
}
|
|
}}
|
|
title={window.title}
|
|
>
|
|
{(() => {
|
|
const Icon = APPS.find(a => a.id === window.app)?.icon
|
|
return Icon ? <Icon size={22} /> : null
|
|
})()}
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="system-tray">
|
|
{sessionActive && (
|
|
<div
|
|
className="tray-icon"
|
|
title="Session Active"
|
|
style={{ color: '#10b981' }}
|
|
>
|
|
<Shield size={18} />
|
|
</div>
|
|
)}
|
|
<div className="tray-icon" title="Network Connected">
|
|
<Wifi size={18} />
|
|
</div>
|
|
|
|
<div className="tray-icon" title="Power">
|
|
<Power size={18} />
|
|
</div>
|
|
|
|
<div className="clock">
|
|
{currentTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Desktop
|