import * as React from "react"; import { Check, ChevronDown, ChevronUp, ExternalLink, MapPin, MousePointerClick, } from "lucide-react"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; /** * Support Agent Primitives — WealthX DS * * Atomic building blocks for the Support Agent panel. * Inspired by Jira Rovo's sidebar chat pattern: * - SupportContextChip — shows current backoffice page + entity (Rovo: page context header) * - SupportSuggestedQuestion — clickable question cards (Rovo: conversation starters) * - SupportStepGuideCard — numbered walkthrough with "Show me" DOM highlight (Rovo: message cards) * - SupportArticleCard — help article reference link (Rovo: linked content cards) * * All components are pure display — no state or API calls. * State and event handling are managed by SupportAgentPanel (the parent organism). */ // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- /** Context injected from the current backoffice route. */ export interface SupportAgentContext { /** Page label from the current route, e.g. "Loan Applications". */ pageLabel: string; /** Entity currently being viewed, e.g. "John Smith". Optional. */ entityLabel?: string; /** Entity type for semantic use, e.g. "client" | "application" | "contact". */ entityType?: string; } /** A single step inside a SupportStepGuideCard. */ export interface SupportAgentStep { id: string; /** Human-readable step instruction. */ label: string; /** * If set, the "Show me" button fires onHighlight(elementId). * The consuming page listens for this and highlights the DOM element * that has data-support-id matching this value. */ elementId?: string; /** Whether the user has marked this step as done. */ completed?: boolean; } /** Rich content embedded inside an assistant message bubble. */ export type SupportAgentRichContent = | { type: "step-guide"; title: string; steps: SupportAgentStep[]; } | { type: "article"; title: string; excerpt: string; href: string; /** If true, opens in a new tab and shows an external link icon. */ isExternal?: boolean; }; // --------------------------------------------------------------------------- // SupportContextChip // --------------------------------------------------------------------------- export interface SupportContextChipProps { context?: SupportAgentContext; /** Show a skeleton loading placeholder. */ isLoading?: boolean; className?: string; } /** * Pill that shows the current backoffice page and optional entity. * Appears below the panel header to ground the AI conversation in context. * * Variants: * - page-only → "📍 Loan Applications" * - page+entity → "📍 Loan Applications › John Smith" * - loading → skeleton placeholder */ export function SupportContextChip({ context, isLoading = false, className, }: SupportContextChipProps) { if (isLoading) { return ( ); } if (!context) return null; return (
); } // --------------------------------------------------------------------------- // SupportSuggestedQuestion // --------------------------------------------------------------------------- export interface SupportSuggestedQuestionProps { question: string; onSelect: (question: string) => void; className?: string; } /** * Single clickable question card — the Jira Rovo "conversation starter" pattern. * Clicking pre-fills the chat input with the question text. */ export function SupportSuggestedQuestion({ question, onSelect, className, }: SupportSuggestedQuestionProps) { return ( ); } // --------------------------------------------------------------------------- // SupportStepGuideCard // --------------------------------------------------------------------------- export interface SupportStepGuideCardProps { title: string; steps: SupportAgentStep[]; /** Called when the user clicks "Show me" on a step that has an elementId. */ onHighlight?: (elementId: string) => void; /** Called when the user marks a step as complete. */ onStepComplete?: (stepId: string) => void; /** Default collapsed if more than 5 steps; otherwise expanded. */ defaultExpanded?: boolean; className?: string; } /** * A numbered walkthrough card embedded inside an AI assistant message bubble. * Inspired by Jira Rovo message cards — bordered container with structured content. * * - Completed steps show a checkmark icon instead of a number. * - Steps with an `elementId` show a "→ Show me" button that fires onHighlight. * - Collapsible when more than 5 steps (default collapsed). */ export function SupportStepGuideCard({ title, steps, onHighlight, onStepComplete, defaultExpanded, className, }: SupportStepGuideCardProps) { const isLong = steps.length > 5; const [expanded, setExpanded] = React.useState(defaultExpanded ?? !isLong); const completedCount = steps.filter((s) => s.completed).length; const allDone = completedCount === steps.length; return (
{/* Card header */} {/* Steps list */} {expanded && (
    {steps.map((step, index) => (
  1. {/* Step number or checkmark */} {/* Step label + show me button */}
    {step.label} {step.elementId && onHighlight && !step.completed && ( )}
  2. ))}
)}
); } // --------------------------------------------------------------------------- // SupportArticleCard // --------------------------------------------------------------------------- export interface SupportArticleCardProps { title: string; excerpt: string; href: string; /** If true, opens in a new tab with an external link icon. */ isExternal?: boolean; className?: string; } /** * A compact help article reference card embedded inside an AI message bubble. * Inspired by Jira Rovo's linked content cards. * * - Internal links: navigates in the same tab (relative URL). * - External links: opens new tab + shows ExternalLink icon. */ export function SupportArticleCard({ title, excerpt, href, isExternal = false, className, }: SupportArticleCardProps) { return (
{title} {isExternal && (

{excerpt}

{isExternal ? "Open article →" : "Read more →"}
); }