← back to Grant
components/ViewModeToggle.tsx
74 lines
'use client';
import { Eye, Wrench } from 'lucide-react';
import { useAuth, type ViewMode } from './AuthProvider';
/**
* Live / Admin view toggle for the top header.
*
* - "Live" → the clean end-user view (admin/dev controls hidden).
* - "Admin" → reveals admin controls (AI discover, generate, seed, debug).
*
* Only rendered for admin-level accounts; the choice is persisted by
* AuthProvider in localStorage.
*/
export default function ViewModeToggle() {
const { isAdmin, viewMode, setViewMode } = useAuth();
if (!isAdmin) return null;
const options: { mode: ViewMode; label: string; Icon: typeof Eye }[] = [
{ mode: 'live', label: 'Live', Icon: Eye },
{ mode: 'admin', label: 'Admin', Icon: Wrench },
];
return (
<div
role="group"
aria-label="View mode"
title={
viewMode === 'admin'
? 'Admin view — admin controls visible. Switch to Live for the end-user view.'
: 'Live view — clean end-user view. Switch to Admin to reveal controls.'
}
style={{
display: 'inline-flex',
padding: 2,
borderRadius: 9999,
backgroundColor: 'var(--color-surface-el, rgba(255,255,255,0.04))',
border: '1px solid var(--color-border)',
}}
>
{options.map(({ mode, label, Icon }) => {
const active = viewMode === mode;
return (
<button
key={mode}
type="button"
onClick={() => setViewMode(mode)}
aria-pressed={active}
style={{
display: 'inline-flex',
alignItems: 'center',
gap: 5,
padding: '4px 10px',
borderRadius: 9999,
border: 'none',
cursor: 'pointer',
fontSize: '0.75rem',
fontWeight: 600,
lineHeight: 1,
transition: 'background-color 0.15s, color 0.15s',
backgroundColor: active ? 'var(--color-primary)' : 'transparent',
color: active ? '#fff' : 'var(--color-text-muted)',
}}
>
<Icon size={13} aria-hidden="true" />
{label}
</button>
);
})}
</div>
);
}