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:
Félix Malfait
2025-04-20 14:18:43 +02:00
committed by GitHub
parent 24873d0c1d
commit aa2f3438fa
4 changed files with 134 additions and 2 deletions

View File

@ -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 <></>;

View File

@ -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],
};

View File

@ -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,
},
};

View File

@ -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 (