amana / frontend /src /components /Header.tsx
Misbahuddin's picture
fix: hide inert provider toggle on public demo; report real model name in telemetry
d641c27
Raw
History Blame Contribute Delete
4.34 kB
import { BookOpen, HelpCircle, History, Monitor, Moon, Sun } from "lucide-react";
import type { Stats } from "../types";
import type { Theme } from "../App";
const THEMES: { key: Theme; Icon: typeof Sun; title: string }[] = [
{ key: "light", Icon: Sun, title: "Light" },
{ key: "auto", Icon: Monitor, title: "Auto (match system)" },
{ key: "dark", Icon: Moon, title: "Dark" },
];
export function Header({
stats,
provider,
onProvider,
onTogglePolicy,
onToggleHistory,
historyCount,
onHelp,
theme,
onTheme,
}: {
stats: Stats | null;
provider: string;
onProvider: (p: string) => void;
onTogglePolicy: () => void;
onToggleHistory: () => void;
historyCount: number;
onHelp: () => void;
theme: Theme;
onTheme: (t: Theme) => void;
}) {
return (
<header className="bg-surface border-b border-line px-6 py-3 flex items-center gap-4">
<div className="flex items-center gap-3">
{/* The seal: a gold-ringed pine monogram — "a trust held in safekeeping". */}
<div className="grid place-items-center w-9 h-9 rounded-full bg-pine text-gold font-display font-semibold text-lg seal-ring shrink-0">
ا
</div>
<div>
<div className="font-display font-semibold text-heading text-xl leading-none">Amana</div>
<div className="text-xs text-muted leading-tight mt-0.5">
Campaign triage — the AI recommends, you decide.
</div>
</div>
</div>
<div className="flex-1" />
{stats && (
<div className="hidden md:flex items-center gap-4 text-xs text-muted">
<span><b className="text-heading">{stats.policy_rules}</b> rules</span>
<span><b className="text-heading">{stats.precedent_cases}</b> precedents</span>
</div>
)}
{/* Provider toggle — hidden on the public demo, where the provider is forced to Anthropic and
the toggle would be inert/misleading. It stays for local dev (Anthropic vs free Ollama). */}
{!stats?.public_demo && (
<div
className="flex items-center rounded-lg border border-line p-0.5 bg-panel"
title="Anthropic = Claude (demo). Ollama = free local model — watch the policy gate hold it to the same floor."
>
{["anthropic", "ollama"].map((p) => (
<button
key={p}
onClick={() => onProvider(p)}
className={`px-3 py-1 text-xs rounded-md capitalize transition ${
provider === p ? "bg-surface shadow-sm text-accent font-semibold" : "text-muted hover:text-heading"
}`}
>
{p}
</button>
))}
</div>
)}
<button
onClick={onHelp}
className="flex items-center gap-1.5 text-sm text-body hover:text-accent transition"
title="What is this? How the triage console works."
>
<HelpCircle size={16} /> <span className="hidden lg:inline">How it works</span>
</button>
<button
onClick={onTogglePolicy}
className="flex items-center gap-1.5 text-sm text-body hover:text-accent transition"
title="Browse the policy and what the rule-ID prefixes (ELIG, PROH, COMP, CONT, DEC) mean."
>
<BookOpen size={16} /> <span className="hidden lg:inline">Policy</span>
</button>
<button
onClick={onToggleHistory}
className="flex items-center gap-1.5 text-sm text-body hover:text-accent transition"
>
<History size={16} /> <span className="hidden lg:inline">History</span>{" "}
<span className="text-xs text-faint">({historyCount})</span>
</button>
{/* Theme: Light / Auto / Dark */}
<div className="flex items-center rounded-lg border border-line p-0.5 bg-panel">
{THEMES.map(({ key, Icon, title }) => (
<button
key={key}
onClick={() => onTheme(key)}
title={title}
aria-label={title}
aria-pressed={theme === key}
className={`grid place-items-center w-7 h-7 rounded-md transition ${
theme === key ? "bg-surface shadow-sm text-accent" : "text-muted hover:text-heading"
}`}
>
<Icon size={14} />
</button>
))}
</div>
</header>
);
}