Translations - Crowdin, Set workspace member locale on signup, and optimizations (#10091)

More progress on translations:
- Migrate from translations.io to crowdin
- Optimize performance and robustness 
- Set workspaceMember/user locale upon signup
This commit is contained in:
Félix Malfait
2025-02-09 22:10:41 +01:00
committed by GitHub
parent fd3f01ab80
commit bb24c97f80
163 changed files with 84053 additions and 2554 deletions

View File

@ -21,6 +21,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { Trans, useLingui } from '@lingui/react/macro';
import { isDefined } from 'twenty-shared';
import { OnboardingStatus } from '~/generated/graphql';
@ -55,6 +56,7 @@ const validationSchema = z
type Form = z.infer<typeof validationSchema>;
export const CreateProfile = () => {
const { t } = useLingui();
const onboardingStatus = useOnboardingStatus();
const setNextOnboardingStatus = useSetNextOnboardingStatus();
const { enqueueSnackBar } = useSnackBar();
@ -148,8 +150,12 @@ export const CreateProfile = () => {
return (
<>
<Title noMarginTop>Create profile</Title>
<SubTitle>How you'll be identified on the app.</SubTitle>
<Title noMarginTop>
<Trans>Create profile</Trans>
</Title>
<SubTitle>
<Trans>How you'll be identified on the app.</Trans>
</SubTitle>
<StyledContentContainer>
<StyledSectionContainer>
<H2Title title="Picture" />
@ -157,8 +163,8 @@ export const CreateProfile = () => {
</StyledSectionContainer>
<StyledSectionContainer>
<H2Title
title="Name"
description="Your name as it will be displayed on the app"
title={t`Name`}
description={t`Your name as it will be displayed on the app`}
/>
{/* TODO: When react-web-hook-form is added to edit page we should create a dedicated component with context */}
<StyledComboInputContainer>
@ -171,7 +177,7 @@ export const CreateProfile = () => {
}) => (
<TextInputV2
autoFocus
label="First Name"
label={t`First Name`}
value={value}
onFocus={() => setIsEditingMode(true)}
onBlur={() => {
@ -193,7 +199,7 @@ export const CreateProfile = () => {
fieldState: { error },
}) => (
<TextInputV2
label="Last Name"
label={t`Last Name`}
value={value}
onFocus={() => setIsEditingMode(true)}
onBlur={() => {
@ -212,7 +218,7 @@ export const CreateProfile = () => {
</StyledContentContainer>
<StyledButtonContainer>
<MainButton
title="Continue"
title={t`Continue`}
onClick={handleSubmit(onSubmit)}
disabled={!isValid || isSubmitting}
fullWidth

View File

@ -15,6 +15,7 @@ import { WorkspaceLogoUploader } from '@/settings/workspace/components/Workspace
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
import { Trans, useLingui } from '@lingui/react/macro';
import { isDefined } from 'twenty-shared';
import {
OnboardingStatus,
@ -34,15 +35,8 @@ const StyledButtonContainer = styled.div`
width: 200px;
`;
const validationSchema = z
.object({
name: z.string().min(1, { message: 'Name can not be empty' }),
})
.required();
type Form = z.infer<typeof validationSchema>;
export const CreateWorkspace = () => {
const { t } = useLingui();
const { enqueueSnackBar } = useSnackBar();
const onboardingStatus = useOnboardingStatus();
const setNextOnboardingStatus = useSetNextOnboardingStatus();
@ -50,6 +44,14 @@ export const CreateWorkspace = () => {
const { loadCurrentUser } = useAuth();
const [activateWorkspace] = useActivateWorkspaceMutation();
const validationSchema = z
.object({
name: z.string().min(1, { message: t`Name can not be empty` }),
})
.required();
type Form = z.infer<typeof validationSchema>;
// Form
const {
control,
@ -75,7 +77,7 @@ export const CreateWorkspace = () => {
});
if (isDefined(result.errors)) {
throw result.errors ?? new Error('Unknown error');
throw result.errors ?? new Error(t`Unknown error`);
}
await loadCurrentUser();
setNextOnboardingStatus();
@ -90,6 +92,7 @@ export const CreateWorkspace = () => {
enqueueSnackBar,
loadCurrentUser,
setNextOnboardingStatus,
t,
],
);
@ -106,20 +109,24 @@ export const CreateWorkspace = () => {
return (
<>
<Title noMarginTop>Create your workspace</Title>
<Title noMarginTop>
<Trans>Create your workspace</Trans>
</Title>
<SubTitle>
A shared environment where you will be able to manage your customer
relations with your team.
<Trans>
A shared environment where you will be able to manage your customer
relations with your team.
</Trans>
</SubTitle>
<StyledContentContainer>
<StyledSectionContainer>
<H2Title title="Workspace logo" />
<H2Title title={t`Workspace logo`} />
<WorkspaceLogoUploader />
</StyledSectionContainer>
<StyledSectionContainer>
<H2Title
title="Workspace name"
description="The name of your organization"
title={t`Workspace name`}
description={t`The name of your organization`}
/>
<Controller
name="name"
@ -144,7 +151,7 @@ export const CreateWorkspace = () => {
</StyledContentContainer>
<StyledButtonContainer>
<MainButton
title="Continue"
title={t`Continue`}
onClick={handleSubmit(onSubmit)}
disabled={!isValid || isSubmitting}
Icon={() => isSubmitting && <Loader />}

View File

@ -71,27 +71,27 @@ export const LocalePicker = () => {
},
{
label: t`French`,
value: APP_LOCALES.fr,
value: APP_LOCALES['fr-FR'],
},
{
label: t`Spanish`,
value: APP_LOCALES.es,
value: APP_LOCALES['es-ES'],
},
{
label: t`German`,
value: APP_LOCALES.de,
value: APP_LOCALES['de-DE'],
},
{
label: t`Italian`,
value: APP_LOCALES.it,
value: APP_LOCALES['it-IT'],
},
{
label: t`Korean`,
value: APP_LOCALES.ko,
value: APP_LOCALES['ko-KR'],
},
{
label: t`Japanese`,
value: APP_LOCALES.ja,
value: APP_LOCALES['ja-JP'],
},
{
label: t`Portuguese — Portugal`,
@ -103,17 +103,17 @@ export const LocalePicker = () => {
},
{
label: t`Chinese — Simplified`,
value: APP_LOCALES['zh-Hans'],
value: APP_LOCALES['zh-CN'],
},
{
label: t`Chinese — Traditional`,
value: APP_LOCALES['zh-Hant'],
value: APP_LOCALES['zh-TW'],
},
];
if (isDebugMode) {
localeOptions.push({
label: t`Pseudo-English`,
value: 'pseudo-en',
value: APP_LOCALES['pseudo-en'],
});
}