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%
1.9 KB · 61 lines tsx
Raw Blame History
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/components/wd/ScorePanel.tsx6 * Description: Dimension score bars — thin single-hue magnitude bars with per-dimension confidence, labels in ink.7 */8import { cn } from "@/lib/utils";910export type UiScore = {11  dimension: string;12  score: number;13  confidence: number;14  reasoning: string;15};1617const DIMENSION_LABELS: Record<string, string> = {18  demand: "Demand",19  neglectedness: "Neglectedness",20  feasibility: "Feasibility",21  why_now: "Why now",22  impact: "Impact",23  competition: "Competitive position",24  risk: "Risk manageability",25};2627export function ScorePanel({ scores }: { scores: UiScore[] }) {28  const ordered = [...scores].sort((a, b) => b.score - a.score);29  return (30    <div className="space-y-4">31      {ordered.map((s) => (32        <div key={s.dimension}>33          <div className="flex items-baseline justify-between gap-2">34            <span className="text-[13px] font-medium text-ink">35              {DIMENSION_LABELS[s.dimension] ?? s.dimension}36            </span>37            <span className="font-mono text-[12px] tabular-nums text-ink">38              {Math.round(s.score)}39              <span40                className={cn(41                  "ml-2 text-[10px] uppercase tracking-wider",42                  s.confidence >= 0.7 ? "text-verdict" : s.confidence >= 0.45 ? "text-signal" : "text-rust",43                )}44              >45                {Math.round(s.confidence * 100)}% conf46              </span>47            </span>48          </div>49          <div className="mt-1.5 h-2 w-full overflow-hidden rounded-[4px] bg-line/60">50            <div51              className="wd-bar h-full rounded-[4px] bg-verdict"52              style={{ width: `${Math.max(0, Math.min(100, s.score))}%` }}53            />54          </div>55          <p className="mt-1.5 text-xs leading-relaxed text-ink-soft">{s.reasoning}</p>56        </div>57      ))}58    </div>59  );60}61