fix(i18n): localise admin system metric display

This commit is contained in:
cesnimda
2026-11-10 13:27:00 +01:00
parent af33e45542
commit 4c12f7691f
4 changed files with 26 additions and 13 deletions
+15 -13
View File
@@ -167,11 +167,12 @@ type SystemStatus = {
ai: AiServiceMetrics;
};
function formatBytes(bytes?: number | null) {
function formatBytes(bytes: number | null | undefined, locale: string) {
if (bytes == null) return "-";
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
if (bytes < 1024) return `${bytes.toLocaleString(locale)} B`;
const options = { minimumFractionDigits: 1, maximumFractionDigits: 1 };
if (bytes < 1024 * 1024) return `${(bytes / 1024).toLocaleString(locale, options)} KB`;
return `${(bytes / (1024 * 1024)).toLocaleString(locale, options)} MB`;
}
function displayMetadata(value?: string | null) {
@@ -182,8 +183,8 @@ function formatDate(value?: string | null, locale?: string) {
return value ? new Date(value).toLocaleString(locale) : "-";
}
function formatPercent(value?: number | null) {
return typeof value === "number" ? `${Math.round(value * 100)}%` : "-";
function formatPercent(value: number | null | undefined, locale: string) {
return typeof value === "number" ? value.toLocaleString(locale, { style: "percent", maximumFractionDigits: 0 }) : "-";
}
function parseBenchmarkIndex(indexJson?: string | null): CvBenchmarkIndex | null {
@@ -225,6 +226,7 @@ const actionErrorKeys: Record<ActionKind, TranslationKey> = { save: "adminSystem
export default function AdminSystemPage() {
const { language, t } = useI18n();
const locale = language === "nb" ? "nb-NO" : "en";
const [tab, setTab] = useState(0);
const [status, setStatus] = useState<SystemStatus | null>(null);
const [emailSettings, setEmailSettings] = useState<EditableEmailSettings | null>(null);
@@ -495,7 +497,7 @@ export default function AdminSystemPage() {
<DetailRow label={t("adminSystemDataRoot")} value={status?.storage.dataRoot || "-"} />
<DetailRow label={t("adminSystemDbPath")} value={status?.storage.dbPath || "-"} />
<DetailRow label={t("adminSystemDbFileExists")} value={status?.storage.dbExists ? t("yes") : t("noWord")} />
<DetailRow label={t("adminSystemDbSize")} value={formatBytes(status?.storage.dbSizeBytes)} />
<DetailRow label={t("adminSystemDbSize")} value={formatBytes(status?.storage.dbSizeBytes, locale)} />
<DetailRow label={t("companies")} value={status?.storage.companyCount ?? 0} />
<DetailRow label={t("adminSystemJobs")} value={status?.storage.jobCount ?? 0} />
<DetailRow label={t("adminSystemDeletedJobs")} value={status?.storage.deletedCount ?? 0} />
@@ -612,9 +614,9 @@ export default function AdminSystemPage() {
<>
<Box sx={{ mt: 2, display: "grid", gridTemplateColumns: { xs: "1fr 1fr", md: "repeat(5, 1fr)" }, gap: 1.25 }}>
<SummaryCard title={t("adminBenchmarkFiles")} value={String(benchmarkIndex.TotalFiles)} subtitle={t("adminBenchmarkCorpusInputs")} />
<SummaryCard title={t("adminBenchmarkCoverage")} value={formatPercent(benchmarkIndex.AverageCoverage)} subtitle={t("adminBenchmarkCoverageHelp")} tone={benchmarkTone(benchmarkIndex.AverageCoverage)} />
<SummaryCard title={t("adminBenchmarkConfidence")} value={formatPercent(benchmarkIndex.AverageConfidence)} subtitle={t("adminBenchmarkConfidenceHelp")} tone={benchmarkTone(benchmarkIndex.AverageConfidence)} />
<SummaryCard title={t("adminBenchmarkConsistency")} value={formatPercent(benchmarkIndex.AverageConsistency)} subtitle={t("adminBenchmarkConsistencyHelp")} tone={benchmarkTone(benchmarkIndex.AverageConsistency)} />
<SummaryCard title={t("adminBenchmarkCoverage")} value={formatPercent(benchmarkIndex.AverageCoverage, locale)} subtitle={t("adminBenchmarkCoverageHelp")} tone={benchmarkTone(benchmarkIndex.AverageCoverage)} />
<SummaryCard title={t("adminBenchmarkConfidence")} value={formatPercent(benchmarkIndex.AverageConfidence, locale)} subtitle={t("adminBenchmarkConfidenceHelp")} tone={benchmarkTone(benchmarkIndex.AverageConfidence)} />
<SummaryCard title={t("adminBenchmarkConsistency")} value={formatPercent(benchmarkIndex.AverageConsistency, locale)} subtitle={t("adminBenchmarkConsistencyHelp")} tone={benchmarkTone(benchmarkIndex.AverageConsistency)} />
<SummaryCard title={t("adminBenchmarkMissingApproved")} value={String(benchmarkIndex.MissingApprovedFixtures)} subtitle={t("adminBenchmarkNeedsReview")} tone={benchmarkIndex.MissingApprovedFixtures > 0 ? "warning" : "success"} />
</Box>
@@ -638,9 +640,9 @@ export default function AdminSystemPage() {
<Box key={entry.Slug} sx={{ p: 1.25, borderRadius: 2, backgroundColor: "background.default", border: "none", boxShadow: "0px 1px 2px 0px rgba(15,23,42,0.04), 0px 8px 24px -12px rgba(15,23,42,0.12)" }}>
<Typography variant="body2" sx={{ fontWeight: 800 }}>{entry.FileName}</Typography>
<Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75 }}>
<Chip size="small" label={t("adminBenchmarkCoverageValue", { value: formatPercent(entry.CoverageScore) })} color={benchmarkTone(entry.CoverageScore)} />
<Chip size="small" label={t("adminBenchmarkConfidenceValue", { value: formatPercent(entry.ConfidenceScore) })} color={benchmarkTone(entry.ConfidenceScore)} />
<Chip size="small" label={t("adminBenchmarkConsistencyValue", { value: formatPercent(entry.ConsistencyScore) })} color={benchmarkTone(entry.ConsistencyScore)} />
<Chip size="small" label={t("adminBenchmarkCoverageValue", { value: formatPercent(entry.CoverageScore, locale) })} color={benchmarkTone(entry.CoverageScore)} />
<Chip size="small" label={t("adminBenchmarkConfidenceValue", { value: formatPercent(entry.ConfidenceScore, locale) })} color={benchmarkTone(entry.ConfidenceScore)} />
<Chip size="small" label={t("adminBenchmarkConsistencyValue", { value: formatPercent(entry.ConsistencyScore, locale) })} color={benchmarkTone(entry.ConsistencyScore)} />
</Box>
<Typography variant="caption" sx={{ display: "block", color: "text.secondary", mt: 0.75 }}>{entry.DiffSummary || "-"}</Typography>
</Box>