Refactor to use ai/rsc (#253)
This commit is contained in:
parent
69ca8fcc22
commit
e85ba803dd
66 changed files with 2799 additions and 740 deletions
94
components/signup-form.tsx
Normal file
94
components/signup-form.tsx
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
'use client'
|
||||
|
||||
import { useFormState, useFormStatus } from 'react-dom'
|
||||
import { signup } from '@/app/signup/actions'
|
||||
import Link from 'next/link'
|
||||
import { useEffect } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { IconSpinner } from './ui/icons'
|
||||
import { useRouter } from 'next/navigation'
|
||||
|
||||
export default function SignupForm() {
|
||||
const router = useRouter()
|
||||
const [result, dispatch] = useFormState(signup, undefined)
|
||||
|
||||
useEffect(() => {
|
||||
if (result) {
|
||||
if (result.type === 'error') {
|
||||
toast.error(result.message)
|
||||
} else {
|
||||
router.refresh()
|
||||
toast.success(result.message)
|
||||
}
|
||||
}
|
||||
}, [result, router])
|
||||
|
||||
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">Sign up for an account!</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="/login" className="flex flex-row gap-1 text-sm text-zinc-400">
|
||||
Already have an account?
|
||||
<div className="font-semibold underline">Log in</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 /> : 'Create account'}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue