39 lines
1.8 KiB
TypeScript
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>
|
|
);
|
|
}
|