0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-17 22:31:28 -05:00

feat(experience): add identifier register page (#6437)

This commit is contained in:
Xiao Yijun 2024-08-13 15:28:53 +08:00 committed by GitHub
parent d9589c88e8
commit 6a809e1307
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 126 additions and 0 deletions

View file

@ -14,6 +14,7 @@ import Continue from './pages/Continue';
import DirectSignIn from './pages/DirectSignIn';
import ErrorPage from './pages/ErrorPage';
import ForgotPassword from './pages/ForgotPassword';
import IdentifierRegister from './pages/IdentifierRegister';
import IdentifierSignIn from './pages/IdentifierSignIn';
import MfaBinding from './pages/MfaBinding';
import BackupCodeBinding from './pages/MfaBinding/BackupCodeBinding';
@ -129,6 +130,12 @@ const App = () => {
path={experience.routes.identifierSignIn}
element={<IdentifierSignIn />}
/>
{/* Identifier register */}
<Route
path={experience.routes.identifierRegister}
element={<IdentifierRegister />}
/>
</>
)}

View file

@ -0,0 +1,41 @@
import { AgreeToTermsPolicy, experience } from '@logto/schemas';
import { useTranslation } from 'react-i18next';
import { Navigate } from 'react-router-dom';
import IdentifierPageLayout from '@/Layout/IdentifierPageLayout';
import { identifierInputDescriptionMap } from '@/utils/form';
import IdentifierRegisterForm from '../Register/IdentifierRegisterForm';
import useIdentifierSignUpMethods from './use-identifier-sign-up-methods';
const IdentifierRegister = () => {
const { t } = useTranslation();
const signUpMethods = useIdentifierSignUpMethods();
/**
* Fallback to sign-in page if no sign up methods are available (not allowed to create an account).
*/
if (signUpMethods.length === 0) {
return <Navigate to={`/${experience.routes.signIn}`} />;
}
return (
<IdentifierPageLayout
pageMeta={{ titleKey: 'description.create_your_account' }}
title="description.create_account"
description={t('description.identifier_register_description', {
types: signUpMethods.map((identifier) => t(identifierInputDescriptionMap[identifier])),
})}
footerTermsDisplayPolicies={[AgreeToTermsPolicy.Automatic]}
authOptionsLink={{
to: `/${experience.routes.register}`,
text: 'description.all_account_creation_options',
}}
>
<IdentifierRegisterForm signUpMethods={signUpMethods} />
</IdentifierPageLayout>
);
};
export default IdentifierRegister;

View file

@ -0,0 +1,35 @@
import { useMemo } from 'react';
import useIdentifierParams from '@/hooks/use-identifier-params';
import { useSieMethods } from '@/hooks/use-sie';
/**
* Read sign-up methods from sign-in experience config and URL identifier parameters.
*
* Sign-up methods fallback logic:
* 1. If no identifiers are provided in the URL, return all sign-up methods from sign-in experience config.
* 2. If identifiers are provided in the URL but all of them are not supported by the sign-in experience config, return all sign-up methods from sign-in experience config.
* 3. If identifiers are provided in the URL and supported by the sign-in experience config, return the intersection of the two.
*/
const useIdentifierSignUpMethods = () => {
const { signUpMethods: signUpMethodsFromSie } = useSieMethods();
const { identifiers } = useIdentifierParams();
return useMemo(() => {
// Fallback to all sign up methods if no identifiers are provided
if (identifiers.length === 0) {
return signUpMethodsFromSie;
}
const methods = signUpMethodsFromSie.filter((identifier) => identifiers.includes(identifier));
// Fallback to all sign up methods if no identifiers are supported
if (methods.length === 0) {
return signUpMethodsFromSie;
}
return methods;
}, [identifiers, signUpMethodsFromSie]);
};
export default useIdentifierSignUpMethods;

View file

@ -105,6 +105,9 @@ const description = {
identifier_sign_in_description:
'Geben Sie Ihre {{types, list(type: disjunction;)}} ein, um sich anzumelden.',
all_sign_in_options: 'Alle Anmeldeoptionen',
identifier_register_description:
'Geben Sie Ihre {{types, list(type: disjunction;)}} ein, um ein neues Konto zu erstellen.',
all_account_creation_options: 'Alle Kontoerstellungsoptionen',
};
export default Object.freeze(description);

View file

@ -90,6 +90,9 @@ const description = {
auto_agreement: 'By continuing, you agree to the <link></link>.',
identifier_sign_in_description: 'Enter you {{types, list(type: disjunction;)}} to sign in.',
all_sign_in_options: 'All sign-in options',
identifier_register_description:
'Enter you {{types, list(type: disjunction;)}} to create a new account.',
all_account_creation_options: 'All account creation options',
};
export default Object.freeze(description);

View file

@ -105,6 +105,9 @@ const description = {
identifier_sign_in_description:
'Ingrese su {{types, list(type: disjunction;)}} para iniciar sesión.',
all_sign_in_options: 'Todas las opciones de inicio de sesión',
identifier_register_description:
'Ingrese su {{types, list(type: disjunction;)}} para crear una nueva cuenta.',
all_account_creation_options: 'Todas las opciones de creación de cuenta',
};
export default Object.freeze(description);

View file

@ -105,6 +105,9 @@ const description = {
identifier_sign_in_description:
'Entrez votre {{types, list(type: disjunction;)}} pour vous connecter.',
all_sign_in_options: 'Toutes les options de connexion',
identifier_register_description:
'Entrez votre {{types, list(type: disjunction;)}} pour créer un nouveau compte.',
all_account_creation_options: 'Toutes les options de création de compte',
};
export default Object.freeze(description);

