Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / frontend/src/tools/recruitmatch/Reports.tsx |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | frontend/src/tools/recruitmatch/Reports.tsx |
| Original SHA-256 | 1ca6ccc5aa2427024c208aa081b040e5fb548a0a21b2a0e96c954d712cc39a6d |
| Git blob SHA | 83ff239a35d47a0977340c0fd9c6bc528037ea17 |
| Reading-copy SHA-256 | 1ca6ccc5aa2427024c208aa081b040e5fb548a0a21b2a0e96c954d712cc39a6d |
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/recruitmatch/Reports.tsx | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / frontend/src/tools/recruitmatch/Reports.tsx | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓166 lines · 7.5 KB
import { useMemo, useState } from 'react'
import { Download, Globe, ShieldCheck } from 'lucide-react'
import { ToolHeader } from '../../components/ToolHeader'
import { Panel } from '../../components/ui'
import { recruitBrand } from './brand'
import { reportApi } from './reportApi'
import { useReport } from './reportQueries'
const chip = (on: boolean) =>
`rounded-full px-3 py-1 text-xs font-semibold transition ${
on
? 'bg-recruit/25 text-recruit shadow-[inset_0_0_0_1px_var(--color-recruit)]'
: 'bg-navy-900 text-faint hover:text-muted border border-line/60'
}`
const PERIODS = [
{ key: 'day', label: 'Daily' },
{ key: 'week', label: 'Weekly' },
{ key: 'month', label: 'Monthly' },
{ key: 'quarter', label: 'Calendar quarter' },
// The one that matters for a federal contractor, and the one a generic tool gets wrong.
{ key: 'fiscal_quarter', label: 'Federal fiscal quarter' },
] as const
const EXPORTS = [
{ kind: 'periods', label: 'This report' },
{ kind: 'pipeline', label: 'Pipeline' },
{ kind: 'placements', label: 'Placements' },
{ kind: 'activity', label: 'Activity' },
] as const
export function Reports() {
const [period, setPeriod] = useState<string>('month')
const [days, setDays] = useState(365)
// Memoised on the window, not recomputed per render: a value derived from Date.now() in the render
// body changes the query key every pass and the screen refetches forever.
const since = useMemo(() => new Date(Date.now() - days * 864e5).toISOString(), [days])
const q = useReport(period, since)
if (q.isLoading) return <Panel className="grid place-items-center py-24 text-muted">Building the report…</Panel>
if (q.isError || !q.data) {
return (
<Panel className="grid place-items-center py-24 text-warn">
Could not build the report. {(q.error as Error)?.message}
</Panel>
)
}
const v = q.data
const max = Math.max(1, ...v.rows.map((r) => Math.max(r.opened, r.placements, r.submissions)))
return (
<div className="space-y-4">
<ToolHeader name={recruitBrand.name} tagline="Reports" accent={recruitBrand.accent}>
<span className="flex items-center gap-1.5 text-[11px] text-faint">
<Globe size={11} />
{v.time_zone}
</span>
</ToolHeader>
<div className="flex flex-wrap items-center gap-2">
{PERIODS.map((p) => (
<button key={p.key} className={chip(period === p.key)} onClick={() => setPeriod(p.key)}>
{p.label}
</button>
))}
<span className="mx-1 h-5 w-px bg-line/60" />
{[90, 365, 730].map((d) => (
<button key={d} className={chip(days === d)} onClick={() => setDays(d)}>
{d === 730 ? '2 years' : d === 365 ? '1 year' : '90 days'}
</button>
))}
</div>
{period === 'fiscal_quarter' && (
<p className="rounded-lg border border-line/60 bg-navy-950/40 p-3 text-[11px] text-muted">
Federal fiscal quarters begin on 1 October, and a fiscal year is named for the calendar year it
ends in, so October 2025 falls in FY2026 Q1. Use the calendar quarter option if your client
reports on the calendar year instead.
</p>
)}
<Panel title="Exports" hint="CSV">
<div className="flex flex-wrap gap-2">
{EXPORTS.map((e) => (
<a
key={e.kind}
href={reportApi.exportUrl(e.kind, period, since)}
className="flex items-center gap-2 rounded-lg border border-line/70 px-3 py-2 text-xs font-semibold text-muted hover:text-ink"
>
<Download size={13} />
{e.label}
</a>
))}
</div>
<p className="mt-3 flex items-start gap-1.5 text-[10px] text-faint">
<ShieldCheck size={11} className="mt-0.5 shrink-0" />
{/* Worth saying plainly: the export is safe to open, and every download is recorded. */}
Cells that would otherwise be read as spreadsheet formulas are neutralised before the file is
written, so an export is safe to open and safe to forward. Every download is recorded against
your account.
</p>
</Panel>
<Panel title={`Activity by ${PERIODS.find((p) => p.key === period)?.label.toLowerCase()}`} hint={`${v.rows.length} periods`}>
{v.rows.length === 0 ? (
<p className="py-8 text-center text-[11px] text-faint">Nothing recorded in this window yet.</p>
) : (
<div className="overflow-x-auto">
<table className="w-full min-w-[720px] text-left text-[11px]">
<thead>
<tr className="border-b border-line/60 text-[10px] uppercase tracking-wider text-faint">
<th className="py-2 pr-3 font-bold">Period</th>
<th className="py-2 pr-3 text-right font-bold">Opened</th>
<th className="py-2 pr-3 text-right font-bold">Filled</th>
<th className="py-2 pr-3 text-right font-bold">Submissions</th>
<th className="py-2 pr-3 text-right font-bold">Placements</th>
<th className="py-2 pr-3 text-right font-bold">Activity</th>
<th className="py-2 pr-3 text-right font-bold">Connects</th>
<th className="py-2 text-right font-bold">Connect %</th>
</tr>
</thead>
<tbody>
{v.rows.map((r) => (
<tr key={r.start} className="border-b border-line/30">
<td className="py-1.5 pr-3">
<div className="flex items-center gap-2">
<span className="w-28 shrink-0 truncate font-semibold">{r.label}</span>
<span
className="h-1.5 rounded-full bg-recruit/70"
style={{ width: `${(r.opened / max) * 60}px` }}
/>
</div>
</td>
<td className="py-1.5 pr-3 text-right">{r.opened}</td>
<td className="py-1.5 pr-3 text-right">{r.filled}</td>
<td className="py-1.5 pr-3 text-right">{r.submissions}</td>
<td className="py-1.5 pr-3 text-right">{r.placements}</td>
<td className="py-1.5 pr-3 text-right">{r.activities}</td>
<td className="py-1.5 pr-3 text-right">{r.connects}</td>
<td className="py-1.5 text-right">{r.connect_rate || '—'}</td>
</tr>
))}
<tr className="border-t border-line/60 font-bold">
<td className="py-2 pr-3">Total</td>
<td className="py-2 pr-3 text-right">{v.totals.opened}</td>
<td className="py-2 pr-3 text-right">{v.totals.filled}</td>
<td className="py-2 pr-3 text-right">{v.totals.submissions}</td>
<td className="py-2 pr-3 text-right">{v.totals.placements}</td>
<td className="py-2 pr-3 text-right">{v.totals.activities}</td>
<td className="py-2 pr-3 text-right">{v.totals.connects}</td>
<td className="py-2 text-right">{v.totals.connect_rate || '—'}</td>
</tr>
</tbody>
</table>
</div>
)}
<p className="mt-3 text-[10px] text-faint">
Each column is counted on the period its own event falls in, so a placement in March against an
order opened in January is March's placement. Days are counted in {v.time_zone}.
</p>
</Panel>
</div>
)
}