88 lines
2.8 KiB
JavaScript
88 lines
2.8 KiB
JavaScript
import { Progress, Space, Tag, Tooltip } from "antd";
|
|
import { useTranslation } from "react-i18next";
|
|
const parseConfidence = (confidenceStr) => {
|
|
if (!confidenceStr || typeof confidenceStr !== "string") return null;
|
|
|
|
const match = confidenceStr.match(/T([\d.]+)\s*-\s*O([\d.]+)\s*-\s*J([\d.]+)/);
|
|
if (!match) return null;
|
|
|
|
return {
|
|
total: parseFloat(match[1]),
|
|
ocr: parseFloat(match[2]),
|
|
jobMatch: parseFloat(match[3])
|
|
};
|
|
};
|
|
|
|
const getConfidenceColor = (value) => {
|
|
if (value >= 80) return "green";
|
|
if (value >= 60) return "orange";
|
|
if (value >= 40) return "gold";
|
|
return "red";
|
|
};
|
|
|
|
const ConfidenceDisplay = ({ rowValue: { confidence, actual_price, actual_cost } }) => {
|
|
const { t } = useTranslation();
|
|
const parsed = parseConfidence(confidence);
|
|
const parsed_actual_price = parseFloat(actual_price);
|
|
const parsed_actual_cost = parseFloat(actual_cost);
|
|
if (!parsed) {
|
|
return <span style={{ color: "#959595", fontSize: "0.85em" }}>N/A</span>;
|
|
}
|
|
|
|
const { total, ocr, jobMatch } = parsed;
|
|
const color = getConfidenceColor(total);
|
|
|
|
return (
|
|
<Tooltip
|
|
title={
|
|
<div style={{ padding: "4px 0" }}>
|
|
<div style={{ marginBottom: 8, fontWeight: 600 }}>{t("bills.labels.ai.confidence.breakdown")}</div>
|
|
<div style={{ marginBottom: 4 }}>
|
|
<strong>{t("bills.labels.ai.confidence.overall")}:</strong> {total.toFixed(1)}%
|
|
<Progress
|
|
percent={total}
|
|
size="small"
|
|
strokeColor={getConfidenceColor(total)}
|
|
showInfo={false}
|
|
style={{ marginTop: 2 }}
|
|
/>
|
|
</div>
|
|
<div style={{ marginBottom: 4 }}>
|
|
<strong>{t("bills.labels.ai.confidence.ocr")}:</strong> {ocr.toFixed(1)}%
|
|
<Progress
|
|
percent={ocr}
|
|
size="small"
|
|
strokeColor={getConfidenceColor(ocr)}
|
|
showInfo={false}
|
|
style={{ marginTop: 2 }}
|
|
/>
|
|
</div>
|
|
<div>
|
|
<strong>{t("bills.labels.ai.confidence.match")}:</strong> {jobMatch.toFixed(1)}%
|
|
<Progress
|
|
percent={jobMatch}
|
|
size="small"
|
|
strokeColor={getConfidenceColor(jobMatch)}
|
|
showInfo={false}
|
|
style={{ marginTop: 2 }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
}
|
|
>
|
|
<Space size="small">
|
|
{!parsed_actual_cost || !parsed_actual_price || parsed_actual_cost === 0 || parsed_actual_price === 0 ? (
|
|
<Tag color="red" style={{ margin: 0, cursor: "help", userSelect: "none" }}>
|
|
{t("bills.labels.ai.confidence.missing_data")}
|
|
</Tag>
|
|
) : null}
|
|
<Tag color={color} style={{ margin: 0, cursor: "help", userSelect: "none" }}>
|
|
{total.toFixed(0)}%
|
|
</Tag>
|
|
</Space>
|
|
</Tooltip>
|
|
);
|
|
};
|
|
|
|
export default ConfidenceDisplay;
|