Login form example
This is a simple login form example. It has client side validation and displays an error message if the login fails.
Sign in
login-form.tsx
'use client';
import { RiLockPasswordLine, RiUser3Line } from '@remixicon/react';
import { redirect } from 'next/navigation';
import { Button } from '@/components/button/button';
import { Checkbox } from '@/components/forms/checkbox';
import { Form, FormRoot } from '@/components/forms/form';
import { FormServerError, FormStatus } from '@/components/forms/form-status';
import { useForm } from '@/components/forms/hooks/use-form';
import { TextField } from '@/components/forms/text-field';
import { validators } from '@/components/forms/util';
import { loginAction } from './action';
import { LoginFormValues } from './types';
export const LoginForm = () => {
const form = useForm<LoginFormValues>({
onSubmit: async ({ values, reset }) => {
await loginAction(values);
redirect('/dashboard');
},
});
return (
<FormRoot context={form}>
<h2 id="login-form-heading" className="mb-4 text-3xl font-bold">
Sign in
</h2>
<FormStatus>
{form.serverError && (
<FormServerError
title="Something went wrong!"
errorMessage={form.serverError}
/>
)}
</FormStatus>
<Form
className="flex flex-col gap-4 rounded-lg border-2 border-gray-200 p-4 shadow-xl"
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"
disabled={form.isPending}
loading={form.isPending}
>
Sign in
</Button>
</Form>
</FormRoot>
);
};