"use client"; import * as React from "react"; import { cn } from "../lib/utils"; import { Button } from "../components/button"; export function AppPage({ title, description, eyebrow, actions, children, width = "wide", className, }: { title: string; description?: React.ReactNode; eyebrow?: React.ReactNode; actions?: React.ReactNode; children: React.ReactNode; width?: "wide" | "reading"; className?: string; }) { return (
{eyebrow &&
{eyebrow}
}

{title}

{description &&

{description}

}
{actions &&
{actions}
}
{children}
); } export function PageToolbar({ children, label = "View controls", className, }: { children: React.ReactNode; label?: string; className?: string; }) { return (
{children}
); } export function EmptyState({ title, description, action, icon, }: { title: string; description?: React.ReactNode; action?: React.ReactNode; icon?: React.ReactNode; }) { return (
{icon && ( )}

{title}

{description &&

{description}

} {action &&
{action}
}
); } export function AppErrorState({ message, onRetry }: { message: string; onRetry?: () => void }) { return (

Something went wrong

{message}

{onRetry && ( )}
); } export function AppLoadingState({ label = "Loading", rows = 5, }: { label?: string; rows?: number; }) { return (
{Array.from({ length: Math.max(1, Math.min(rows, 12)) }, (_, i) => (
))} {label}
); } export function StatusBadge({ children, tone = "neutral", }: { children: React.ReactNode; tone?: "neutral" | "info" | "success" | "warning" | "danger"; }) { return ( ); } export function SplitView({ list, detail, label = "Details", }: { list: React.ReactNode; detail?: React.ReactNode; label?: string; }) { return (
{list}
{detail && ( )}
); } export function DetailPanel({ title, subtitle, onClose, children, actions, }: { title: string; subtitle?: React.ReactNode; onClose?: () => void; children: React.ReactNode; actions?: React.ReactNode; }) { return (
{subtitle &&
{subtitle}
}

{title}

{onClose && ( )}
{children}
{actions &&
{actions}
}
); } export interface RecordColumn { key: string; label: string; render: (record: T) => React.ReactNode; secondary?: boolean; align?: "start" | "end"; } export function RecordTable({ records, columns, rowKey, onOpen, label = "Records", empty, }: { records: readonly T[]; columns: readonly RecordColumn[]; rowKey: (record: T) => string; onOpen?: (record: T) => void; label?: string; empty?: React.ReactNode; }) { if (!records.length) return ( <>{empty ?? } ); return (
{columns.map((column) => ( ))} {records.map((record) => ( {columns.map((column, i) => ( ))} ))}
{column.label}
{i === 0 && onOpen ? ( ) : ( column.render(record) )}
); } export function Board({ children, label = "Board", }: { children: React.ReactNode; label?: string; }) { return (
{children}
); } export function BoardColumn({ title, count, children, action, }: { title: string; count?: number; children: React.ReactNode; action?: React.ReactNode; }) { return (

{title}

{count !== undefined && {count}} {action}
{children}
); } export function BoardCard({ title, children, footer, onOpen, }: { title: string; children?: React.ReactNode; footer?: React.ReactNode; onOpen?: () => void; }) { return (

{onOpen ? ( ) : ( title )}

{children &&
{children}
} {footer &&
{footer}
}
); } export function SettingsSection({ title, description, children, }: { title: string; description?: string; children: React.ReactNode; }) { const id = React.useId(); return (

{title}

{description &&

{description}

}
{children}
); }