Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | frontend/src/components/MissionCheckModal.tsx |
| Original SHA-256 | b0d0a62fe149908e0697f3d4fc33024d4c092dad97da149fb50d0d7738f7a468 |
| Git blob SHA | 1ab4ba2f7cec17ca74e2093d6e6b4161aa7d343a |
| Reading-copy SHA-256 | b0d0a62fe149908e0697f3d4fc33024d4c092dad97da149fb50d0d7738f7a468 |
Every recorded occurrence
These 35 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/components/MissionCheckModal.tsx | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | per-tenant-routing | 9bde0f9a74b89d01980fa658e5253acda7528d0c | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws6-retrieval | 6c56e29231ec05735927fa265c97d517499dfeaf | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-a-shared-core | e0de03ac3a1ec826bd15d0e048e3b02baa23eeff | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | m5-price-to-win | 41000ad30fff4129fdaf5ec84e15ba14c27d4890 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-c-slatematch | 5cd60c918301b46ecd6ed3e03e20c395da0062e2 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws1-ontology-sync | b596f449a32a1016fbd403c36505cc00a1ac9ee6 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws8-teaching-loop | c823f0fb6bb2aba0f39001eb6de96f4000d9321f | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | w3-ai-staffing-recommendations | 43d56387270ef4da4cabd794d97ca6a49909bc7d | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | mag-substrate | b82c7100a492dec67dfd1eda6b3f53def859be35 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws3-clearance | 4b8e7ce594c068621867f9c9deed0ec64ae6c553 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-d-command-center | 255e7d1d420abf5e277d0cd8c9b14f6f72b6acb9 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | phase2-eval-fairness | d361af254701975fe239927656ababb56374655e | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-e-dataflow-deploy | 433815a042f9741411e60fa553fe72143e9b10db | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ruthless-debug-sweep | b7d742f8f032984be3817efffa3eb8b13b651c1f | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ai-intelligence-layer | 5d5ddff70393a197c5f54a45280bb5dd42b24755 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | graphrag-foundation | b0ddeb9f633fd138d09309d1a17b7d13bc3a67f7 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-a-opportunity-intelligence | 1675031db74316e100782d063e9eda1a597fe3a1 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | deploy-and-ops | bdacd9d0b4d5998d25fc74bf4007f4c3ec538c7a | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws9-bench-ingestion | f585a9ef32fa554663ce1fba9a414a54b6e49cf0 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws2-alias-relationship | e4dada4601c6eb101830f9d223a9655dfa120616 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-b-screenmatch | 09015496d565a172bcaa15cfe9a8e4b072b13df0 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ws7-federal-signal | 6a9f6ce9cfb13345ffb47770d4960e7c2d9c17c2 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-e-commercial-stubs | 4437da660539284a400ee380b9b427a300c369ee | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | ai-brain-live | aac32fc49c878cc5bca099459307611562d0bac1 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-d-missionmatch | 3be46ba89edb737182075a2b320509b42dc916f8 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | phase2-connectors | e038d4c687aec16f8bd9bc4d907eea14d91f8704 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | workstream-b-sam-contract-awards | d5101cceb98e70000cebb31d3e7ac73d747d3a6d | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / frontend/src/components/MissionCheckModal.tsx | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓388 lines · 14.4 KB
import { useEffect, useState } from 'react'
import { CheckCircle2, Compass, FileUp, Loader2, ScanSearch, UploadCloud } from 'lucide-react'
import { Badge, Bar, Modal, Panel } from './ui'
import { ScreeningResults } from './ScreeningResults'
import { useMissionCheckJD, useMissionCheckOpportunities, useSaveCandidate } from '../lib/queries'
import { bandColor, missionRecColor, num } from '../lib/format'
import type {
CandidateListView,
ParsedCandidate,
ParsedRequirement,
RequirementListView,
SaveCandidateRequest,
} from '../lib/types'
type Mode = 'opportunities' | 'jd'
// MissionCheckModal is the W1 surface. It parses a resume to text in the browser (nothing is uploaded),
// then scores it server side: Mode A against every open opportunity, Mode B against a pasted job
// description. The result is advisory and a human decides; the optional Save Candidate persists a
// reviewed, audited record.
export function MissionCheckModal({ open, onClose }: { open: boolean; onClose: () => void }) {
const [mode, setMode] = useState<Mode>('opportunities')
const [resumeText, setResumeText] = useState('')
const [jdText, setJdText] = useState('')
const [fileNote, setFileNote] = useState('')
const [parseError, setParseError] = useState('')
const [parsing, setParsing] = useState(false)
const modeA = useMissionCheckOpportunities()
const modeB = useMissionCheckJD()
function close() {
modeA.reset()
modeB.reset()
setResumeText('')
setJdText('')
setFileNote('')
setParseError('')
onClose()
}
async function onFile(file: File | undefined) {
if (!file) return
setParseError('')
setFileNote('')
setParsing(true)
try {
// Lazy load the PDF and DOCX parsers (about 1 MB) only when a file is actually parsed, so they
// never weigh down the initial page load.
const { extractResumeText } = await import('../lib/resume')
const r = await extractResumeText(file)
if (r.lowConfidence || r.text.trim() === '') {
setParseError('That file had little or no selectable text. It may be a scan, so paste the resume text instead.')
} else {
setResumeText(r.text)
setFileNote(`Parsed ${file.name} in memory as ${r.source.toUpperCase()}. The file was not uploaded or stored.`)
}
} catch (e) {
setParseError(e instanceof Error && e.message ? e.message : 'Could not read that file. Paste the text instead.')
} finally {
setParsing(false)
}
}
function run() {
setParseError('')
if (mode === 'opportunities') modeA.mutate({ text: resumeText })
else modeB.mutate({ resume: resumeText, jd: jdText })
}
const pending = modeA.isPending || modeB.isPending
const runError = (mode === 'opportunities' ? modeA.error : modeB.error) as Error | null
const canRun =
resumeText.trim() !== '' && (mode === 'jd' ? jdText.trim() !== '' : true) && !pending && !parsing
return (
<Modal open={open} onClose={close} title="Mission Check">
<div className="space-y-4">
<div className="flex flex-wrap items-center justify-between gap-2">
<p className="text-sm text-muted">
Score a resume against the mission. Parsed in your browser, nothing is uploaded or stored.
</p>
<Badge color="var(--color-gold)" subtle>
Parsed in memory, not stored
</Badge>
</div>
{/* mode tabs */}
<div className="flex gap-1 rounded-lg border border-line/70 bg-navy-900 p-1">
<Tab active={mode === 'opportunities'} onClick={() => setMode('opportunities')} label="Match all opportunities" />
<Tab active={mode === 'jd'} onClick={() => setMode('jd')} label="Match a job description" />
</div>
{/* resume input */}
<DropZone parsing={parsing} fileNote={fileNote} onFile={onFile} />
<div>
<label className="mb-1 block text-[11px] font-semibold uppercase tracking-wider text-muted">
Or paste the resume text
</label>
<textarea
value={resumeText}
onChange={(e) => setResumeText(e.target.value)}
rows={4}
placeholder="Paste the resume text here"
className="w-full rounded-lg border border-line/70 bg-navy-950/60 px-3 py-2 text-sm text-ink outline-none focus:border-blue/60"
/>
</div>
{mode === 'jd' && (
<div>
<label className="mb-1 block text-[11px] font-semibold uppercase tracking-wider text-muted">
Job description
</label>
<textarea
value={jdText}
onChange={(e) => setJdText(e.target.value)}
rows={4}
placeholder="Paste the job description to score against"
className="w-full rounded-lg border border-line/70 bg-navy-950/60 px-3 py-2 text-sm text-ink outline-none focus:border-blue/60"
/>
</div>
)}
{parseError && <p className="text-sm text-warn">{parseError}</p>}
<div className="flex items-center gap-3">
<button
onClick={run}
disabled={!canRun}
className="flex items-center gap-2 rounded-lg bg-gradient-to-r from-blue to-navy-700 px-4 py-2 text-sm font-bold text-white hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-50"
>
{pending ? <Loader2 className="animate-spin" size={15} /> : <ScanSearch size={15} />}
Run Mission Check
</button>
<span className="text-[11px] text-faint">
Advisory only, a human makes the final decision. No demographic data is used.
</span>
</div>
{runError && <p className="text-sm text-risk">{runError.message}</p>}
{/* results */}
{mode === 'opportunities' && modeA.data && <ModeAResult data={modeA.data} />}
{mode === 'jd' && modeB.data && <ModeBResult data={modeB.data} />}
</div>
</Modal>
)
}
function Tab({ active, onClick, label }: { active: boolean; onClick: () => void; label: string }) {
return (
<button
onClick={onClick}
className={`flex-1 rounded-md px-3 py-1.5 text-xs font-semibold transition ${
active ? 'bg-blue/25 text-blue-soft' : 'text-faint hover:text-muted'
}`}
>
{label}
</button>
)
}
function DropZone({
parsing,
fileNote,
onFile,
}: {
parsing: boolean
fileNote: string
onFile: (f: File | undefined) => void
}) {
const [over, setOver] = useState(false)
return (
<div
onDragOver={(e) => {
e.preventDefault()
setOver(true)
}}
onDragLeave={() => setOver(false)}
onDrop={(e) => {
e.preventDefault()
setOver(false)
onFile(e.dataTransfer.files?.[0])
}}
className={`rounded-lg border border-dashed px-4 py-5 text-center transition ${
over ? 'border-blue/70 bg-blue/10' : 'border-line/70 bg-navy-950/40'
}`}
>
<div className="flex flex-col items-center gap-1.5">
{parsing ? (
<Loader2 className="animate-spin text-blue-soft" size={20} />
) : (
<UploadCloud className="text-muted" size={20} />
)}
<div className="text-sm text-muted">Drag a PDF or DOCX resume here</div>
<label className="mt-1 inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-line/70 px-3 py-1.5 text-xs font-semibold text-muted hover:border-blue/60 hover:text-blue-soft">
<FileUp size={13} /> Browse
<input
type="file"
accept=".pdf,.docx"
className="hidden"
onChange={(e) => onFile(e.target.files?.[0])}
/>
</label>
</div>
{fileNote && <p className="mt-2 text-[11px] text-ok">{fileNote}</p>}
</div>
)
}
function RecommendationBanner({ value, reason }: { value: string; reason: string }) {
const color = missionRecColor(value)
return (
<div className="flex items-center gap-3 rounded-lg border px-4 py-3" style={{ borderColor: color }}>
<CheckCircle2 size={26} style={{ color }} />
<div>
<div className="text-lg font-extrabold" style={{ color }}>
{value}
</div>
<div className="text-xs text-muted">{reason}</div>
</div>
</div>
)
}
function ModeAResult({ data }: { data: import('../lib/types').MissionCheckModeAResult }) {
return (
<div className="space-y-3">
<Panel title="Top opportunity matches" hint="ranked by Mission Readiness">
{data.rows.length === 0 ? (
<p className="text-sm text-faint">No open opportunities to match against yet.</p>
) : (
<div className="space-y-2.5">
{data.rows.map((o) => (
<div key={o.requirement_id}>
<div className="mb-1 flex items-center justify-between text-sm">
<span className="flex items-center gap-1.5">
<Compass size={13} style={{ color: 'var(--color-blue-soft)' }} />
{o.title}
</span>
<span className="flex items-center gap-2">
<Badge color={missionRecColor(o.recommendation)} subtle>
{o.recommendation}
</Badge>
<span className="font-semibold tabular-nums" style={{ color: bandColor(o.band) }}>
{num(o.score).toFixed(0)}%
</span>
</span>
</div>
<Bar value={num(o.score)} color={bandColor(o.band)} />
</div>
))}
</div>
)}
</Panel>
<SaveSection candidate={data.candidate} />
<Disclosure assumptions={data.assumptions} categories={data.data_categories} />
</div>
)
}
function ModeBResult({ data }: { data: import('../lib/types').MissionCheckModeBResult }) {
return (
<div className="space-y-3">
<RecommendationBanner value={data.recommendation} reason={data.recommendation_reason} />
<ScreeningResults
view={data.view}
candidate={candidateStub(data.candidate)}
requirement={reqStub(data.requirement)}
hideHeader
/>
<SaveSection candidate={data.candidate} />
<Disclosure assumptions={data.assumptions} categories={data.data_categories} />
</div>
)
}
// SaveSection persists the reviewed parse as an audited candidate (recruiter capability). The name is
// editable because resume name detection is best effort; saving needs a name.
function SaveSection({ candidate }: { candidate: ParsedCandidate }) {
const save = useSaveCandidate()
const [name, setName] = useState(candidate.full_name)
// A new Mission Check run yields a new candidate object, so reset the name and clear any prior save
// success, otherwise the success state would carry over and wrongly mark the new result as saved.
useEffect(() => {
setName(candidate.full_name)
save.reset()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [candidate])
if (save.isSuccess) {
return (
<Panel className="flex items-center gap-2 text-sm text-ok">
<CheckCircle2 size={16} /> Candidate saved. It is now in your workforce, clearance self reported.
</Panel>
)
}
function doSave() {
const body: SaveCandidateRequest = {
full_name: name.trim(),
clearance_level: candidate.clearance_level,
clearance_poly: candidate.clearance_poly,
clearance_status: candidate.clearance_status,
years_experience: candidate.years_experience,
location: candidate.location,
remote: false,
relocatable: false,
available: true,
skills: candidate.skills,
certifications: candidate.certifications,
customer_experience: candidate.customer_experience,
}
save.mutate(body)
}
return (
<Panel title="Save as candidate" hint="recruiter capability, audited">
<div className="space-y-2">
<div className="flex flex-wrap gap-1.5 text-[11px]">
{candidate.skills.slice(0, 8).map((s) => (
<span key={s} className="rounded-full bg-blue/15 px-2 py-0.5 text-blue-soft">
{s}
</span>
))}
{candidate.years_experience > 0 && (
<span className="rounded-full bg-navy-800 px-2 py-0.5 text-muted">
{candidate.years_experience} yrs
</span>
)}
</div>
<div className="flex items-center gap-2">
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Candidate name"
className="flex-1 rounded-md border border-line/70 bg-navy-950/60 px-3 py-1.5 text-sm text-ink outline-none focus:border-blue/60"
/>
<button
onClick={doSave}
disabled={name.trim() === '' || save.isPending}
title={name.trim() === '' ? 'A candidate name is required to save' : 'Save this candidate'}
className="flex items-center gap-1.5 rounded-md bg-blue/20 px-3 py-1.5 text-sm font-semibold text-blue-soft hover:bg-blue/30 disabled:cursor-not-allowed disabled:opacity-50"
>
{save.isPending ? <Loader2 className="animate-spin" size={14} /> : <CheckCircle2 size={14} />}
Save Candidate
</button>
</div>
<p className="text-[11px] text-faint">
Clearance is a self reported, detected indicator, not verified. The real check is the customer FSO through DISS.
</p>
{save.isError && <p className="text-[11px] text-risk">{(save.error as Error).message}</p>}
</div>
</Panel>
)
}
function Disclosure({ assumptions, categories }: { assumptions: string[]; categories: string[] }) {
return (
<p className="text-[11px] leading-relaxed text-faint">
This is an automated employment decision aid: it is advisory, a human decides, it takes no demographic input, and
each run is logged. Assumptions: {assumptions.join('; ')}. Data assessed: {categories.join(', ')}.
</p>
)
}
function candidateStub(p: ParsedCandidate): CandidateListView {
return {
id: 'mission_check',
full_name: p.full_name || 'Uploaded resume',
clearance_level: p.clearance_level,
clearance_status: p.clearance_status,
years_experience: p.years_experience,
location: p.location || undefined,
available: true,
}
}
function reqStub(p: ParsedRequirement): RequirementListView {
return {
id: 'pasted_jd',
title: p.title,
required_level: p.required_level,
customer_agency: p.customer_agency || undefined,
key_personnel: p.key_personnel,
}
}