Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / frontend/src/tools/missionmatch/Candidates.tsx |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | frontend/src/tools/missionmatch/Candidates.tsx |
| Original SHA-256 | ede529973674beb663d8b2c9696721064b5f15d6079cbb6227bad2b936c9d6d5 |
| Git blob SHA | 1a5c92422a7bd55f5abdcb4a02a5659666bc081c |
| Reading-copy SHA-256 | ede529973674beb663d8b2c9696721064b5f15d6079cbb6227bad2b936c9d6d5 |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / frontend/src/tools/missionmatch/Candidates.tsx | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / frontend/src/tools/missionmatch/Candidates.tsx | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓365 lines · 15.4 KB
import { type ReactNode, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { ChevronRight, LayoutGrid, Rows3, ScanSearch, ShieldQuestion, Target, Trash2, TrendingUp, Trophy } from 'lucide-react'
import { useDeleteExternalCandidate } from '../../lib/queries'
import { useMissionIntelligence } from './queries'
import { missionBrand } from './brand'
import type { CandidateIntelligence, IntelClearance } from '../../lib/types'
import { Badge, Panel } from '../../components/ui'
import { MissionCheckModal } from '../../components/MissionCheckModal'
import { ToolHeader } from '../../components/ToolHeader'
import { bandColor, num, proposalColor, winImpactColor } from '../../lib/format'
type View = 'intelligence' | 'list'
const VIEW_KEY = 'screenmatch.candidatesView'
export function Candidates() {
const { data, isLoading, isError, error, refetch } = useMissionIntelligence()
const [view, setView] = useState<View>(() => (localStorage.getItem(VIEW_KEY) as View) || 'intelligence')
const [missionCheck, setMissionCheck] = useState(false)
useEffect(() => {
localStorage.setItem(VIEW_KEY, view)
}, [view])
const rows = data ?? []
const greens = rows.filter((c) => c.mission_readiness.band === 'green').length
const highImpact = rows.filter((c) => c.win_impact.level === 'HIGH').length
return (
<div className="space-y-4">
<ToolHeader name={missionBrand.name} tagline="Candidates Intelligence View" accent={missionBrand.accent} />
<Panel className="flex flex-wrap items-center justify-between gap-3 p-4">
<div>
<div className="flex items-center gap-2">
<span className="text-sm font-bold">Cleared Workforce Intelligence</span>
<Badge color="var(--color-gold)" subtle>Demo data</Badge>
</div>
<div className="mt-0.5 text-xs text-faint">
{isLoading
? 'Scoring the workforce against open requirements…'
: `${rows.length} synthetic candidates, ${greens} proposal ready, ${highImpact} fill an open gap. Shaped for Galapagos cleared IT and cyber.`}
</div>
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setMissionCheck(true)}
className="flex items-center gap-1.5 rounded-lg border border-gold/50 px-3 py-1.5 text-xs font-semibold text-gold hover:bg-gold/10"
>
<ScanSearch size={14} /> Mission Check
</button>
<div className="flex items-center gap-1 rounded-lg border border-line/70 bg-navy-900 p-1">
<ToggleButton active={view === 'intelligence'} onClick={() => setView('intelligence')} icon={<LayoutGrid size={14} />} label="Intelligence View" />
<ToggleButton active={view === 'list'} onClick={() => setView('list')} icon={<Rows3 size={14} />} label="List View" />
</div>
</div>
</Panel>
<MissionCheckModal open={missionCheck} onClose={() => setMissionCheck(false)} />
{isLoading ? (
<Panel className="py-10 text-center text-muted">Computing Mission Readiness, Win Impact, and Best Fit…</Panel>
) : isError ? (
// A FAILED load is not an empty bench. This previously fell through to "No candidates yet", which
// tells a recruiter their entire pool is gone when the API is simply down.
<Panel className="grid place-items-center gap-3 py-10 text-center">
<p className="text-sm font-semibold text-warn">Could not load candidates.</p>
<p className="max-w-md text-xs text-faint">{(error as Error)?.message}</p>
<button
onClick={() => void refetch()}
className="rounded-lg border border-line/70 px-3 py-1.5 text-xs font-semibold text-muted hover:text-ink"
>
Try again
</button>
</Panel>
) : rows.length === 0 ? (
<Panel className="py-10 text-center text-muted">No candidates yet.</Panel>
) : view === 'intelligence' ? (
<IntelligenceView rows={rows} />
) : (
<ListView rows={rows} />
)}
<p className="px-1 text-[11px] leading-relaxed text-faint">
Mission Readiness, Proposal Ready, Win Impact, and Best Fit are computed live from the shared scoring engine and the
Command Center coverage, so a candidate shows the same Mission Readiness here, on the dashboard, in Top Matches, and in
the evaluation view. Every candidate shown is synthetic Demo data, a generated profile for demonstration, not a real
person. The sourced External leads additionally carry an Unknown clearance. Clearance is a self reported clearance
intelligence indicator, never verified. The real check is the hiring client FSO through DISS at onboarding. When
Galapagos loads their own bench the staffing picture becomes real.
</p>
</div>
)
}
function ToggleButton({ active, onClick, icon, label }: { active: boolean; onClick: () => void; icon: ReactNode; label: string }) {
return (
<button
onClick={onClick}
className={`flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-semibold transition ${
active ? 'bg-blue/25 text-blue-soft' : 'text-faint hover:text-muted'
}`}
>
{icon}
{label}
</button>
)
}
// ---------------- List View ----------------
function ListView({ rows }: { rows: CandidateIntelligence[] }) {
const nav = useNavigate()
const del = useDeleteExternalCandidate()
return (
<Panel title="Candidates" hint={`${rows.length} ranked by Mission Readiness`}>
<div className="overflow-x-auto">
<table className="w-full min-w-[60rem] text-sm">
<thead>
<tr className="text-left text-[11px] uppercase tracking-wider text-faint">
<th className="pb-2 font-semibold">Candidate</th>
<th className="pb-2 font-semibold">Clearance Intelligence</th>
<th className="pb-2 font-semibold">Mission Ready</th>
<th className="pb-2 font-semibold">Proposal Ready</th>
<th className="pb-2 font-semibold">Win Impact</th>
<th className="pb-2 font-semibold">Best Fit</th>
<th className="pb-2" />
</tr>
</thead>
<tbody className="divide-y divide-line/50">
{rows.map((c) => (
<tr key={c.id} className="align-top hover:bg-navy-800/40">
<td className="py-3 pr-3">
<div className="font-semibold">{c.full_name}</div>
<div className="mt-0.5 flex items-center gap-1.5 text-[11px] text-faint">
{c.years_experience} yrs{c.location ? ` · ${c.location}` : ''}
{c.source === 'external' && (
<Badge color="var(--color-warn)" subtle>
External · Demo
</Badge>
)}
</div>
</td>
<td className="py-3 pr-3">
<ClearanceCell c={c.clearance} />
</td>
<td className="py-3 pr-3">
<span className="text-base font-bold tabular-nums" style={{ color: bandColor(c.mission_readiness.band) }}>
{num(c.mission_readiness.score).toFixed(0)}%
</span>
<div className="text-[11px] text-faint">{c.mission_readiness.status}</div>
</td>
<td className="py-3 pr-3">
<span title={c.proposal_ready.reason}>
<Badge color={proposalColor(c.proposal_ready.value)} subtle>
{c.proposal_ready.value}
</Badge>
</span>
<div className="mt-0.5 max-w-[12rem] truncate text-[11px] text-faint" title={c.proposal_ready.reason}>
{c.proposal_ready.reason}
</div>
</td>
<td className="py-3 pr-3">
<span title={c.win_impact.basis}>
<Badge color={winImpactColor(c.win_impact.level)} subtle>
{c.win_impact.level}
</Badge>
</span>
</td>
<td className="py-3 pr-3">
<div className="font-semibold">{c.best_fit.name}</div>
<div className="text-[11px] text-faint">
{c.best_fit.customer_agency ? `${c.best_fit.customer_agency} · ` : ''}
{num(c.best_fit.score).toFixed(0)}% fit
</div>
</td>
<td className="py-3 text-right">
<div className="inline-flex items-center gap-1.5">
{c.source === 'external' && (
<button
onClick={() => del.mutate(c.id)}
disabled={del.isPending}
title="Delete this sourced record"
className="grid size-7 place-items-center rounded-md border border-line/70 text-muted hover:border-risk/60 hover:text-risk disabled:opacity-50"
>
<Trash2 size={13} />
</button>
)}
<button
onClick={() => nav(`/screen/evaluate/${c.id}/${c.best_fit.requirement_id}`)}
className="inline-flex items-center gap-1 rounded-md border border-line/70 px-2.5 py-1 text-xs font-semibold text-muted hover:border-blue/60 hover:text-blue-soft"
>
Review <ChevronRight size={13} />
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</Panel>
)
}
// ---------------- Intelligence View ----------------
function IntelligenceView({ rows }: { rows: CandidateIntelligence[] }) {
return (
<div className="grid gap-3 lg:grid-cols-2 xl:grid-cols-3">
{rows.map((c) => (
<IntelCard key={c.id} c={c} />
))}
</div>
)
}
function IntelCard({ c }: { c: CandidateIntelligence }) {
const nav = useNavigate()
const del = useDeleteExternalCandidate()
const r = c.mission_readiness
return (
<Panel className="flex flex-col gap-3 p-4">
<div className="flex items-start justify-between gap-2">
<div className="min-w-0">
<div className="truncate font-bold">{c.full_name}</div>
<div className="mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-faint">
{c.years_experience} yrs{c.location ? ` · ${c.location}` : ''}
{c.source === 'external' && (
<Badge color="var(--color-warn)" subtle>
External · Demo
</Badge>
)}
</div>
</div>
<Ring value={num(r.score)} color={bandColor(r.band)} />
</div>
<div className="flex flex-wrap items-center gap-2">
<span title={c.proposal_ready.reason}>
<Badge color={proposalColor(c.proposal_ready.value)} subtle>
<Trophy size={11} /> Proposal {c.proposal_ready.value}
</Badge>
</span>
<span title={c.win_impact.basis}>
<Badge color={winImpactColor(c.win_impact.level)} subtle>
<TrendingUp size={11} /> Win {c.win_impact.level}
</Badge>
</span>
<span className="text-[11px] text-faint">{r.status}</span>
</div>
<ClearanceCell c={c.clearance} />
<div className="rounded-lg bg-navy-950/40 px-3 py-2">
<div className="flex items-center gap-1.5 text-[11px] font-bold uppercase tracking-wider text-gold">
<Target size={12} /> Best Fit
</div>
<div className="mt-0.5 text-sm font-semibold">{c.best_fit.name}</div>
<div className="text-[11px] text-faint">
{c.best_fit.customer_agency ? `${c.best_fit.customer_agency} · ` : ''}
{num(c.best_fit.score).toFixed(0)}% fit
</div>
<div className="mt-1 text-[11px] text-faint" title={c.win_impact.basis}>
{c.win_impact.basis}
</div>
</div>
<div>
<div className="mb-1 text-[11px] font-bold uppercase tracking-wider text-muted">Labor Category Coverage</div>
{c.labor_category_coverage.length > 0 ? (
<div className="flex flex-wrap gap-1.5">
{c.labor_category_coverage.map((l) => (
<span key={l} className="rounded-full bg-blue/15 px-2.5 py-1 text-[11px] font-semibold text-blue-soft">
{l}
</span>
))}
</div>
) : (
<div className="text-[11px] text-faint">
{c.headline ? c.headline : 'Qualification review pending'}
</div>
)}
</div>
<div className="mt-auto flex items-center justify-between gap-2 pt-1">
{c.source === 'external' ? (
<button
onClick={() => del.mutate(c.id)}
disabled={del.isPending}
className="inline-flex items-center gap-1.5 rounded-md border border-line/70 px-2.5 py-1 text-xs font-semibold text-muted hover:border-risk/60 hover:text-risk disabled:opacity-50"
>
<Trash2 size={12} /> Delete
</button>
) : (
<span />
)}
<button
onClick={() => nav(`/screen/evaluate/${c.id}/${c.best_fit.requirement_id}`)}
className="inline-flex items-center gap-1 rounded-md bg-blue/20 px-3 py-1.5 text-xs font-semibold text-blue-soft hover:bg-blue/30"
>
Review <ChevronRight size={13} />
</button>
</div>
</Panel>
)
}
// ---------------- shared ----------------
function ClearanceCell({ c }: { c: IntelClearance }) {
const unknown = !c.sci_known || c.level === 'Unknown'
const lapsed = c.sci_known && c.status !== 'Active' // Expired or Inactive, never shown as confident
const badgeColor = unknown ? 'var(--color-muted)' : lapsed ? 'var(--color-warn)' : 'var(--color-blue)'
return (
<div className="flex items-start gap-2">
<Badge color={badgeColor} subtle>
{unknown ? (
<span className="inline-flex items-center gap-1">
<ShieldQuestion size={11} /> {c.level || 'Unknown'}
</span>
) : (
c.level
)}
</Badge>
<div className="space-y-0.5 text-[11px] text-faint">
{!unknown && (
<div className={lapsed ? 'font-semibold text-warn' : ''}>
{c.status}
{c.sci_eligible ? ' · SCI eligible' : ''}
{c.investigation_year ? ` · investigated ${c.investigation_year}` : ''}
</div>
)}
<div className={c.verified ? 'font-semibold text-ok' : ''}>
{c.verified ? '✓ ' : ''}
{c.provenance}
</div>
<div>{c.available ? 'Available now' : 'Engaged'}</div>
</div>
</div>
)
}
function Ring({ value, color }: { value: number; color: string }) {
const r = 22
const circ = 2 * Math.PI * r
return (
<div className="relative grid size-[58px] shrink-0 place-items-center">
<svg width="58" height="58" className="-rotate-90">
<circle cx="29" cy="29" r={r} fill="none" stroke="#13314f" strokeWidth="6" />
<circle
cx="29"
cy="29"
r={r}
fill="none"
stroke={color}
strokeWidth="6"
strokeLinecap="round"
strokeDasharray={circ}
strokeDashoffset={circ * (1 - value / 100)}
/>
</svg>
<span className="absolute text-[13px] font-bold tabular-nums">{value.toFixed(0)}</span>
</div>
)
}