import { nteeDescription } from '@novelpad/outreach-core'; import { serverGetMatchDetail, serverSetMatchReview, } from '@novelpad/outreach-core/server'; import { Form, Link, redirect } from 'react-router'; import { db } from '#~/db.server.js'; import type { Route } from './+types/matches.$matchId.js'; export async function loader({ request, params }: Route.LoaderArgs) { if (request.method === 'HEAD') return; const detail = await serverGetMatchDetail(db, params.matchId); if (detail == null) { throw new Response('Match not found', { status: 404 }); } return { detail }; } export async function action({ request, params }: Route.ActionArgs) { if (request.method === 'HEAD') return; const formData = await request.formData(); const decision = formData.get('decision'); if (decision !== 'approved' && decision !== 'rejected') { throw new Response('Invalid review submission', { status: 400 }); } await serverSetMatchReview(db, { matchId: params.matchId, reviewStatus: decision, rejectReason: decision === 'rejected' ? 'other' : undefined, }); return redirect('/'); } function dollars(n: number | null): string { if (n == null) return '—'; return `$${n.toLocaleString('en-US')}`; } const SUBSCORE_MAX: Record = { missionFit: 30, funderPrecedent: 25, capacityFit: 15, competition: 15, effort: 10, runway: 5, }; const JUDGE_VERDICT_STYLE: Record = { strong_fit: 'bg-green-100 text-green-800', plausible: 'bg-blue-100 text-blue-800', weak: 'bg-amber-100 text-amber-800', mismatch: 'bg-red-100 text-red-800', }; export default function MatchDetail({ loaderData }: Route.ComponentProps) { const { detail } = loaderData ?? {}; if (detail == null) return null; const { match, org, grant, funderGivingHistory, funderApplicationInfo } = detail; const applyInfo = (funderApplicationInfo ?? null) as { preselectedOnly?: boolean; recipientName?: string; formAndInfoAndMaterials?: string; submissionDeadlines?: string; restrictionsOnAwards?: string; } | null; const subscores = (match.subscores ?? {}) as Record; const orgPrograms = (org.programs ?? null) as Array<{ name: string; description?: string | null; populationServed?: string | null; sourceUrl?: string | null; }> | null; const orgFunders = (org.knownFunders ?? null) as Array<{ name: string }> | null; const orgStaff = (org.staff ?? null) as Array<{ name: string; role?: string | null; }> | null; const rationale = (match.rationale ?? {}) as Record; const nhHistory = funderGivingHistory; return (

{org.name} ↔ {grant.funder}

Score {match.totalScore}/100 {match.easyWin ? ' · Easy win' : ''} {match.isHero ? ' · Hero' : ''} · Status: {match.reviewStatus}

{!match.fitViable && (

Hidden from the pending queue — mission fit below floor or judged non-viable.

)}

Organization

Location:
{[org.city, org.state].filter(Boolean).join(', ')}
Focus (NTEE):
{org.nteeCode ?? '—'} {nteeDescription(org.nteeCode) != null && ` — ${nteeDescription(org.nteeCode)}`}
Annual revenue:
{dollars(org.totalRevenue)}
Mission (profile):
{org.missionStatement ?? '—'} {org.profileConfidence != null && org.profileConfidence <= 0.2 && ( {' '} (auto-generated stub — verify on their website) )}
{orgPrograms != null && orgPrograms.length > 0 && (

Programs (researched)

    {orgPrograms.map( (p, i) => (
  • {p.name} {p.populationServed != null && ` — serving ${p.populationServed}`} {p.sourceUrl != null && ( <> {' '} src )}
  • ), )}
)} {orgFunders != null && orgFunders.length > 0 && (

Known funders: {orgFunders.map((f) => f.name).join(', ')}

)} {orgStaff != null && orgStaff.length > 0 && (

Staff: {orgStaff .map((s) => (s.role != null ? `${s.name} (${s.role})` : s.name)) .join(', ')}

)}

Grant

Title:
{grant.title}
Award:
{dollars(grant.awardFloor)} – {dollars(grant.awardCeiling)}
Closes:
{grant.closeDate == null ? 'Rolling / no stated deadline' : new Date(grant.closeDate).toLocaleDateString('en-US')}
Source:
{grant.source}
{grant.eligibilityEntityTypes != null && grant.eligibilityEntityTypes.length > 0 && (
Eligibility:
{grant.eligibilityEntityTypes.join('; ')}
)}

Score breakdown

{Object.entries(SUBSCORE_MAX).map(([key, max]) => ( ))}
{key.replace(/([A-Z])/g, ' $1').toLowerCase()} {subscores[key] ?? 0} / {max}
{typeof rationale.similarity === 'number' && (

Embedding similarity: {(rationale.similarity as number).toFixed(3)} {Array.isArray(rationale.gateFailures) && (rationale.gateFailures as string[]).length > 0 && ` · Ignored gate flags: ${(rationale.gateFailures as string[]).join(', ')}`}

)}
{match.judgeVerdict != null && (

Mission-fit judge{' '} {match.judgeVerdict.replace('_', ' ')}

{match.judgeRationale}

{match.judgedAt != null && (

Judged {new Date(match.judgedAt).toLocaleDateString('en-US')} — the verdict replaces the embedding mission-fit score above.

)}
)} {applyInfo != null && (

How to apply (funder's own 990-PF, Part XV)

{applyInfo.preselectedOnly === true && (

This funder states it only contributes to preselected organizations and does not accept unsolicited requests — do not pitch.

)}
{applyInfo.formAndInfoAndMaterials != null && (
Application form:
{applyInfo.formAndInfoAndMaterials}
)} {applyInfo.submissionDeadlines != null && (
Deadlines:
{applyInfo.submissionDeadlines}
)} {applyInfo.restrictionsOnAwards != null && (
Restrictions:
{applyInfo.restrictionsOnAwards}
)} {applyInfo.recipientName != null && (
Applications to:
{applyInfo.recipientName}
)}
)}

Grant synopsis

{grant.synopsis ?? '—'}

{nhHistory.length > 0 && (

{grant.source === 'irs_990pf' ? 'Funder giving history (from 990-PF filings)' : 'Recent program awards to NH recipients (USASpending)'}

The concrete evidence behind the precedent score —{' '} {grant.source === 'irs_990pf' ? 'who this funder actually paid, sorted in-state first.' : 'who this federal program actually funded in NH recently, peers first. Only "peer" recipients (registered NH nonprofits our size) count toward the precedent score — universities, hospital systems, and companies do not.'}

{nhHistory.map((g, i) => ( ))}
Recipient City Amount Year Purpose
{g.recipientName} {g.isPeer === true && ( peer )} {g.recipientCity ?? '—'} {dollars(g.amount)} {g.taxYear} {g.purpose ?? '—'}
)}
); }