View file

@ -102,6 +102,9 @@ const description = {
identifier_sign_in_description:
'Inserisci il tuo {{types, list(type: disjunction;)}} per accedere.',
all_sign_in_options: 'Tutte le opzioni di accesso',
identifier_register_description:
'Inserisci il tuo {{types, list(type: disjunction;)}} per creare un nuovo account.',
all_account_creation_options: 'Tutte le opzioni di creazione account',
};
export default Object.freeze(description);

View file

@ -101,6 +101,9 @@ const description = {
auto_agreement: '続行することで、<link></link>に同意したことになります。',
identifier_sign_in_description: '{{types, list(type: disjunction;)}}を入力してサインインします。',
all_sign_in_options: 'すべてのサインインオプション',
identifier_register_description:
'{{types, list(type: disjunction;)}}を入力して新しいアカウントを作成します。',
all_account_creation_options: 'すべてのアカウント作成オプション',
};
export default Object.freeze(description);

View file

@ -96,6 +96,9 @@ const description = {
identifier_sign_in_description:
'로그인하려면 {{types, list(type: disjunction;)}}을(를) 입력하세요.',
all_sign_in_options: '모든 로그인 옵션',
identifier_register_description:
'새 계정을 만들려면 {{types, list(type: disjunction;)}}을(를) 입력하세요.',
all_account_creation_options: '모든 계정 생성 옵션',
};
export default Object.freeze(description);

View file

@ -103,6 +103,9 @@ const description = {
identifier_sign_in_description:
'Wprowadź swoje {{types, list(type: disjunction;)}} aby się zalogować.',
all_sign_in_options: 'Wszystkie opcje logowania',
identifier_register_description:
'Wprowadź swoje {{types, list(type: disjunction;)}} aby utworzyć nowe konto.',
all_account_creation_options: 'Wszystkie opcje tworzenia konta',
};
export default Object.freeze(description);

View file

@ -99,6 +99,9 @@ const description = {
auto_agreement: 'Ao continuar, você concorda com os <link></link>.',
identifier_sign_in_description: 'Digite seu {{types, list(type: disjunction;)}} para entrar.',
all_sign_in_options: 'Todas as opções de login',
identifier_register_description:
'Digite seu {{types, list(type: disjunction;)}} para criar uma nova conta.',
all_account_creation_options: 'Todas as opções de criação de conta',
};
export default Object.freeze(description);

View file

@ -100,6 +100,9 @@ const description = {
identifier_sign_in_description:
'Introduza o seu {{types, list(type: disjunction;)}} para iniciar sessão.',
all_sign_in_options: 'Todas as opções de início de sessão',
identifier_register_description:
'Introduza o seu {{types, list(type: disjunction;)}} para criar uma nova conta.',
all_account_creation_options: 'Todas as opções de criação de conta',
};
export default Object.freeze(description);

View file

@ -103,6 +103,9 @@ const description = {
auto_agreement: 'Продолжая, вы соглашаетесь с <link></link>.',
identifier_sign_in_description: 'Введите свои {{types, list(type: disjunction;)}} для входа.',
all_sign_in_options: 'Все варианты входа',
identifier_register_description:
'Введите свои {{types, list(type: disjunction;)}} чтобы создать новую учётную запись.',
all_account_creation_options: 'Все варианты создания учётной записи',
};
export default Object.freeze(description);

View file

@ -99,6 +99,9 @@ const description = {
auto_agreement: 'Devam ederek <link></link> kabul etmiş oluyorsunuz.',
identifier_sign_in_description: 'Oturum açmak için {{types, list(type: disjunction;)}} girin.',
all_sign_in_options: 'Tüm oturum açma seçenekleri',
identifier_register_description:
'Yeni bir hesap oluşturmak için {{types, list(type: disjunction;)}} girin.',
all_account_creation_options: 'Tüm hesap oluşturma seçenekleri',
};
export default Object.freeze(description);

View file

@ -79,6 +79,8 @@ const description = {
auto_agreement: '继续即表示您同意<link></link>。',
identifier_sign_in_description: '输入您的{{types, list(type: disjunction;)}}以登录。',
all_sign_in_options: '所有登录选项',
identifier_register_description: '输入您的{{types, list(type: disjunction;)}}以创建新账户。',
all_account_creation_options: '所有账户创建选项',
};
export default Object.freeze(description);

View file

@ -91,6 +91,8 @@ const description = {
auto_agreement: '繼續即表示您同意<link></link>。',
identifier_sign_in_description: '輸入您的{{types, list(type: disjunction;)}}以登入。',
all_sign_in_options: '所有登入選項',
identifier_register_description: '輸入您的{{types, list(type: disjunction;)}}以建立新帳戶。',
all_account_creation_options: '所有帳戶創建選項',
};
export default Object.freeze(description);

View file

@ -91,6 +91,8 @@ const description = {
auto_agreement: '繼續即表示您同意<link></link>。',
identifier_sign_in_description: '輸入您的{{types, list(type: disjunction;)}}以登入。',
all_sign_in_options: '所有登入選項',
identifier_register_description: '輸入您的{{types, list(type: disjunction;)}}以建立新帳戶。',
all_account_creation_options: '所有帳戶創建選項',
};
export default Object.freeze(description);

View file

@ -4,6 +4,7 @@ const routes = Object.freeze({
sso: 'single-sign-on',
consent: 'consent',
identifierSignIn: 'identifier-sign-in',
identifierRegister: 'identifier-register',
});
export const experience = Object.freeze({