// AdminGate.jsx — password gate for any Administration change. // // Anywhere in the app, call: // window.askAdminPassword('Save settings', () => doSave()) // — if already unlocked this session, the callback runs immediately; // — otherwise a modal prompts for the admin password. On success the // callback runs and the unlock is cached in sessionStorage so the // admin doesn't get prompted on every click in the same session. // // Default password (prototype): 3873134 // In production this will validate against the server. const ADMIN_PASSWORD = '3873134'; function AdminGateMount() { const [request, setRequest] = React.useState(null); // { label, callback } const [pwd, setPwd] = React.useState(''); const [error, setError] = React.useState(false); const [shake, setShake] = React.useState(false); const inputRef = React.useRef(null); React.useEffect(() => { window.askAdminPassword = (label, callback) => { if (sessionStorage.getItem('admin-unlocked') === '1') { callback(); return; } setRequest({ label, callback }); setPwd(''); setError(false); }; }, []); React.useEffect(() => { if (request && inputRef.current) { setTimeout(() => inputRef.current.focus(), 50); } }, [request]); if (!request) return null; const submit = (e) => { if (e) e.preventDefault(); if (pwd === ADMIN_PASSWORD) { sessionStorage.setItem('admin-unlocked', '1'); const cb = request.callback; setRequest(null); setPwd(''); cb(); } else { setError(true); setShake(true); setTimeout(() => setShake(false), 400); } }; const cancel = () => { setRequest(null); setPwd(''); setError(false); }; return (
e.stopPropagation()} onSubmit={submit} style={{maxWidth: 420, animation: shake ? 'shake 280ms cubic-bezier(.36,.07,.19,.97)' : 'none'}} >
Administrator Password
{request.label}
Administration changes require re-authentication. Enter the admin password to continue. The unlock applies for the rest of this session.
{ setPwd(e.target.value); setError(false); }} style={{ width: '100%', height: 44, fontSize: 16, letterSpacing: '0.2em', borderColor: error ? '#dc2626' : 'var(--color-grey-300)', background: error ? '#fef2f2' : 'white', }} placeholder="••••••••" autoComplete="off" /> {error ? (
Incorrect password. Try again.
) : (
Default prototype password: 3873134
)}
); } Object.assign(window, { AdminGateMount });