This commit is contained in:
+96
-103
@@ -7,112 +7,105 @@ import { Button, Card } from "@/components/ui";
|
||||
import { Logo } from "@/components/Logo";
|
||||
|
||||
export default function LoginPage() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [orgName, setOrgName] = useState("");
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [orgName, setOrgName] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const s = await auth.bootstrapStatus();
|
||||
if (s.needs_setup) {
|
||||
window.location.href = "/setup";
|
||||
return;
|
||||
}
|
||||
if (s.org_name) setOrgName(s.org_name);
|
||||
} catch {
|
||||
|
||||
}
|
||||
try {
|
||||
await auth.me();
|
||||
window.location.href = "/";
|
||||
} catch {
|
||||
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const s = await auth.bootstrapStatus();
|
||||
if (s.needs_setup) {
|
||||
window.location.href = "/setup";
|
||||
return;
|
||||
}
|
||||
if (s.org_name) setOrgName(s.org_name);
|
||||
} catch {}
|
||||
try {
|
||||
await auth.me();
|
||||
window.location.href = "/";
|
||||
} catch {}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
const { mutate: signIn, isPending, error } = useMutation({
|
||||
mutationFn: () => auth.login(email, password),
|
||||
onSuccess: () => {
|
||||
window.location.href = "/";
|
||||
},
|
||||
});
|
||||
const {
|
||||
mutate: signIn,
|
||||
isPending,
|
||||
error,
|
||||
} = useMutation({
|
||||
mutationFn: () => auth.login(email, password),
|
||||
onSuccess: () => {
|
||||
window.location.href = "/";
|
||||
},
|
||||
});
|
||||
|
||||
function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
signIn();
|
||||
}
|
||||
function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
signIn();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-background p-4">
|
||||
<div className="w-full max-w-sm">
|
||||
<div className="mb-8 flex flex-col items-center gap-3">
|
||||
<Logo className="h-11 w-auto text-text-primary" />
|
||||
<h1 className="text-xl font-semibold text-text-primary">
|
||||
{orgName ? `Sign in to ${orgName}` : "Sign in to Vantage"}
|
||||
</h1>
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-background p-4">
|
||||
<div className="w-full max-w-sm">
|
||||
<div className="mb-8 flex flex-col items-center gap-3">
|
||||
<Logo className="h-11 w-auto text-text-primary" />
|
||||
<h1 className="text-sxl font-semibold text-text-primary">Sign in to Vantage</h1>
|
||||
<h4 className="font-semibold text-text-secondary">Organisation: {orgName}</h4>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="email" className="mb-1.5 block text-sm font-medium text-text-secondary">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
required
|
||||
autoComplete="username"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="password" className="mb-1.5 block text-sm font-medium text-text-secondary">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
required
|
||||
autoComplete="current-password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && <div className="rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">{(error as Error).message}</div>}
|
||||
|
||||
<Button type="submit" variant="primary" loading={isPending} className="w-full justify-center">
|
||||
Sign In
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="my-5 flex items-center gap-3">
|
||||
<div className="h-px flex-1 bg-border" />
|
||||
<span className="text-xs uppercase tracking-wider text-text-tertiary">or</span>
|
||||
<div className="h-px flex-1 bg-border" />
|
||||
</div>
|
||||
|
||||
<a href="/auth/oidc/start" className="block">
|
||||
<Button type="button" variant="secondary" className="w-full justify-center">
|
||||
Sign in with your organization's SSO
|
||||
</Button>
|
||||
</a>
|
||||
<p className="mt-3 text-center text-xs text-text-tertiary">SSO must be enabled for this organization by an administrator.</p>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="email" className="mb-1.5 block text-sm font-medium text-text-secondary">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
required
|
||||
autoComplete="username"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="password" className="mb-1.5 block text-sm font-medium text-text-secondary">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
required
|
||||
autoComplete="current-password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary focus:border-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && (
|
||||
<div className="rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">
|
||||
{(error as Error).message}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button type="submit" variant="primary" loading={isPending} className="w-full justify-center">
|
||||
Sign In
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="my-5 flex items-center gap-3">
|
||||
<div className="h-px flex-1 bg-border" />
|
||||
<span className="text-xs uppercase tracking-wider text-text-tertiary">or</span>
|
||||
<div className="h-px flex-1 bg-border" />
|
||||
</div>
|
||||
|
||||
<a href="/auth/oidc/start" className="block">
|
||||
<Button type="button" variant="secondary" className="w-full justify-center">
|
||||
Sign in with your organization's SSO
|
||||
</Button>
|
||||
</a>
|
||||
<p className="mt-3 text-center text-xs text-text-tertiary">
|
||||
SSO must be enabled for this organization by an administrator.
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user