diff --git a/packages/twenty-front/src/App.tsx b/packages/twenty-front/src/App.tsx
index bdf99f5bd..9abf50e83 100644
--- a/packages/twenty-front/src/App.tsx
+++ b/packages/twenty-front/src/App.tsx
@@ -62,7 +62,7 @@ export const App = () => {
} />
} />
} />
- } />
+ } />
} />
} />
diff --git a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx
index 841e0b18b..80ae45b00 100644
--- a/packages/twenty-front/src/effect-components/PageChangeEffect.tsx
+++ b/packages/twenty-front/src/effect-components/PageChangeEffect.tsx
@@ -39,7 +39,7 @@ export const PageChangeEffect = () => {
const [workspaceFromInviteHashQuery] =
useGetWorkspaceFromInviteHashLazyQuery();
- const { addToCommandMenu, setToIntitialCommandMenu } = useCommandMenu();
+ const { addToCommandMenu, setToInitialCommandMenu } = useCommandMenu();
const openCreateActivity = useOpenCreateActivityDrawer();
@@ -209,7 +209,7 @@ export const PageChangeEffect = () => {
}, [isMatchingLocation, setHotkeyScope]);
useEffect(() => {
- setToIntitialCommandMenu();
+ setToInitialCommandMenu();
addToCommandMenu([
{
@@ -221,7 +221,7 @@ export const PageChangeEffect = () => {
onCommandClick: () => openCreateActivity({ type: 'Task' }),
},
]);
- }, [addToCommandMenu, setToIntitialCommandMenu, openCreateActivity]);
+ }, [addToCommandMenu, setToInitialCommandMenu, openCreateActivity]);
useEffect(() => {
setTimeout(() => {
diff --git a/packages/twenty-front/src/generated/graphql.tsx b/packages/twenty-front/src/generated/graphql.tsx
index 84b54666b..1973079ae 100644
--- a/packages/twenty-front/src/generated/graphql.tsx
+++ b/packages/twenty-front/src/generated/graphql.tsx
@@ -577,6 +577,7 @@ export type Verify = {
export type Workspace = {
__typename?: 'Workspace';
+ activationStatus: Scalars['String'];
allowImpersonation: Scalars['Boolean'];
createdAt: Scalars['DateTime'];
deletedAt?: Maybe;
@@ -782,7 +783,7 @@ export type ImpersonateMutationVariables = Exact<{
}>;
-export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
+export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type RenewTokenMutationVariables = Exact<{
refreshToken: Scalars['String'];
@@ -813,7 +814,7 @@ export type VerifyMutationVariables = Exact<{
}>;
-export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
+export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type CheckUserExistsQueryVariables = Exact<{
email: Scalars['String'];
@@ -850,7 +851,7 @@ export type UploadImageMutationVariables = Exact<{
export type UploadImageMutation = { __typename?: 'Mutation', uploadImage: string };
-export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } };
+export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } };
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
@@ -867,7 +868,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
-export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } } };
+export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, subscriptionStatus: string, activationStatus: string, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: string, key: string, value: boolean, workspaceId: string }> | null } } };
export type ActivateWorkspaceMutationVariables = Exact<{
input: ActivateWorkspaceInput;
@@ -988,6 +989,7 @@ export const UserQueryFragmentFragmentDoc = gql`
inviteHash
allowImpersonation
subscriptionStatus
+ activationStatus
featureFlags {
id
key
@@ -1721,6 +1723,7 @@ export const GetCurrentUserDocument = gql`
inviteHash
allowImpersonation
subscriptionStatus
+ activationStatus
featureFlags {
id
key
diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts
new file mode 100644
index 000000000..ec243bb32
--- /dev/null
+++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts
@@ -0,0 +1,44 @@
+import { useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useRecoilValue } from 'recoil';
+
+import { CurrentWorkspace } from '@/auth/states/currentWorkspaceState.ts';
+import { billingState } from '@/client-config/states/billingState.ts';
+import { AppPath } from '@/types/AppPath.ts';
+import { WorkspaceMember } from '~/generated/graphql.tsx';
+
+export const useNavigateAfterSignInUp = () => {
+ const navigate = useNavigate();
+ const billing = useRecoilValue(billingState);
+ const navigateAfterSignInUp = useCallback(
+ (
+ currentWorkspace: CurrentWorkspace,
+ currentWorkspaceMember: WorkspaceMember | null,
+ ) => {
+ if (
+ billing?.isBillingEnabled &&
+ currentWorkspace.subscriptionStatus !== 'active'
+ ) {
+ navigate(AppPath.PlanRequired);
+ return;
+ }
+
+ if (currentWorkspace.activationStatus !== 'active') {
+ navigate(AppPath.CreateWorkspace);
+ return;
+ }
+
+ if (
+ !currentWorkspaceMember?.name.firstName ||
+ !currentWorkspaceMember?.name.lastName
+ ) {
+ navigate(AppPath.CreateProfile);
+ return;
+ }
+
+ navigate(AppPath.Index);
+ },
+ [billing, navigate],
+ );
+ return { navigateAfterSignInUp };
+};
diff --git a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx
index fdaca81ca..142b78813 100644
--- a/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx
+++ b/packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSignInUp.tsx
@@ -1,10 +1,9 @@
import { useCallback, useState } from 'react';
import { SubmitHandler, UseFormReturn } from 'react-hook-form';
-import { useNavigate, useParams } from 'react-router-dom';
-import { useRecoilValue } from 'recoil';
+import { useParams } from 'react-router-dom';
+import { useNavigateAfterSignInUp } from '@/auth/sign-in-up/hooks/useNavigateAfterSignInUp.ts';
import { Form } from '@/auth/sign-in-up/hooks/useSignInUpForm.ts';
-import { billingState } from '@/client-config/states/billingState';
import { AppPath } from '@/types/AppPath';
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
@@ -26,14 +25,18 @@ export enum SignInUpStep {
}
export const useSignInUp = (form: UseFormReturn