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

refactor(console): replace mfa upsell notification with InlineUpsell component (#4868)

This commit is contained in:
Xiao Yijun 2023-11-14 10:52:59 +08:00 committed by GitHub
parent b277cb3b99
commit 8730570f3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 54 additions and 72 deletions

View file

@ -1,21 +1,27 @@
import { type AdminConsoleKey } from '@logto/phrases';
import classNames from 'classnames';
import { type TFuncKey } from 'i18next';
import { Trans, useTranslation } from 'react-i18next';
import { contactEmailLink } from '@/consts';
import InlineNotification from '@/ds-components/InlineNotification';
import TextLink from '@/ds-components/TextLink';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import ContactUsPhraseLink from '../ContactUsPhraseLink';
import * as styles from './index.module.scss';
type Props = {
className?: string;
for: TFuncKey<'translation', 'admin_console.upsell.paywall'>;
/**
* The text to be displayed on the clickable action button which links to the subscription page.
* @default 'upsell.compare_plans'
*/
actionButtonText?: AdminConsoleKey;
};
/** Displays an inline notification that explains the paywall and links to the subscription page. */
function InlineUpsell({ className, for: forFeature }: Props) {
/** Displays an inline notification that explains the paywall and provides a clickable action button which links to the subscription page. */
function InlineUpsell({ className, for: forFeature, actionButtonText }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.upsell.paywall' });
const { navigate } = useTenantPathname();
@ -23,7 +29,7 @@ function InlineUpsell({ className, for: forFeature }: Props) {
<InlineNotification
hasIcon={false}
severity="info"
action="upsell.compare_plans"
action={actionButtonText ?? 'upsell.compare_plans'}
className={classNames(styles.notification, className)}
onClick={() => {
navigate('/tenant-settings/subscription');
@ -31,7 +37,7 @@ function InlineUpsell({ className, for: forFeature }: Props) {
>
<Trans
components={{
a: <TextLink href={contactEmailLink} target="_blank" />,
a: <ContactUsPhraseLink />,
}}
>
{t(forFeature)}

View file

@ -61,7 +61,7 @@ function MauExceededModal() {
title="upsell.mau_exceeded_modal.title"
footer={
<>
<a href={contactEmailLink} target="_blank" className={styles.linkButton} rel="noopener">
<a href={contactEmailLink} className={styles.linkButton} rel="noopener">
<Button title="general.contact_us_action" />
</a>
<Button

View file

@ -45,7 +45,7 @@ function PaymentOverdueModal() {
title="upsell.payment_overdue_modal.title"
footer={
<>
<a href={contactEmailLink} target="_blank" className={styles.linkButton} rel="noopener">
<a href={contactEmailLink} className={styles.linkButton} rel="noopener">
<Button title="general.contact_us_action" />
</a>
<Button

View file

@ -2,11 +2,11 @@ import { MfaFactor, MfaPolicy, type SignInExperience } from '@logto/schemas';
import { useContext, useMemo } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { Trans, useTranslation } from 'react-i18next';
import { useTranslation } from 'react-i18next';
import ContactUsPhraseLink from '@/components/ContactUsPhraseLink';
import DetailsForm from '@/components/DetailsForm';
import FormCard from '@/components/FormCard';
import InlineUpsell from '@/components/InlineUpsell';
import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal';
import { isCloud } from '@/consts/env';
import { TenantsContext } from '@/contexts/TenantsProvider';
@ -18,7 +18,6 @@ import Switch from '@/ds-components/Switch';
import useApi from '@/hooks/use-api';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import useSubscriptionPlan from '@/hooks/use-subscription-plan';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import { trySubmitSafe } from '@/utils/form';
import { type MfaConfigForm, type MfaConfig } from '../types';
@ -36,7 +35,6 @@ type Props = {
function MfaForm({ data, onMfaUpdated }: Props) {
const { currentTenantId } = useContext(TenantsContext);
const { data: currentPlan } = useSubscriptionPlan(currentTenantId);
const { navigate } = useTenantPathname();
const isMfaDisabled = isCloud && !currentPlan?.quota.mfaEnabled;
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
@ -128,21 +126,11 @@ function MfaForm({ data, onMfaUpdated }: Props) {
</div>
</FormField>
{isMfaDisabled && (
<InlineNotification
<InlineUpsell
for="mfa"
className={styles.unlockMfaNotice}
action="mfa.view_plans"
onClick={() => {
navigate('/tenant-settings/subscription');
}}
>
<Trans
components={{
a: <ContactUsPhraseLink />,
}}
>
{t('mfa.unlock_reminder')}
</Trans>
</InlineNotification>
actionButtonText="upsell.view_plans"
/>
)}
</FormCard>
<FormCard title="mfa.policy">

View file

@ -134,7 +134,7 @@ function SwitchPlanActionBar({
);
})}
<div>
<a href={contactEmailLink} target="_blank" className={styles.buttonLink} rel="noopener">
<a href={contactEmailLink} className={styles.buttonLink} rel="noopener">
<Button title="general.contact_us_action" type="primary" />
</a>
</div>

View file

@ -2,10 +2,9 @@ import classNames from 'classnames';
import { useTranslation, Trans } from 'react-i18next';
import { type TenantResponse } from '@/cloud/types/router';
import ContactUsPhraseLink from '@/components/ContactUsPhraseLink';
import { tenantAbbreviatedTagNameMap } from '@/components/TenantEnvTag';
import { contactEmailLink } from '@/consts';
import DeleteConfirmModal from '@/ds-components/DeleteConfirmModal';
import TextLink from '@/ds-components/TextLink';
import * as styles from './index.module.scss';
@ -46,7 +45,7 @@ function DeleteModal({ isOpen, isLoading, onClose, onDelete, tenant }: Props) {
<Trans
components={{
span: <span className={styles.highlight} />,
a: <TextLink href={contactEmailLink} target="_blank" />,
a: <ContactUsPhraseLink />,
}}
>
{t('tenants.delete_modal.description_line2')}

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: 'Benutzer müssen immer MFA bei der Anmeldung verwenden',
mandatory_tip:
'Benutzer müssen MFA beim ersten Mal bei der Anmeldung oder Anmeldung einrichten und es für alle zukünftigen Anmeldungen verwenden.',
unlock_reminder:
'Schalten Sie MFA zur Sicherheitsüberprüfung frei, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Zögern Sie nicht, uns zu <a>kontaktieren</a>, wenn Sie Unterstützung benötigen.',
view_plans: 'Pläne anzeigen',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Upgrade plan',
compare_plans: 'Pläne vergleichen',
view_plans: 'Pläne anzeigen',
create_tenant: {
title: 'Wählen Sie Ihren Tenant-Plan aus',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Sie haben das Limit von {{count, number}} <planName/>-Webhooks erreicht. Upgraden Sie Ihren Plan, um mehr Webhooks zu erstellen. Zögern Sie nicht, <a>Kontaktieren Sie uns</a>, wenn Sie Hilfe benötigen.',
hooks_other:
'Sie haben das Limit von {{count, number}} <planName/>-Webhooks erreicht. Upgraden Sie Ihren Plan, um mehr Webhooks zu erstellen. Zögern Sie nicht, <a>Kontaktieren Sie uns</a>, wenn Sie Hilfe benötigen.',
mfa: 'Schalten Sie MFA zur Sicherheitsüberprüfung frei, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Zögern Sie nicht, uns zu <a>kontaktieren</a>, wenn Sie Unterstützung benötigen.',
};
export default Object.freeze(paywall);

View file

@ -28,9 +28,6 @@ const mfa = {
mandatory: 'Users are always required to use MFA at sign-in',
mandatory_tip:
'Users must set up MFA the first time at sign-in or sign-up, and use it for all future sign-ins.',
unlock_reminder:
'Unlock MFA to verification security by upgrading to a paid plan. Dont hesitate to <a>contact us</a> if you need any assistance.',
view_plans: 'View plans',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Upgrade plan',
compare_plans: 'Compare plans',
view_plans: 'View plans',
create_tenant: {
title: 'Select your tenant plan',
description:

View file

@ -45,6 +45,7 @@ const paywall = {
'{{count, number}} webhook of <planName/> limit reached. Upgrade plan to create more webhooks. Feel free to <a>contact us</a> if you need any assistance.',
hooks_other:
'{{count, number}} webhooks of <planName/> limit reached. Upgrade plan to create more webhooks. Feel free to <a>contact us</a> if you need any assistance.',
mfa: 'Unlock MFA to verification security by upgrading to a paid plan. Dont hesitate to <a>contact us</a> if you need any assistance.',
};
export default Object.freeze(paywall);

View file

@ -31,9 +31,6 @@ const mfa = {
mandatory: 'Siempre se requiere que los usuarios usen MFA al iniciar sesión',
mandatory_tip:
'Los usuarios deben configurar MFA la primera vez al iniciar sesión o registrarse, y usarlo en todas las futuras sesiones de inicio de sesión.',
unlock_reminder:
'Desbloquea MFA para verificar la seguridad al actualizar a un plan pago. No dudes en <a>contactarnos</a> si necesitas ayuda.',
view_plans: 'Ver planes',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Plan de actualización',
compare_plans: 'Comparar planes',
view_plans: 'Ver planes',
create_tenant: {
title: 'Selecciona tu plan de tenant',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Has alcanzado el límite de {{count, number}} webhooks de <planName/>. Actualiza el plan para crear más webhooks. Si necesitas ayuda, no dudes en <a>contactarnos</a>.',
hooks_other:
'Has alcanzado el límite de {{count, number}} webhooks de <planName/>. Actualiza el plan para crear más webhooks. Si necesitas ayuda, no dudes en <a>contactarnos</a>.',
mfa: 'Desbloquea MFA para verificar la seguridad al actualizar a un plan pago. No dudes en <a>contactarnos</a> si necesitas ayuda.',
};
export default Object.freeze(paywall);

View file

@ -31,9 +31,6 @@ const mfa = {
mandatory: 'Les utilisateurs doivent toujours utiliser MFA à la connexion',
mandatory_tip:
"Les utilisateurs doivent configurer MFA la première fois à la connexion ou à l'inscription, et l'utiliser pour toutes les connexions futures.",
unlock_reminder:
"Déverrouillez MFA pour vérifier la sécurité en passant à un plan payant. N'hésitez pas à <a>nous contacter</a> si vous avez besoin d'aide.",
view_plans: 'Voir les plans',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Mettre à niveau le plan',
compare_plans: 'Comparer les plans',
view_plans: 'Voir les plans',
create_tenant: {
title: 'Sélectionnez votre plan pour le locataire',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
"Vous avez atteint la limite de {{count, number}} webhook de <planName/>. Mettez à niveau votre plan pour créer plus de webhooks. N'hésitez pas à <a>nous contacter</a> si vous avez besoin d'aide.",
hooks_other:
"Vous avez atteint la limite de {{count, number}} webhooks de <planName/>. Mettez à niveau votre plan pour créer plus de webhooks. N'hésitez pas à <a>nous contacter</a> si vous avez besoin d'aide.",
mfa: "Déverrouillez MFA pour vérifier la sécurité en passant à un plan payant. N'hésitez pas à <a>nous contacter</a> si vous avez besoin d'aide.",
};
export default Object.freeze(paywall);

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: "Gli utenti devono sempre utilizzare MFA all'accesso",
mandatory_tip:
"Gli utenti devono configurare MFA la prima volta all'accesso o alla registrazione, e usarlo per tutti gli accessi futuri.",
unlock_reminder:
'Sblocca MFA per verificare la sicurezza passando a un piano a pagamento. Non esitare a <a>contattarci</a> se hai bisogno di assistenza.',
view_plans: 'Visualizza piani',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Aggiorna piano',
compare_plans: 'Confronta i piani',
view_plans: 'Visualizza piani',
create_tenant: {
title: 'Seleziona il piano del tenant',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Hai raggiunto il limite di {{count, number}} webhook di <planName/>. Aggiorna il piano per creare altri webhook. Non esitare a <a>contattarci</a> se hai bisogno di assistenza.',
hooks_other:
'Hai raggiunto il limite di {{count, number}} webhook di <planName/>. Aggiorna il piano per creare altri webhook. Non esitare a <a>contattarci</a> se hai bisogno di assistenza.',
mfa: 'Sblocca MFA per verificare la sicurezza passando a un piano a pagamento. Non esitare a <a>contattarci</a> se hai bisogno di assistenza.',
};
export default Object.freeze(paywall);

View file

@ -29,9 +29,6 @@ const mfa = {
mandatory: 'ユーザーは常にサインイン時にMFAの使用が必要です',
mandatory_tip:
'ユーザーは最初のサインインまたはサインアップ時にMFAを設定し、将来のすべてのサインインでそれを使用する必要があります。',
unlock_reminder:
'セキュリティを確認するためにMFAを解除して有料プランにアップグレードしてください。ご質問があれば、<a>お問い合わせください</a>。',
view_plans: 'プランを見る',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'プランをアップグレード',
compare_plans: 'プラン比較',
view_plans: 'プランを見る',
create_tenant: {
title: 'テナントプランを選択',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'{{count, number}}の<planName/>ウェブフック制限に達しました。追加のウェブフックを作成するにはプランをアップグレードしてください。<a>お問い合わせ</a>は何かお手伝いが必要な場合はお気軽にどうぞ。',
hooks_other:
'{{count, number}}の<planName/>ウェブフック制限に達しました。追加のウェブフックを作成するにはプランをアップグレードしてください。<a>お問い合わせ</a>は何かお手伝いが必要な場合はお気軽にどうぞ。',
mfa: 'セキュリティを確認するためにMFAを解除して有料プランにアップグレードしてください。ご質問があれば、<a>お問い合わせください</a>。',
};
export default Object.freeze(paywall);

View file

@ -27,9 +27,6 @@ const mfa = {
mandatory: '사용자는 항상 로그인 시 MFA 사용이 필요합니다',
mandatory_tip:
'사용자는 처음 로그인 또는 가입 시에 MFA를 설정하고 모든 향후 로그인에서 그것을 사용해야 합니다.',
unlock_reminder:
'보안을 확인하기 위해 MFA를 잠금 해제하여 유료 플랜으로 업그레이드하세요. 궁금한 점이 있으면 <a>문의하세요</a>.',
view_plans: '플랜 보기',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: '플랜 업그레이드',
compare_plans: '플랜 비교',
view_plans: '플랜 보기',
create_tenant: {
title: '테넌트 플랜 선택하기',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'<planName/>의 {{count, number}}개 웹훅 한도에 도달했습니다. 더 많은 웹훅을 생성하려면 플랜을 업그레이드하세요. 도움이 필요하면 <a>문의하기</a>로 연락 주세요.',
hooks_other:
'<planName/>의 {{count, number}}개 웹훅 한도에 도달했습니다. 더 많은 웹훅을 생성하려면 플랜을 업그레이드하세요. 도움이 필요하면 <a>문의하기</a>로 연락 주세요.',
mfa: '보안을 확인하기 위해 MFA를 잠금 해제하여 유료 플랜으로 업그레이드하세요. 궁금한 점이 있으면 <a>문의하세요</a>.',
};
export default Object.freeze(paywall);

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: 'Użytkownicy zawsze muszą korzystać z MFA podczas logowania',
mandatory_tip:
'Użytkownicy muszą skonfigurować MFA podczas pierwszego logowania lub rejestracji i używać go przy każdym kolejnym logowaniu.',
unlock_reminder:
'Odblokuj MFA, aby zweryfikować bezpieczeństwo, przechodząc na płatny plan. Nie wahaj się <a>skontaktować z nami</a>, jeśli potrzebujesz pomocy.',
view_plans: 'Zobacz plany',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Ulepsz plan',
compare_plans: 'Porównaj plany',
view_plans: 'Zobacz plany',
create_tenant: {
title: 'Wybierz swój plan najemcy',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Osiągnięto limit {{count, number}} webhooków w planie <planName/>. Ulepsz plan, aby tworzyć więcej webhooków. Jeśli potrzebujesz pomocy, nie wahaj się <a>skontaktować z nami</a>.',
hooks_other:
'Osiągnięto limit {{count, number}} webhooków w planie <planName/>. Ulepsz plan, aby tworzyć więcej webhooków. Jeśli potrzebujesz pomocy, nie wahaj się <a>skontaktować z nami</a>.',
mfa: 'Odblokuj MFA, aby zweryfikować bezpieczeństwo, przechodząc na płatny plan. Nie wahaj się <a>skontaktować z nami</a>, jeśli potrzebujesz pomocy.',
};
export default Object.freeze(paywall);

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: 'Os usuários sempre precisam usar o MFA no login',
mandatory_tip:
'Os usuários devem configurar o MFA na primeira vez do login ou inscrição e usá-lo em todos os logins futuros.',
unlock_reminder:
'Desbloqueie o MFA para verificar a segurança, fazendo upgrade para um plano pago. Não hesite em <a>nos contatar</a> se precisar de alguma assistência.',
view_plans: 'Ver planos',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Atualizar plano',
compare_plans: 'Comparar planos',
view_plans: 'Ver planos',
create_tenant: {
title: 'Selecione o seu plano de inquilino',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Atingiu o limite de {{count, number}} webhooks de <planName/>. Atualize o plano para criar mais webhooks. Não hesite em <a>Contacte-nos</a> se precisar de ajuda.',
hooks_other:
'Atingiu o limite de {{count, number}} webhooks de <planName/>. Atualize o plano para criar mais webhooks. Não hesite em <a>Contacte-nos</a> se precisar de ajuda.',
mfa: 'Desbloqueie o MFA para verificar a segurança, fazendo upgrade para um plano pago. Não hesite em <a>nos contatar</a> se precisar de alguma assistência.',
};
export default Object.freeze(paywall);

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: 'Os usuários sempre precisam usar o MFA no login',
mandatory_tip:
'Os usuários devem configurar o MFA na primeira vez no login ou inscrição e usá-lo em todos os logins futuros.',
unlock_reminder:
'Desbloqueie o MFA para a verificação de segurança ao atualizar para um plano pago. Não hesite em <a>entrar em contato conosco</a> se precisar de assistência.',
view_plans: 'Ver planos',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Atualizar plano',
compare_plans: 'Comparar planos',
view_plans: 'Ver planos',
create_tenant: {
title: 'Selecione o seu plano de inquilino',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Atingiu o limite de {{count, number}} webhooks de <planName/>. Atualize o plano para criar mais webhooks. Não hesite em <a>Contacte-nos</a> se precisar de ajuda.',
hooks_other:
'Atingiu o limite de {{count, number}} webhooks de <planName/>. Atualize o plano para criar mais webhooks. Não hesite em <a>Contacte-nos</a> se precisar de ajuda.',
mfa: 'Desbloqueie o MFA para a verificação de segurança ao atualizar para um plano pago. Não hesite em <a>entrar em contato conosco</a> se precisar de assistência.',
};
export default Object.freeze(paywall);

View file

@ -30,9 +30,6 @@ const mfa = {
mandatory: 'Пользователям всегда нужно использовать MFA при входе',
mandatory_tip:
'Пользователи должны настроить MFA при первом входе или регистрации и использовать его для всех последующих входов.',
unlock_reminder:
'Разблокируйте MFA для повышения безопасности с помощью перехода на платный план. Не стесняйтесь <a>связаться с нами</a>, если вам нужна помощь.',
view_plans: 'Просмотреть планы',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Повысить план',
compare_plans: 'Сравнить планы',
view_plans: 'Просмотреть планы',
create_tenant: {
title: 'Выберите план арендатора',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'Достигнут лимит {{count, number}} вебхуков в плане <planName/>. Повысьте план, чтобы создать больше вебхуков. Если вам нужна помощь, не стесняйтесь <a>связаться с нами</a>.',
hooks_other:
'Достигнут лимит {{count, number}} вебхуков в плане <planName/>. Повысьте план, чтобы создать больше вебхуков. Если вам нужна помощь, не стесняйтесь <a>связаться с нами</a>.',
mfa: 'Разблокируйте MFA для повышения безопасности с помощью перехода на платный план. Не стесняйтесь <a>связаться с нами</a>, если вам нужна помощь.',
};
export default Object.freeze(paywall);

View file

@ -31,9 +31,6 @@ const mfa = {
mandatory: 'Kullanıcılar her zaman girişte MFA kullanmak zorundadır',
mandatory_tip:
'Kullanıcılar, ilk kez giriş veya kayıt sırasında MFA kurmalı ve tüm gelecekteki girişlerde kullanmalıdır.',
unlock_reminder:
"Güvenliği kontrol etmek için MFA'yı bir ücretli plana geçerek kilidini açın. Yardıma ihtiyacınız olursa bize <a>iletişim kurmaktan</a> çekinmeyin.",
view_plans: 'Planları Görüntüle',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: 'Planı Yükselt',
compare_plans: 'Planları Karşılaştır',
view_plans: 'Planları Görüntüle',
create_tenant: {
title: 'Kiracı planınızı seçin',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'{{count, number}} <planName/> webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardıma ihtiyacınız olursa, <a>iletişime geçin</a>.',
hooks_other:
'{{count, number}} <planName/> webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardıma ihtiyacınız olursa, <a>iletişime geçin</a>.',
mfa: "Güvenliği kontrol etmek için MFA'yı bir ücretli plana geçerek kilidini açın. Yardıma ihtiyacınız olursa bize <a>iletişim kurmaktan</a> çekinmeyin.",
};
export default Object.freeze(paywall);

View file

@ -22,8 +22,6 @@ const mfa = {
user_controlled_tip: '用户可以在首次登录或注册时跳过MFA设置或在账户设置中启用/禁用MFA。',
mandatory: '用户始终需要在登录时使用MFA',
mandatory_tip: '用户必须在首次登录或注册时设置MFA并在所有未来的登录中使用它。',
unlock_reminder: '升级到付费计划以解锁MFA进行安全验证。如果需要任何帮助请随时<a>联系我们</a>。',
view_plans: '查看计划',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: '升级计划',
compare_plans: '比较计划',
view_plans: '查看计划',
create_tenant: {
title: '选择您的租户计划',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'已达到<planName/>的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助请<a>联系我们</a>。',
hooks_other:
'已达到<planName/>的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助请<a>联系我们</a>。',
mfa: '升级到付费计划以解锁MFA进行安全验证。如果需要任何帮助请随时<a>联系我们</a>。',
};
export default Object.freeze(paywall);

View file

@ -22,8 +22,6 @@ const mfa = {
user_controlled_tip: '用戶可以在首次登錄或註冊時跳過MFA設置或在帳戶設置中啟用/禁用它。',
mandatory: '用戶總是需要在登錄時使用MFA',
mandatory_tip: '用戶必須在首次登錄或註冊時設置MFA並在以後的所有登錄中使用它。',
unlock_reminder: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助請隨時<a>聯繫我們</a>。',
view_plans: '查看計劃',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,7 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: '升級計劃',
compare_plans: '比較計劃',
view_plans: '查看計劃',
create_tenant: {
title: '選擇您的租戶計劃',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'已達到<planName/>的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助請<a>聯繫我們</a>。',
hooks_other:
'已達到<planName/>的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助請<a>聯繫我們</a>。',
mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助請隨時<a>聯繫我們</a>。',
};
export default Object.freeze(paywall);

View file

@ -22,8 +22,6 @@ const mfa = {
user_controlled_tip: '用戶可以在首次登錄或註冊時跳過MFA設置或在帳戶設置中啟用/禁用它。',
mandatory: '用戶總是需要在登錄時使用MFA',
mandatory_tip: '用戶必須在首次登錄或註冊時設置MFA並在以後的所有登錄中使用它。',
unlock_reminder: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助請隨時<a>聯繫我們</a>。',
view_plans: '查看計劃',
};
export default Object.freeze(mfa);

View file

@ -3,6 +3,8 @@ import paywall from './paywall.js';
const upsell = {
upgrade_plan: '升級計劃',
compare_plans: '比較計劃',
view_plans: '查看計劃',
create_tenant: {
title: '選擇您的租戶計劃',
description:

View file

@ -48,6 +48,7 @@ const paywall = {
'已達到<planName/>的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助請<a>聯繫我們</a>。',
hooks_other:
'已達到<planName/>的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助請<a>聯繫我們</a>。',
mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助請隨時<a>聯繫我們</a>。',
};
export default Object.freeze(paywall);