"use client" import { forwardRef, type HTMLAttributes, type ReactNode } from "react" import { cn } from "../../utils/cn" import { formatTime } from "../../utils/format-date" export interface AiAssistantInfoProps extends HTMLAttributes { /** Rendered inside the standard 48px framed box (typically a 24px icon). */ icon?: ReactNode /** Replaces the framed icon box entirely (e.g. a round 48px avatar for the * `direct-chat` variant). Wins over `icon` when both are set. */ leading?: ReactNode title: string /** Secondary line under the title. Omitted → the row is title-only. */ body?: ReactNode /** Timestamp of the message row this block came in on. */ timestamp?: Date } /** * Figma `ai-assistant-info` — the shared in-thread status card: a framed * icon (or avatar), a title with a right-aligned time, and a secondary line. * One presentational shell for every lifecycle receipt in a chat thread * (handoff, technician joined, ticket resolved/reopened, …); the per-event * components (`TicketEscalatedMessage`, `TicketEventMessage`) own the copy * and icon choice and delegate the chrome here. * * The body WRAPS, deliberately diverging from the mock's single-line * ellipsis: the mock's 72px comes from its placeholder copy fitting one * line, while real wire text is a full sentence, and clipping the only * explanation of a lifecycle change is not recoverable on touch. The title * still truncates — it holds one line so the timestamp is never pushed out * of the row at narrow widths. */ const AiAssistantInfo = forwardRef( ({ className, icon, leading, title, body, timestamp, ...props }, ref) => { return (
{leading ?? (
{icon}
)}

{title}

{timestamp && ( {formatTime(timestamp)} )}
{body != null && body !== "" && (

{body}

)}
) }, ) AiAssistantInfo.displayName = "AiAssistantInfo" export { AiAssistantInfo }