// V2 eval report cover — ported from EvalReportV2Cover.tsx import { Page, View, Text, Image } from '@react-pdf/renderer'; import { styles, colors, logoPath } from '../styles.js'; import { getResultsScoreMetrics, getScoreHexColor } from '../scoring.js'; import type { EvaluationResult } from './types.js'; interface EvalReportV2CoverProps { customerName: string; reportDate: string; results: EvaluationResult[]; } export function EvalReportV2Cover({ customerName, reportDate, results }: EvalReportV2CoverProps) { const metrics = getResultsScoreMetrics(results); const criteriaRate = metrics.criteriaRate !== null ? Math.round(metrics.criteriaRate * 100) : 0; const rubricRate = metrics.rubricRate !== null ? Math.round(metrics.rubricRate * 100) : null; const singleTurnCount = results.filter(r => r.item_type === 'single_turn' || r.item_type === undefined).length; const scenarioCount = results.filter(r => r.item_type === 'scenario').length; const transcriptCount = results.filter(r => r.item_type === 'transcript').length; return ( {/* Logo */} {/* Title */} Evaluation Report {customerName} {reportDate} {/* Key Highlights */} Key Highlights {/* Scores - side by side */} {metrics.criteriaTotal > 0 && ( {criteriaRate}% Criteria ({metrics.criteriaPassed}/{metrics.criteriaTotal} checks) )} {rubricRate !== null && ( {rubricRate}% Rubric ({metrics.rubricRulesPassed}/{metrics.rubricRulesTotal} rules) )} {/* Item type breakdown */} {'\u2022'} {results.length} test items evaluated {(() => { const parts: string[] = []; if (singleTurnCount > 0) parts.push(`${singleTurnCount} single-turn`); if (scenarioCount > 0) parts.push(`${scenarioCount} scenario${scenarioCount > 1 ? 's' : ''}`); if (transcriptCount > 0) parts.push(`${transcriptCount} transcript${transcriptCount > 1 ? 's' : ''}`); return parts.length > 1 ? ` (${parts.join(', ')})` : parts.length === 1 ? ` (all ${parts[0]})` : ''; })()} {/* Footer */} Powered by Indemn Evals Page 1 ); }