Refactor login (#748)
* wip refactor login * wip refactor login * Fix lint conflicts * Complete Sign In only * Feature complete * Fix test * Fix test
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
@ -8,11 +8,9 @@ import { useRecoilState } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import { SubTitle } from '@/auth/components/ui/SubTitle';
|
||||
import { Title } from '@/auth/components/ui/Title';
|
||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
import { Title } from '@/auth/components/Title';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { MainButton } from '@/ui/button/components/MainButton';
|
||||
@ -25,18 +23,14 @@ import { useUpdateUserMutation } from '~/generated/graphql';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
width: 100%;
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(6)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSectionContainer = styled.div`
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
||||
}
|
||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||
width: 200px;
|
||||
`;
|
||||
|
||||
@ -59,7 +53,6 @@ type Form = Yup.InferType<typeof validationSchema>;
|
||||
|
||||
export function CreateProfile() {
|
||||
const navigate = useNavigate();
|
||||
const onboardingStatus = useOnboardingStatus();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
@ -129,12 +122,6 @@ export function CreateProfile() {
|
||||
[onSubmit],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (onboardingStatus !== OnboardingStatus.OngoingProfileCreation) {
|
||||
navigate('/');
|
||||
}
|
||||
}, [onboardingStatus, navigate]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title>Create profile</Title>
|
||||
@ -159,6 +146,7 @@ export function CreateProfile() {
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
autoFocus
|
||||
label="First Name"
|
||||
value={value}
|
||||
onBlur={onBlur}
|
||||
@ -166,6 +154,7 @@ export function CreateProfile() {
|
||||
placeholder="Tim"
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@ -184,6 +173,7 @@ export function CreateProfile() {
|
||||
placeholder="Cook"
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
@ -6,10 +6,8 @@ import styled from '@emotion/styled';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import { SubTitle } from '@/auth/components/ui/SubTitle';
|
||||
import { Title } from '@/auth/components/ui/Title';
|
||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
import { Title } from '@/auth/components/Title';
|
||||
import { WorkspaceLogoUploader } from '@/settings/workspace/components/WorkspaceLogoUploader';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { MainButton } from '@/ui/button/components/MainButton';
|
||||
@ -18,22 +16,21 @@ import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
||||
import { GET_CURRENT_USER } from '@/users/queries';
|
||||
import { useUpdateWorkspaceMutation } from '~/generated/graphql';
|
||||
import {
|
||||
useGetCurrentUserLazyQuery,
|
||||
useUpdateWorkspaceMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
width: 100%;
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(6)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSectionContainer = styled.div`
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
||||
}
|
||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||
width: 200px;
|
||||
`;
|
||||
|
||||
@ -47,11 +44,11 @@ type Form = Yup.InferType<typeof validationSchema>;
|
||||
|
||||
export function CreateWorkspace() {
|
||||
const navigate = useNavigate();
|
||||
const onboardingStatus = useOnboardingStatus();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
const [updateWorkspace] = useUpdateWorkspaceMutation();
|
||||
useGetCurrentUserLazyQuery();
|
||||
|
||||
// Form
|
||||
const {
|
||||
@ -84,7 +81,9 @@ export function CreateWorkspace() {
|
||||
throw result.errors ?? new Error('Unknown error');
|
||||
}
|
||||
|
||||
navigate('/auth/create/profile');
|
||||
setTimeout(() => {
|
||||
navigate('/create/profile');
|
||||
}, 20);
|
||||
} catch (error: any) {
|
||||
enqueueSnackBar(error?.message, {
|
||||
variant: 'error',
|
||||
@ -103,12 +102,6 @@ export function CreateWorkspace() {
|
||||
[onSubmit],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (onboardingStatus !== OnboardingStatus.OngoingWorkspaceCreation) {
|
||||
navigate('/auth/create/profile');
|
||||
}
|
||||
}, [onboardingStatus, navigate]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title>Create your workspace</Title>
|
||||
@ -119,7 +112,6 @@ export function CreateWorkspace() {
|
||||
<StyledContentContainer>
|
||||
<StyledSectionContainer>
|
||||
<SubSectionTitle title="Workspace logo" />
|
||||
{/* Picture is actually uploaded on the fly */}
|
||||
<WorkspaceLogoUploader />
|
||||
</StyledSectionContainer>
|
||||
<StyledSectionContainer>
|
||||
@ -135,12 +127,14 @@ export function CreateWorkspace() {
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
autoFocus
|
||||
value={value}
|
||||
placeholder="Apple"
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -1,119 +0,0 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { FooterNote } from '@/auth/components/ui/FooterNote';
|
||||
import { HorizontalSeparator } from '@/auth/components/ui/HorizontalSeparator';
|
||||
import { Logo } from '@/auth/components/ui/Logo';
|
||||
import { Title } from '@/auth/components/ui/Title';
|
||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { AnimatedEaseIn } from '@/ui/animation/components/AnimatedEaseIn';
|
||||
import { MainButton } from '@/ui/button/components/MainButton';
|
||||
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
||||
import { IconBrandGoogle } from '@/ui/icon';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
width: 200px;
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(3)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledFooterNote = styled(FooterNote)`
|
||||
max-width: 283px;
|
||||
`;
|
||||
|
||||
export function Index() {
|
||||
const navigate = useNavigate();
|
||||
const theme = useTheme();
|
||||
const [authProviders] = useRecoilState(authProvidersState);
|
||||
const [demoMode] = useRecoilState(isDemoModeState);
|
||||
|
||||
const [authFlowUserEmail, setAuthFlowUserEmail] = useRecoilState(
|
||||
authFlowUserEmailState,
|
||||
);
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const onGoogleLoginClick = useCallback(() => {
|
||||
window.location.href = process.env.REACT_APP_AUTH_URL + '/google' || '';
|
||||
}, []);
|
||||
|
||||
const onPasswordLoginClick = useCallback(() => {
|
||||
if (!visible) {
|
||||
setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
navigate('/auth/password-login');
|
||||
}, [navigate, visible]);
|
||||
|
||||
useScopedHotkeys(
|
||||
'enter',
|
||||
() => {
|
||||
onPasswordLoginClick();
|
||||
},
|
||||
PageHotkeyScope.AuthIndex,
|
||||
[onPasswordLoginClick],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setAuthFlowUserEmail(demoMode ? 'tim@apple.dev' : '');
|
||||
}, [navigate, setAuthFlowUserEmail, demoMode]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<AnimatedEaseIn>
|
||||
<Logo />
|
||||
</AnimatedEaseIn>
|
||||
<Title animate>Welcome to Twenty</Title>
|
||||
<StyledContentContainer>
|
||||
{authProviders.google && (
|
||||
<MainButton
|
||||
icon={<IconBrandGoogle size={theme.icon.size.sm} stroke={4} />}
|
||||
title="Continue with Google"
|
||||
onClick={onGoogleLoginClick}
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
{visible && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
transition={{
|
||||
type: 'spring',
|
||||
stiffness: 800,
|
||||
damping: 35,
|
||||
}}
|
||||
>
|
||||
<HorizontalSeparator />
|
||||
<TextInput
|
||||
value={authFlowUserEmail}
|
||||
placeholder="Email"
|
||||
onChange={(value) => setAuthFlowUserEmail(value)}
|
||||
fullWidth={true}
|
||||
/>
|
||||
</motion.div>
|
||||
)}
|
||||
<MainButton
|
||||
title="Continue with Email"
|
||||
onClick={onPasswordLoginClick}
|
||||
disabled={!authFlowUserEmail && visible}
|
||||
variant="secondary"
|
||||
fullWidth
|
||||
/>
|
||||
</StyledContentContainer>
|
||||
<StyledFooterNote>
|
||||
By using Twenty, you agree to the Terms of Service and Data Processing
|
||||
Agreement.
|
||||
</StyledFooterNote>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -1,203 +0,0 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import styled from '@emotion/styled';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import { Logo } from '@/auth/components/ui/Logo';
|
||||
import { SubTitle } from '@/auth/components/ui/SubTitle';
|
||||
import { Title } from '@/auth/components/ui/Title';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { authFlowUserEmailState } from '@/auth/states/authFlowUserEmailState';
|
||||
import { PASSWORD_REGEX } from '@/auth/utils/passwordRegex';
|
||||
import { isDemoModeState } from '@/client-config/states/isDemoModeState';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { MainButton } from '@/ui/button/components/MainButton';
|
||||
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { useSnackBar } from '@/ui/snack-bar/hooks/useSnackBar';
|
||||
import { SubSectionTitle } from '@/ui/title/components/SubSectionTitle';
|
||||
import { useCheckUserExistsQuery } from '~/generated/graphql';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
width: 100%;
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(6)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledForm = styled.form`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledSectionContainer = styled.div`
|
||||
> * + * {
|
||||
margin-top: ${({ theme }) => theme.spacing(4)};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
width: 200px;
|
||||
`;
|
||||
|
||||
const validationSchema = Yup.object()
|
||||
.shape({
|
||||
exist: Yup.boolean().required(),
|
||||
email: Yup.string().email('Email must be a valid email').required(),
|
||||
password: Yup.string()
|
||||
.matches(PASSWORD_REGEX, 'Password must contain at least 8 characters')
|
||||
.required(),
|
||||
})
|
||||
.required();
|
||||
|
||||
type Form = Yup.InferType<typeof validationSchema>;
|
||||
|
||||
export function PasswordLogin() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
const [isDemoMode] = useRecoilState(isDemoModeState);
|
||||
const [authFlowUserEmail] = useRecoilState(authFlowUserEmailState);
|
||||
const [showErrors, setShowErrors] = useState(false);
|
||||
|
||||
const workspaceInviteHash = useParams().workspaceInviteHash;
|
||||
|
||||
const { data: checkUserExistsData } = useCheckUserExistsQuery({
|
||||
variables: {
|
||||
email: authFlowUserEmail,
|
||||
},
|
||||
});
|
||||
|
||||
const { login, signUp } = useAuth();
|
||||
|
||||
// Form
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
watch,
|
||||
getValues,
|
||||
} = useForm<Form>({
|
||||
mode: 'onChange',
|
||||
defaultValues: {
|
||||
exist: false,
|
||||
email: authFlowUserEmail,
|
||||
password: isDemoMode ? 'Applecar2025' : '',
|
||||
},
|
||||
resolver: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
const onSubmit: SubmitHandler<Form> = useCallback(
|
||||
async (data) => {
|
||||
try {
|
||||
if (!data.email || !data.password) {
|
||||
throw new Error('Email and password are required');
|
||||
}
|
||||
if (checkUserExistsData?.checkUserExists.exists) {
|
||||
await login(data.email, data.password);
|
||||
} else {
|
||||
await signUp(data.email, data.password, workspaceInviteHash);
|
||||
}
|
||||
navigate('/auth/create/workspace');
|
||||
} catch (err: any) {
|
||||
enqueueSnackBar(err?.message, {
|
||||
variant: 'error',
|
||||
});
|
||||
}
|
||||
},
|
||||
[
|
||||
checkUserExistsData?.checkUserExists.exists,
|
||||
navigate,
|
||||
login,
|
||||
signUp,
|
||||
workspaceInviteHash,
|
||||
enqueueSnackBar,
|
||||
],
|
||||
);
|
||||
useScopedHotkeys(
|
||||
'enter',
|
||||
() => {
|
||||
onSubmit(getValues());
|
||||
},
|
||||
PageHotkeyScope.PasswordLogin,
|
||||
[onSubmit],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Logo />
|
||||
<Title>Welcome to Twenty</Title>
|
||||
<SubTitle>
|
||||
Enter your credentials to sign{' '}
|
||||
{checkUserExistsData?.checkUserExists.exists ? 'in' : 'up'}
|
||||
</SubTitle>
|
||||
<StyledForm
|
||||
onSubmit={(event) => {
|
||||
setShowErrors(true);
|
||||
return handleSubmit(onSubmit)(event);
|
||||
}}
|
||||
>
|
||||
<StyledContentContainer>
|
||||
<StyledSectionContainer>
|
||||
<SubSectionTitle title="Email" />
|
||||
<Controller
|
||||
name="email"
|
||||
control={control}
|
||||
render={({
|
||||
field: { onChange, onBlur, value },
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
value={value}
|
||||
placeholder="Email"
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
error={showErrors ? error?.message : undefined}
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</StyledSectionContainer>
|
||||
<StyledSectionContainer>
|
||||
<SubSectionTitle title="Password" />
|
||||
<Controller
|
||||
name="password"
|
||||
control={control}
|
||||
render={({
|
||||
field: { onChange, onBlur, value },
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
value={value}
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
onBlur={onBlur}
|
||||
onChange={onChange}
|
||||
error={showErrors ? error?.message : undefined}
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</StyledSectionContainer>
|
||||
</StyledContentContainer>
|
||||
<StyledButtonContainer>
|
||||
<MainButton
|
||||
title="Continue"
|
||||
type="submit"
|
||||
disabled={!watch('email') || !watch('password') || isSubmitting}
|
||||
fullWidth
|
||||
/>
|
||||
</StyledButtonContainer>
|
||||
</StyledForm>
|
||||
</>
|
||||
);
|
||||
}
|
||||
5
front/src/pages/auth/SignInUp.tsx
Normal file
5
front/src/pages/auth/SignInUp.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { SignInUpForm } from '../../modules/auth/sign-in-up/components/SignInUpForm';
|
||||
|
||||
export function SignInUp() {
|
||||
return <SignInUpForm />;
|
||||
}
|
||||
@ -4,6 +4,8 @@ import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
|
||||
import { AppPath } from '../../modules/types/AppPath';
|
||||
|
||||
export function Verify() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const loginToken = searchParams.get('loginToken');
|
||||
@ -16,10 +18,11 @@ export function Verify() {
|
||||
useEffect(() => {
|
||||
async function getTokens() {
|
||||
if (!loginToken) {
|
||||
return;
|
||||
navigate(AppPath.SignIn);
|
||||
} else {
|
||||
await verify(loginToken);
|
||||
navigate('/');
|
||||
}
|
||||
await verify(loginToken);
|
||||
navigate('/');
|
||||
}
|
||||
|
||||
if (!isLogged) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AuthModal } from '@/auth/components/ui/Modal';
|
||||
import { AuthModal } from '@/auth/components/Modal';
|
||||
import { AuthLayout } from '@/ui/layout/components/AuthLayout';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AuthModal } from '@/auth/components/ui/Modal';
|
||||
import { AuthModal } from '@/auth/components/Modal';
|
||||
import { AuthLayout } from '@/ui/layout/components/AuthLayout';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
@ -23,7 +23,7 @@ export const Default: Story = {
|
||||
<CreateWorkspace />
|
||||
</AuthModal>
|
||||
</AuthLayout>,
|
||||
'/auth/create-workspace',
|
||||
'/create-workspace',
|
||||
),
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AuthModal } from '@/auth/components/ui/Modal';
|
||||
import { AuthModal } from '@/auth/components/Modal';
|
||||
import { AuthLayout } from '@/ui/layout/components/AuthLayout';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
|
||||
import { Index } from '../Index';
|
||||
import { SignInUp } from '../SignInUp';
|
||||
|
||||
const meta: Meta<typeof Index> = {
|
||||
title: 'Pages/Auth/Index',
|
||||
component: Index,
|
||||
const meta: Meta<typeof SignInUp> = {
|
||||
title: 'Pages/Auth/SignInUp',
|
||||
component: SignInUp,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof Index>;
|
||||
export type Story = StoryObj<typeof SignInUp>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: getRenderWrapperForPage(
|
||||
<AuthLayout>
|
||||
<AuthModal>
|
||||
<Index />
|
||||
<SignInUp />
|
||||
</AuthModal>
|
||||
</AuthLayout>,
|
||||
'/auth',
|
||||
'/',
|
||||
),
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AuthModal } from '@/auth/components/ui/Modal';
|
||||
import { AuthLayout } from '@/ui/layout/components/AuthLayout';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
|
||||
import { PasswordLogin } from '../PasswordLogin';
|
||||
|
||||
const meta: Meta<typeof PasswordLogin> = {
|
||||
title: 'Pages/Auth/PasswordLogin',
|
||||
component: PasswordLogin,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof PasswordLogin>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: getRenderWrapperForPage(
|
||||
<AuthLayout>
|
||||
<AuthModal>
|
||||
<PasswordLogin />
|
||||
</AuthModal>
|
||||
</AuthLayout>,
|
||||
'/auth/password-login',
|
||||
),
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
@ -85,7 +85,7 @@ export function SettingsWorkspaceMembers() {
|
||||
description="Send an invitation to use Twenty"
|
||||
/>
|
||||
<WorkspaceInviteLink
|
||||
inviteLink={`${window.location.origin}/auth/invite/${workspace?.inviteHash}`}
|
||||
inviteLink={`${window.location.origin}/invite/${workspace?.inviteHash}`}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -2,7 +2,6 @@ import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { within } from '@storybook/testing-library';
|
||||
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { mockedUserJWT } from '~/testing/mock-data/jwt';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
|
||||
import { SettingsProfile } from '../SettingsProfile';
|
||||
@ -20,9 +19,6 @@ export const Default: Story = {
|
||||
render: getRenderWrapperForPage(<SettingsProfile />, '/settings/profile'),
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
cookie: {
|
||||
tokenPair: `{%22accessToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-07-18T15:06:40.704Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22refreshToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-10-15T15:06:41.558Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22__typename%22:%22AuthTokenPair%22}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { mockedUserJWT } from '~/testing/mock-data/jwt';
|
||||
import { getRenderWrapperForPage } from '~/testing/renderWrappers';
|
||||
|
||||
import { SettingsWorkspaceMembers } from '../SettingsWorkspaceMembers';
|
||||
@ -22,8 +21,5 @@ export const Default: Story = {
|
||||
),
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
cookie: {
|
||||
tokenPair: `{%22accessToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-07-18T15:06:40.704Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22refreshToken%22:{%22token%22:%22${mockedUserJWT}%22%2C%22expiresAt%22:%222023-10-15T15:06:41.558Z%22%2C%22__typename%22:%22AuthToken%22}%2C%22__typename%22:%22AuthTokenPair%22}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user