public booking flow: /book browse → magic-link signup → confirm

This commit is contained in:
2026-05-02 08:46:12 -04:00
parent 415813470a
commit 4c70fe2f39
12 changed files with 1116 additions and 22 deletions

View File

@@ -2,16 +2,24 @@ import { signIn } from "@/auth";
export const metadata = { title: "Sign in — TouchBase" };
type SearchParams = Promise<{ callbackUrl?: string }>;
async function requestMagicLink(formData: FormData) {
"use server";
const email = String(formData.get("email") ?? "").trim();
const callbackUrl = String(formData.get("callbackUrl") ?? "/admin");
if (!email) return;
// signIn with redirectTo handles the redirect to /login/check-email itself
// (configured as `pages.verifyRequest` in src/auth.ts).
await signIn("nodemailer", { email, redirectTo: "/admin" });
await signIn("nodemailer", { email, redirectTo: callbackUrl });
}
export default function LoginPage() {
export default async function LoginPage({
searchParams,
}: {
searchParams: SearchParams;
}) {
const params = await searchParams;
const callbackUrl = params.callbackUrl ?? "/admin";
return (
<main className="mx-auto flex min-h-full max-w-sm flex-col justify-center gap-6 p-8">
<h1 className="text-2xl font-semibold tracking-tight">Sign in</h1>
@@ -19,6 +27,7 @@ export default function LoginPage() {
Enter your email and we&apos;ll send you a sign-in link.
</p>
<form action={requestMagicLink} className="flex flex-col gap-3">
<input type="hidden" name="callbackUrl" value={callbackUrl} />
<label htmlFor="email" className="text-sm font-medium">
Email
</label>
@@ -28,7 +37,7 @@ export default function LoginPage() {
type="email"
autoComplete="email"
required
placeholder="you@touchbase.local"
placeholder="you@example.com"
className="rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm shadow-sm placeholder:text-zinc-400 focus:border-zinc-500 focus:outline-none focus:ring-1 focus:ring-zinc-500 dark:border-zinc-700 dark:bg-zinc-900"
/>
<button