gitdataai/src/components/room/FunctionCallBadge.tsx
2026-04-15 09:08:09 +08:00

57 lines
2.2 KiB
TypeScript

import type { FunctionCall } from '@/lib/functionCallParser';
import { formatDuration } from '@/lib/functionCallParser';
import { cn } from '@/lib/utils';
import { CheckCircle2, Clock, Loader2, ShieldAlert, ShieldCheck, ShieldX } from 'lucide-react';
interface FunctionCallBadgeProps {
functionCall: FunctionCall;
className?: string;
}
export function FunctionCallBadge({ functionCall, className }: FunctionCallBadgeProps) {
const { functionName, status, duration, authStatus } = functionCall;
return (
<div
className={cn(
'inline-flex items-center gap-1.5 rounded-md border px-1 py-0.5 text-xs font-medium',
status === 'running'
? 'border-blue-200 bg-blue-50 text-blue-700 dark:border-blue-800 dark:bg-blue-950/30 dark:text-blue-400'
: 'border-green-200 bg-green-50 text-green-700 dark:border-green-800 dark:bg-green-950/30 dark:text-green-400',
className,
)}
>
{status === 'running' ? (
<Loader2 className="h-3 w-3 animate-spin" />
) : (
<CheckCircle2 className="h-3 w-3" />
)}
<span className="font-mono">{functionName}</span>
{authStatus && (
<span
className={cn(
'inline-flex items-center gap-0.5 rounded px-1 py-0.5 text-[10px] font-semibold uppercase',
authStatus === 'pending' && 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-400',
authStatus === 'approved' && 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400',
authStatus === 'denied' && 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-400',
)}
>
{authStatus === 'pending' && <ShieldAlert className="h-2.5 w-2.5" />}
{authStatus === 'approved' && <ShieldCheck className="h-2.5 w-2.5" />}
{authStatus === 'denied' && <ShieldX className="h-2.5 w-2.5" />}
{authStatus}
</span>
)}
{status === 'completed' && duration !== undefined && (
<>
<span className="text-muted-foreground"></span>
<span className="flex items-center gap-0.5">
<Clock className="h-3 w-3" />
{formatDuration(duration)}
</span>
</>
)}
</div>
);
}