import { AlertTriangle, ArrowRight, CheckCircle, ChevronDown, ChevronRight, Clock, Scale, User, XCircle, } from 'lucide-react'; import { useState } from 'react'; const BG = { surface: 'var(--gi-bg-surface)', elevated: 'var(--gi-bg-raised)' }; const BORDER = { subtle: 'rgba(255,255,255,0.04)', muted: 'rgba(255,255,255,0.07)' }; const TEXT = { primary: 'rgba(255,255,255,0.88)', secondary: 'rgba(255,255,255,0.55)', tertiary: 'rgba(255,255,255,0.28)', muted: 'rgba(255,255,255,0.14)', }; export type PolicyOutcome = 'approved' | 'denied' | 'escalated' | 'pending'; export interface PolicyEvaluation { policyId: string; policyName: string; outcome: PolicyOutcome; reason: string; evaluatedAt: string; durationMs: number; } export interface ApprovalStep { role: string; approver: string; status: 'approved' | 'pending' | 'rejected'; timestamp?: string; comment?: string; } export interface EscalationPath { from: string; to: string; reason: string; triggeredAt: string; } export interface AuditEntry { timestamp: string; action: string; actor: string; detail?: string; } export interface PolicyGatePanelProps { finalOutcome: PolicyOutcome; evaluations: PolicyEvaluation[]; approvalChain: ApprovalStep[]; escalation?: EscalationPath; auditTrail: AuditEntry[]; compact?: boolean; } const OUTCOME_CFG: Record< PolicyOutcome, { color: string; bg: string; icon: typeof CheckCircle; label: string } > = { approved: { color: '#6b8f71', bg: 'rgba(107,143,113,0.1)', icon: CheckCircle, label: 'Approved' }, denied: { color: '#c45a4a', bg: 'rgba(196,90,74,0.1)', icon: XCircle, label: 'Denied' }, escalated: { color: '#ec4899', bg: 'rgba(236,72,153,0.1)', icon: AlertTriangle, label: 'Escalated', }, pending: { color: '#c8953c', bg: 'rgba(200,149,60,0.1)', icon: Clock, label: 'Pending' }, }; export function PolicyGatePanel({ finalOutcome, evaluations, approvalChain, escalation, auditTrail, compact, }: PolicyGatePanelProps) { const [showAudit, setShowAudit] = useState(false); const outcomeCfg = OUTCOME_CFG[finalOutcome]; const OutcomeIcon = outcomeCfg.icon; if (compact) { return (
Covenant Policy Gate
{outcomeCfg.label}
{evaluations.length} policies evaluated
{approvalChain.map((step, i) => { const stepCfg = step.status === 'approved' ? OUTCOME_CFG.approved : step.status === 'rejected' ? OUTCOME_CFG.denied : OUTCOME_CFG.pending; const StepIcon = stepCfg.icon; return (
); })}
); } return (
Covenant Policy Gate
{outcomeCfg.label.toUpperCase()}
Policy Evaluations
{evaluations.map((ev) => { const evCfg = OUTCOME_CFG[ev.outcome]; const EvIcon = evCfg.icon; return (
{ev.policyName}
{ev.reason}
{ev.durationMs}ms
); })}
Approval Chain
{approvalChain.map((step, i) => { const stepCfg = step.status === 'approved' ? OUTCOME_CFG.approved : step.status === 'rejected' ? OUTCOME_CFG.denied : OUTCOME_CFG.pending; const StepIcon = stepCfg.icon; return (
{i < approvalChain.length - 1 && (
)}
{step.role} — {step.approver} {step.timestamp && ( {step.timestamp} )}
{step.comment && (
"{step.comment}"
)} {step.status === 'pending' && i > 0 && approvalChain[i - 1]?.status === 'approved' && (
)}
); })}
{escalation && (
Escalation
{escalation.from}{' '} {' '} {escalation.to}
{escalation.reason} · {escalation.triggeredAt}
)} {showAudit && (
{auditTrail.map((entry, i) => (
{entry.timestamp} {entry.action} {entry.actor}
))}
synthetic · demo scenario No live systems connected — audit log is illustrative
)}
); }