import { useEffect, useMemo, useState } from 'react' import { Link, useNavigate } from 'react-router-dom' import { BookOpenText, ChevronRight, Columns3, ExternalLink, Info } from 'lucide-react' import { useSamOpportunities } from '../../lib/queries' import { useScreenRanked, useScreenRequirements } from './queries' import { screenBrand } from './brand' import type { OpportunityFilters, RequirementListView, SamOpportunity } from '../../lib/types' import { Badge, Panel } from '../../components/ui' import { ToolHeader } from '../../components/ToolHeader' import { bandColor, clearanceLabel, fmtDate, GALAPAGOS, num } from '../../lib/format' const selectCls = 'rounded-lg border border-line/70 bg-navy-900 px-3 py-2 text-sm text-ink outline-none focus:border-blue min-w-[24rem]' // The screen flow opens on the relevant, non empty Galapagos slice: their NAICS with Air Force and // Space Force as the customers. (The strict 8A plus HI, NM intersection is often empty in real data.) const pickerFilters: OpportunityFilters = { naics: [...GALAPAGOS.naics], sub_agency: ['AIR FORCE', 'SPACE FORCE'], active_only: true, limit: 100, } // Map an opportunity to a representative demo requirement so the engine can score synthetic candidates // with real, structured criteria. SAM notices don't carry structured clearance/skill specs, so this // is an explicit, labeled demo bridge, not derived clearance. const KEYWORDS: string[][] = [ ['cyber', 'security', 'defensive', 'soc'], ['intel', 'sigint', 'analyst', 'intelligence'], ['data', 'machine learning', ' ai ', 'scientist'], ['cloud', 'devops', 'aws', 'azure'], ['software', 'developer', 'engineer', 'programming'], ['network', 'systems', 'infrastructure', 'architect'], ] function pickRequirement(opp: SamOpportunity | undefined, reqs: RequirementListView[]): RequirementListView | null { if (!reqs.length) return null const t = (opp?.title ?? '').toLowerCase() for (const words of KEYWORDS) { if (words.some((w) => t.includes(w.trim()))) { const match = reqs.find((r) => words.some((w) => r.title.toLowerCase().includes(w.trim()))) if (match) return match } } return reqs[0] } function MiniRing({ value, color }: { value: number; color: string }) { const r = 22 const c = 2 * Math.PI * r return (
{value.toFixed(0)}
) } export function ScreeningQueue() { const opportunities = useSamOpportunities(pickerFilters) const requirements = useScreenRequirements() const [noticeId, setNoticeId] = useState('') const [compareIds, setCompareIds] = useState([]) const nav = useNavigate() const toggleCompare = (id: string) => { setCompareIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : prev.length >= 3 ? prev : [...prev, id], ) } const opps = useMemo(() => opportunities.data ?? [], [opportunities.data]) useEffect(() => { // Re-anchor to the first opportunity on initial load OR when a refetch drops the selected notice // (otherwise the picker shows a blank selection) [review FE-2]. if (opps.length && (!noticeId || !opps.some((o) => o.notice_id === noticeId))) { setNoticeId(opps[0].notice_id) } }, [opps, noticeId]) const selectedOpp = opps.find((o) => o.notice_id === noticeId) const repReq = pickRequirement(selectedOpp, requirements.data ?? []) const ranked = useScreenRanked(repReq?.id ?? null) return (
{selectedOpp && (
Sol# {selectedOpp.solicitation_number || 'n/a'} NAICS {selectedOpp.naics_code || 'n/a'} {selectedOpp.set_aside_code && ( {selectedOpp.set_aside_code} )} Response due {fmtDate(selectedOpp.response_deadline)} {selectedOpp.ui_link && ( View on SAM.gov )}
)} {repReq && (

Candidate scoring runs against a representative cleared role, {repReq.title}{' '} (demo requirement). Clearance shown is a self reported or detected indicator, not verified. Candidates are Demo data; opportunities are live from SAM.gov.

)}
Acronyms and terms
{opps.length === 0 ? (

No cached opportunities to screen against. Run the SAM sync to populate the feed.

) : ranked.isLoading ? (

Scoring candidates…

) : (
    {ranked.data?.map((c) => { const color = bandColor(c.band) return (
  • repReq && nav(`/screen/evaluate/${c.candidate_id}/${repReq.id}`)} className="flex cursor-pointer items-center gap-4 rounded-xl border border-line/60 bg-surface/70 px-4 py-3 transition hover:border-screen/60 hover:bg-navy-800/50" > toggleCompare(c.candidate_id)} onClick={(e) => e.stopPropagation()} className="size-4 shrink-0 accent-[var(--color-blue)]" aria-label={`Select ${c.full_name} for comparison`} />
    {c.full_name .split(' ') .map((p) => p[0]) .slice(0, 2) .join('')}
    {c.full_name}
    {clearanceLabel[c.clearance_level] ?? c.clearance_level} (self reported) · {c.years_experience} yrs {c.location ? ` · ${c.location}` : ''}
    {c.status}
  • ) })}
)}
) }