Fix email verification (#11660)
Email verification modal had been broken and looked bad I also added stories to make it more evident if this happens again
This commit is contained in:
@ -5,6 +5,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
@ -70,7 +71,11 @@ export const VerifyEmailEffect = () => {
|
||||
}, []);
|
||||
|
||||
if (isError) {
|
||||
return <EmailVerificationSent email={email} isError={true} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { VerifyEmailEffect } from '../VerifyEmailEffect';
|
||||
|
||||
// Mock component that just renders the error state of VerifyEmailEffect directly
|
||||
// (since normal VerifyEmailEffect has async logic that's hard to test in Storybook)
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../../sign-in-up/components/EmailVerificationSent';
|
||||
|
||||
const VerifyEmailEffectErrorState = ({ email = 'user@example.com' }) => {
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof VerifyEmailEffectErrorState> = {
|
||||
title: 'Pages/Auth/VerifyEmailEffect',
|
||||
component: VerifyEmailEffectErrorState,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div style={{ padding: '24px' }}>
|
||||
<RecoilRoot>
|
||||
<Story />
|
||||
</RecoilRoot>
|
||||
</div>
|
||||
),
|
||||
SnackBarDecorator,
|
||||
],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'IMPORTANT: When rendering EmailVerificationSent from VerifyEmailEffect, always wrap it with Modal.Content to maintain consistent styling.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof VerifyEmailEffect>;
|
||||
|
||||
export const ErrorState: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
},
|
||||
};
|
||||
|
||||
export const IntegratedExample: StoryObj<typeof VerifyEmailEffect> = {
|
||||
render: () => (
|
||||
<RecoilRoot>
|
||||
<MemoryRouter
|
||||
initialEntries={[
|
||||
'/verify-email?email=user@example.com&emailVerificationToken=invalid-token',
|
||||
]}
|
||||
>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/verify-email"
|
||||
element={<VerifyEmailEffectErrorState email="user@example.com" />}
|
||||
/>
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
</RecoilRoot>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
'This demonstrates how the component should look when rendered in the app with proper Modal.Content wrapping.',
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [SnackBarDecorator],
|
||||
};
|
||||
@ -0,0 +1,48 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../EmailVerificationSent';
|
||||
|
||||
// Wrap the component in Modal.Content to reflect how it's used in the app
|
||||
const RenderWithModal = (
|
||||
args: React.ComponentProps<typeof EmailVerificationSent>,
|
||||
) => {
|
||||
return (
|
||||
<Modal padding="none" modalVariant="primary">
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={args.email} isError={args.isError} />
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof EmailVerificationSent> = {
|
||||
title: 'Pages/Auth/EmailVerificationSent',
|
||||
component: EmailVerificationSent,
|
||||
decorators: [ComponentDecorator, SnackBarDecorator],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'This component should always be wrapped with Modal.Content in the app.\n\nCorrect usage:\n```tsx\n<Modal.Content isVerticalCentered isHorizontalCentered>\n <EmailVerificationSent email={email} />\n</Modal.Content>\n```\n',
|
||||
},
|
||||
},
|
||||
render: RenderWithModal,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof EmailVerificationSent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const Error: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: true,
|
||||
},
|
||||
};
|
||||
@ -120,7 +120,11 @@ export const SignInUp = () => {
|
||||
]);
|
||||
|
||||
if (signInUpStep === SignInUpStep.EmailVerification) {
|
||||
return <EmailVerificationSent email={searchParams.get('email')} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={searchParams.get('email')} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user