Refactor to use ai/rsc (#253)
This commit is contained in:
parent
69ca8fcc22
commit
e85ba803dd
66 changed files with 2799 additions and 740 deletions
93
components/login-form.tsx
Normal file
93
components/login-form.tsx
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
'use client'
|
||||
|
||||
import { useFormState, useFormStatus } from 'react-dom'
|
||||
import { authenticate } from '@/app/login/actions'
|
||||
import Link from 'next/link'
|
||||
import { useEffect } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { IconSpinner } from './ui/icons'
|
||||
|
||||
export default function LoginForm() {
|
||||
const [result, dispatch] = useFormState(authenticate, undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (result) {
|
||||
if (result.type === 'error') {
|
||||
toast.error(result.message)
|
||||
} else {
|
||||
toast.success(result.message)
|
||||
}
|
||||
}
|
||||
}, [result])
|
||||
|
||||
return (
|
||||
<form
|
||||
action={dispatch}
|
||||
className="flex flex-col items-center gap-4 space-y-3"
|
||||
>
|
||||
<div className="w-full flex-1 rounded-lg border bg-white px-6 pb-4 pt-8 shadow-md dark:bg-zinc-950 md:w-96">
|
||||
<h1 className="mb-3 text-2xl font-bold">Please log in to continue.</h1>
|
||||
<div className="w-full">
|
||||
<div>
|
||||
<label
|
||||
className="mb-3 mt-5 block text-xs font-medium text-zinc-400"
|
||||
htmlFor="email"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
className="peer block w-full rounded-md border bg-zinc-50 px-2 py-[9px] text-sm outline-none placeholder:text-zinc-500 dark:border-zinc-800 dark:bg-zinc-950"
|
||||
id="email"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Enter your email address"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<label
|
||||
className="mb-3 mt-5 block text-xs font-medium text-zinc-400"
|
||||
htmlFor="password"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
className="peer block w-full rounded-md border bg-zinc-50 px-2 py-[9px] text-sm outline-none placeholder:text-zinc-500 dark:border-zinc-800 dark:bg-zinc-950"
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Enter password"
|
||||
required
|
||||
minLength={6}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LoginButton />
|
||||
</div>
|
||||
|
||||
<Link
|
||||
href="/signup"
|
||||
className="flex flex-row gap-1 text-sm text-zinc-400"
|
||||
>
|
||||
No account yet? <div className="font-semibold underline">Sign up</div>
|
||||
</Link>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
function LoginButton() {
|
||||
const { pending } = useFormStatus()
|
||||
|
||||
return (
|
||||
<button
|
||||
className="flex flex-row justify-center items-center my-4 h-10 w-full rounded-md bg-zinc-900 p-2 text-sm font-semibold text-zinc-100 hover:bg-zinc-800 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200"
|
||||
aria-disabled={pending}
|
||||
>
|
||||
{pending ? <IconSpinner /> : 'Log in'}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue