Login: show demo users with email and password; one click signs in
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
709690b5ef
commit
265c16f88b
@ -47,6 +47,9 @@ export const TOUCH_POINTS: Array<{ label: string; keys: string[] }> = [
|
|||||||
{ label: 'Buyer / Account', keys: ['buyer_account'] },
|
{ label: 'Buyer / Account', keys: ['buyer_account'] },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** Demo only: every demo user shares this password, shown on the login page. */
|
||||||
|
export const DEMO_PASSWORD = 'Bunker@2026';
|
||||||
|
|
||||||
export const DEMO_USERS = [
|
export const DEMO_USERS = [
|
||||||
{ email: 'ops.mundra@bunker-demo.example', name: 'Rakesh Patel', role: 'Operations, Mundra' },
|
{ email: 'ops.mundra@bunker-demo.example', name: 'Rakesh Patel', role: 'Operations, Mundra' },
|
||||||
{ email: 'ops.hazira@bunker-demo.example', name: 'Sneha Iyer', role: 'Operations, Hazira' },
|
{ email: 'ops.hazira@bunker-demo.example', name: 'Sneha Iyer', role: 'Operations, Hazira' },
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Droplet } from 'lucide-react';
|
import { Droplet } from 'lucide-react';
|
||||||
import { useZino } from '../api/provider';
|
import { useZino } from '../api/provider';
|
||||||
import { DEMO_USERS, ORG_ID } from '../api/config';
|
import { DEMO_PASSWORD, DEMO_USERS, ORG_ID } from '../api/config';
|
||||||
import { ErrorNote } from '../components/ui';
|
import { ErrorNote } from '../components/ui';
|
||||||
|
|
||||||
export function Login() {
|
export function Login() {
|
||||||
@ -11,13 +11,14 @@ export function Login() {
|
|||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
const submit = async (e: React.FormEvent) => {
|
const signIn = async (em: string, pw: string) => {
|
||||||
e.preventDefault();
|
|
||||||
setBusy(true); setError(null);
|
setBusy(true); setError(null);
|
||||||
try { await login(email.trim(), password, ORG_ID); }
|
try { await login(em.trim(), pw, ORG_ID); }
|
||||||
catch (err) { setError((err as { message?: string })?.message ?? 'Sign-in failed'); }
|
catch (err) { setError((err as { message?: string })?.message ?? 'Sign-in failed'); }
|
||||||
finally { setBusy(false); }
|
finally { setBusy(false); }
|
||||||
};
|
};
|
||||||
|
const submit = (e: React.FormEvent) => { e.preventDefault(); void signIn(email, password); };
|
||||||
|
const pick = (em: string) => { setEmail(em); setPassword(DEMO_PASSWORD); void signIn(em, DEMO_PASSWORD); };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center px-4">
|
<div className="flex min-h-screen items-center justify-center px-4">
|
||||||
@ -42,12 +43,19 @@ export function Login() {
|
|||||||
<button className="btn btn-cta w-full justify-center" disabled={busy}>{busy ? 'Signing in…' : 'Sign in'}</button>
|
<button className="btn btn-cta w-full justify-center" disabled={busy}>{busy ? 'Signing in…' : 'Sign in'}</button>
|
||||||
</form>
|
</form>
|
||||||
<div className="card mt-4 p-4">
|
<div className="card mt-4 p-4">
|
||||||
<p className="mb-2 text-xs font-semibold uppercase tracking-wide text-muted">Demo users</p>
|
<div className="mb-2 flex items-baseline justify-between gap-2">
|
||||||
|
<p className="text-xs font-semibold uppercase tracking-wide text-muted">Demo users · click to sign in</p>
|
||||||
|
<p className="text-xs text-muted">Password <code className="rounded bg-surface-2 px-1.5 py-0.5 font-semibold text-ink">{DEMO_PASSWORD}</code></p>
|
||||||
|
</div>
|
||||||
<ul className="space-y-1">
|
<ul className="space-y-1">
|
||||||
{DEMO_USERS.map((u) => (
|
{DEMO_USERS.map((u) => (
|
||||||
<li key={u.email}>
|
<li key={u.email}>
|
||||||
<button type="button" onClick={() => setEmail(u.email)} className="flex w-full items-center justify-between rounded px-2 py-1 text-left text-sm hover:bg-surface-2">
|
<button type="button" disabled={busy} onClick={() => pick(u.email)} className="flex w-full items-center justify-between gap-3 rounded px-2 py-1.5 text-left text-sm hover:bg-surface-2 disabled:opacity-50">
|
||||||
<span className="font-semibold">{u.name}</span><span className="text-muted">{u.role}</span>
|
<span className="min-w-0">
|
||||||
|
<span className="block font-semibold">{u.name}</span>
|
||||||
|
<span className="block truncate text-xs text-muted">{u.email}</span>
|
||||||
|
</span>
|
||||||
|
<span className="shrink-0 text-muted">{u.role}</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user