2026-03-18 15:17:40 +01:00
|
|
|
import styles from './LayoutSection.module.css'
|
|
|
|
|
import { Sidebar } from '../../../design-system/layout/Sidebar/Sidebar'
|
2026-04-02 18:10:09 +02:00
|
|
|
import { SidebarTree } from '../../../design-system/layout/Sidebar/SidebarTree'
|
|
|
|
|
import type { SidebarTreeNode } from '../../../design-system/layout/Sidebar/SidebarTree'
|
|
|
|
|
import { StatusDot } from '../../../design-system/primitives/StatusDot/StatusDot'
|
|
|
|
|
import { Box, Settings, FileText, ChevronRight } from 'lucide-react'
|
2026-03-18 15:17:40 +01:00
|
|
|
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>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 18:10:09 +02:00
|
|
|
// ── Sample tree nodes ────────────────────────────────────────────────────────
|
2026-03-18 15:17:40 +01:00
|
|
|
|
2026-04-02 18:10:09 +02:00
|
|
|
const SAMPLE_APP_NODES: SidebarTreeNode[] = [
|
2026-03-18 15:17:40 +01:00
|
|
|
{
|
2026-03-18 17:50:41 +01:00
|
|
|
id: 'app1',
|
2026-04-02 18:10:09 +02:00
|
|
|
label: 'cameleer-prod',
|
2026-04-02 18:13:03 +02:00
|
|
|
icon: <StatusDot variant="live" />,
|
2026-04-02 18:10:09 +02:00
|
|
|
badge: '14.3k',
|
|
|
|
|
path: '/apps/app1',
|
|
|
|
|
starrable: true,
|
|
|
|
|
starKey: 'app:app1',
|
|
|
|
|
children: [
|
|
|
|
|
{ id: 'app1/r1', label: 'order-ingest', icon: <ChevronRight size={12} />, badge: '5,421', path: '/apps/app1/r1' },
|
|
|
|
|
{ id: 'app1/r2', label: 'payment-validate', icon: <ChevronRight size={12} />, badge: '3,102', path: '/apps/app1/r2' },
|
2026-03-18 17:50:41 +01:00
|
|
|
],
|
2026-03-18 15:17:40 +01:00
|
|
|
},
|
|
|
|
|
{
|
2026-03-18 17:50:41 +01:00
|
|
|
id: 'app2',
|
2026-04-02 18:10:09 +02:00
|
|
|
label: 'cameleer-staging',
|
2026-04-02 18:13:03 +02:00
|
|
|
icon: <StatusDot variant="stale" />,
|
2026-04-02 18:10:09 +02:00
|
|
|
badge: '871',
|
|
|
|
|
path: '/apps/app2',
|
|
|
|
|
starrable: true,
|
|
|
|
|
starKey: 'app:app2',
|
|
|
|
|
children: [
|
|
|
|
|
{ id: 'app2/r3', label: 'notify-customer', icon: <ChevronRight size={12} />, badge: '2,201', path: '/apps/app2/r3' },
|
2026-03-18 17:50:41 +01:00
|
|
|
],
|
2026-03-18 15:17:40 +01:00
|
|
|
},
|
|
|
|
|
{
|
2026-03-18 17:50:41 +01:00
|
|
|
id: 'app3',
|
2026-04-02 18:10:09 +02:00
|
|
|
label: 'cameleer-dev',
|
2026-04-02 18:13:03 +02:00
|
|
|
icon: <StatusDot variant="dead" />,
|
2026-04-02 18:10:09 +02:00
|
|
|
badge: '42',
|
|
|
|
|
path: '/apps/app3',
|
|
|
|
|
starrable: true,
|
|
|
|
|
starKey: 'app:app3',
|
2026-03-18 15:17:40 +01:00
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
// ── 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}>
|
2026-03-19 16:33:34 +01:00
|
|
|
TopBar — breadcrumb · search · filters · time range · env badge · user avatar
|
2026-03-18 15:17:40 +01:00
|
|
|
</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>
|
2026-03-18 17:50:41 +01:00
|
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Applications tree</span>
|
|
|
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Agents tree</span>
|
|
|
|
|
<span style={{ fontWeight: 400, fontSize: 10 }}>Starred</span>
|
2026-03-18 15:17:40 +01:00
|
|
|
</div>
|
|
|
|
|
<div className={styles.shellDiagramMain}>
|
|
|
|
|
<children> — page content rendered here
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</DemoCard>
|
|
|
|
|
|
|
|
|
|
{/* 2. Sidebar */}
|
|
|
|
|
<DemoCard
|
|
|
|
|
id="sidebar"
|
|
|
|
|
title="Sidebar"
|
2026-04-02 18:10:09 +02:00
|
|
|
description="Composable navigation sidebar with sections, tree navigation, and icon-rail collapse mode."
|
2026-03-18 15:17:40 +01:00
|
|
|
>
|
|
|
|
|
<div className={styles.sidebarPreview}>
|
2026-04-02 18:10:09 +02:00
|
|
|
<Sidebar>
|
|
|
|
|
<Sidebar.Header logo={<span style={{ fontSize: 20 }}>🐪</span>} title="cameleer" version="v3.2.1" />
|
|
|
|
|
<Sidebar.Section label="Applications" icon={<Box size={14} />} open={true} onToggle={() => {}} active={false}>
|
|
|
|
|
<SidebarTree nodes={SAMPLE_APP_NODES} isStarred={() => false} onToggleStar={() => {}} />
|
|
|
|
|
</Sidebar.Section>
|
|
|
|
|
<Sidebar.Footer>
|
|
|
|
|
<Sidebar.FooterLink icon={<Settings size={14} />} label="Admin" />
|
|
|
|
|
<Sidebar.FooterLink icon={<FileText size={14} />} label="API Docs" />
|
|
|
|
|
</Sidebar.Footer>
|
|
|
|
|
</Sidebar>
|
2026-03-18 15:17:40 +01:00
|
|
|
</div>
|
|
|
|
|
</DemoCard>
|
|
|
|
|
|
|
|
|
|
{/* 3. TopBar */}
|
|
|
|
|
<DemoCard
|
|
|
|
|
id="topbar"
|
|
|
|
|
title="TopBar"
|
2026-03-19 16:33:34 +01:00
|
|
|
description="Top navigation bar with breadcrumb, search trigger, status filters, time range, environment badge, and user avatar."
|
2026-03-18 15:17:40 +01:00
|
|
|
>
|
|
|
|
|
<div className={styles.topbarPreview}>
|
|
|
|
|
<TopBar
|
|
|
|
|
breadcrumb={[
|
|
|
|
|
{ label: 'Dashboard', href: '#' },
|
|
|
|
|
{ label: 'Applications', href: '#' },
|
|
|
|
|
{ label: 'order-ingest' },
|
|
|
|
|
]}
|
|
|
|
|
environment="production"
|
2026-03-18 20:06:25 +01:00
|
|
|
|
2026-03-18 15:17:40 +01:00
|
|
|
user={{ name: 'Hendrik' }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</DemoCard>
|
|
|
|
|
</section>
|
|
|
|
|
)
|
|
|
|
|
}
|