import { useState } from "react"; import type { Change } from "../api/types"; import { WrapIcon } from "./icons"; function DiffView({ content, wrap }: { content: string; wrap: boolean }) { const lines = content.split("\n"); return (
{lines.map((line, i) => {
let cls = "";
if (line.startsWith("+++") || line.startsWith("---")) cls = "diff-meta";
else if (line.startsWith("@@")) cls = "diff-hunk";
else if (line.startsWith("+")) cls = "diff-add";
else if (line.startsWith("-")) cls = "diff-del";
else if (line.startsWith("diff ") || line.startsWith("index ")) cls = "diff-meta";
return (
{line || " "}
);
})}
);
}
function fmtValue(v: unknown): string {
if (v === null || v === undefined) return "∅";
if (typeof v === "object") return JSON.stringify(v);
return String(v);
}
function percentDelta(before: unknown, after: unknown): string | null {
const b = Number(before);
const a = Number(after);
if (!Number.isFinite(b) || !Number.isFinite(a) || b === 0) return null;
const pct = Math.round(((a - b) / Math.abs(b)) * 100);
if (pct === 0) return null;
return `${pct > 0 ? "+" : ""}${pct}%`;
}
function BeforeAfter({
before,
after,
contentType,
}: {
before: unknown;
after: unknown;
contentType?: string | null;
}) {
const delta = contentType === "integer" || contentType === "number" ? percentDelta(before, after) : null;
return (
{fmtValue(before)}
→
{fmtValue(after)}
{delta && {delta}}
{contentType && ({contentType})}
{change.path}
>
)}
{change.type === "config" && (
<>
{typeChip("config", "bg-accent/15 text-accent")}
{change.path}
>
)}
{change.type === "custom" && (
<>
{typeChip("custom", "bg-changes/15 text-changes")}
{change.label}
>
)}