amana / frontend /src /components /PolicyReference.tsx
Misbahuddin's picture
feat(ui): first-run welcome modal + Light/Auto/Dark theme
61cdd31
Raw
History Blame Contribute Delete
2.76 kB
import { useEffect, useRef } from "react";
import { X } from "lucide-react";
import type { PolicySection } from "../types";
// Side drawer (mirrors AuditHistory) that doubles as the acronym glossary + full policy reference.
// Cited rule IDs in the decision card link here via `focusRule`, which scrolls to and highlights
// the matching rule row with the gold "seal" accent.
export function PolicyReference({
sections,
focusRule,
onClose,
}: {
sections: PolicySection[];
focusRule: string | null;
onClose: () => void;
}) {
const rowRefs = useRef<Record<string, HTMLDivElement | null>>({});
useEffect(() => {
if (focusRule) rowRefs.current[focusRule]?.scrollIntoView({ block: "center" });
}, [focusRule, sections]);
return (
<aside className="w-80 shrink-0 border-l border-line bg-surface overflow-y-auto">
<div className="flex items-center justify-between px-4 py-3 border-b border-line sticky top-0 bg-surface">
<span className="text-xs font-semibold uppercase tracking-wide text-faint">
Policy reference
</span>
<button onClick={onClose} className="text-faint hover:text-heading">
<X size={16} />
</button>
</div>
{sections.length === 0 && (
<div className="p-4 text-sm text-faint">Policy not loaded.</div>
)}
<div className="divide-y divide-line">
{sections.map((sec) => (
<section key={sec.prefix} className="px-4 py-3">
<div className="flex items-center gap-2">
<span className="font-mono text-xs font-semibold bg-accent-soft text-accent-on rounded px-1.5 py-0.5">
{sec.prefix}
</span>
<span className="text-sm font-semibold text-heading">{sec.name}</span>
</div>
<p className="text-xs text-muted mt-1">{sec.description}</p>
<div className="mt-2 space-y-1.5">
{sec.rules.map((rule) => {
const focused = rule.rule_id === focusRule;
return (
<div
key={rule.rule_id}
ref={(el) => {
rowRefs.current[rule.rule_id] = el;
}}
className={`rounded-lg border px-3 py-2 text-sm transition ${
focused ? "border-gold ring-2 ring-gold/40 bg-gold-soft/50" : "border-line"
}`}
>
<span className="font-mono text-xs font-semibold text-accent">{rule.rule_id}</span>
<p className="text-body mt-0.5">{rule.text}</p>
</div>
);
})}
</div>
</section>
))}
</div>
</aside>
);
}