Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: email verification support flow #21094

Merged
merged 17 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export const FEATURE_FLAGS = {
SUBSCRIBE_FROM_PAYGATE: 'subscribe-from-paygate', // owner: #team-growth
REVERSE_PROXY_ONBOARDING: 'reverse-proxy-onboarding', // owner: @zlwaterfield
SESSION_REPLAY_MOBILE_ONBOARDING: 'session-replay-mobile-onboarding', // owner: #team-replay
EMAIL_VERIFICATION_TICKET_SUBMISSION: 'email-verification-ticket-submission', // owner: #team-growth
THEME: 'theme', // owner: @aprilfools
} as const
export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]
Expand Down
112 changes: 95 additions & 17 deletions frontend/src/scenes/authentication/signup/verify-email/VerifyEmail.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { LemonButton } from '@posthog/lemon-ui'
import { LemonButton, LemonCheckbox, LemonModal } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { BridgePage } from 'lib/components/BridgePage/BridgePage'
import { HeartHog, MailHog, SurprisedHog } from 'lib/components/hedgehogs'
import { supportLogic } from 'lib/components/Support/supportLogic'
import { FEATURE_FLAGS } from 'lib/constants'
import { Spinner } from 'lib/lemon-ui/Spinner/Spinner'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { useState } from 'react'
import { SceneExport } from 'scenes/sceneTypes'

import { verifyEmailLogic } from './verifyEmailLogic'
Expand All @@ -13,16 +16,20 @@ export const scene: SceneExport = {
logic: verifyEmailLogic,
}

export const VerifyEmailHelpLinks = (): JSX.Element => {
interface SupportButtonsProps {
disabledReason?: string
}

const SupportButtons = ({ disabledReason }: SupportButtonsProps): JSX.Element => {
const { openSupportForm } = useActions(supportLogic)
const { requestVerificationLink } = useActions(verifyEmailLogic)
const { uuid } = useValues(verifyEmailLogic)
const { openSupportForm } = useActions(supportLogic)

return (
<div className="flex flex-row gap-x-4">
<div className="flex flex-row gap-x-4 justify-start">
<LemonButton
type="secondary"
className="mt-8"
type="primary"
disabledReason={disabledReason}
onClick={() => {
openSupportForm({ kind: 'bug', target_area: 'login' })
}}
Expand All @@ -31,8 +38,8 @@ export const VerifyEmailHelpLinks = (): JSX.Element => {
</LemonButton>
{uuid && (
<LemonButton
type="secondary"
className="mt-8"
type="primary"
disabledReason={disabledReason}
onClick={() => {
requestVerificationLink(uuid)
}}
Expand All @@ -44,26 +51,97 @@ export const VerifyEmailHelpLinks = (): JSX.Element => {
)
}

export const VerifyEmailHelpLinks = (): JSX.Element => {
const [checkListValues, setCheckListValues] = useState<boolean[]>([])

const checklist = [
'Wait 5 minutes. Sometimes it takes a bit for ISPs to deliver emails.',
zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
'Check your spam folder',
zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
'Check any firewalls you may have active',
'Ask your company IT department to allow any emails from @posthog.com',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention the quarantine thing here?

zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
"Make sure you can receive emails to your email address, especially if it's an alias",
'Channel your inner hedgehog and take another peek at your inbox',
zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️ 🦔


const handleChecklistChange = (index: number): void => {
const newCheckListValues = [...checkListValues]
newCheckListValues[index] = !newCheckListValues[index]
setCheckListValues(newCheckListValues)
zlwaterfield marked this conversation as resolved.
Show resolved Hide resolved
}

const allChecked = checklist.every((_, index) => checkListValues[index])

return (
<div className="bg-bg-3000 p-4 rounded relative w-full max-w-160">
<div className="flex flex-col justify-center">
<div className="space-y-2 text-left">
{checklist.map((item, index) => (
<LemonCheckbox
key={index}
onChange={() => handleChecklistChange(index)}
checked={checkListValues[index]}
label={item}
bordered
size="small"
/>
))}
</div>
</div>
<div className="mt-4">
<p className="text-left mb-2">Choose one of the following options:</p>
<SupportButtons
disabledReason={!allChecked ? "Please confirm you've done all the steps above" : undefined}
/>
</div>
</div>
)
}

const GetHelp = (): JSX.Element => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<LemonButton type="primary" onClick={() => setIsOpen(true)}>
Get help
</LemonButton>
<LemonModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Get help"
description={
<p className="max-w-160">
Sorry you're having troubles! We're here to help, but first we ask that you check a few things
first on your end. Generally any issues with email happen after they leave our hands.
</p>
}
>
<VerifyEmailHelpLinks />
</LemonModal>
</>
)
}

export function VerifyEmail(): JSX.Element {
const { view } = useValues(verifyEmailLogic)
const { featureFlags } = useValues(featureFlagLogic)

return (
<div className="flex h-full flex-col">
<div className="flex h-full">
<BridgePage view="verifyEmail" fixedWidth={false}>
<div className="px-12 py-8 text-center flex flex-col items-center max-w-200">
<div className="px-12 py-8 text-center flex flex-col items-center max-w-160 w-full">
{view === 'pending' ? (
<>
<h1 className="text-xl">Welcome to PostHog!</h1>
<h1 className="text-3xl font-bold">Let's verify your email address.</h1>
<div className="max-w-80 my-12">
<div className="max-w-60 my-10">
<MailHog className="w-full h-full" />
</div>
<p>
An email has been sent to with a link to verify your email address. If you have not
received the email in a few minutes, please check your spam folder.
</p>
<VerifyEmailHelpLinks />
<p>An email has been sent with a link to verify your email address.</p>
{featureFlags[FEATURE_FLAGS.EMAIL_VERIFICATION_TICKET_SUBMISSION] === 'test' ? (
<GetHelp />
) : (
<SupportButtons />
)}
</>
) : view === 'verify' ? (
<>
Expand All @@ -85,7 +163,7 @@ export function VerifyEmail(): JSX.Element {
<SurprisedHog className="w-full h-full" />
</div>
<p>Seems like that link isn't quite right. Try again?</p>
<VerifyEmailHelpLinks />
<SupportButtons />
</>
) : (
<Spinner className="text-4xl" />
Expand Down
Loading