Last active
April 17, 2024 13:02
-
-
Save DevanB/b75f27154e345498699441664c7d3d3a to your computer and use it in GitHub Desktop.
Zod + RW Form issues
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect } from 'react' | |
import { zodResolver } from '@hookform/resolvers/zod' | |
import { z } from 'zod' | |
import { | |
EmailField, | |
FieldError, | |
Form, | |
Label, | |
Submit, | |
SubmitHandler, | |
useForm, | |
} from '@redwoodjs/forms' | |
import { navigate, routes } from '@redwoodjs/router' | |
import { Metadata } from '@redwoodjs/web' | |
import { toast, Toaster } from '@redwoodjs/web/toast' | |
import { useAuth } from 'src/auth' | |
const ForgotPasswordSchema = z.object({ | |
email: z | |
.string({ required_error: 'Please enter an email address' }) | |
.email({ message: 'Please enter a valid email address' }), | |
}) | |
type ForgotPasswordType = z.infer<typeof ForgotPasswordSchema> | |
const ForgotPasswordPage = () => { | |
const { isAuthenticated, forgotPassword } = useAuth() | |
const formMethods = useForm<ForgotPasswordType>({ | |
mode: 'onBlur', | |
resolver: zodResolver(ForgotPasswordSchema), | |
}) | |
useEffect(() => { | |
if (isAuthenticated) navigate(routes.dashboard()) | |
}, [isAuthenticated]) | |
const onSubmit: SubmitHandler<ForgotPasswordType> = async (data) => { | |
const response = await forgotPassword(data.email) | |
if (response.error) { | |
toast.error(response.error) | |
} else { | |
// The function `forgotPassword.handler` in api/src/functions/auth.js has | |
// been invoked, let the user know how to get the link to reset their | |
// password (sent in email, perhaps?) | |
toast.success( | |
'A link to reset your password was sent to ' + response.email | |
) | |
navigate(routes.logIn()) | |
} | |
} | |
return ( | |
<> | |
<Metadata title="Forgot Password" /> | |
<Toaster toastOptions={{ className: 'rw-toast', duration: 6000 }} /> | |
<div className="flex min-h-full flex-1 flex-col justify-center bg-gray-50 py-12 sm:px-6 lg:px-8"> | |
<div className="sm:mx-auto sm:w-full sm:max-w-md"> | |
<h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"> | |
Forgot your password? | |
</h2> | |
</div> | |
<div className="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px]"> | |
<div className="border bg-white px-6 py-12 sm:rounded-lg sm:px-12"> | |
<Form | |
className="space-y-6" | |
formMethods={formMethods} | |
onSubmit={onSubmit} | |
> | |
{/* Email */} | |
<div> | |
<Label | |
name="email" | |
className="block text-sm font-medium leading-6 text-gray-900" | |
errorClassName="block text-sm font-medium leading-6 text-red-700" | |
> | |
Email address | |
</Label> | |
<div className="mt-2"> | |
<EmailField | |
name="email" | |
autoComplete="email" | |
autoCapitalize="off" | |
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-700 sm:text-sm sm:leading-6" | |
errorClassName="block w-full rounded-md border-0 py-1.5 text-red-900 shadow-sm ring-1 ring-inset ring-red-300 transition duration-150 ease-in-out placeholder:text-red-300 focus:ring-2 focus:ring-inset focus:ring-red-500 sm:text-sm sm:leading-6" | |
/> | |
<FieldError name="email" className="text-sm text-red-600" /> | |
</div> | |
</div> | |
<div> | |
<Submit className="flex w-full justify-center rounded-md bg-gray-900 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm transition duration-150 ease-in-out hover:bg-gray-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700"> | |
Continue | |
</Submit> | |
</div> | |
</Form> | |
</div> | |
</div> | |
</div> | |
</> | |
) | |
} | |
export default ForgotPasswordPage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect } from 'react' | |
import { zodResolver } from '@hookform/resolvers/zod' | |
import { z } from 'zod' | |
import { | |
EmailField, | |
FieldError, | |
Form, | |
Label, | |
PasswordField, | |
Submit, | |
SubmitHandler, | |
useForm, | |
} from '@redwoodjs/forms' | |
import { navigate, routes } from '@redwoodjs/router' | |
import { Metadata } from '@redwoodjs/web' | |
import { toast, Toaster } from '@redwoodjs/web/toast' | |
import { useAuth } from 'src/auth' | |
const LogInSchema = z.object({ | |
email: z | |
.string({ required_error: 'Please enter an email address' }) | |
.email({ message: 'Please enter a valid email address' }), | |
password: z.string({ required_error: 'Please enter a password' }), | |
}) | |
type LogInType = z.infer<typeof LogInSchema> | |
const LogInPage = () => { | |
const { isAuthenticated, logIn } = useAuth() | |
const formMethods = useForm<LogInType>({ | |
mode: 'onBlur', | |
resolver: zodResolver(LogInSchema), | |
}) | |
useEffect(() => { | |
if (isAuthenticated) navigate(routes.dashboard()) | |
}, [isAuthenticated]) | |
const onSubmit: SubmitHandler<LogInType> = async (data) => { | |
const response = await logIn({ | |
username: data.email, | |
password: data.password, | |
}) | |
if (response.message) { | |
// auth details good, but user not logged in | |
toast(response.message) | |
} else if (response.error) { | |
// error while authenticating | |
toast.error(response.error) | |
} else { | |
// user logged in | |
toast.success('Welcome back!') | |
} | |
} | |
return ( | |
<> | |
<Metadata title="Log In" /> | |
<Toaster toastOptions={{ className: 'rw-toast', duration: 6000 }} /> | |
<div className="flex min-h-full flex-1 flex-col justify-center bg-gray-50 py-12 sm:px-6 lg:px-8"> | |
<div className="sm:mx-auto sm:w-full sm:max-w-md"> | |
<h2 className="mt-6 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900"> | |
Log in to your account | |
</h2> | |
</div> | |
<div className="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px]"> | |
<div className="border bg-white px-6 py-12 sm:rounded-lg sm:px-12"> | |
<Form | |
className="space-y-6" | |
formMethods={formMethods} | |
onSubmit={onSubmit} | |
> | |
{/* Email */} | |
<div> | |
<Label | |
name="email" | |
className="block text-sm font-medium leading-6 text-gray-900" | |
errorClassName="block text-sm font-medium leading-6 text-red-700" | |
> | |
Email address | |
</Label> | |
<div className="mt-2"> | |
<EmailField | |
name="email" | |
autoComplete="email" | |
autoCapitalize="off" | |
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-700 sm:text-sm sm:leading-6" | |
errorClassName="block w-full rounded-md border-0 py-1.5 text-red-900 shadow-sm ring-1 ring-inset ring-red-300 transition duration-150 ease-in-out placeholder:text-red-300 focus:ring-2 focus:ring-inset focus:ring-red-500 sm:text-sm sm:leading-6" | |
/> | |
<FieldError name="email" className="text-sm text-red-600" /> | |
</div> | |
</div> | |
{/* Password */} | |
<div> | |
<Label | |
name="password" | |
className="block text-sm font-medium leading-6 text-gray-900" | |
errorClassName="block text-sm font-medium leading-6 text-red-700" | |
> | |
Password | |
</Label> | |
<div className="mt-2"> | |
<PasswordField | |
name="password" | |
autoComplete="current-password" | |
autoCapitalize="off" | |
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-700 sm:text-sm sm:leading-6" | |
errorClassName="block w-full rounded-md border-0 py-1.5 text-red-900 shadow-sm ring-1 ring-inset ring-red-300 transition duration-150 ease-in-out placeholder:text-red-300 focus:ring-2 focus:ring-inset focus:ring-red-500 sm:text-sm sm:leading-6" | |
/> | |
<FieldError | |
name="password" | |
className="text-sm text-red-600" | |
/> | |
</div> | |
</div> | |
<div> | |
<Submit className="flex w-full justify-center rounded-md bg-gray-900 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm transition duration-150 ease-in-out hover:bg-gray-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-700"> | |
Log in | |
</Submit> | |
</div> | |
</Form> | |
</div> | |
</div> | |
</div> | |
</> | |
) | |
} | |
export default LogInPage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment