* Replace Terms & Conditions with Sign Up Link on Sign In #4502 * terms replaced with signup link * begin fix (incomplete / do not merge) * Revert * Introduce welcome page * Update Twenty website --------- Co-authored-by: Mamatha Yarramaneni <mamathayarramaneni@Mamathas-Macbook.local> Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
@ -57,8 +57,7 @@ export const App = () => {
|
|||||||
<DefaultLayout>
|
<DefaultLayout>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path={AppPath.Verify} element={<VerifyEffect />} />
|
<Route path={AppPath.Verify} element={<VerifyEffect />} />
|
||||||
<Route path={AppPath.SignIn} element={<SignInUp />} />
|
<Route path={AppPath.SignInUp} element={<SignInUp />} />
|
||||||
<Route path={AppPath.SignUp} element={<SignInUp />} />
|
|
||||||
<Route path={AppPath.Invite} element={<SignInUp />} />
|
<Route path={AppPath.Invite} element={<SignInUp />} />
|
||||||
<Route path={AppPath.ResetPassword} element={<PasswordReset />} />
|
<Route path={AppPath.ResetPassword} element={<PasswordReset />} />
|
||||||
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
||||||
|
|||||||
@ -57,8 +57,7 @@ export const PageChangeEffect = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isMatchingOngoingUserCreationRoute =
|
const isMatchingOngoingUserCreationRoute =
|
||||||
isMatchingLocation(AppPath.SignUp) ||
|
isMatchingLocation(AppPath.SignInUp) ||
|
||||||
isMatchingLocation(AppPath.SignIn) ||
|
|
||||||
isMatchingLocation(AppPath.Invite) ||
|
isMatchingLocation(AppPath.Invite) ||
|
||||||
isMatchingLocation(AppPath.Verify);
|
isMatchingLocation(AppPath.Verify);
|
||||||
|
|
||||||
@ -73,7 +72,7 @@ export const PageChangeEffect = () => {
|
|||||||
enqueueSnackBar('workspace does not exist', {
|
enqueueSnackBar('workspace does not exist', {
|
||||||
variant: 'error',
|
variant: 'error',
|
||||||
});
|
});
|
||||||
navigate(AppPath.SignUp);
|
navigate(AppPath.SignInUp);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -81,7 +80,7 @@ export const PageChangeEffect = () => {
|
|||||||
!isMatchingOngoingUserCreationRoute &&
|
!isMatchingOngoingUserCreationRoute &&
|
||||||
!isMatchingLocation(AppPath.ResetPassword)
|
!isMatchingLocation(AppPath.ResetPassword)
|
||||||
) {
|
) {
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
} else if (
|
} else if (
|
||||||
isDefined(onboardingStatus) &&
|
isDefined(onboardingStatus) &&
|
||||||
onboardingStatus === OnboardingStatus.Incomplete &&
|
onboardingStatus === OnboardingStatus.Incomplete &&
|
||||||
@ -141,8 +140,6 @@ export const PageChangeEffect = () => {
|
|||||||
navigateToSignUp();
|
navigateToSignUp();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else if (isMatchingLocation(AppPath.SignUp) && isSignUpDisabled) {
|
|
||||||
navigate(AppPath.SignIn);
|
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
enqueueSnackBar,
|
enqueueSnackBar,
|
||||||
@ -185,11 +182,7 @@ export const PageChangeEffect = () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case isMatchingLocation(AppPath.SignIn): {
|
case isMatchingLocation(AppPath.SignInUp): {
|
||||||
setHotkeyScope(PageHotkeyScope.SignInUp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case isMatchingLocation(AppPath.SignUp): {
|
|
||||||
setHotkeyScope(PageHotkeyScope.SignInUp);
|
setHotkeyScope(PageHotkeyScope.SignInUp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ jest.mock('react-router-dom', () => {
|
|||||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
<RecoilRoot>
|
<RecoilRoot>
|
||||||
<MemoryRouter
|
<MemoryRouter
|
||||||
initialEntries={['/sign-in', '/verify', '/opportunities']}
|
initialEntries={['/welcome', '/verify', '/opportunities']}
|
||||||
initialIndex={2}
|
initialIndex={2}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
@ -44,7 +44,7 @@ describe('useApolloFactory', () => {
|
|||||||
expect(res).toHaveProperty('query');
|
expect(res).toHaveProperty('query');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate to /sign-in on unauthenticated error', async () => {
|
it('should navigate to /welcome on unauthenticated error', async () => {
|
||||||
const errors = [
|
const errors = [
|
||||||
{
|
{
|
||||||
extensions: {
|
extensions: {
|
||||||
@ -90,7 +90,7 @@ describe('useApolloFactory', () => {
|
|||||||
expect((error as ApolloError).message).toBe('Error message not found.');
|
expect((error as ApolloError).message).toBe('Error message not found.');
|
||||||
|
|
||||||
expect(mockNavigate).toHaveBeenCalled();
|
expect(mockNavigate).toHaveBeenCalled();
|
||||||
expect(mockNavigate).toHaveBeenCalledWith('/sign-in');
|
expect(mockNavigate).toHaveBeenCalledWith('/welcome');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -41,12 +41,11 @@ export const useApolloFactory = () => {
|
|||||||
setTokenPair(null);
|
setTokenPair(null);
|
||||||
if (
|
if (
|
||||||
!isMatchingLocation(AppPath.Verify) &&
|
!isMatchingLocation(AppPath.Verify) &&
|
||||||
!isMatchingLocation(AppPath.SignIn) &&
|
!isMatchingLocation(AppPath.SignInUp) &&
|
||||||
!isMatchingLocation(AppPath.SignUp) &&
|
|
||||||
!isMatchingLocation(AppPath.Invite) &&
|
!isMatchingLocation(AppPath.Invite) &&
|
||||||
!isMatchingLocation(AppPath.ResetPassword)
|
!isMatchingLocation(AppPath.ResetPassword)
|
||||||
) {
|
) {
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
extraLinks: [],
|
extraLinks: [],
|
||||||
|
|||||||
@ -94,10 +94,17 @@ export const SignInUpForm = () => {
|
|||||||
return `Join ${workspace?.displayName ?? ''} team`;
|
return `Join ${workspace?.displayName ?? ''} team`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
signInUpStep === SignInUpStep.Init ||
|
||||||
|
signInUpStep === SignInUpStep.Email
|
||||||
|
) {
|
||||||
|
return 'Welcome to Twenty';
|
||||||
|
}
|
||||||
|
|
||||||
return signInUpMode === SignInUpMode.SignIn
|
return signInUpMode === SignInUpMode.SignIn
|
||||||
? 'Sign in to Twenty'
|
? 'Sign in to Twenty'
|
||||||
: 'Sign up to Twenty';
|
: 'Sign up to Twenty';
|
||||||
}, [signInUpMode, workspace?.displayName, isInviteMode]);
|
}, [signInUpMode, workspace?.displayName, isInviteMode, signInUpStep]);
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@ -230,14 +237,14 @@ export const SignInUpForm = () => {
|
|||||||
/>
|
/>
|
||||||
</StyledForm>
|
</StyledForm>
|
||||||
</StyledContentContainer>
|
</StyledContentContainer>
|
||||||
{signInUpStep === SignInUpStep.Password ? (
|
{signInUpStep === SignInUpStep.Password && (
|
||||||
<ActionLink onClick={handleResetPassword(form.getValues('email'))}>
|
<ActionLink onClick={handleResetPassword(form.getValues('email'))}>
|
||||||
Forgot your password?
|
Forgot your password?
|
||||||
</ActionLink>
|
</ActionLink>
|
||||||
) : (
|
)}
|
||||||
|
{signInUpStep === SignInUpStep.Init && (
|
||||||
<FooterNote>
|
<FooterNote>
|
||||||
By using Twenty, you agree to the Terms of Service and Data Processing
|
By using Twenty, you agree to the Terms of Service and Privacy Policy.
|
||||||
Agreement.
|
|
||||||
</FooterNote>
|
</FooterNote>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export const useSignInUp = (form: UseFormReturn<Form>) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [signInUpMode, setSignInUpMode] = useState<SignInUpMode>(() => {
|
const [signInUpMode, setSignInUpMode] = useState<SignInUpMode>(() => {
|
||||||
return isMatchingLocation(AppPath.SignIn)
|
return isMatchingLocation(AppPath.SignInUp)
|
||||||
? SignInUpMode.SignIn
|
? SignInUpMode.SignIn
|
||||||
: SignInUpMode.SignUp;
|
: SignInUpMode.SignUp;
|
||||||
});
|
});
|
||||||
@ -53,7 +53,7 @@ export const useSignInUp = (form: UseFormReturn<Form>) => {
|
|||||||
const continueWithEmail = useCallback(() => {
|
const continueWithEmail = useCallback(() => {
|
||||||
setSignInUpStep(SignInUpStep.Email);
|
setSignInUpStep(SignInUpStep.Email);
|
||||||
setSignInUpMode(
|
setSignInUpMode(
|
||||||
isMatchingLocation(AppPath.SignIn)
|
isMatchingLocation(AppPath.SignInUp)
|
||||||
? SignInUpMode.SignIn
|
? SignInUpMode.SignIn
|
||||||
: SignInUpMode.SignUp,
|
: SignInUpMode.SignUp,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export const useSignInUpForm = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isSignInPrefilled) {
|
if (isSignInPrefilled === true) {
|
||||||
form.setValue('email', 'tim@apple.dev');
|
form.setValue('email', 'tim@apple.dev');
|
||||||
form.setValue('password', 'Applecar2025');
|
form.setValue('password', 'Applecar2025');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export const SettingsNavigationDrawerItems = () => {
|
|||||||
|
|
||||||
const handleLogout = useCallback(() => {
|
const handleLogout = useCallback(() => {
|
||||||
signOut();
|
signOut();
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
}, [signOut, navigate]);
|
}, [signOut, navigate]);
|
||||||
|
|
||||||
const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
|
const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export const DeleteAccount = () => {
|
|||||||
|
|
||||||
const handleLogout = useCallback(() => {
|
const handleLogout = useCallback(() => {
|
||||||
signOut();
|
signOut();
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
}, [signOut, navigate]);
|
}, [signOut, navigate]);
|
||||||
|
|
||||||
const deleteAccount = async () => {
|
const deleteAccount = async () => {
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const DeleteWorkspace = () => {
|
|||||||
|
|
||||||
const handleLogout = useCallback(() => {
|
const handleLogout = useCallback(() => {
|
||||||
signOut();
|
signOut();
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
}, [signOut, navigate]);
|
}, [signOut, navigate]);
|
||||||
|
|
||||||
const deleteWorkspace = async () => {
|
const deleteWorkspace = async () => {
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
export enum AppPath {
|
export enum AppPath {
|
||||||
// Not logged-in
|
// Not logged-in
|
||||||
Verify = '/verify',
|
Verify = '/verify',
|
||||||
SignIn = '/sign-in',
|
SignInUp = '/welcome',
|
||||||
SignUp = '/sign-up',
|
|
||||||
Invite = '/invite/:workspaceInviteHash',
|
Invite = '/invite/:workspaceInviteHash',
|
||||||
ResetPassword = '/reset-password/:passwordResetToken',
|
ResetPassword = '/reset-password/:passwordResetToken',
|
||||||
|
|
||||||
|
|||||||
@ -66,15 +66,6 @@ const StyledInputContainer = styled.div`
|
|||||||
margin-bottom: ${({ theme }) => theme.spacing(3)};
|
margin-bottom: ${({ theme }) => theme.spacing(3)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledFooterContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
|
||||||
display: flex;
|
|
||||||
font-size: ${({ theme }) => theme.font.size.sm};
|
|
||||||
text-align: center;
|
|
||||||
max-width: 280px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const PasswordReset = () => {
|
export const PasswordReset = () => {
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
|
|
||||||
@ -107,7 +98,7 @@ export const PasswordReset = () => {
|
|||||||
variant: 'error',
|
variant: 'error',
|
||||||
});
|
});
|
||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
} else {
|
} else {
|
||||||
navigate(AppPath.Index);
|
navigate(AppPath.Index);
|
||||||
}
|
}
|
||||||
@ -253,10 +244,6 @@ export const PasswordReset = () => {
|
|||||||
</StyledForm>
|
</StyledForm>
|
||||||
)}
|
)}
|
||||||
</StyledContentContainer>
|
</StyledContentContainer>
|
||||||
<StyledFooterContainer>
|
|
||||||
By using Twenty, you agree to the Terms of Service and Data Processing
|
|
||||||
Agreement.
|
|
||||||
</StyledFooterContainer>
|
|
||||||
</StyledMainContainer>
|
</StyledMainContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const VerifyEffect = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getTokens = async () => {
|
const getTokens = async () => {
|
||||||
if (!loginToken) {
|
if (!loginToken) {
|
||||||
navigate(AppPath.SignIn);
|
navigate(AppPath.SignInUp);
|
||||||
} else {
|
} else {
|
||||||
await verify(loginToken);
|
await verify(loginToken);
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
title: 'Pages/Auth/SignInUp',
|
title: 'Pages/Auth/SignInUp',
|
||||||
component: SignInUp,
|
component: SignInUp,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: { routePath: AppPath.SignIn },
|
args: { routePath: AppPath.SignInUp },
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: {
|
msw: {
|
||||||
handlers: [
|
handlers: [
|
||||||
|
|||||||
@ -3,8 +3,9 @@ import { getPageTitleFromPath } from '../title-utils';
|
|||||||
describe('title-utils', () => {
|
describe('title-utils', () => {
|
||||||
it('should return the correct title for a given path', () => {
|
it('should return the correct title for a given path', () => {
|
||||||
expect(getPageTitleFromPath('/verify')).toBe('Verify');
|
expect(getPageTitleFromPath('/verify')).toBe('Verify');
|
||||||
expect(getPageTitleFromPath('/sign-in')).toBe('Sign In');
|
expect(getPageTitleFromPath('/welcome')).toBe(
|
||||||
expect(getPageTitleFromPath('/sign-up')).toBe('Sign Up');
|
'Sign in or Create an account',
|
||||||
|
);
|
||||||
expect(getPageTitleFromPath('/invite/:workspaceInviteHash')).toBe('Invite');
|
expect(getPageTitleFromPath('/invite/:workspaceInviteHash')).toBe('Invite');
|
||||||
expect(getPageTitleFromPath('/create/workspace')).toBe('Create Workspace');
|
expect(getPageTitleFromPath('/create/workspace')).toBe('Create Workspace');
|
||||||
expect(getPageTitleFromPath('/create/profile')).toBe('Create Profile');
|
expect(getPageTitleFromPath('/create/profile')).toBe('Create Profile');
|
||||||
|
|||||||
@ -6,10 +6,8 @@ export const getPageTitleFromPath = (pathname: string): string => {
|
|||||||
switch (pathname) {
|
switch (pathname) {
|
||||||
case AppPath.Verify:
|
case AppPath.Verify:
|
||||||
return 'Verify';
|
return 'Verify';
|
||||||
case AppPath.SignIn:
|
case AppPath.SignInUp:
|
||||||
return 'Sign In';
|
return 'Sign in or Create an account';
|
||||||
case AppPath.SignUp:
|
|
||||||
return 'Sign Up';
|
|
||||||
case AppPath.Invite:
|
case AppPath.Invite:
|
||||||
return 'Invite';
|
return 'Invite';
|
||||||
case AppPath.CreateWorkspace:
|
case AppPath.CreateWorkspace:
|
||||||
|
|||||||
@ -7,10 +7,8 @@ import {
|
|||||||
export const CallToAction = () => {
|
export const CallToAction = () => {
|
||||||
return (
|
return (
|
||||||
<CallToActionContainer>
|
<CallToActionContainer>
|
||||||
<LinkNextToCTA href="https://github.com/twentyhq/twenty">
|
<LinkNextToCTA href="https://app.twenty.com">Sign in</LinkNextToCTA>
|
||||||
Sign in
|
<a href="https://app.twenty.com">
|
||||||
</LinkNextToCTA>
|
|
||||||
<a href="https://twenty.com/stripe-redirection">
|
|
||||||
<StyledButton>Get Started</StyledButton>
|
<StyledButton>Get Started</StyledButton>
|
||||||
</a>
|
</a>
|
||||||
</CallToActionContainer>
|
</CallToActionContainer>
|
||||||
|
|||||||
Reference in New Issue
Block a user