inspector/clients/web/src/components/layouts/ConnectedLayout/ConnectedLayout.tsx
cliffhall d53c3d338f feat: Add HomeLayout and ConnectedLayout components with Storybook stories
- HomeLayout: AppShell with header (title + theme toggle) for disconnected state
- ConnectedLayout: AppShell with server name, status indicator, tab navigation,
  theme toggle, and disconnect button for connected state

All 6 phases of the Storybook component plan are now complete:
12 atoms, 25 molecules, 7 organisms, 2 layouts = 46 components total

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:47:52 -04:00

83 lines
2.2 KiB
TypeScript

import type { ReactNode } from 'react';
import { ActionIcon, AppShell, Button, Group, Tabs, Text } from '@mantine/core';
import { useComputedColorScheme } from '@mantine/core';
import { StatusIndicator } from '../../atoms/StatusIndicator/StatusIndicator';
export interface ConnectedLayoutProps {
serverName: string;
status: 'connected' | 'connecting' | 'failed';
latencyMs?: number;
activeTab: string;
availableTabs: string[];
onTabChange: (tab: string) => void;
onDisconnect: () => void;
onToggleTheme: () => void;
children: ReactNode;
}
const ServerName = Text.withProps({
fw: 600,
size: 'lg',
});
export function ConnectedLayout({
serverName,
status,
latencyMs,
activeTab,
availableTabs,
onTabChange,
onDisconnect,
onToggleTheme,
children,
}: ConnectedLayoutProps) {
const colorScheme = useComputedColorScheme();
return (
<AppShell header={{ height: 60 }} padding="md">
<AppShell.Header>
<Group h="100%" px="md" justify="space-between" wrap="nowrap">
<Group gap="md" wrap="nowrap">
<ServerName>{serverName}</ServerName>
<StatusIndicator status={status} latencyMs={latencyMs} />
</Group>
<Tabs
value={activeTab}
onChange={(value) => value && onTabChange(value)}
variant="default"
>
<Tabs.List>
{availableTabs.map((tab) => (
<Tabs.Tab key={tab} value={tab}>
{tab}
</Tabs.Tab>
))}
</Tabs.List>
</Tabs>
<Group gap="sm">
<ActionIcon
variant="default"
size="lg"
aria-label="Toggle color scheme"
onClick={onToggleTheme}
>
{colorScheme === 'dark' ? '\u2600' : '\u263E'}
</ActionIcon>
<Button
variant="outline"
color="red"
size="sm"
onClick={onDisconnect}
>
Disconnect
</Button>
</Group>
</Group>
</AppShell.Header>
<AppShell.Main>{children}</AppShell.Main>
</AppShell>
);
}