This commit is contained in:
2026-03-18 22:51:17 -05:00
parent dc07bfc8e0
commit 17b73a4597
8 changed files with 128 additions and 122 deletions
@@ -100,7 +100,7 @@ function buildFieldChanges(left: ComparisonField[], right: ComparisonField[]): A
function ComparisonCard({ label, document }: { label: string; document: ComparisonDocument }) {
return (
<article className="rounded-[18px] border border-line/70 bg-page/60 p-4">
<article className="rounded-[18px] border border-line/70 bg-page/60 px-3 py-3">
<div className="flex flex-wrap items-start justify-between gap-3">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">{label}</p>
@@ -111,7 +111,7 @@ function ComparisonCard({ label, document }: { label: string; document: Comparis
{document.status}
</span>
</div>
<dl className="mt-4 grid gap-3 sm:grid-cols-2">
<dl className="mt-3 grid gap-2 sm:grid-cols-2">
{document.metaFields.map((field) => (
<div key={`${label}-${field.label}`}>
<dt className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{field.label}</dt>
@@ -119,15 +119,15 @@ function ComparisonCard({ label, document }: { label: string; document: Comparis
</div>
))}
</dl>
<div className="mt-4 grid gap-3 sm:grid-cols-2">
<div className="mt-3 grid gap-2 sm:grid-cols-2">
{document.totalFields.map((field) => (
<div key={`${label}-total-${field.label}`} className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div key={`${label}-total-${field.label}`} className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{field.label}</div>
<div className="mt-1 text-sm font-semibold text-text">{field.value}</div>
</div>
))}
</div>
<div className="mt-4">
<div className="mt-3">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">Notes</div>
<p className="mt-2 whitespace-pre-line text-sm leading-6 text-text">{document.notes || "No notes recorded."}</p>
</div>
@@ -164,11 +164,11 @@ export function DocumentRevisionComparison({
const totalChanges = buildFieldChanges(leftDocument.totalFields, rightDocument.totalFields);
return (
<section className="rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5">
<section className="surface-panel">
<div className="flex flex-col gap-3 xl:flex-row xl:items-start xl:justify-between">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">{title}</p>
<p className="mt-2 text-sm text-muted">{description}</p>
<p className="section-kicker">{title}</p>
<p className="mt-1 text-sm text-muted">{description}</p>
</div>
<div className="grid gap-3 sm:grid-cols-2">
<label className="block min-w-[220px]">
@@ -202,19 +202,19 @@ export function DocumentRevisionComparison({
</label>
</div>
</div>
<div className="mt-5 grid gap-3 xl:grid-cols-2">
<div className="mt-3 grid gap-3 xl:grid-cols-2">
<ComparisonCard label="Baseline" document={leftDocument} />
<ComparisonCard label="Compare To" document={rightDocument} />
</div>
<div className="mt-5 grid gap-3 xl:grid-cols-2">
<article className="rounded-[18px] border border-line/70 bg-page/60 p-4">
<div className="mt-3 grid gap-3 xl:grid-cols-2">
<article className="rounded-[18px] border border-line/70 bg-page/60 px-3 py-3">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Field Changes</p>
{metaChanges.length === 0 && totalChanges.length === 0 ? (
<div className="mt-4 text-sm text-muted">No header or total changes between the selected revisions.</div>
<div className="mt-3 text-sm text-muted">No header or total changes.</div>
) : (
<div className="mt-4 space-y-3">
<div className="mt-3 space-y-2">
{[...metaChanges, ...totalChanges].map((change) => (
<div key={change.label} className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div key={change.label} className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{change.label}</div>
<div className="mt-2 text-sm text-text">
{change.leftValue} {"->"} {change.rightValue}
@@ -224,28 +224,28 @@ export function DocumentRevisionComparison({
</div>
)}
</article>
<article className="rounded-[18px] border border-line/70 bg-page/60 p-4">
<article className="rounded-[18px] border border-line/70 bg-page/60 px-3 py-3">
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">Line Changes</p>
<div className="mt-4 grid gap-3 sm:grid-cols-3">
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div className="mt-3 grid gap-2 sm:grid-cols-3">
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">Added</div>
<div className="mt-1 text-base font-bold text-text">{diffRows.filter((row) => row.status === "ADDED").length}</div>
</div>
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">Removed</div>
<div className="mt-1 text-base font-bold text-text">{diffRows.filter((row) => row.status === "REMOVED").length}</div>
</div>
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">Changed</div>
<div className="mt-1 text-base font-bold text-text">{diffRows.filter((row) => row.status === "CHANGED").length}</div>
</div>
</div>
{diffRows.length === 0 ? (
<div className="mt-4 text-sm text-muted">No line-level changes between the selected revisions.</div>
<div className="mt-3 text-sm text-muted">No line-level changes.</div>
) : (
<div className="mt-4 space-y-3">
<div className="mt-3 space-y-2">
{diffRows.map((row) => (
<div key={row.key} className="rounded-[16px] border border-line/70 bg-surface/80 px-3 py-3">
<div key={row.key} className="rounded-[16px] border border-line/70 bg-surface/80 px-2 py-2">
<div className="flex flex-wrap items-center justify-between gap-3">
<div className="text-sm font-semibold text-text">{row.right?.title ?? row.left?.title}</div>
<span className="text-xs font-semibold uppercase tracking-[0.16em] text-muted">{row.status}</span>
@@ -133,12 +133,12 @@ export function FileAttachmentsPanel({
}
return (
<article className="min-w-0 rounded-[20px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5">
<article className="surface-panel min-w-0">
<div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">{eyebrow}</p>
<h4 className="mt-2 text-lg font-bold text-text">{title}</h4>
<p className="mt-2 text-sm text-muted">{description}</p>
<p className="section-kicker">{eyebrow}</p>
<h4 className="text-lg font-bold text-text">{title}</h4>
<p className="mt-1 text-sm text-muted">{description}</p>
</div>
{canWriteFiles ? (
<label className="inline-flex cursor-pointer items-center justify-center rounded-2xl bg-brand px-2 py-2 text-sm font-semibold text-white">
@@ -147,17 +147,17 @@ export function FileAttachmentsPanel({
</label>
) : null}
</div>
<div className="mt-5 rounded-2xl border border-line/70 bg-page/70 px-2 py-2 text-sm text-muted">{status}</div>
<div className="mt-3 rounded-2xl border border-line/70 bg-page/70 px-2 py-2 text-sm text-muted">{status}</div>
{!canReadFiles ? (
<div className="mt-5 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-4 py-8 text-center text-sm text-muted">
<div className="mt-3 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-3 py-5 text-center text-sm text-muted">
You do not have permission to view file attachments.
</div>
) : attachments.length === 0 ? (
<div className="mt-5 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-4 py-8 text-center text-sm text-muted">
<div className="mt-3 rounded-[18px] border border-dashed border-line/70 bg-page/60 px-3 py-5 text-center text-sm text-muted">
{emptyMessage}
</div>
) : (
<div className="mt-5 space-y-3">
<div className="mt-3 space-y-2">
{attachments.map((attachment) => (
<div
key={attachment.id}
@@ -166,7 +166,7 @@ export function FileAttachmentsPanel({
<div className="min-w-0">
<p className="truncate text-sm font-semibold text-text">{attachment.originalName}</p>
<p className="mt-1 text-xs text-muted">
{attachment.mimeType} · {formatFileSize(attachment.sizeBytes)} · {new Date(attachment.createdAt).toLocaleString()}
{attachment.mimeType} - {formatFileSize(attachment.sizeBytes)} - {new Date(attachment.createdAt).toLocaleString()}
</p>
</div>
<div className="flex shrink-0 gap-3">