supplier-segmentation / src /components /PasswordGate.tsx
brestok's picture
fix date
09f152a
Raw History Blame Contribute Delete
2.12 kB
import React, { useState } from 'react';
import { Field, TextInput } from './controls';
/**
* Temporary front-end lock until the backend has real auth. The password ships
* in the bundle, so this only keeps casual visitors out — it protects nothing.
*/
const PASSWORD = process.env.REACT_APP_ACCESS_PASSWORD || 'Taric-Kiwi-7428';
const STORAGE_KEY = 'cargoflow.unlocked';
function readUnlocked(): boolean {
try {
return localStorage.getItem(STORAGE_KEY) === PASSWORD;
} catch {
return false;
}
}
export function PasswordGate({ children }: { children: React.ReactNode }) {
const [unlocked, setUnlocked] = useState(readUnlocked);
const [value, setValue] = useState('');
const [wrong, setWrong] = useState(false);
if (unlocked) return <>{children}</>;
const onSubmit = (event: React.FormEvent) => {
event.preventDefault();
if (value !== PASSWORD) {
setWrong(true);
return;
}
try {
localStorage.setItem(STORAGE_KEY, PASSWORD);
} catch {
// Private mode: stay unlocked for this tab only.
}
setUnlocked(true);
};
return (
<main className="mx-auto my-[52px] max-w-[420px] px-[22px] max-[560px]:my-[30px] max-[560px]:px-4">
<div className="mb-6 text-center text-2xl font-[750] tracking-[-1px]">
Cargo<span className="text-brand-accent">Flow</span>
</div>
<form className="cf-card" onSubmit={onSubmit}>
<Field label="Password" htmlFor="access-password">
<TextInput
id="access-password"
type="password"
autoFocus
autoComplete="current-password"
value={value}
aria-invalid={wrong}
className={wrong ? 'border-danger' : ''}
onChange={(event) => {
setValue(event.target.value);
setWrong(false);
}}
/>
{wrong ? <p className="mt-2 text-xs text-danger">Wrong password.</p> : null}
</Field>
<button type="submit" className="cf-primary" disabled={value === ''}>
Enter
</button>
</form>
</main>
);
}