wip:milestone 0 fixes
Some checks failed
CI/CD Pipeline / unit-tests (push) Failing after 1m16s
CI/CD Pipeline / integration-tests (push) Failing after 2m32s
CI/CD Pipeline / lint (push) Successful in 5m22s
CI/CD Pipeline / e2e-tests (push) Has been skipped
CI/CD Pipeline / build (push) Has been skipped

This commit is contained in:
2026-03-15 12:35:42 +02:00
parent 6708cf28a7
commit cffdf8af86
61266 changed files with 4511646 additions and 1938 deletions

View File

@@ -0,0 +1,152 @@
import React, { useState } from 'react'
import {
AppBar,
Box,
Toolbar,
Typography,
Drawer,
List,
ListItem,
ListItemIcon,
ListItemText,
ListItemButton,
IconButton,
Divider,
Chip,
} from '@mui/material'
import {
Menu as MenuIcon,
Dashboard as DashboardIcon,
Dns as ServerIcon,
Description as TemplateIcon,
Cloud as ProviderIcon,
TrendingUp as ScalingIcon,
Favorite as HealthIcon,
Settings as SettingsIcon,
} from '@mui/icons-material'
import { useNavigate, useLocation } from 'react-router-dom'
const drawerWidth = 240
const menuItems = [
{ text: 'Dashboard', icon: <DashboardIcon />, path: '/' },
{ text: 'Servers', icon: <ServerIcon />, path: '/servers' },
{ text: 'Templates', icon: <TemplateIcon />, path: '/templates' },
{ text: 'Providers', icon: <ProviderIcon />, path: '/providers' },
{ text: 'Scaling', icon: <ScalingIcon />, path: '/scaling' },
{ text: 'Cluster Health', icon: <HealthIcon />, path: '/cluster' },
{ text: 'Settings', icon: <SettingsIcon />, path: '/settings' },
]
interface LayoutProps {
children: React.ReactNode
}
export default function Layout({ children }: LayoutProps) {
const [mobileOpen, setMobileOpen] = useState(false)
const navigate = useNavigate()
const location = useLocation()
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen)
}
const drawer = (
<div>
<Toolbar>
<Typography variant="h6" noWrap component="div" sx={{ fontWeight: 'bold' }}>
MadBase
</Typography>
<Chip label="Control Plane" size="small" sx={{ ml: 1 }} />
</Toolbar>
<Divider />
<List>
{menuItems.map((item) => (
<ListItem key={item.text} disablePadding>
<ListItemButton
selected={location.pathname === item.path}
onClick={() => navigate(item.path)}
>
<ListItemIcon>{item.icon}</ListItemIcon>
<ListItemText primary={item.text} />
</ListItemButton>
</ListItem>
))}
</List>
<Divider />
<Box sx={{ p: 2 }}>
<Typography variant="caption" color="text.secondary">
v0.1.0
</Typography>
</Box>
</div>
)
return (
<Box sx={{ display: 'flex' }}>
<AppBar
position="fixed"
sx={{
width: { sm: `calc(100% - ${drawerWidth}px)` },
ml: { sm: `${drawerWidth}px` },
}}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { sm: 'none' } }}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap component="div" sx={{ flexGrow: 1 }}>
{menuItems.find((item) => item.path === location.pathname)?.text || 'MadBase Control Plane'}
</Typography>
<Chip label="API Online" color="success" size="small" variant="outlined" />
</Toolbar>
</AppBar>
<Box
component="nav"
sx={{ width: { sm: drawerWidth }, flexShrink: { sm: 0 } }}
>
<Drawer
variant="temporary"
open={mobileOpen}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true,
}}
sx={{
display: { xs: 'block', sm: 'none' },
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
>
{drawer}
</Drawer>
<Drawer
variant="permanent"
sx={{
display: { xs: 'none', sm: 'block' },
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
open
>
{drawer}
</Drawer>
</Box>
<Box
component="main"
sx={{
flexGrow: 1,
p: 3,
width: { sm: `calc(100% - ${drawerWidth}px)` },
}}
>
<Toolbar />
{children}
</Box>
</Box>
)
}