import React from "react"; import { Box, Paper, Tooltip, Typography } from "@mui/material"; import type { FactAnnotationResponse } from "../types"; interface TextHighlightProps { text: string; annotations: FactAnnotationResponse[]; } interface AnnotationStyle { bgcolor: string; borderColor: string; } function getAnnotationStyle(color: string): AnnotationStyle { switch (color.toLowerCase()) { case "green": return { bgcolor: "rgba(74, 222, 128, 0.15)", borderColor: "#4ade80" }; case "yellow": return { bgcolor: "rgba(251, 191, 36, 0.15)", borderColor: "#fbbf24" }; case "orange": return { bgcolor: "rgba(249, 115, 22, 0.25)", borderColor: "#f97316" }; case "red": return { bgcolor: "rgba(248, 113, 113, 0.15)", borderColor: "#f87171" }; default: return { bgcolor: "rgba(148, 163, 184, 0.10)", borderColor: "#94a3b8" }; } } function TooltipContent({ ann }: { ann: FactAnnotationResponse }): React.ReactElement { return ( {ann.subject} → {ann.predicate} → {ann.object} Time: {ann.time} Status: {ann.status} Confidence: {Math.round(ann.confidence * 100)}% {ann.status === "inconsistent" && ann.inconsistencies.map((desc, i) => ( • {desc} ))} ); } const LEGEND_ITEMS = [ { color: "#4ade80", label: "Consistent" }, { color: "#fbbf24", label: "Minor" }, { color: "#f97316", label: "Moderate" }, { color: "#f87171", label: "Severe" }, ] as const; function TextHighlight({ text, annotations }: TextHighlightProps): React.ReactElement { const sentences = text.split(/(?<=[.!?])\s+(?=[A-Z])/).filter((s) => s.trim().length > 0); const annotationMap = new Map(); annotations.forEach((ann) => { if (!annotationMap.has(ann.sentence_idx)) { annotationMap.set(ann.sentence_idx, ann); } }); return ( Article Text {LEGEND_ITEMS.map(({ color, label }) => ( {label} ))} {sentences.map((sentence, idx) => { const ann = annotationMap.get(idx); if (ann) { const { bgcolor, borderColor } = getAnnotationStyle(ann.color); return ( } arrow placement="top" > {sentence} ); } return ( {sentence} ); })} ); } export default TextHighlight;