import {zodResolver} from '@hookform/resolvers/zod'; import {AuthenticationSchemas} from '@plunk/shared'; import { Button, Card, CardContent, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input, } from '@plunk/ui'; import {AnimatePresence, motion} from 'framer-motion'; import {NextSeo} from 'next-seo'; import Image from 'next/image'; import Link from 'next/link'; import {useRouter} from 'next/router'; import React, {useState} from 'react'; import {useForm} from 'react-hook-form'; import type {z} from 'zod'; import {API_URI} from '../../lib/constants'; import {useConfig} from '../../lib/hooks/useConfig'; import {useProjects} from '../../lib/hooks/useProject'; import {useUser} from '../../lib/hooks/useUser'; import {network} from '../../lib/network'; const Spinner = () => ( ); export default function Login() { const {mutate: userMutate} = useUser(); const {mutate: projectsMutate} = useProjects(); const router = useRouter(); const form = useForm>({ resolver: zodResolver(AuthenticationSchemas.login), defaultValues: { email: '', password: '', }, }); const [errorMessage, setErrorMessage] = useState(null); const [showReset, setShowReset] = useState(false); const [resetEmail, setResetEmail] = useState(''); const [resetStatus, setResetStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle'); const [resetError, setResetError] = useState(null); const {data: config} = useConfig(); const oauthConfig = { github: config?.features.authProviders.github ?? false, google: config?.features.authProviders.google ?? false, }; async function onSubmit(values: z.infer) { try { const response = await network.fetch< { success: boolean; data: {id: string; email: string}; }, typeof AuthenticationSchemas.login >('POST', '/auth/login', values); if (!response.success) { setErrorMessage('Email or password is incorrect'); } else { setErrorMessage(null); await userMutate(); await projectsMutate(); await router.push('/'); } } catch (error) { setErrorMessage(error instanceof Error ? error.message : 'Something went wrong'); } } async function handleResetPassword(e: React.FormEvent) { e.preventDefault(); setResetStatus('loading'); setResetError(null); try { const response = await network.fetch<{success: boolean}, typeof AuthenticationSchemas.requestPasswordReset>( 'POST', '/auth/request-password-reset', { email: resetEmail, }, ); if (response.success) { setResetStatus('success'); } else { setResetStatus('error'); setResetError('Something went wrong.'); } } catch { setResetStatus('error'); setResetError('Something went wrong.'); } } return ( <>
Plunk
{ e.preventDefault(); void form.handleSubmit(onSubmit)(e); }} className="p-8" >

Welcome back

Sign in to your account

{(oauthConfig.github || oauthConfig.google) && ( <>
{oauthConfig.google && ( )} {oauthConfig.github && ( )}
or
)}
( Email )} /> (
Password
)} />
{errorMessage && ( {errorMessage} )}

Don't have an account?{' '} Sign up

{ setShowReset(open); if (!open) { setResetStatus('idle'); setResetEmail(''); setResetError(null); } }} > Reset your password Enter your email to receive a password reset link.
{ void handleResetPassword(e); }} className="flex flex-col gap-3 mt-2" > setResetEmail(e.target.value)} required autoFocus />
{resetStatus === 'success' && (

If an account exists, a reset link has been sent to your email.

)} {resetStatus === 'error' &&

{resetError}

}
); }