diff --git a/packages/experience/src/containers/VerificationCode/index.test.tsx b/packages/experience/src/containers/VerificationCode/index.test.tsx
index c6006db2522..45dfbb1a95c 100644
--- a/packages/experience/src/containers/VerificationCode/index.test.tsx
+++ b/packages/experience/src/containers/VerificationCode/index.test.tsx
@@ -1,3 +1,4 @@
+import resource from '@logto/phrases-experience';
import { SignInIdentifier } from '@logto/schemas';
import { act, fireEvent, waitFor } from '@testing-library/react';
@@ -8,6 +9,7 @@ import {
addProfileWithVerificationCodeIdentifier,
} from '@/apis/interaction';
import { sendVerificationCodeApi } from '@/apis/utils';
+import { setupI18nForTesting } from '@/jest.setup';
import { UserFlow } from '@/types';
import VerificationCode from '.';
@@ -69,19 +71,37 @@ describe('', () => {
});
it('fire resend event', async () => {
+ /**
+ * Apply the resource with resend_passcode for testing nested translation
+ * Since the 'resend_passcode' phrase need be rendered into the following structure for testing:
+ * ```
+ *
+ * ```
+ * otherwise this phrase will be rendered as 'description.resend_passcode'.
+ * That will cause the resend button cannot be clicked.
+ */
+ await setupI18nForTesting({
+ translation: {
+ description: { resend_passcode: resource.en.translation.description.resend_passcode },
+ },
+ });
+
const { getByText } = renderWithPageContext(
);
act(() => {
jest.advanceTimersByTime(1e3 * 60);
});
- const resendButton = getByText('description.resend_passcode');
+ const resendButton = getByText('Resend verification code');
await waitFor(() => {
fireEvent.click(resendButton);
});
expect(sendVerificationCodeApi).toBeCalledWith(UserFlow.SignIn, { email });
+
+ // Reset i18n
+ await setupI18nForTesting();
});
describe('sign-in', () => {
diff --git a/packages/experience/src/containers/VerificationCode/index.tsx b/packages/experience/src/containers/VerificationCode/index.tsx
index 8d3732639d1..ecd180b67a0 100644
--- a/packages/experience/src/containers/VerificationCode/index.tsx
+++ b/packages/experience/src/containers/VerificationCode/index.tsx
@@ -61,24 +61,30 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ
error={errorMessage}
onChange={setCode}
/>
- {isRunning ? (
-
+
+ {isRunning ? (
}}>
{t('description.resend_after_seconds', { seconds })}
-
- ) : (
-
{
- clearErrorMessage();
- await onResendVerificationCode();
- setCode([]);
- }}
- />
- )}
-
+ ) : (
+ {
+ clearErrorMessage();
+ await onResendVerificationCode();
+ setCode([]);
+ }}
+ />
+ ),
+ }}
+ >
+ {t('description.resend_passcode')}
+
+ )}
+
{flow === UserFlow.SignIn && hasPasswordButton && (
)}
diff --git a/packages/experience/src/jest.setup.ts b/packages/experience/src/jest.setup.ts
index 4a3e18cc560..4b4b223eabf 100644
--- a/packages/experience/src/jest.setup.ts
+++ b/packages/experience/src/jest.setup.ts
@@ -1,5 +1,7 @@
// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
+import { type LocalePhrase } from '@logto/phrases-experience';
+import { type DeepPartial } from '@silverhand/essentials';
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
@@ -19,9 +21,18 @@ Object.defineProperty(window, 'matchMedia', {
})),
});
-void i18next.use(initReactI18next).init({
- // Simple resources for testing
- resources: { en: { translation: { action: { agree: 'Agree' } } } },
- lng: 'en',
- react: { useSuspense: false },
-});
+// Simple resources for testing
+const defaultI18nResources: DeepPartial = {
+ translation: { action: { agree: 'Agree' } },
+};
+
+export const setupI18nForTesting = async (
+ enPhrase: DeepPartial = defaultI18nResources
+) =>
+ i18next.use(initReactI18next).init({
+ resources: { en: enPhrase },
+ lng: 'en',
+ react: { useSuspense: false },
+ });
+
+void setupI18nForTesting();
diff --git a/packages/phrases-experience/src/locales/de/description.ts b/packages/phrases-experience/src/locales/de/description.ts
index a9b4070c9d5..1f8e5316c3c 100644
--- a/packages/phrases-experience/src/locales/de/description.ts
+++ b/packages/phrases-experience/src/locales/de/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'und',
enter_passcode: 'Der Bestätigungscode wurde an deine {{address}} gesendet',
passcode_sent: 'Der Bestätigungscode wurde erneut gesendet',
- resend_after_seconds: 'Nach {{seconds}} Sekunden erneut senden',
- resend_passcode: 'Bestätigungscode erneut senden',
+ resend_after_seconds: 'Noch nicht erhalten? Erneut senden nach {{seconds}} Sekunden',
+ resend_passcode: 'Noch nicht erhalten? Bestätigungscode erneut senden',
create_account_id_exists:
'Das Konto mit {{type}} {{value}} existiert bereits, möchtest du dich anmelden?',
link_account_id_exists:
diff --git a/packages/phrases-experience/src/locales/en/description.ts b/packages/phrases-experience/src/locales/en/description.ts
index a4c6b3c4389..48a8f3dfe6e 100644
--- a/packages/phrases-experience/src/locales/en/description.ts
+++ b/packages/phrases-experience/src/locales/en/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'and',
enter_passcode: 'The verification code has been sent to your {{address}} {{target}}',
passcode_sent: 'The verification code has been resent',
- resend_after_seconds: 'Resend after {{seconds}} seconds',
- resend_passcode: 'Resend verification code',
+ resend_after_seconds: 'Not received yet? Resend after {{seconds}} seconds',
+ resend_passcode: 'Not received yet? Resend verification code',
create_account_id_exists:
'The account with {{type}} {{value}} already exists, would you like to sign in?',
link_account_id_exists:
diff --git a/packages/phrases-experience/src/locales/es/description.ts b/packages/phrases-experience/src/locales/es/description.ts
index c3464f1dbdd..a26a05893fd 100644
--- a/packages/phrases-experience/src/locales/es/description.ts
+++ b/packages/phrases-experience/src/locales/es/description.ts
@@ -14,8 +14,9 @@ const description = {
and: 'y',
enter_passcode: 'El código de verificación ha sido enviado a su {{address}} {{target}}',
passcode_sent: 'El código de verificación ha sido reenviado',
- resend_after_seconds: 'Reenviar después de {{seconds}} segundos',
- resend_passcode: 'Reenviar código de verificación',
+ resend_after_seconds:
+ '¿No lo has recibido? Reenviar después de {{seconds}} segundos',
+ resend_passcode: '¿No lo has recibido? Reenviar código de verificación',
create_account_id_exists: 'La cuenta con {{type}} {{value}} ya existe, ¿desea iniciar sesión?',
link_account_id_exists: 'La cuenta con {{type}} {{value}} ya existe. ¿Desea vincular?',
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/fr/description.ts b/packages/phrases-experience/src/locales/fr/description.ts
index ac844fe3cb2..6d829b8ef5f 100644
--- a/packages/phrases-experience/src/locales/fr/description.ts
+++ b/packages/phrases-experience/src/locales/fr/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'et',
enter_passcode: 'Le code a été envoyé à {{address}} {{target}}',
passcode_sent: 'Le code a été renvoyé',
- resend_after_seconds: 'Renvoyer après {{seconds}} secondes',
- resend_passcode: 'Renvoyer le code',
+ resend_after_seconds: 'Pas encore reçu ? Renvoyer après {{seconds}} secondes',
+ resend_passcode: 'Pas encore reçu ? Renvoyer le code de vérification',
create_account_id_exists:
'Le compte avec {{type}} {{value}} existe déjà, voulez-vous vous connecter?',
link_account_id_exists: 'Le compte avec {{type}} {{value}} existe déjà, voulez-vous le lier?',
diff --git a/packages/phrases-experience/src/locales/it/description.ts b/packages/phrases-experience/src/locales/it/description.ts
index 734f6d548b1..91cd6c3d937 100644
--- a/packages/phrases-experience/src/locales/it/description.ts
+++ b/packages/phrases-experience/src/locales/it/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'e',
enter_passcode: 'Il codice di verifica è stato inviato alla tua {{address}} {{target}}',
passcode_sent: 'Il codice di verifica è stato inviato di nuovo',
- resend_after_seconds: 'Inviare di nuovo dopo {{seconds}} secondi',
- resend_passcode: 'Inviare nuovamente il codice di verifica',
+ resend_after_seconds: 'Non ricevuto? Invia di nuovo dopo {{seconds}} secondi',
+ resend_passcode: 'Non ricevuto? Invia di nuovo il codice di verifica',
create_account_id_exists: "L'account con {{type}} {{value}} già esiste, vuoi accedere?",
link_account_id_exists: "L'account con {{type}} {{value}} è già esistente. Vuoi collegarlo?",
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/ja/description.ts b/packages/phrases-experience/src/locales/ja/description.ts
index d46650b94c2..8e2617601a6 100644
--- a/packages/phrases-experience/src/locales/ja/description.ts
+++ b/packages/phrases-experience/src/locales/ja/description.ts
@@ -14,8 +14,8 @@ const description = {
and: '及び',
enter_passcode: '確認コードが{{address}} {{target}}に送信されました',
passcode_sent: '確認コードを再送します',
- resend_after_seconds: '{{seconds}}秒後に再送信',
- resend_passcode: '確認コードを再送信します',
+ resend_after_seconds: 'まだ届いていませんか? {{seconds}} 秒後に再送',
+ resend_passcode: 'まだ届いていませんか? 認証コードを再送',
create_account_id_exists:
'{{type}} {{value}}でアカウントが既に存在しています。ログインしますか?',
link_account_id_exists: '{{type}} {{value}}でアカウントが既に存在しています。リンクしますか?',
diff --git a/packages/phrases-experience/src/locales/ko/description.ts b/packages/phrases-experience/src/locales/ko/description.ts
index 8abcd22f474..875994bc2e2 100644
--- a/packages/phrases-experience/src/locales/ko/description.ts
+++ b/packages/phrases-experience/src/locales/ko/description.ts
@@ -14,8 +14,8 @@ const description = {
and: '그리고',
enter_passcode: '{{address}} {{target}} 으로 비밀번호가 전송되었어요.',
passcode_sent: '비밀번호가 재전송되었어요.',
- resend_after_seconds: '{{seconds}} 초 후에 재전송',
- resend_passcode: '비밀번호 재전송',
+ resend_after_seconds: '아직 못 받으셨나요? {{seconds}} 초 후에 다시 보내기',
+ resend_passcode: '아직 못 받으셨나요? 인증 코드를 다시 보내기',
create_account_id_exists:
'{{type}} {{value}} 계정은 다른 계정과 연결되어 있습니다. 다른 {{type}}을(를) 시도해주세요.',
link_account_id_exists: '{{type}} {{value}}와/과 연동된 계정이 이미 존재해요. 연동할까요?',
diff --git a/packages/phrases-experience/src/locales/pl-pl/description.ts b/packages/phrases-experience/src/locales/pl-pl/description.ts
index 1c13236213d..9bce984ab9a 100644
--- a/packages/phrases-experience/src/locales/pl-pl/description.ts
+++ b/packages/phrases-experience/src/locales/pl-pl/description.ts
@@ -14,8 +14,9 @@ const description = {
and: 'i',
enter_passcode: 'Kod weryfikacyjny został wysłany na twoje {{address}} {{target}}',
passcode_sent: 'Kod weryfikacyjny został wysłany ponownie',
- resend_after_seconds: 'Wyślij ponownie po {{seconds}} sekundach',
- resend_passcode: 'Wyślij kod weryfikacyjny ponownie',
+ resend_after_seconds:
+ 'Nie otrzymałeś jeszcze? Wyślij ponownie za {{seconds}} sekund',
+ resend_passcode: 'Nie otrzymałeś jeszcze? Wyślij ponownie kod weryfikacyjny',
create_account_id_exists: 'Konto z {{type}} {{value}} już istnieje. Czy chcesz się zalogować?',
link_account_id_exists: 'Konto z {{type}} {{value}} już istnieje. Czy chcesz je połączyć?',
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/pt-br/description.ts b/packages/phrases-experience/src/locales/pt-br/description.ts
index 51a0bac5ba4..08ca8d690ac 100644
--- a/packages/phrases-experience/src/locales/pt-br/description.ts
+++ b/packages/phrases-experience/src/locales/pt-br/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'e',
enter_passcode: 'O código de verificação foi enviado para o seu {{address}} {{target}}',
passcode_sent: 'O código de verificação foi reenviado',
- resend_after_seconds: 'Reenviar depois {{seconds}} segundos',
- resend_passcode: 'Reenviar código de verificação',
+ resend_after_seconds: 'Ainda não recebeu? Reenviar após {{seconds}} segundos',
+ resend_passcode: 'Ainda não recebeu? Reenviar código de verificação',
create_account_id_exists: 'A conta com {{type}} {{value}} já existe, gostaria de entrar?',
link_account_id_exists: 'A conta com {{type}} {{value}} já existe, gostaria de vincular?',
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/pt-pt/description.ts b/packages/phrases-experience/src/locales/pt-pt/description.ts
index f46f669e7e0..3a997738af0 100644
--- a/packages/phrases-experience/src/locales/pt-pt/description.ts
+++ b/packages/phrases-experience/src/locales/pt-pt/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'e',
enter_passcode: 'O código de verificação foi enviado para o seu {{address}} {{target}}',
passcode_sent: 'O código de verificação foi reenviado',
- resend_after_seconds: 'Reenviar após {{seconds}} segundos',
- resend_passcode: 'Reenviar código de verificação',
+ resend_after_seconds: 'Ainda não recebeu? Reenviar após {{seconds}} segundos',
+ resend_passcode: 'Ainda não recebeu? Reenviar código de verificação',
create_account_id_exists: 'A conta com {{type}} {{value}} já existe, gostaria de fazer login?',
link_account_id_exists: 'A conta com {{type}} {{value}} já existe, gostaria de vinculá-la?',
sign_in_id_does_not_exist: 'A conta com {{type}} {{value}} não existe, gostaria de criar uma?',
diff --git a/packages/phrases-experience/src/locales/ru/description.ts b/packages/phrases-experience/src/locales/ru/description.ts
index b6f7259677a..ddb129bfef0 100644
--- a/packages/phrases-experience/src/locales/ru/description.ts
+++ b/packages/phrases-experience/src/locales/ru/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 'и',
enter_passcode: 'Код подтверждения был отправлен на {{address}}',
passcode_sent: 'Код подтверждения был отправлен повторно',
- resend_after_seconds: 'Отправить повторно через {{seconds}} сек.',
- resend_passcode: 'Отправить повторно',
+ resend_after_seconds: 'Еще не получили? Отправить повторно через {{seconds}} секунд',
+ resend_passcode: 'Еще не получили? Отправить повторно код подтверждения',
create_account_id_exists: 'Учетная запись для {{value}} уже существует, хотите войти?',
link_account_id_exists: 'Учетная запись для {{value}} уже существует, хотите привязать?',
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/tr-tr/description.ts b/packages/phrases-experience/src/locales/tr-tr/description.ts
index 6163506d69a..490e00de2cf 100644
--- a/packages/phrases-experience/src/locales/tr-tr/description.ts
+++ b/packages/phrases-experience/src/locales/tr-tr/description.ts
@@ -14,8 +14,8 @@ const description = {
and: 've',
enter_passcode: 'Doğrulama kodu {{address}} {{target}} adresinize gönderildi',
passcode_sent: 'Doğrulama kodu yeniden gönderildi',
- resend_after_seconds: '{{seconds}} saniye sonra tekrar gönder',
- resend_passcode: 'Doğrulama kodunu tekrar gönder',
+ resend_after_seconds: 'Henüz almadınız mı? {{seconds}} saniye sonra tekrar gönderin',
+ resend_passcode: 'Henüz almadınız mı? Doğrulama kodunu tekrar gönderin',
create_account_id_exists: '{{type}} {{value}} ile hesap mevcut, giriş yapmak ister misiniz?',
link_account_id_exists: '{{type}} {{value}} olan hesap zaten var, bağlamak ister misiniz?',
sign_in_id_does_not_exist:
diff --git a/packages/phrases-experience/src/locales/zh-cn/description.ts b/packages/phrases-experience/src/locales/zh-cn/description.ts
index cbc2946b4de..ebbff55278d 100644
--- a/packages/phrases-experience/src/locales/zh-cn/description.ts
+++ b/packages/phrases-experience/src/locales/zh-cn/description.ts
@@ -14,8 +14,8 @@ const description = {
and: '和',
enter_passcode: '验证码已经发送至你的{{ address }} {{target}}',
passcode_sent: '验证码已经发送',
- resend_after_seconds: '在 {{ seconds }} 秒后重发',
- resend_passcode: '重发验证码',
+ resend_after_seconds: '还没收到? {{seconds}} 秒后重发',
+ resend_passcode: '还没收到? 重发验证码',
create_account_id_exists: '{{type}}为 {{value}} 的帐号已存在,你要登录吗?',
link_account_id_exists: ' {{type}}为 {{value}} 的账号已注册,你要绑定至这个账号吗?',
sign_in_id_does_not_exist: '{{type}}为 {{value}} 的帐号不存在,你要创建一个新帐号吗?',
diff --git a/packages/phrases-experience/src/locales/zh-hk/description.ts b/packages/phrases-experience/src/locales/zh-hk/description.ts
index c451a1ccd01..867aa242641 100644
--- a/packages/phrases-experience/src/locales/zh-hk/description.ts
+++ b/packages/phrases-experience/src/locales/zh-hk/description.ts
@@ -14,8 +14,8 @@ const description = {
and: '和',
enter_passcode: '驗證碼已經發送至你的{{ address }} {{target}}',
passcode_sent: '驗證碼已經發送',
- resend_after_seconds: '在 {{ seconds }} 秒後重發',
- resend_passcode: '重發驗證碼',
+ resend_after_seconds: '還沒收到? {{seconds}} 秒後重發',
+ resend_passcode: '還沒收到? 重發驗證碼',
create_account_id_exists: '{{type}}為 {{value}} 的帳號已存在,你要登錄嗎?',
link_account_id_exists: ' {{type}}為 {{value}} 的帳號已註冊,你要綁定至這個帳號嗎?',
sign_in_id_does_not_exist: '{{type}}為 {{value}} 的帳號不存在,你要創建一個新帳號嗎?',
diff --git a/packages/phrases-experience/src/locales/zh-tw/description.ts b/packages/phrases-experience/src/locales/zh-tw/description.ts
index 5b818c4ada8..ef05f7f1ccc 100644
--- a/packages/phrases-experience/src/locales/zh-tw/description.ts
+++ b/packages/phrases-experience/src/locales/zh-tw/description.ts
@@ -14,8 +14,8 @@ const description = {
and: '和',
enter_passcode: '驗證碼已經發送至你的{{address}} {{target}}',
passcode_sent: '驗證碼已經發送',
- resend_after_seconds: '在 {{seconds}} 秒後重新發送',
- resend_passcode: '重新發送驗證碼',
+ resend_after_seconds: '還沒收到? {{seconds}} 秒後重發',
+ resend_passcode: '還沒收到? 重發驗證碼',
create_account_id_exists: '{{type}} 為 {{value}} 的帳號已存在,你要登錄嗎?',
link_account_id_exists: ' {{type}} 為 {{value}} 的帳號已註冊,你要綁定至這個帳號嗎?',
sign_in_id_does_not_exist: '{{type}} 為 {{value}} 的帳號不存在,你要創建一個新帳號嗎?',