Files
twenty_crm/packages/twenty-front/src/modules/users/components/UserProviderEffect.tsx
Guillim 10e140495c Fixing Singup sequence FLASHING💥 (#11371)
After investiagting the different options ([see related
issue](https://github.com/twentyhq/core-team-issues/issues/660#issuecomment-2766030972))
I decided to add a "Verify Component" and a to build a custom Layout for
this route.

Reason I cannot use the default one is to have all preloaded once the
user changes website and lands on the verify route.

Reason I did not modify the DefaultLayout to match our need is that is
would require many changes in order to avoid preloading states for our
specific usecase.

Fixes https://github.com/twentyhq/core-team-issues/issues/660

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-04 15:25:15 +00:00

148 lines
5.3 KiB
TypeScript

import { useEffect, useState } from 'react';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { currentWorkspaceMembersState } from '@/auth/states/currentWorkspaceMembersStates';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadingState';
import { workspacesState } from '@/auth/states/workspaces';
import { DateFormat } from '@/localization/constants/DateFormat';
import { TimeFormat } from '@/localization/constants/TimeFormat';
import { dateTimeFormatState } from '@/localization/states/dateTimeFormatState';
import { detectDateFormat } from '@/localization/utils/detectDateFormat';
import { detectTimeFormat } from '@/localization/utils/detectTimeFormat';
import { detectTimeZone } from '@/localization/utils/detectTimeZone';
import { getDateFormatFromWorkspaceDateFormat } from '@/localization/utils/getDateFormatFromWorkspaceDateFormat';
import { getTimeFormatFromWorkspaceTimeFormat } from '@/localization/utils/getTimeFormatFromWorkspaceTimeFormat';
import { AppPath } from '@/types/AppPath';
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { APP_LOCALES, SOURCE_LOCALE } from 'twenty-shared/translations';
import { isDefined } from 'twenty-shared/utils';
import { WorkspaceMember } from '~/generated-metadata/graphql';
import { useGetCurrentUserQuery } from '~/generated/graphql';
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
export const UserProviderEffect = () => {
const [isLoading, setIsLoading] = useState(true);
const { isMatchingLocation } = useIsMatchingLocation();
const [isCurrentUserLoaded, setIsCurrentUserLoaded] = useRecoilState(
isCurrentUserLoadedState,
);
const setCurrentUser = useSetRecoilState(currentUserState);
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
const setCurrentUserWorkspace = useSetRecoilState(currentUserWorkspaceState);
const setWorkspaces = useSetRecoilState(workspacesState);
const setDateTimeFormat = useSetRecoilState(dateTimeFormatState);
const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState,
);
const setCurrentWorkspaceMembers = useSetRecoilState(
currentWorkspaceMembersState,
);
const { loading: queryLoading, data: queryData } = useGetCurrentUserQuery({
skip:
isCurrentUserLoaded ||
isMatchingLocation(AppPath.Verify) ||
isMatchingLocation(AppPath.VerifyEmail),
});
useEffect(() => {
if (!queryLoading) {
setIsLoading(false);
setIsCurrentUserLoaded(true);
}
if (!isDefined(queryData?.currentUser)) return;
setCurrentUser(queryData.currentUser);
if (isDefined(queryData.currentUser.currentWorkspace)) {
setCurrentWorkspace({
...queryData.currentUser.currentWorkspace,
defaultRole: queryData.currentUser.currentWorkspace.defaultRole ?? null,
});
}
if (isDefined(queryData.currentUser.currentUserWorkspace)) {
setCurrentUserWorkspace(queryData.currentUser.currentUserWorkspace);
}
const {
workspaceMember,
workspaceMembers,
workspaces: userWorkspaces,
} = queryData.currentUser;
const affectDefaultValuesOnEmptyWorkspaceMemberFields = (
workspaceMember: WorkspaceMember,
) => {
return {
...workspaceMember,
colorScheme: (workspaceMember.colorScheme as ColorScheme) ?? 'Light',
locale:
(workspaceMember.locale as keyof typeof APP_LOCALES) ?? SOURCE_LOCALE,
};
};
if (isDefined(workspaceMember)) {
setCurrentWorkspaceMember(
affectDefaultValuesOnEmptyWorkspaceMemberFields(workspaceMember),
);
// TODO: factorize
setDateTimeFormat({
timeZone:
workspaceMember.timeZone && workspaceMember.timeZone !== 'system'
? workspaceMember.timeZone
: detectTimeZone(),
dateFormat: isDefined(workspaceMember.dateFormat)
? getDateFormatFromWorkspaceDateFormat(workspaceMember.dateFormat)
: DateFormat[detectDateFormat()],
timeFormat: isDefined(workspaceMember.timeFormat)
? getTimeFormatFromWorkspaceTimeFormat(workspaceMember.timeFormat)
: TimeFormat[detectTimeFormat()],
});
dynamicActivate(
(workspaceMember.locale as keyof typeof APP_LOCALES) ?? SOURCE_LOCALE,
);
}
if (isDefined(workspaceMembers)) {
setCurrentWorkspaceMembers(
workspaceMembers.map(affectDefaultValuesOnEmptyWorkspaceMemberFields) ??
[],
);
}
if (isDefined(userWorkspaces)) {
const workspaces = userWorkspaces
.map(({ workspace }) => workspace)
.filter(isDefined);
setWorkspaces(workspaces);
}
}, [
setCurrentUser,
setCurrentUserWorkspace,
setCurrentWorkspaceMembers,
isLoading,
queryLoading,
setCurrentWorkspace,
setCurrentWorkspaceMember,
setWorkspaces,
queryData?.currentUser,
setIsCurrentUserLoaded,
setDateTimeFormat,
]);
return <></>;
};