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;