Login form example
This is a simple login form:
- If you enter an invalid email address or password you will see inline client-side validation errors.
- If you enter an email address that doesn't end with @functn.com you will see an error message from the server.
Sign in
login-form.tsx
'use client';
import { RiLockPasswordLine, RiUser3Line } from '@remixicon/react';
import { redirect } from 'next/navigation';
import { Button } from '@/ui/components/button/button';
import { Checkbox } from '@/ui/components/forms/checkbox';
import { Form } from '@/ui/components/forms/form';
import { useForm } from '@/ui/components/forms/hooks/use-form';
import { TextField } from '@/ui/components/forms/text-field';
import {
FormErrors,
ServerError,
validators,
} from '@/ui/components/forms/validation';
import { loginAction } from './action';
export const LoginForm = () => {
const form = useForm<{
email: string;
password: string;
rememberMe: string;
}>({
onSubmit: async ({ values }) => {
await loginAction(values);
redirect('/dashboard');
},
});
return (
<FormRoot
context={form}
className="max-w-lg rounded-lg border-2 border-gray-200 p-4 shadow-xl"
>
<h2 id="login-form-heading" className="text-3xl font-bold">
Sign in
</h2>
<FormErrors>
<ServerError title="Could not sign in" />
</FormErrors>
<Form
className="flex flex-col gap-4"
aria-labelledby="login-form-heading"
>
<TextField
id="email"
name="email"
label="Email"
type="email"
autoComplete="email"
icon={<RiUser3Line size={18} />}
validate={(value) => {
if (!value) {
return 'Please enter your email address';
}
if (!validators.email(value)) {
return 'Please enter a valid email address';
}
}}
isRequired
/>
<TextField
id="password"
name="password"
label="Password"
type="password"
icon={<RiLockPasswordLine size={18} />}
autoComplete="current-password"
validate={(value) => {
if (!value) {
return 'Please enter your password';
}
}}
isRequired
/>
<Checkbox
id="rememberMe"
name="rememberMe"
label="Remember me for 30 days"
/>
<Button type="submit" loading={form.isPending}>
Sign in
</Button>
</Form>
</FormRoot>
);
};