From 4cf5bf95cc2eeccfb95fb078115c84d8344f8acb Mon Sep 17 00:00:00 2001 From: Douglas Fabris <devfabris@gmail.com> Date: Wed, 30 Nov 2022 17:58:58 -0300 Subject: [PATCH] Regression: Login and Registration UI Tweaks (#27411) --- apps/meteor/client/providers/UserProvider.tsx | 24 +++++++----- .../rocketchat-i18n/i18n/en.i18n.json | 21 ++++++---- apps/meteor/tests/e2e/forgot-password.spec.ts | 10 ++--- apps/meteor/tests/e2e/page-objects/auth.ts | 8 ++-- packages/ui-contexts/src/UserContext.ts | 3 +- .../web-ui-registration/src/LoginForm.tsx | 25 ++++++------ .../src/{Services.tsx => LoginServices.tsx} | 9 +++-- .../src/LoginServicesButton.tsx | 38 +++++++++++++++++++ .../web-ui-registration/src/RegisterForm.tsx | 13 +++---- .../src/ResetPasswordForm.tsx | 11 +++--- .../src/ServicesButton.tsx | 37 ------------------ .../src/components/LoginPoweredBy.tsx | 2 +- .../src/components/RegisterTitle.tsx | 11 +----- 13 files changed, 102 insertions(+), 110 deletions(-) rename packages/web-ui-registration/src/{Services.tsx => LoginServices.tsx} (71%) create mode 100644 packages/web-ui-registration/src/LoginServicesButton.tsx delete mode 100644 packages/web-ui-registration/src/ServicesButton.tsx diff --git a/apps/meteor/client/providers/UserProvider.tsx b/apps/meteor/client/providers/UserProvider.tsx index fe52016ac32..a05435a42e6 100644 --- a/apps/meteor/client/providers/UserProvider.tsx +++ b/apps/meteor/client/providers/UserProvider.tsx @@ -17,16 +17,20 @@ const getUser = (): IUser | null => Meteor.user() as IUser | null; const capitalize = (str: string): string => str.charAt(0).toUpperCase() + str.slice(1); const config: Record<string, Partial<LoginService>> = { - 'facebook': { buttonColor: '#325c99' }, - 'twitter': { buttonColor: '#02acec' }, - 'google': { buttonColor: '#dd4b39' }, - 'github': { buttonColor: '#4c4c4c', title: 'GitHub' }, - 'github_enterprise': { buttonColor: '#4c4c4c', title: 'GitHub Enterprise' }, - 'gitlab': { buttonColor: '#373d47', title: 'GitLab' }, - 'trello': { buttonColor: '#026aa7' }, - 'meteor-developer': { buttonColor: '#de4f4f', title: 'Meteor' }, - 'wordpress': { buttonColor: '#1e8cbe', title: 'WordPress' }, - 'linkedin': { buttonColor: '#1b86bc' }, + 'apple': { title: 'Apple', icon: 'apple' }, + 'facebook': { title: 'Facebook', icon: 'facebook' }, + 'twitter': { title: 'Twitter', icon: 'twitter' }, + 'google': { title: 'Google', icon: 'google' }, + 'github': { title: 'Github', icon: 'github' }, + 'github_enterprise': { title: 'Github Enterprise', icon: 'github' }, + 'gitlab': { title: 'Gitlab', icon: 'gitlab' }, + 'dolphin': { title: 'Dolphin', icon: 'dophin' }, + 'drupal': { title: 'Drupal', icon: 'drupal' }, + 'nextcloud': { title: 'Nextcloud', icon: 'nextcloud' }, + 'tokenpass': { title: 'Tokenpass', icon: 'tokenpass' }, + 'meteor-developer': { title: 'Meteor', icon: 'meteor' }, + 'wordpress': { title: 'WordPress', icon: 'wordpress' }, + 'linkedin': { title: 'Linkedin', icon: 'linkedin' }, }; const logout = (): Promise<void> => diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 558d18deb4e..53fc9b1aeb4 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -4393,6 +4393,7 @@ "Sidebar": "Sidebar", "Sidebar_list_mode": "Sidebar Channel List Mode", "Sign_in_to_start_talking": "Sign in to start talking", + "Sign_in_with__provider__": "Sign in with __provider__", "since_creation": "since %s", "Site_Name": "Site Name", "Site_Url": "Site URL", @@ -5433,27 +5434,29 @@ "registration.page.login.errors.licenseUserLimitReached": "The maximum number of users has been reached.", "registration.page.login.errors.AppUserNotAllowedToLogin": "App users are not allowed to log in directly.", "registration.page.registration.waitActivationWarning": "Before you can login, your account must be manually activated by an administrator.", - "onboarding.component.form.requiredField": "This field is required", - "registration.page.login.register": "New here? <1>Register</1>", + "registration.page.login.register": "New here? <1>Create an account</1>", "registration.page.login.forgot": "Forgot your password?", "registration.page.register.back": "Back to Login", "registration.page.emailVerification.subTitle": "This server requires verified email addresses. Please check your email inbox for a verification link.", "registration.page.emailVerification.sent": "Verification email sent, please check your inbox.", "registration.page.resetPassword.sent": "If this email is registered, we'll send instructions on how to reset your password. If you do not receive an email shortly, please come back and try again.", - "registration.page.poweredBy": "Powered by <1>RocketChat</1>", - "registration.component.welcome": "Welcome to <1>Rocket.chat</1>", + "registration.page.resetPassword.sendInstructions": "Send instructions", + "registration.page.resetPassword.errors.invalidEmail": "Invalid Email", + "registration.page.poweredBy": "Powered by <1>Rocket.Chat</1>", + "registration.component.welcome": "Welcome to <1>Rocket.Chat</1> workspace", "registration.component.login": "Login", + "registration.component.login.userNotFound": "User not found", + "registration.component.login.incorrectPassword": "Incorrect password", "registration.component.switchLanguage": "Switch to <1>en</1>", "registration.component.resetPassword": "Reset password", "registration.component.form.emailOrUsername": "Email or username", - "registration.component.form.emailOrUsernamePlaceholder": "jon.doe", "registration.component.form.email": "Email", - "registration.component.form.emailPlaceholder": "your@email.com", - "registration.component.form.emailHint": "Please enter your email address", + "registration.component.form.emailPlaceholder": "example@example.com", "registration.component.form.password": "Password", "registration.component.form.divider": "or", "registration.component.form.submit": "Submit", "registration.component.form.requiredField": "This field is required", + "onboarding.component.form.requiredField": "This field is required", "onboarding.component.form.steps": "Step {{currentStep}} of {{stepCount}}", "onboarding.component.form.action.back": "Back", "onboarding.component.form.action.next": "Next", @@ -5531,5 +5534,7 @@ "Something_Went_Wrong": "Something went wrong", "Toolbox_room_actions": "Primary Room actions", "Theme_light": "Light", - "Theme_dark": "Dark" + "Theme_dark": "Dark", + "Join_your_team": "Join your team", + "Create_an_account": "Create an account" } \ No newline at end of file diff --git a/apps/meteor/tests/e2e/forgot-password.spec.ts b/apps/meteor/tests/e2e/forgot-password.spec.ts index 498e4d4f495..44cb45475d8 100644 --- a/apps/meteor/tests/e2e/forgot-password.spec.ts +++ b/apps/meteor/tests/e2e/forgot-password.spec.ts @@ -13,31 +13,29 @@ test.describe.parallel('Forgot Password', () => { test('Email validation', async () => { await test.step('expect trigger a validation error if no email is provided', async () => { - await poRegistration.btnSubmit.click(); + await poRegistration.btnSendInstructions.click(); await expect(poRegistration.inputEmail).toBeInvalid(); }); await test.step('expect trigger a validation if a invalid email is provided (1)', async () => { await poRegistration.inputEmail.fill('mail@mail'); - await poRegistration.btnSubmit.click(); + await poRegistration.btnSendInstructions.click(); await expect(poRegistration.inputEmail).toBeInvalid(); }); await test.step('expect trigger a validation if a invalid email is provided (2)', async () => { await poRegistration.inputEmail.fill('mail'); - await poRegistration.btnSubmit.click(); + await poRegistration.btnSendInstructions.click(); await expect(poRegistration.inputEmail).toBeInvalid(); }); await test.step('expect to show a success toast if a valid email is provided', async () => { await poRegistration.inputEmail.fill('mail@mail.com'); - await poRegistration.btnSubmit.click(); + await poRegistration.btnSendInstructions.click(); await expect(poRegistration.forgotPasswordEmailCallout).toBeVisible(); }); }); - - // test('Reset Password disabled', async () => {}); }); diff --git a/apps/meteor/tests/e2e/page-objects/auth.ts b/apps/meteor/tests/e2e/page-objects/auth.ts index 96cde1f0899..02b1811f996 100644 --- a/apps/meteor/tests/e2e/page-objects/auth.ts +++ b/apps/meteor/tests/e2e/page-objects/auth.ts @@ -7,8 +7,8 @@ export class Registration { this.page = page; } - get btnSubmit(): Locator { - return this.page.locator('role=button[name="Submit"]'); + get btnSendInstructions(): Locator { + return this.page.locator('role=button[name="Send instructions"]'); } get btnLogin(): Locator { @@ -16,7 +16,7 @@ export class Registration { } get goToRegister(): Locator { - return this.page.locator('role=link[name="Register"]'); + return this.page.locator('role=link[name="Create an account"]'); } get main(): Locator { @@ -28,7 +28,7 @@ export class Registration { } get btnRegister(): Locator { - return this.page.locator('role=button[name="Register"]'); + return this.page.locator('role=button[name="Join your team"]'); } get btnRegisterConfirmUsername(): Locator { diff --git a/packages/ui-contexts/src/UserContext.ts b/packages/ui-contexts/src/UserContext.ts index 712149d8383..9fa335e95ce 100644 --- a/packages/ui-contexts/src/UserContext.ts +++ b/packages/ui-contexts/src/UserContext.ts @@ -34,8 +34,7 @@ export type LoginService = { service: string; buttonLabelText?: string; - buttonLabelColor?: string; - buttonColor?: string; + icon?: string; }; export type UserContextValue = { diff --git a/packages/web-ui-registration/src/LoginForm.tsx b/packages/web-ui-registration/src/LoginForm.tsx index 0ca5cdbc5e4..89225ff354a 100644 --- a/packages/web-ui-registration/src/LoginForm.tsx +++ b/packages/web-ui-registration/src/LoginForm.tsx @@ -11,7 +11,7 @@ import { Trans, useTranslation } from 'react-i18next'; import EmailConfirmationForm from './EmailConfirmationForm'; import type { DispatchLoginRouter } from './hooks/useLoginRouter'; -import Services from './Services'; +import LoginServices from './LoginServices'; type LoginErrors = | 'error-user-is-not-activated' @@ -38,14 +38,10 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute mode: 'onChange', }); + const { t } = useTranslation(); const formLabelId = useUniqueId(); - const [errorOnSubmit, setErrorOnSubmit] = useState<LoginErrors | undefined>(undefined); - const isResetPasswordAllowed = useSetting('Accounts_PasswordReset'); - - const { t } = useTranslation(); - const login = useLoginWithPassword(); const loginMutation: UseMutationResult< @@ -71,8 +67,8 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute } setErrorOnSubmit('user-not-found'); - setError('username', { type: 'user-not-found', message: t('User_not_found') }); - setError('password', { type: 'user-not-found', message: t('User_not_found') }); + setError('username', { type: 'user-not-found', message: t('registration.component.login.userNotFound') }); + setError('password', { type: 'user-not-found', message: t('registration.component.login.incorrectPassword') }); }, }); @@ -100,7 +96,6 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute <Form.Title id={formLabelId}>{t('registration.component.login')}</Form.Title> </Form.Header> <Form.Container> - <Services disabled={loginMutation.isLoading} /> <FieldGroup disabled={loginMutation.isLoading}> <Field> <Field.Label htmlFor='username'>{t('registration.component.form.emailOrUsername')}</Field.Label> @@ -109,7 +104,7 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute {...register('username', { required: true, })} - placeholder={t('registration.component.form.emailOrUsernamePlaceholder')} + placeholder={t('registration.component.form.emailPlaceholder')} error={ errors.username?.message || (errors.username?.type === 'required' ? t('registration.component.form.requiredField') : undefined) @@ -130,7 +125,6 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute {...register('password', { required: true, })} - placeholder='*****' error={ errors.password?.message || (errors.password?.type === 'required' ? t('registration.component.form.requiredField') : undefined) @@ -165,10 +159,13 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute {errorOnSubmit === 'error-app-user-is-not-allowed-to-login' && ( <Callout type='danger'>{t('registration.page.login.errors.AppUserNotAllowedToLogin')}</Callout> )} + {errorOnSubmit === 'user-not-found' && <Callout type='danger'>{t('registration.page.login.errors.wrongCredentials')}</Callout>} + {errorOnSubmit === 'error-login-blocked-for-ip' && ( <Callout type='danger'>{t('registration.page.login.errors.loginBlockedForIp')}</Callout> )} + {errorOnSubmit === 'error-login-blocked-for-user' && ( <Callout type='danger'>{t('registration.page.login.errors.loginBlockedForUser')}</Callout> )} @@ -176,21 +173,21 @@ export const LoginForm = ({ setLoginRoute }: { setLoginRoute: DispatchLoginRoute {errorOnSubmit === 'error-license-user-limit-reached' && ( <Callout type='warning'>{t('registration.page.login.errors.licenseUserLimitReached')}</Callout> )} - {/* error-invalid-email */} </FieldGroup> </Form.Container> <Form.Footer> <ButtonGroup stretch> - <Button type='submit' primary> + <Button disabled={loginMutation.isLoading} type='submit' primary> {t('registration.component.login')} </Button> </ButtonGroup> <p> <Trans i18nKey='registration.page.login.register'> - New here? <ActionLink onClick={(): void => setLoginRoute('register')}>Register</ActionLink> + New here? <ActionLink onClick={(): void => setLoginRoute('register')}>Create an account</ActionLink> </Trans> </p> </Form.Footer> + <LoginServices disabled={loginMutation.isLoading} /> </Form> ); }; diff --git a/packages/web-ui-registration/src/Services.tsx b/packages/web-ui-registration/src/LoginServices.tsx similarity index 71% rename from packages/web-ui-registration/src/Services.tsx rename to packages/web-ui-registration/src/LoginServices.tsx index d67237932d4..07152b15b58 100644 --- a/packages/web-ui-registration/src/Services.tsx +++ b/packages/web-ui-registration/src/LoginServices.tsx @@ -3,23 +3,24 @@ import { useLoginServices } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; -import ServicesButton from './ServicesButton'; +import LoginServicesButton from './LoginServicesButton'; const Services = ({ disabled }: { disabled?: boolean }): ReactElement | null => { - const services = useLoginServices(); const { t } = useTranslation(); + const services = useLoginServices(); + if (services.length === 0) { return null; } return ( <> + <Divider mb={24} p={0} children={t('registration.component.form.divider')} /> <ButtonGroup vertical stretch small> {services.map((service) => ( - <ServicesButton disabled={disabled} key={service.service} {...service} /> + <LoginServicesButton disabled={disabled} key={service.service} {...service} /> ))} </ButtonGroup> - <Divider children={t('registration.component.form.divider')} /> </> ); }; diff --git a/packages/web-ui-registration/src/LoginServicesButton.tsx b/packages/web-ui-registration/src/LoginServicesButton.tsx new file mode 100644 index 00000000000..c00e7519bda --- /dev/null +++ b/packages/web-ui-registration/src/LoginServicesButton.tsx @@ -0,0 +1,38 @@ +import { Button, Icon } from '@rocket.chat/fuselage'; +import type { LoginService } from '@rocket.chat/ui-contexts'; +import { useLoginWithService, useTranslation } from '@rocket.chat/ui-contexts'; +import type { ReactElement, ComponentProps } from 'react'; + +const LoginServicesButton = <T extends LoginService>({ + buttonLabelText, + icon, + title, + clientConfig, + service, + className, + disabled, + ...props +}: T & { + className?: string; + disabled?: boolean; +}): ReactElement => { + const t = useTranslation(); + const handler = useLoginWithService({ service, buttonLabelText, title, clientConfig, ...props }); + + return ( + <Button + className={className} + onClick={handler} + title={buttonLabelText && buttonLabelText !== title ? title : undefined} + disabled={disabled} + alignItems='center' + display='flex' + justifyContent='center' + > + {icon && <Icon size='x20' mie='x4' name={icon as ComponentProps<typeof Icon>['name']} />} + {buttonLabelText || t('Sign_in_with__provider__', { provider: title })} + </Button> + ); +}; + +export default LoginServicesButton; diff --git a/packages/web-ui-registration/src/RegisterForm.tsx b/packages/web-ui-registration/src/RegisterForm.tsx index 8c17f48b66d..ec83ba8f8a4 100644 --- a/packages/web-ui-registration/src/RegisterForm.tsx +++ b/packages/web-ui-registration/src/RegisterForm.tsx @@ -63,7 +63,7 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo return ( <Form aria-labelledby={formLabelId} onSubmit={handleSubmit(handleRegister)}> <Form.Header> - <Form.Title id={formLabelId}>{t('Register')}</Form.Title> + <Form.Title id={formLabelId}>{t('Create_an_account')}</Form.Title> </Form.Header> <Form.Container> <FieldGroup> @@ -74,7 +74,6 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo {...register('name', { required: requireNameForRegister, })} - placeholder={'Jon Doe'} error={ errors.name && t('The_field_is_required', { @@ -102,7 +101,7 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo {...register('email', { required: true, })} - placeholder={'your@email.com'} + placeholder='example@example.com' error={ errors.email && t('The_field_is_required', { @@ -138,7 +137,7 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo } aria-invalid={errors.username ? 'true' : undefined} id='username' - placeholder={t('Username')} + placeholder='jon.doe' /> </Field.Row> {errors.username?.message && <Field.Error>{errors.username.message}</Field.Error>} @@ -153,7 +152,6 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo {...register('password', { required: t('The_field_is_required', { postProcess: 'sprintf', sprintf: [t('Password')] }), })} - placeholder='******' error={errors.password && (errors.password?.message || t('registration.component.form.requiredField'))} aria-invalid={errors.password ? 'true' : undefined} id='password' @@ -172,7 +170,6 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo validate: (val: string) => watch('password') === val, })} error={errors.passwordConfirmation?.type === 'validate' ? t('Invalid_confirm_pass') : undefined} - placeholder='******' aria-invalid={errors.passwordConfirmation ? 'true' : false} id='passwordConfirmation' /> @@ -215,8 +212,8 @@ export const LoginRegisterForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo </Form.Container> <Form.Footer> <ButtonGroup> - <Button type='submit' primary> - {t('Register')} + <Button type='submit' disabled={registerUser.isLoading} primary> + {t('Join_your_team')} </Button> </ButtonGroup> <ActionLink diff --git a/packages/web-ui-registration/src/ResetPasswordForm.tsx b/packages/web-ui-registration/src/ResetPasswordForm.tsx index 9c4d92e1d4a..3eba7d28782 100644 --- a/packages/web-ui-registration/src/ResetPasswordForm.tsx +++ b/packages/web-ui-registration/src/ResetPasswordForm.tsx @@ -15,7 +15,7 @@ export const ResetPasswordForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo const { register, handleSubmit, - formState: { errors }, + formState: { errors, isSubmitting }, } = useForm<{ email: string; }>(); @@ -42,7 +42,7 @@ export const ResetPasswordForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo required: true, pattern: { value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, - message: t('error-invalid-email-address'), + message: t('registration.page.resetPassword.errors.invalidEmail'), }, })} error={errors.email && (errors.email?.message || t('registration.component.form.requiredField'))} @@ -53,12 +53,11 @@ export const ResetPasswordForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo /> </Field.Row> {errors.email && <Field.Error>{errors.email.message || t('registration.component.form.requiredField')}</Field.Error>} - <Field.Hint>{t('registration.component.form.emailHint')}</Field.Hint> </Field> </FieldGroup> {sent && ( <FieldGroup> - <Callout role='status' type='warning'> + <Callout role='status' mbs='x24' icon='mail'> {t('registration.page.resetPassword.sent')} </Callout> </FieldGroup> @@ -66,8 +65,8 @@ export const ResetPasswordForm = ({ setLoginRoute }: { setLoginRoute: DispatchLo </Form.Container> <Form.Footer> <ButtonGroup> - <Button type='submit' primary> - {t('registration.component.form.submit')} + <Button type='submit' disabled={isSubmitting} primary> + {t('registration.page.resetPassword.sendInstructions')} </Button> </ButtonGroup> diff --git a/packages/web-ui-registration/src/ServicesButton.tsx b/packages/web-ui-registration/src/ServicesButton.tsx deleted file mode 100644 index d88838918dc..00000000000 --- a/packages/web-ui-registration/src/ServicesButton.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Button } from '@rocket.chat/fuselage'; -import type { LoginService } from '@rocket.chat/ui-contexts'; -import { useLoginWithService } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; - -const ServicesButton = <T extends LoginService>({ - buttonLabelColor, - buttonColor, - buttonLabelText, - title, - clientConfig, - service, - className, - disabled, - ...props -}: T & { - className?: string; - disabled?: boolean; -}): ReactElement => { - const handler = useLoginWithService({ service, buttonLabelColor, buttonColor, buttonLabelText, title, clientConfig, ...props }); - return ( - <Button - primary - className={className} - onClick={handler} - title={buttonLabelText && buttonLabelText !== title ? title : undefined} - backgroundColor={buttonColor} - borderColor={buttonColor} - color={buttonLabelColor} - disabled={disabled} - > - {buttonLabelText || title} - </Button> - ); -}; - -export default ServicesButton; diff --git a/packages/web-ui-registration/src/components/LoginPoweredBy.tsx b/packages/web-ui-registration/src/components/LoginPoweredBy.tsx index af32f792d07..a1d72f0d74a 100644 --- a/packages/web-ui-registration/src/components/LoginPoweredBy.tsx +++ b/packages/web-ui-registration/src/components/LoginPoweredBy.tsx @@ -5,7 +5,7 @@ import React from 'react'; export const LoginPoweredBy = (): ReactElement => ( <Trans i18nKey='registration.page.poweredBy'> - {'Powered by '} + Powered by <Link href='https://rocket.chat/' target='_blank' rel='noopener noreferrer'> Rocket.Chat </Link> diff --git a/packages/web-ui-registration/src/components/RegisterTitle.tsx b/packages/web-ui-registration/src/components/RegisterTitle.tsx index cd196afcb9e..8684947a20b 100644 --- a/packages/web-ui-registration/src/components/RegisterTitle.tsx +++ b/packages/web-ui-registration/src/components/RegisterTitle.tsx @@ -1,17 +1,8 @@ -import { Box } from '@rocket.chat/fuselage'; import { useSetting } from '@rocket.chat/ui-contexts'; import type { ReactElement } from 'react'; import { Trans } from 'react-i18next'; export const RegisterTitle = (): ReactElement => { const siteName = String(useSetting('Site_Name')); - return ( - <Trans i18nKey='registration.component.welcome'> - Welcome to - <Box is='span' color='primary-500'> - {' '} - {siteName} - </Box> - </Trans> - ); + return <Trans i18nKey='registration.component.welcome'>Welcome to {siteName} workspace</Trans>; }; -- GitLab