feat(web): Next.js 15 shell — design tokens, landing, auth pages
This commit is contained in:
38
apps/web/components/status-pill.tsx
Normal file
38
apps/web/components/status-pill.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user