import React from 'react'; import { ArrowRightIcon, CircleAlertIcon, CircleCheckIcon, LoaderCircleIcon, } from 'lucide-react'; import { Button } from '../../ui/button'; import { cn } from '../cn'; /** How a status card reads: still going, done, done with nothing, or failed. */ export type StatusTone = 'working' | 'done' | 'quiet' | 'failed'; /** The button on a status card. */ export interface StatusAction { label: string; onClick: () => void; /** Whether it is the filled button; the tone decides when this is unset. */ primary?: boolean; } /** The card's frame, by tone. */ const CARD_CLASS: Record = { working: 'border-brand/20 bg-brand/5', done: 'border-brand/20 bg-brand/5 duration-300 animate-in fade-in', quiet: 'border-border bg-muted duration-300 animate-in fade-in', failed: 'border-amber-500/40 bg-amber-500/5 duration-300 animate-in fade-in', }; /** Whether a tone's action is filled when the card does not say. */ const DEFAULT_PRIMARY: Record = { working: false, done: true, quiet: false, failed: true, }; /** * The mark at the left of a status card. * * @param props - Component props. * @param props.tone - How the card reads. * @return The icon. */ function StatusIcon({ tone }: { tone: StatusTone }): React.ReactElement { if (tone === 'working') { return ( ); } if (tone === 'failed') { return ; } return ( ); } /** * The card under a turn that started something long-running: a spinner and a * bar while it runs, a tick when it lands, a way to what it produced. Every * long job in the conversation wears this same object, so "working" looks the * same whether it is an article, a scan or a Company ID read. * * @param props - Component props. * @param props.tone - How the card reads. * @param props.title - The headline. * @param props.detail - The line under it. * @param props.action - The button, when there is somewhere to go. * @return The card. */ export function StatusCard({ tone, title, detail, action, }: { tone: StatusTone; title: string; detail: string; action?: StatusAction; }): React.ReactElement { return (
{/* A container query, not a breakpoint: the card is narrow when the panel is docked, whatever the window is doing. */}

{title}

{detail}

{action && ( )}
{tone === 'working' && (
)}
); }