buildmymcpserver/apps/web/components/status-pill.tsx

39 lines
1.8 KiB
TypeScript

import type { ServerStatus, BuildStatus } from '@bmm/types';
import { cn } from '@/lib/cn';
type AnyStatus = ServerStatus | BuildStatus;
const map: Record<string, { label: string; dot: string; fg: string; bg: string; pulse?: boolean }> = {
draft: { label: 'Draft', dot: 'bg-zinc-500', fg: 'text-zinc-400', bg: 'bg-zinc-500/10' },
queued: { label: 'Queued', dot: 'bg-zinc-400', fg: 'text-zinc-300', bg: 'bg-zinc-400/10' },
generating: { label: 'Generating', dot: 'bg-amber-400', fg: 'text-amber-300', bg: 'bg-amber-400/10', pulse: true },
building: { label: 'Building', dot: 'bg-amber-400', fg: 'text-amber-300', bg: 'bg-amber-400/10', pulse: true },
deploying: { label: 'Deploying', dot: 'bg-indigo-400', fg: 'text-indigo-300', bg: 'bg-indigo-400/10', pulse: true },
live: { label: 'Live', dot: 'bg-emerald-400', fg: 'text-emerald-300', bg: 'bg-emerald-400/10', pulse: true },
success: { label: 'Success', dot: 'bg-emerald-400', fg: 'text-emerald-300', bg: 'bg-emerald-400/10' },
failed: { label: 'Failed', dot: 'bg-red-400', fg: 'text-red-300', bg: 'bg-red-400/10' },
cancelled: { label: 'Cancelled', dot: 'bg-zinc-500', fg: 'text-zinc-400', bg: 'bg-zinc-500/10' },
paused: { label: 'Paused', dot: 'bg-zinc-500', fg: 'text-zinc-400', bg: 'bg-zinc-500/10' },
};
export function StatusPill({ status, className }: { status: AnyStatus; className?: string }) {
const s = map[status] ?? map.draft;
if (!s) return null;
return (
<span
className={cn(
'inline-flex items-center gap-1.5 rounded-full border border-[--color-border] px-2 py-0.5 text-[11px] font-medium tracking-tight',
s.bg,
s.fg,
className,
)}
>
<span
className={cn('size-1.5 rounded-full', s.dot)}
style={s.pulse ? { animation: 'pulse-dot 1.6s ease-in-out infinite' } : undefined}
/>
{s.label}
</span>
);
}