Skip to content

Commit

Permalink
fix verify, add resend verify page (#94)
Browse files Browse the repository at this point in the history
Signed-off-by: Sarah Funkhouser <[email protected]>
  • Loading branch information
golanglemonade authored Dec 4, 2024
1 parent 1841683 commit 4b869f7
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 44 deletions.
12 changes: 12 additions & 0 deletions apps/console/src/app/(auth)/resend-verify/page.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { tv, type VariantProps } from 'tailwind-variants'

const pageStyles = tv({
slots: {
content: 'flex items-center justify-center h-screen relative',
form: 'w-full relative z-3 px-4'
},
})

export type PageVariants = VariantProps<typeof pageStyles>

export { pageStyles }
17 changes: 17 additions & 0 deletions apps/console/src/app/(auth)/resend-verify/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'

import { Resend } from '@/components/pages/auth/resend-verify/resend'
import { pageStyles } from './page.styles'

const ResendVerification: React.FC = () => {
const { content, form } = pageStyles()
return (
<main className={content()}>
<div className={form()}>
<Resend />
</div>
</main>
)
}

export default ResendVerification
8 changes: 4 additions & 4 deletions apps/console/src/app/(auth)/verify/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

import { Suspense } from 'react'
import { LoaderCircle } from 'lucide-react'
import { TokenVerifier } from '@/components/pages/auth/subscriber-verify/verifier'
import { TokenVerifier } from '@/components/pages/auth/verify/verifier'

export const dynamic = 'force-dynamic'

const VerifyUser: React.FC = () => {
return(
return (
<Suspense
fallback={<LoaderCircle className="animate-spin" size={20} />}
>
<TokenVerifier />
</Suspense>
)
}
)
}

export default VerifyUser
4 changes: 2 additions & 2 deletions apps/console/src/app/(auth)/waitlist/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Logo } from '@repo/ui/logo'
import { Panel } from '@repo/ui/panel'
import {Subscribe} from '@/components/pages/auth/subscribe/subscribe'
import { Subscribe } from '@/components/pages/auth/subscribe/subscribe'
import Link from 'next/link'

const Waitlist: React.FC = () => {
Expand All @@ -18,7 +18,7 @@ const Waitlist: React.FC = () => {
<div className="flex flex-col text-center text-oxford-blue-100">
We are currently in a private beta, please subscribe to our newsletter to get notified when we launch.
</div>
</Panel>
</Panel>

<Subscribe />

Expand Down
21 changes: 21 additions & 0 deletions apps/console/src/app/api/auth/resend/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NextResponse } from 'next/server'

export async function POST(request: Request) {
const bodyData = await request.json()

const fData = await fetch(`${process.env.API_REST_URL}/v1/resend`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(bodyData),
})

if (fData.ok) {
return NextResponse.json(await fData.json(), { status: 200 })
}

if (fData.status !== 201) {
return NextResponse.json(await fData.json(), { status: fData.status })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { tv, type VariantProps } from 'tailwind-variants'

const resendStyles = tv({
slots: {
logo: 'flex justify-center mb-10',
text: "text-center text-sm",
header: "text-xl text-center",
wrapper: 'relative mt-1 flex flex-col gap-2 md:flex-row',
input: 'w-full h-12 md:h-auto text-ziggurat-900',
button:
'absolute h-10 text-md md:relative md:text-md md:top-0 md:h-14',
errorMessage: 'text-ziggurat-200 mt-14',
success:
'mt-14 text-center bg-ziggurat-900 bg-opacity-20 p-5 rounded-md text-white flex gap-3',
successMessage: 'flex-1',
successIcon: 'mt-1',
},
})


export type ResendVariants = VariantProps<typeof resendStyles>

export { resendStyles }
89 changes: 89 additions & 0 deletions apps/console/src/components/pages/auth/resend-verify/resend.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client'

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { z } from 'zod'

import { Button } from '@repo/ui/button'
import {
Form,
FormField,
FormControl,
FormMessage,
FormLabel,
} from '@repo/ui/form'
import { Input } from '@repo/ui/input'
import { resendStyles } from './resend.styles'
import { resendVerification } from '@/lib/user'
import { useRouter } from 'next/navigation'
import { Panel } from '@repo/ui/panel'
import { Logo } from '@repo/ui/logo'

const formSchema = z.object({
email: z.string().email(),
})

export const Resend = () => {
const router = useRouter()

const {
wrapper,
input,
button,
text,
header,
logo,
} = resendStyles()

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: '',
},
})

const onSubmit = ({ email }: z.infer<typeof formSchema>) => {
const result = resendVerification({ email })
router.push('/verify')
}


