81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import Link from "next/link";
|
|
import { redirect } from "next/navigation";
|
|
|
|
import { getAuthenticatedUser } from "@/lib/auth";
|
|
import { singleValue } from "@/lib/query";
|
|
import { isSetupComplete } from "@/lib/setup";
|
|
|
|
type LoginPageProps = {
|
|
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
|
|
};
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export default async function LoginPage({ searchParams }: LoginPageProps) {
|
|
if (!(await isSetupComplete())) {
|
|
redirect("/setup");
|
|
}
|
|
|
|
const user = await getAuthenticatedUser();
|
|
if (user) {
|
|
redirect("/dashboard");
|
|
}
|
|
|
|
const query = await searchParams;
|
|
const error = singleValue(query.error);
|
|
|
|
return (
|
|
<main className="page-shell flex flex-1 items-center py-12">
|
|
<section className="surface-card auth-panel rounded-3xl p-6 sm:p-9">
|
|
<h1 className="text-3xl font-semibold tracking-tight">Welcome back</h1>
|
|
<p className="mt-3 text-sm text-[color:var(--muted)]">
|
|
After logging in, manage your <b>YOUR</b> channel.
|
|
</p>
|
|
|
|
{error ? <div className="alert alert-error mt-5">{error}</div> : null}
|
|
|
|
<form action="/api/auth/login" method="post" className="mt-7 space-y-5">
|
|
<div className="field">
|
|
<label htmlFor="username" className="field-label">
|
|
Username
|
|
</label>
|
|
<input
|
|
id="username"
|
|
name="username"
|
|
required
|
|
minLength={3}
|
|
maxLength={32}
|
|
className="field-input"
|
|
/>
|
|
</div>
|
|
|
|
<div className="field">
|
|
<label htmlFor="password" className="field-label">
|
|
Password
|
|
</label>
|
|
<input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
required
|
|
minLength={8}
|
|
maxLength={128}
|
|
className="field-input"
|
|
/>
|
|
</div>
|
|
|
|
<button type="submit" className="btn btn-deep btn-block">
|
|
Sign in
|
|
</button>
|
|
</form>
|
|
|
|
<div className="mt-6 text-center text-sm text-[color:var(--muted)]">
|
|
<Link href="/" className="font-medium text-[color:var(--brand)] hover:underline">
|
|
Back to channel
|
|
</Link>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|