SPB Git

spb/worthdoing Public

Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL

TypeScript 91.5% SQL 5.8% CSS 2.2%
2.9 KB · 101 lines tsx
Raw Blame History
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/components/wd/badges.tsx6 * Description: Status/phase badges — color always paired with a text label, never color alone.7 */8import { cn } from "@/lib/utils";910const HYPOTHESIS_STYLES: Record<string, string> = {11  proposed: "bg-secondary text-ink-soft",12  investigating: "bg-tele/10 text-tele",13  supported: "bg-verdict/10 text-verdict",14  validated: "bg-verdict/15 text-verdict",15  weakened: "bg-signal/12 text-signal",16  rejected: "bg-rust/10 text-rust",17};1819export function HypothesisBadge({ status }: { status: string }) {20  return (21    <span22      className={cn(23        "inline-flex items-center rounded-full px-2 py-0.5 font-mono text-[10px] uppercase tracking-wider",24        HYPOTHESIS_STYLES[status] ?? "bg-secondary text-ink-soft",25      )}26    >27      {status}28    </span>29  );30}3132const PHASE_LABELS: Record<string, string> = {33  scouting: "Scouting",34  investigating: "Investigating",35  skeptic: "Skeptic phase",36  synthesizing: "Synthesizing",37  done: "Done",38};3940const PHASE_STYLES: Record<string, string> = {41  scouting: "bg-tele/10 text-tele",42  investigating: "bg-verdict/10 text-verdict",43  skeptic: "bg-signal/12 text-signal",44  synthesizing: "bg-ink/8 text-ink",45  done: "bg-secondary text-ink-soft",46};4748export function PhaseBadge({ phase, live }: { phase: string; live?: boolean }) {49  return (50    <span51      className={cn(52        "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 font-mono text-[11px] uppercase tracking-wider",53        PHASE_STYLES[phase] ?? "bg-secondary text-ink-soft",54      )}55    >56      {live && <span className="wd-live-dot h-1.5 w-1.5 rounded-full bg-current" />}57      {PHASE_LABELS[phase] ?? phase}58    </span>59  );60}6162const STATUS_STYLES: Record<string, string> = {63  pending: "bg-secondary text-ink-soft",64  running: "bg-verdict/10 text-verdict",65  completed: "bg-ink/8 text-ink",66  failed: "bg-rust/10 text-rust",67  cancelled: "bg-secondary text-ink-soft",68};6970export function InvestigationStatusBadge({ status, live }: { status: string; live?: boolean }) {71  return (72    <span73      className={cn(74        "inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 font-mono text-[11px] uppercase tracking-wider",75        STATUS_STYLES[status] ?? "bg-secondary text-ink-soft",76      )}77    >78      {live && status === "running" && <span className="wd-live-dot h-1.5 w-1.5 rounded-full bg-current" />}79      {status}80    </span>81  );82}8384export function EvidenceKindBadge({ kind }: { kind: string }) {85  const styles: Record<string, string> = {86    support: "bg-verdict/10 text-verdict",87    contradict: "bg-rust/10 text-rust",88    context: "bg-secondary text-ink-soft",89  };90  return (91    <span92      className={cn(93        "inline-flex items-center rounded-full px-2 py-0.5 font-mono text-[10px] uppercase tracking-wider",94        styles[kind] ?? styles.context,95      )}96    >97      {kind}98    </span>99  );100}101