"use client";
import NextLink from "next/link";
import { useActionState } from "react";
import { Link } from "@unlocalhosted/metalui";
import { loginAction, signupAction, twoFactorLoginAction } from "@/app/actions/auth";
import { TextField } from "./settings-fields";
import { Alert, Button } from "./ui";
export function LoginForm({ next }: { next: string }) {
const [state, action, pending] = useActionState(loginAction, undefined);
return (
<form action={action} className="flex flex-col gap-4">
<input type="hidden" name="next" value={next} />
{state?.error && <Alert>{state.error}</Alert>}
<TextField label="Username or email address" name="login" required autoFocus autoComplete="username" />
<TextField label="Password" name="password" type="password" required autoComplete="current-password" />
<Button variant="primary" className="mt-1 w-full" disabled={pending}>
{pending ? "Signing in…" : "Sign In"}
</Button>
</form>
);
}
export function TwoFactorLoginForm({ next }: { next: string }) {
const [state, action, pending] = useActionState(twoFactorLoginAction, undefined);
return (
<form action={action} className="flex flex-col gap-4">
<input type="hidden" name="next" value={next} />
{state?.error && <Alert>{state.error}</Alert>}
<TextField
label="Authentication code"
description="From your authenticator app. Lost your device? Enter one of your recovery codes."
name="code"
required
autoFocus
autoComplete="one-time-code"
autoCapitalize="none"
spellCheck={false}
maxLength={20}
mono
/>
<Button variant="primary" className="mt-1 w-full" disabled={pending}>
{pending ? "Verifying…" : "Verify"}
</Button>
</form>
);
}
export function SignupForm({ next }: { next: string }) {
const [state, action, pending] = useActionState(signupAction, undefined);
return (
<form action={action} className="flex flex-col gap-4">
<input type="hidden" name="next" value={next} />
{state?.error && <Alert>{state.error}</Alert>}
<TextField label="Email" name="email" type="email" required autoFocus autoComplete="email" />
<TextField
label="Password"
description="At least 8 characters."
name="password"
type="password"
required
minLength={8}
autoComplete="new-password"
/>
<TextField
label="Username"
description="Letters, numbers and hyphens. This becomes your URL."
name="username"
required
pattern="[A-Za-z0-9][A-Za-z0-9\-]{0,38}"
autoComplete="username"
/>
<TextField label="Name" optional name="name" autoComplete="name" />
<Button variant="primary" className="mt-1 w-full" disabled={pending}>
{pending ? "Creating account…" : "Create Account"}
</Button>
<p className="text-center type-body text-ink2">
Already have an account?{" "}
<Link render={<NextLink href={`/login${next !== "/" ? `?next=${encodeURIComponent(next)}` : ""}`} />}>Sign in</Link>
</p>
</form>
);
}