return (
<>
<Panel>
<div className={logo()}>
<Logo width={300} />
</div>
<h2 className={header()}>Can't find that email?</h2>
<p className={text()}>
We got you, enter your email to have our robots <br />
resend that verification email right over to you. </p>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className={wrapper()}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<>
<FormLabel>Email</FormLabel>
<FormControl>
<Input
type="email"
placeholder="[email protected]"
className={input()}
{...field}
/>
</FormControl>
<FormMessage />
</>
)}
/>
<Button type="submit" className={button()}>
Resend Verification
</Button>
</form>
</Form>
</Panel >
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const Subscribe = () => {

return (
<>
{data ? (
{data ? (
<div className={success()}>
<MailCheck size={24} className={successIcon()} />
<span className={successMessage()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { verificationStyles } from './page.styles'
import { Logo } from '@repo/ui/logo'

export const TokenVerifier = () => {
const { errorMessage, successMessage, successIcon, success, loading } =
verificationStyles()
const { errorMessage, successMessage, successIcon, success, loading } =
verificationStyles()

const searchParams = useSearchParams()
const token = searchParams.get('token')
Expand Down Expand Up @@ -41,7 +41,7 @@ export const TokenVerifier = () => {
return (
<>
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
<Logo theme='dark' />
</div>
<div className={errorMessage()}>
No token provided, please check your email for a verification link.
Expand All @@ -52,40 +52,40 @@ export const TokenVerifier = () => {

if (error) {
return (
<>
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
</div>
<div className={errorMessage()}>{error}</div>
</>
<>
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
</div>
<div className={errorMessage()}>{error}</div>
</>
)
}

if (message) {
return (
<>
<div className="mx-auto animate-pulse w-96">
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
</div>
<div className={success()}>
<SparklesIcon size={24} className={successIcon()} />
<span className={successMessage()}>
Thank you for subscribing. Your email is now verified.
</span>
</div>
</div>
<div className={success()}>
<SparklesIcon size={24} className={successIcon()} />
<span className={successMessage()}>
Thank you for subscribing. Your email is now verified.
</span>
</div>
</>
)
}

return (
<>
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
</div>
<div className={loading()}>
<LoaderCircle className="animate-spin" size={20} />
<span className={successMessage()}>Verifying</span>
</div>
<div className="mx-auto animate-pulse w-96">
<Logo theme='dark' />
</div>
<div className={loading()}>
<LoaderCircle className="animate-spin" size={20} />
<span className={successMessage()}>Verifying</span>
</div>
</>
)
}
22 changes: 22 additions & 0 deletions apps/console/src/components/pages/auth/verify/page.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { tv, type VariantProps } from 'tailwind-variants'

const verificationStyles = tv({
slots: {
content: 'flex flex-col min-h-screen w-full items-center space-between dark:bg-dk-surface-0 bg-surface-0',
wrapper: 'flex flex-col justify-center mx-auto my-auto w-full p-6 sm:w-1/3 h-full relative ease-in-out',
errorMessage: 'text-ziggurat-200 mt-14',
success:
'mt-14 bg-ziggurat-900 bg-opacity-20 p-5 rounded-md text-white justify-center text-center',
successMessage: 'text-center',
successIcon: 'mt-1 justify-center items-center',
loading: 'mt-14 p-5 rounded-md text-white flex gap-3',
resendMessage: 'text-xs text-gray-400 mt-4 text-center',
button: 'mt-12 flex w-full justify-center',
logo: 'mx-auto b-3',
verifying: 'text-3xl text-center mt-4 animate-pulse',
},
})

export type VerificationVariants = VariantProps<typeof verificationStyles>

export { verificationStyles }
31 changes: 19 additions & 12 deletions apps/console/src/components/pages/auth/verify/verifier.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

import { useEffect } from 'react'
import { Button } from '@repo/ui/button'
import { useSearchParams } from 'next/navigation'
import { useRouter, useSearchParams } from 'next/navigation'
import { signIn } from 'next-auth/react'
import { Logo } from '@repo/ui/logo'
import { useVerifyUser } from '@/lib/user'
import { verificationStyles } from './page.styles'
import { buttonVariants } from '@repo/ui/plate-ui/button'

export const TokenVerifier = () => {
const { successMessage, button, success, content, logo, wrapper, verifying } =
verificationStyles()

const router = useRouter()
const searchParams = useSearchParams()
const token = searchParams?.get('token')

Expand All @@ -27,28 +33,29 @@ export const TokenVerifier = () => {
}, [verified, error])

return (
<main className="flex flex-col min-h-screen w-full items-center space-between dark:bg-dk-surface-0 bg-surface-0">
<div className="flex flex-col justify-center mx-auto my-auto w-full p-6 sm:w-1/3 h-full relative ease-in-out">
<div className="mx-auto mb-3">
<main className={content()}>
<div className={wrapper()}>
<div className={logo()}>
<Logo width={200} />
</div>
{isLoading ? (
<h1 className="text-3xl text-center mt-4 animate-pulse">
<h1 className={verifying()}>
Verifying your account...
</h1>
) : null}
{!isLoading && (
<div>
<h1 className="text-3xl text-center mt-4 text-oxford-blue-100" >
Please check your email to verify your account.
</h1>
<div className={success()}>
<span className={successMessage()}>
Thank you for signing up for Openlane! <br />
Check your email and give that awesome verification link a click to get started.
</span>
</div>
)}
<div className="mt-12">
<div className={button()}>
<Button
className="mr-auto mt-2 w-full"
className={buttonVariants({ size: 'lg', variant: 'ghost' })}
onClick={() => {
// TODO: Call resend email endpoint
router.push('/resend-verify')
}}
type="button"
>
Expand Down
Loading

0 comments on commit 4b869f7

Please sign in to comment.