import { type ReactNode } from 'react' import { Link, useParams } from 'react-router-dom' import { ArrowLeft, CheckCircle2, Clock, Compass, FileDown, Layers, Loader2, MapPin, Share2, ShieldCheck, } from 'lucide-react' import { useScreenCandidate, useScreenOpportunities, useScreenRequirement, useScreenScreen } from './queries' import { Badge, Bar, Panel } from '../../components/ui' import { OutcomeBar } from '../../components/OutcomeBar' import { ScreeningResults } from '../../components/ScreeningResults' import { WorkforceDNA } from '../../components/WorkforceDNA' import { bandColor, clearanceLabel, num, statusLabel } from '../../lib/format' import type { Band } from '../../lib/types' function proposal(band: Band) { if (band === 'green') return { label: 'PROPOSAL READY', color: 'var(--color-ok)' } if (band === 'yellow') return { label: 'REVIEW REQUIRED', color: 'var(--color-warn)' } return { label: 'RECRUITING REQUIRED', color: 'var(--color-risk)' } } export function CandidateEvaluation() { const { candidateId = '', requirementId = '' } = useParams() const candidateQuery = useScreenCandidate(candidateId || null) const requirementQuery = useScreenRequirement(requirementId || null) const opps = useScreenOpportunities(candidateId || null) // Scoring this pair is a read, so it is a keyed query rather than a mutation fired from an effect. // The key carries the pair, which is what guarantees a stale score can never render under the new // candidate's identity during a transition: a different pair is a different cache slot. const screen = useScreenScreen(candidateId || null, requirementId || null) const candidate = candidateQuery.data const requirement = requirementQuery.data return (
{(screen.error as Error).message}
Scoring opportunities…
) : !opps.data?.length ? (No matching opportunities.
) : (