Files
metube/src/app/login/page.tsx
T
2026-04-14 14:39:13 -05:00

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>
);
}