141 lines
4.7 KiB
TypeScript
141 lines
4.7 KiB
TypeScript
|
|
import styles from './LayoutSection.module.css'
|
||
|
|
import { Sidebar } from '../../../design-system/layout/Sidebar/Sidebar'
|
||
|
|
import { TopBar } from '../../../design-system/layout/TopBar/TopBar'
|
||
|
|
|
||
|
|
// ── DemoCard helper ──────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
interface DemoCardProps {
|
||
|
|
id: string
|
||
|
|
title: string
|
||
|
|
description: string
|
||
|
|
children: React.ReactNode
|
||
|
|
}
|
||
|
|
|
||
|
|
function DemoCard({ id, title, description, children }: DemoCardProps) {
|
||
|
|
return (
|
||
|
|
<div id={id} className={styles.componentCard}>
|
||
|
|
<h3 className={styles.componentTitle}>{title}</h3>
|
||
|
|
<p className={styles.componentDesc}>{description}</p>
|
||
|
|
<div className={styles.demoArea}>{children}</div>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ── Sample data ───────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
const SAMPLE_APPS = [
|
||
|
|
{ id: 'app1', name: 'cameleer-prod', agentCount: 3, health: 'live' as const, execCount: 14320 },
|
||
|
|
{ id: 'app2', name: 'cameleer-staging', agentCount: 2, health: 'stale' as const, execCount: 871 },
|
||
|
|
{ id: 'app3', name: 'cameleer-dev', agentCount: 1, health: 'dead' as const, execCount: 42 },
|
||
|
|
]
|
||
|
|
|
||
|
|
const SAMPLE_ROUTES = [
|
||
|
|
{ id: 'r1', name: 'order-ingest', execCount: 5421 },
|
||
|
|
{ id: 'r2', name: 'payment-validate', execCount: 3102 },
|
||
|
|
{ id: 'r3', name: 'notify-customer', execCount: 2201 },
|
||
|
|
]
|
||
|
|
|
||
|
|
const SAMPLE_AGENTS = [
|
||
|
|
{
|
||
|
|
id: 'ag1',
|
||
|
|
name: 'agent-prod-1',
|
||
|
|
service: 'camel-core',
|
||
|
|
version: 'v3.2.1',
|
||
|
|
tps: '42 tps',
|
||
|
|
lastSeen: '1m ago',
|
||
|
|
status: 'live' as const,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'ag2',
|
||
|
|
name: 'agent-prod-2',
|
||
|
|
service: 'camel-core',
|
||
|
|
version: 'v3.2.1',
|
||
|
|
tps: '38 tps',
|
||
|
|
lastSeen: '2m ago',
|
||
|
|
status: 'live' as const,
|
||
|
|
errorRate: '0.4%',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'ag3',
|
||
|
|
name: 'agent-staging-1',
|
||
|
|
service: 'camel-core',
|
||
|
|
version: 'v3.1.9',
|
||
|
|
tps: '5 tps',
|
||
|
|
lastSeen: '8m ago',
|
||
|
|
status: 'stale' as const,
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
// ── LayoutSection ─────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
export function LayoutSection() {
|
||
|
|
return (
|
||
|
|
<section id="layout" className={styles.section}>
|
||
|
|
<h2 className={styles.sectionTitle}>Layout</h2>
|
||
|
|
|
||
|
|
{/* 1. AppShell */}
|
||
|
|
<DemoCard
|
||
|
|
id="appshell"
|
||
|
|
title="AppShell"
|
||
|
|
description="Full-page shell that composes Sidebar + TopBar + main content area. Cannot be nested — shown as a structural diagram."
|
||
|
|
>
|
||
|
|
<div className={styles.shellDiagram}>
|
||
|
|
<div className={styles.shellDiagramTop}>
|
||
|
|
TopBar — breadcrumb · search · env badge · shift · user avatar
|
||
|
|
</div>
|
||
|
|
<div className={styles.shellDiagramBody}>
|
||
|
|
<div className={styles.shellDiagramSide}>
|
||
|
|
<span>Sidebar</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10, marginTop: 4 }}>Logo</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Search</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Navigation</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Applications</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Routes</span>
|
||
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Agents</span>
|
||
|
|
</div>
|
||
|
|
<div className={styles.shellDiagramMain}>
|
||
|
|
<children> — page content rendered here
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</DemoCard>
|
||
|
|
|
||
|
|
{/* 2. Sidebar */}
|
||
|
|
<DemoCard
|
||
|
|
id="sidebar"
|
||
|
|
title="Sidebar"
|
||
|
|
description="Navigation sidebar with app/route/agent sections, search filter, health dots, and exec counts."
|
||
|
|
>
|
||
|
|
<div className={styles.sidebarPreview}>
|
||
|
|
<Sidebar
|
||
|
|
apps={SAMPLE_APPS}
|
||
|
|
routes={SAMPLE_ROUTES}
|
||
|
|
agents={SAMPLE_AGENTS}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</DemoCard>
|
||
|
|
|
||
|
|
{/* 3. TopBar */}
|
||
|
|
<DemoCard
|
||
|
|
id="topbar"
|
||
|
|
title="TopBar"
|
||
|
|
description="Top navigation bar with breadcrumb, search trigger, environment badge, shift info, and user avatar."
|
||
|
|
>
|
||
|
|
<div className={styles.topbarPreview}>
|
||
|
|
<TopBar
|
||
|
|
breadcrumb={[
|
||
|
|
{ label: 'Dashboard', href: '#' },
|
||
|
|
{ label: 'Applications', href: '#' },
|
||
|
|
{ label: 'order-ingest' },
|
||
|
|
]}
|
||
|
|
environment="production"
|
||
|
|
shift="Morning"
|
||
|
|
user={{ name: 'Hendrik' }}
|
||
|
|
onSearchClick={() => undefined}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</DemoCard>
|
||
|
|
</section>
|
||
|
|
)
|
||
|
|
}
|