"use client";
import { ThemeProvider as BjorkDemoThemeProvider } from "next-themes";
import { useState } from "react";
import { ApprovalGate, SAMPLE_APPROVAL_REQUESTS, type ApprovalDecision } from "@/components/ui/bjork-approval-gate";
const RISKS = ["high", "medium", "low"] as const;
type Risk = (typeof RISKS)[number];
const DEFAULT_RISK: Risk = "high";
const DEFAULT_TIMEOUT = true;
function Demo({
risk,
timeout,
run,
last,
onDecision,
}: {
risk: Risk;
timeout: boolean;
run: number;
last: ApprovalDecision | null;
onDecision: (decision: ApprovalDecision) => void;
}) {
const isPreview = false;
const request = SAMPLE_APPROVAL_REQUESTS.find((r) => r.risk === risk) ?? SAMPLE_APPROVAL_REQUESTS[0];
if (isPreview) {
return (
<div className="w-[min(540px,calc(100vw-56px))]">
<ApprovalGate
request={SAMPLE_APPROVAL_REQUESTS[0]}
requireHold
timeoutMs={30_000}
pose={{ hold: 0.58, remaining: 0.64 }}
/>
</div>
);
}
return (
<div className="flex w-[min(540px,calc(100vw-56px))] flex-col items-stretch gap-6">
<ApprovalGate
key={`${run}-${risk}-${timeout}`}
request={request}
requireHold
timeoutMs={timeout ? 30_000 : undefined}
onDecision={onDecision}
/>
<p className="min-h-5 text-center font-mono text-[11px] text-[color:var(--bjork-text-faint)]">
{last
? `onDecision → ${last.status}${last.reason ? ` · "${last.reason}"` : ""}${last.alwaysAllow ? " · always allow" : ""}`
: "High risk asks you to hold Approve. Hover the card to pause the countdown."}
</p>
</div>
);
}
function SourceDemo(){
const [risk, setRisk] = useState<Risk>(DEFAULT_RISK);
const [timeout, setTimeoutOn] = useState(DEFAULT_TIMEOUT);
const [run, setRun] = useState(0);
const [last, setLast] = useState<ApprovalDecision | null>(null);
const reset = () => {
setRisk(DEFAULT_RISK);
setTimeoutOn(DEFAULT_TIMEOUT);
setLast(null);
setRun((r) => r + 1);
};
return <>
<Demo risk={risk} timeout={timeout} run={run} last={last} onDecision={setLast} />
</>;
}
export default function BjorkRegistryPreview(){return <BjorkDemoThemeProvider attribute="class" defaultTheme="dark" enableSystem={false} storageKey="bjork-review-demo-theme"><div data-component-demo className="dark flex min-h-screen w-full items-center justify-center bg-[var(--bjork-bg)] p-8 text-[var(--bjork-text)]"><div className="w-full max-w-[850px]"><SourceDemo/></div></div></BjorkDemoThemeProvider>}