0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(experience): avoid disabled button for continue button (#6271)

This commit is contained in:
Xiao Yijun 2024-07-19 11:54:37 +08:00 committed by GitHub
parent e9a70ba6d9
commit 216859a906
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 49 additions and 21 deletions

View file

@ -1,4 +1,5 @@
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Button from '@/components/Button';
import VerificationCodeInput from '@/components/VerificationCode';
@ -18,17 +19,28 @@ type Props = {
};
const TotpCodeVerification = ({ flow }: Props) => {
const { t } = useTranslation();
const [codeInput, setCodeInput] = useState<string[]>([]);
const [inputErrorMessage, setInputErrorMessage] = useState<string>();
const errorCallback = useCallback(() => {
setCodeInput([]);
setInputErrorMessage(undefined);
}, []);
const { errorMessage, onSubmit } = useTotpCodeVerification(flow, errorCallback);
const { errorMessage: submitErrorMessage, onSubmit } = useTotpCodeVerification(
flow,
errorCallback
);
const [isSubmitting, setIsSubmitting] = useState(false);
const errorMessage = inputErrorMessage ?? submitErrorMessage;
const handleSubmit = useCallback(
async (code: string[]) => {
setInputErrorMessage(undefined);
setIsSubmitting(true);
await onSubmit(code.join(''));
setIsSubmitting(false);
@ -55,8 +67,12 @@ const TotpCodeVerification = ({ flow }: Props) => {
type="primary"
className={styles.continueButton}
isLoading={isSubmitting}
isDisabled={!isCodeReady(codeInput)}
onClick={() => {
if (!isCodeReady(codeInput)) {
setInputErrorMessage(t('error.invalid_passcode'));
return;
}
void handleSubmit(codeInput);
}}
/>

View file

@ -23,6 +23,8 @@ type Props = {
const VerificationCode = ({ flow, identifier, className, hasPasswordButton, target }: Props) => {
const [codeInput, setCodeInput] = useState<string[]>([]);
const [inputErrorMessage, setInputErrorMessage] = useState<string>();
const { t } = useTranslation();
const isCodeInputReady = useMemo(
@ -34,13 +36,16 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ
const errorCallback = useCallback(() => {
setCodeInput([]);
setInputErrorMessage(undefined);
}, []);
const { errorMessage, clearErrorMessage, onSubmit } = useVerificationCode(
identifier,
target,
errorCallback
);
const {
errorMessage: submitErrorMessage,
clearErrorMessage,
onSubmit,
} = useVerificationCode(identifier, target, errorCallback);
const errorMessage = inputErrorMessage ?? submitErrorMessage;
const { seconds, isRunning, onResendVerificationCode } = useResendVerificationCode(
flow,
@ -52,6 +57,8 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ
const handleSubmit = useCallback(
async (code: string[]) => {
setInputErrorMessage(undefined);
setIsSubmitting(true);
await onSubmit(
@ -110,10 +117,14 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ
<Button
title="action.continue"
type="primary"
isDisabled={!isCodeInputReady}
isLoading={isSubmitting}
className={styles.continueButton}
onClick={() => {
if (!isCodeInputReady) {
setInputErrorMessage(t('error.invalid_passcode'));
return;
}
void handleSubmit(codeInput);
}}
/>

View file

@ -24,6 +24,7 @@ const useErrorHandler = () => {
const logtoError = await error.response.json<RequestErrorBody>();
const { code, message } = logtoError;
const handler = errorHandlers?.[code] ?? errorHandlers?.global;
if (handler) {

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: 'Die Email ist ungültig',
invalid_phone: 'Die Telefonnummer ist ungültig',
passwords_do_not_match: 'Passwörter stimmen nicht überein',
invalid_passcode: 'Der Bestätigungscode ist ungültig',
invalid_passcode: 'Der Bestätigungscode ist ungültig.',
invalid_connector_auth: 'Die Autorisierung ist ungültig',
invalid_connector_request: 'Connector Daten sind ungültig',
unknown: 'Unbekannter Fehler. Versuche es später noch einmal.',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: 'The email is invalid',
invalid_phone: 'The phone number is invalid',
passwords_do_not_match: 'Your passwords dont match. Please try again.',
invalid_passcode: 'The verification code is invalid',
invalid_passcode: 'The verification code is invalid.',
invalid_connector_auth: 'The authorization is invalid',
invalid_connector_request: 'The connector data is invalid',
unknown: 'Unknown error. Please try again later.',

View file

@ -12,7 +12,7 @@ const error = {
invalid_email: 'El correo electrónico no es válido',
invalid_phone: 'El número de teléfono no es válido',
passwords_do_not_match: 'Las contraseñas no coinciden. Por favor intente de nuevo',
invalid_passcode: 'El código de verificación no es válido',
invalid_passcode: 'El código de verificación no es válido.',
invalid_connector_auth: 'La autorización no es válida',
invalid_connector_request: 'Los datos del conector no son válidos',
unknown: 'Error desconocido. Por favor intente de nuevo más tarde.',

View file

@ -13,7 +13,7 @@ const error = {
invalid_email: "L'email n'est pas valide",
invalid_phone: "Le numéro de téléphone n'est pas valide",
passwords_do_not_match: 'Les mots de passe ne correspondent pas',
invalid_passcode: 'Le code est invalide',
invalid_passcode: 'Le code est invalide.',
invalid_connector_auth: "L'autorisation n'est pas valide",
invalid_connector_request: 'Les données du connecteur ne sont pas valides',
unknown: 'Erreur inconnue. Veuillez réessayer plus tard.',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: "L'email non è valida",
invalid_phone: 'Il numero di telefono non è valido',
passwords_do_not_match: 'Le password non corrispondono. Per favore prova di nuovo.',
invalid_passcode: 'Il codice di verifica non è valido',
invalid_passcode: 'Il codice di verifica non è valido.',
invalid_connector_auth: "L'autorizzazione è invalida",
invalid_connector_request: 'I dati del connettore non sono validi',
unknown: 'Errore sconosciuto. Si prega di riprovare più tardi.',

View file

@ -12,7 +12,7 @@ const error = {
invalid_email: 'メールアドレスが無効です',
invalid_phone: '電話番号が無効です',
passwords_do_not_match: 'パスワードが一致しません。もう一度お試しください。',
invalid_passcode: '検証コードが無効です',
invalid_passcode: '検証コードが無効です',
invalid_connector_auth: '認証が無効です',
invalid_connector_request: 'コネクターデータが無効です',
unknown: '不明なエラーが発生しました。後でもう一度お試しください。',

View file

@ -12,7 +12,7 @@ const error = {
invalid_email: 'Nieprawidłowy adres e-mail',
invalid_phone: 'Nieprawidłowy numer telefonu',
passwords_do_not_match: 'Hasła nie pasują do siebie. Proszę spróbuj ponownie.',
invalid_passcode: 'Nieprawidłowy kod weryfikacyjny',
invalid_passcode: 'Nieprawidłowy kod weryfikacyjny.',
invalid_connector_auth: 'Nieprawidłowa autoryzacja',
invalid_connector_request: 'Nieprawidłowe dane konektora',
unknown: 'Nieznany błąd. Proszę spróbuj ponownie później.',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: 'O e-mail é inválido',
invalid_phone: 'O número de telefone é inválido',
passwords_do_not_match: 'Suas senhas não correspondem. Por favor, tente novamente.',
invalid_passcode: 'O código de verificação é inválido',
invalid_passcode: 'O código de verificação é inválido.',
invalid_connector_auth: 'A autorização é inválida',
invalid_connector_request: 'Os dados do conector são inválidos',
unknown: 'Erro desconhecido. Por favor, tente novamente mais tarde.',

View file

@ -12,7 +12,7 @@ const error = {
invalid_email: 'Электронная почта указана неправильно',
invalid_phone: 'Номер телефона указан неправильно',
passwords_do_not_match: 'Пароли не совпадают. Пожалуйста, попробуйте еще раз.',
invalid_passcode: 'Неправильный код подтверждения',
invalid_passcode: 'Неправильный код подтверждения.',
invalid_connector_auth: 'Авторизация недействительна',
invalid_connector_request: 'Данные коннектора недействительны.',
unknown: 'Неизвестная ошибка. Пожалуйста, повторите попытку позднее.',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: 'E-posta adresi geçersiz',
invalid_phone: 'Telefon numarası geçersiz',
passwords_do_not_match: 'Şifreler eşleşmiyor',
invalid_passcode: 'Doğrulama kodu geçersiz',
invalid_passcode: 'Doğrulama kodu geçersiz.',
invalid_connector_auth: 'Yetki geçersiz',
invalid_connector_request: 'Bağlayıcı veri geçersiz',
unknown: 'Bilinmeyen hata. Lütfen daha sonra tekrar deneyiniz.',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: '无效的邮箱',
invalid_phone: '无效的手机号',
passwords_do_not_match: '两次输入的密码不一致,请重试。',
invalid_passcode: '无效的验证码',
invalid_passcode: '无效的验证码',
invalid_connector_auth: '登录失败',
invalid_connector_request: '无效的登录请求',
unknown: '未知错误,请稍后重试。',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: '無效的電子郵件',
invalid_phone: '無效的手機號碼',
passwords_do_not_match: '兩次輸入的密碼不一致,請重試。',
invalid_passcode: '無效的驗證碼',
invalid_passcode: '無效的驗證碼',
invalid_connector_auth: '登錄失敗',
invalid_connector_request: '無效的登錄請求',
unknown: '未知錯誤,請稍後重試。',

View file

@ -11,7 +11,7 @@ const error = {
invalid_email: '無效的郵箱',
invalid_phone: '無效的手機號',
passwords_do_not_match: '兩次輸入的密碼不一致,請重試。',
invalid_passcode: '無效的驗證碼',
invalid_passcode: '無效的驗證碼',
invalid_connector_auth: '登錄失敗',
invalid_connector_request: '無效的登錄請求',
unknown: '未知錯誤,請稍後重試。',