import type { ReactNode } from "react"; import { AlertCircle, Check, Loader2 } from "lucide-react"; import { Card, CardContent } from "@multica/ui/components/ui/card"; import { cn } from "@multica/ui/lib/utils"; export type SettingsSaveStatus = "idle" | "saving" | "saved" | "error"; export function SettingsTab({ title, description, children, }: { title: ReactNode; description?: ReactNode; children: ReactNode; }) { return (

{title}

{description ? (

{description}

) : null}
{children}
); } export function SettingsSection({ title, description, action, children, className, }: { title?: ReactNode; description?: ReactNode; action?: ReactNode; children: ReactNode; className?: string; }) { return (
{title || description || action ? (
{title ?

{title}

: null} {description ? (

{description}

) : null}
{action ?
{action}
: null}
) : null} {children}
); } export function SettingsCard({ children, className, }: { children: ReactNode; className?: string; }) { return ( {children} ); } /** * Width tiers for the control column. Within a card, every text-entry * control shares the `text` tier so their edges align; a row may only * drop to a smaller tier when the field is deliberately short (a code, * an enum select) — the difference must read as intentional. Pick a * tier instead of adding per-row ad-hoc widths. */ const SETTINGS_CONTROL_WIDTHS = { /** Text inputs and textareas — the standard control column. */ text: "sm:w-96", /** Selects/pickers with long option labels (timezone, model). */ "select-wide": "sm:w-72", /** Compact enum selects (theme, language). */ select: "sm:w-48", /** Short fixed-format codes (issue prefix). */ code: "sm:w-40", /** Unconstrained — non-input content like avatar uploads. */ none: "sm:max-w-none", } as const; export type SettingsControlSize = keyof typeof SETTINGS_CONTROL_WIDTHS; export function SettingsRow({ label, description, children, className, size, align = "center", }: { label: ReactNode; description?: ReactNode; children: ReactNode; className?: string; /** Control column width tier; omit for content-hugging controls (buttons, switches). */ size?: SettingsControlSize; align?: "center" | "start"; }) { return (
{label}
{description ? (
{description}
) : null}
{children}
); } export function SettingsSaveState({ status, savingLabel, savedLabel, errorLabel, }: { status: SettingsSaveStatus; savingLabel: string; savedLabel: string; errorLabel: string; }) { if (status === "idle") return null; const content = status === "saving" ? ( <> {savingLabel} ) : status === "saved" ? ( <> {savedLabel} ) : ( <> {errorLabel} ); return ( {content} ); }