diff --git a/recipients_app/lib/l10n/app_en.arb b/recipients_app/lib/l10n/app_en.arb index db09fe632..8a3a917f0 100644 --- a/recipients_app/lib/l10n/app_en.arb +++ b/recipients_app/lib/l10n/app_en.arb @@ -130,8 +130,8 @@ } } }, - "survey12Months": "12 months survey", - "survey12MonthsInfo": "Please take 5 minutes to answer questions and help to improve Social Income", + "surveyCardTitle": "Survey", + "surveyCardInfo": "Please take 5 minutes to answer questions and help to improve Social Income", "verification": "Verification", "verificationSent": "We sent you a verification code to {phoneNumber}", "@verificationSent": { @@ -145,8 +145,110 @@ "yourMobilePhone": "Your mobile phone", "continueText": "Continue", "phoneNumber": "Phone number", + "invalidPhoneNumberError": "Invalid phone number. Please check your phone number and try again.", "invalidVerificationCodeError": "Invalid verification code. Please check provided SMS code and try again.", "userDisabledError": "Your user account was disabled. Contact with us if you need more information.", - "invalidCredentialError": "Provided phone number or verification code are no longer valid. Please try again." + "invalidCredentialError": "Provided phone number or verification code are no longer valid. Please try again.", + "adminOnlyOperation": "This operation is only allowed for admin users", + "argumentError": "Invalid argument provided", + "appNotAuthorized": "App not authorized", + "appNotInstalled": "App not installed", + "captchaCheckFailed": "CAPTCHA check failed", + "codeExpired": "Code expired", + "cordovaNotReady": "Cordova is not ready", + "corsUnsupported": "CORS is unsupported", + "credentialAlreadyInUse": "Credential already in use", + "credentialMismatch": "Credential mismatch", + "credentialTooOldLoginAgain": "Credential too old, please login again", + "dependentSdkInitBeforeAuth": "Dependent SDK initialized before auth", + "dynamicLinkNotActivated": "Dynamic link not activated", + "emailChangeNeedsVerification": "Email change needs verification", + "emailExists": "Email already exists", + "emulatorConfigFailed": "Emulator configuration failed", + "expiredOobCode": "Expired action code", + "expiredPopupRequest": "Expired popup request", + "internalError": "Internal error", + "invalidApiKey": "Invalid API key", + "invalidAppCredential": "Invalid app credential", + "invalidAppId": "Invalid app ID", + "invalidAuth": "Invalid user token", + "invalidAuthEvent": "Invalid auth event", + "invalidCertHash": "Invalid cert hash", + "invalidCode": "Invalid verification code", + "invalidContinueUri": "Invalid resource", + "invalidCordovaConfiguration": "Invalid Cordova configuration", + "invalidCustomToken": "Invalid custom token", + "invalidDynamicLinkDomain": "Invalid dynamic link domain", + "invalidEmail": "Invalid email", + "invalidEmulatorScheme": "Invalid emulator scheme", + "invalidIdpResponse": "Invalid credential", + "invalidMessagePayload": "Invalid message payload", + "invalidMfaSession": "Invalid multi-factor session", + "invalidOauthClientId": "Invalid OAuth client ID", + "invalidOauthProvider": "Invalid OAuth provider", + "invalidOobCode": "Invalid action code", + "invalidOrigin": "Unauthorized domain", + "invalidPassword": "Wrong password", + "invalidPersistence": "Invalid persistence type", + "invalidProviderId": "Invalid provider ID", + "invalidRecipientEmail": "Invalid recipient email", + "invalidSender": "Invalid sender", + "invalidSessionInfo": "Invalid verification ID", + "invalidTenantId": "Invalid tenant ID", + "mfaInfoNotFound": "Multi-factor info not found", + "mfaRequired": "Multi-factor authentication required", + "missingAndroidPackageName": "Missing Android package name", + "missingAppCredential": "Missing app credential", + "missingAuthDomain": "Auth domain configuration required", + "missingCode": "Missing verification code", + "missingContinueUri": "Missing ressource", + "missingIframeStart": "Missing iframe start", + "missingIosBundleId": "Missing iOS bundle ID", + "missingOrInvalidNonce": "Missing or invalid nonce", + "missingMfaInfo": "Missing multi-factor info", + "missingMfaSession": "Missing multi-factor session", + "missingPhoneNumber": "Missing phone number", + "missingSessionInfo": "Missing verification ID", + "moduleDestroyed": "App deleted", + "needConfirmation": "Account exists with different credential", + "networkRequestFailed": "Network request failed", + "nullUser": "Null user", + "noAuthEvent": "No auth event", + "noSuchProvider": "No such provider", + "operationNotAllowed": "Operation not allowed", + "operationNotSupported": "Operation not supported in this environment", + "popupBlocked": "Popup blocked", + "popupClosedByUser": "Popup closed by user", + "providerAlreadyLinked": "Provider already linked", + "quotaExceeded": "Quota exceeded", + "redirectCancelledByUser": "Redirect cancelled by user", + "redirectOperationPending": "Redirect operation pending", + "rejectedCredential": "Rejected credential", + "secondFactorAlreadyEnrolled": "Second factor already enrolled", + "secondFactorLimitExceeded": "Maximum second factor count exceeded", + "tenantIdMismatch": "Tenant ID mismatch", + "timeoutError": "Timeout", + "tokenExpired": "User token expired", + "tooManyAttemptsTryLater": "Too many requests, try again later", + "unauthorizedDomain": "Unauthorized domain for resource", + "unsupportedFirstFactor": "Unsupported first factor", + "unsupportedPersistence": "Unsupported persistence type", + "unsupportedTenantOperation": "Unsupported tenant operation", + "unverifiedEmail": "Unverified email", + "userCancelled": "User cancelled", + "userDeleted": "User not found", + "userMismatch": "User mismatch", + "userSignedOut": "User signed out", + "weakPassword": "Weak password", + "webStorageUnsupported": "Web storage unsupported", + "alreadyInitialized": "Already initialized", + "recaptchaNotEnabled": "reCAPTCHA not enabled", + "missingRecaptchaToken": "Missing reCAPTCHA token", + "invalidRecaptchaToken": "Invalid reCAPTCHA token", + "invalidRecaptchaAction": "Invalid reCAPTCHA action", + "missingClientType": "Missing client type", + "missingRecaptchaVersion": "Missing reCAPTCHA version", + "invalidRecaptchaVersion": "Invalid reCAPTCHA version", + "invalidReqType": "Invalid request type" } diff --git a/recipients_app/lib/l10n/app_kri.arb b/recipients_app/lib/l10n/app_kri.arb index 8515691dc..40ee6dbbf 100644 --- a/recipients_app/lib/l10n/app_kri.arb +++ b/recipients_app/lib/l10n/app_kri.arb @@ -131,8 +131,8 @@ } } }, - "survey12Months": "12 mɔnt sɔve", - "survey12MonthsInfo": "Duya tek 5 minit fɔ ansa di kwɛstyɔn dɛm ɛn ɛp wi fɔ mek Social Income bɛtɛ", + "surveyCardTitle": "Sɔve", + "surveyCartInfo": "Duya tek 5 minit fɔ ansa di kwɛstyɔn dɛm ɛn ɛp wi fɔ mek Social Income bɛtɛ", "verification": "Fɔ sho se na yu", "verificationSent": "Wi dɔn sɛn yu wan spɛshal kod fɔ sho se na yu na yu {phoneNumber}", "@verificationSent": { diff --git a/recipients_app/lib/view/error_localization_helper.dart b/recipients_app/lib/view/error_localization_helper.dart new file mode 100644 index 000000000..783c0faf2 --- /dev/null +++ b/recipients_app/lib/view/error_localization_helper.dart @@ -0,0 +1,123 @@ +import "package:firebase_auth/firebase_auth.dart"; +import "package:flutter_gen/gen_l10n/app_localizations.dart"; + +String localizeExceptionMessage(Exception? ex, AppLocalizations localizations) { + if (ex is FirebaseAuthException) { + return switch (ex.code) { + "invalid-verification-code" => localizations.invalidVerificationCodeError, + "invalid-phone-number" => localizations.invalidPhoneNumberError, + "invalid-credential" => localizations.invalidCredentialError, + "user-disabled" => localizations.userDisabledError, + "admin-only-operation" => localizations.adminOnlyOperation, + "argument-error" => localizations.argumentError, + "app-not-authorized" => localizations.appNotAuthorized, + "app-not-installed" => localizations.appNotInstalled, + "captcha-check-failed" => localizations.captchaCheckFailed, + "code-expired" => localizations.codeExpired, + "cordova-not-ready" => localizations.cordovaNotReady, + "cors-unsupported" => localizations.corsUnsupported, + "credential-already-in-use" => localizations.credentialAlreadyInUse, + "credential-mismatch" => localizations.credentialMismatch, + "credential-too-old-login-again" => + localizations.credentialTooOldLoginAgain, + "dependent-sdk-init-before-auth" => + localizations.dependentSdkInitBeforeAuth, + "dynamic-link-not-activated" => localizations.dynamicLinkNotActivated, + "email-change-needs-verification" => + localizations.emailChangeNeedsVerification, + "email-exists" => localizations.emailExists, + "emulator-config-failed" => localizations.emulatorConfigFailed, + "expired-oob-code" => localizations.expiredOobCode, + "expired-popup-request" => localizations.expiredPopupRequest, + "internal-error" => localizations.internalError, + "invalid-api-key" => localizations.invalidApiKey, + "invalid-app-credential" => localizations.invalidAppCredential, + "invalid-app-id" => localizations.invalidAppId, + "invalid-auth" => localizations.invalidAuth, + "invalid-auth-event" => localizations.invalidAuthEvent, + "invalid-cert-hash" => localizations.invalidCertHash, + "invalid-code" => localizations.invalidCode, + "invalid-continue-uri" => localizations.invalidContinueUri, + "invalid-cordova-configuration" => + localizations.invalidCordovaConfiguration, + "invalid-custom-token" => localizations.invalidCustomToken, + "invalid-dynamic-link-domain" => localizations.invalidDynamicLinkDomain, + "invalid-email" => localizations.invalidEmail, + "invalid-emulator-scheme" => localizations.invalidEmulatorScheme, + "invalid-idp-response" => localizations.invalidIdpResponse, + "invalid-message-payload" => localizations.invalidMessagePayload, + "invalid-mfa-session" => localizations.invalidMfaSession, + "invalid-oauth-client-id" => localizations.invalidOauthClientId, + "invalid-oauth-provider" => localizations.invalidOauthProvider, + "invalid-oob-code" => localizations.invalidOobCode, + "invalid-origin" => localizations.invalidOrigin, + "invalid-password" => localizations.invalidPassword, + "invalid-persistence" => localizations.invalidPersistence, + "invalid-provider-id" => localizations.invalidProviderId, + "invalid-recipient-email" => localizations.invalidRecipientEmail, + "invalid-sender" => localizations.invalidSender, + "invalid-session-info" => localizations.invalidSessionInfo, + "invalid-tenant-id" => localizations.invalidTenantId, + "mfa-info-not-found" => localizations.mfaInfoNotFound, + "mfa-required" => localizations.mfaRequired, + "missing-android-package-name" => localizations.missingAndroidPackageName, + "missing-app-credential" => localizations.missingAppCredential, + "missing-auth-domain" => localizations.missingAuthDomain, + "missing-code" => localizations.missingCode, + "missing-continue-uri" => localizations.missingContinueUri, + "missing-iframe-start" => localizations.missingIframeStart, + "missing-ios-bundle-id" => localizations.missingIosBundleId, + "missing-or-invalid-nonce" => localizations.missingOrInvalidNonce, + "missing-mfa-info" => localizations.missingMfaInfo, + "missing-mfa-session" => localizations.missingMfaSession, + "missing-phone-number" => localizations.missingPhoneNumber, + "missing-session-info" => localizations.missingSessionInfo, + "module-destroyed" => localizations.moduleDestroyed, + "need-confirmation" => localizations.needConfirmation, + "network-request-failed" => localizations.networkRequestFailed, + "null-user" => localizations.nullUser, + "no-auth-event" => localizations.noAuthEvent, + "no-such-provider" => localizations.noSuchProvider, + "operation-not-allowed" => localizations.operationNotAllowed, + "operation-not-supported" => localizations.operationNotSupported, + "popup-blocked" => localizations.popupBlocked, + "popup-closed-by-user" => localizations.popupClosedByUser, + "provider-already-linked" => localizations.providerAlreadyLinked, + "quota-exceeded" => localizations.quotaExceeded, + "redirect-cancelled-by-user" => localizations.redirectCancelledByUser, + "redirect-operation-pending" => localizations.redirectOperationPending, + "rejected-credential" => localizations.rejectedCredential, + "second-factor-already-enrolled" => + localizations.secondFactorAlreadyEnrolled, + "second-factor-limit-exceeded" => localizations.secondFactorLimitExceeded, + "tenant-id-mismatch" => localizations.tenantIdMismatch, + "timeout" => localizations.timeoutError, + "token-expired" => localizations.tokenExpired, + "too-many-attempts-try-later" => localizations.tooManyAttemptsTryLater, + "unauthorized-domain" => localizations.unauthorizedDomain, + "unsupported-first-factor" => localizations.unsupportedFirstFactor, + "unsupported-persistence" => localizations.unsupportedPersistence, + "unsupported-tenant-operation" => + localizations.unsupportedTenantOperation, + "unverified-email" => localizations.unverifiedEmail, + "user-cancelled" => localizations.userCancelled, + "user-deleted" => localizations.userDeleted, + "user-mismatch" => localizations.userMismatch, + "user-signed-out" => localizations.userSignedOut, + "weak-password" => localizations.weakPassword, + "web-storage-unsupported" => localizations.webStorageUnsupported, + "already-initialized" => localizations.alreadyInitialized, + "recaptcha-not-enabled" => localizations.recaptchaNotEnabled, + "missing-recaptcha-token" => localizations.missingRecaptchaToken, + "invalid-recaptcha-token" => localizations.invalidRecaptchaToken, + "invalid-recaptcha-action" => localizations.invalidRecaptchaAction, + "missing-client-type" => localizations.missingClientType, + "missing-recaptcha-version" => localizations.missingRecaptchaVersion, + "invalid-recaptcha-version" => localizations.invalidRecaptchaVersion, + "invalid-req-type" => localizations.invalidReqType, + _ => ex.toString(), + }; + } + + return ex.toString(); +} diff --git a/recipients_app/lib/view/pages/welcome_page.dart b/recipients_app/lib/view/pages/welcome_page.dart index 272805dec..769317a6b 100644 --- a/recipients_app/lib/view/pages/welcome_page.dart +++ b/recipients_app/lib/view/pages/welcome_page.dart @@ -2,9 +2,9 @@ import "package:app/core/cubits/signup/signup_cubit.dart"; import "package:app/core/helpers/flushbar_helper.dart"; import "package:app/data/repositories/repositories.dart"; +import "package:app/view/error_localization_helper.dart"; import "package:app/view/widgets/welcome/otp_input_page.dart"; import "package:app/view/widgets/welcome/phone_input_page.dart"; -import "package:firebase_auth/firebase_auth.dart"; import "package:flutter/material.dart"; import "package:flutter_bloc/flutter_bloc.dart"; import "package:flutter_gen/gen_l10n/app_localizations.dart"; @@ -37,13 +37,13 @@ class _WelcomeView extends StatelessWidget { if (state.status == SignupStatus.verificationFailure) { FlushbarHelper.showFlushbar( context, - message: _localizeExceptionMessage(state.exception, localizations), + message: localizeExceptionMessage(state.exception, localizations), type: FlushbarType.error, ); } else if (state.status == SignupStatus.phoneNumberFailure) { FlushbarHelper.showFlushbar( context, - message: _localizeExceptionMessage(state.exception, localizations), + message: localizeExceptionMessage(state.exception, localizations), type: FlushbarType.error, ); } @@ -64,18 +64,4 @@ class _WelcomeView extends StatelessWidget { ), ); } - - String _localizeExceptionMessage(Exception? ex, AppLocalizations localizations) { - if (ex is FirebaseAuthException) { - return switch (ex.code) { - "invalid-verification-code" => localizations.invalidVerificationCodeError, - "invalid-phone-number" => localizations.invalidPhoneNumberError, - "invalid-credential" => "", - "user-disabled" => "", - _ => ex.toString(), - }; - } - - return ex.toString(); - } } diff --git a/recipients_app/lib/view/widgets/survey/survey_card_container.dart b/recipients_app/lib/view/widgets/survey/survey_card_container.dart index de42c3dea..f8655a7e4 100644 --- a/recipients_app/lib/view/widgets/survey/survey_card_container.dart +++ b/recipients_app/lib/view/widgets/survey/survey_card_container.dart @@ -33,7 +33,7 @@ class SurveyCardContainer extends DashboardItem { mainAxisSize: MainAxisSize.min, children: [ Text( - localizations.survey12Months, + localizations.surveyCardTitle, style: const TextStyle( color: Colors.black, fontSize: 13.0, @@ -52,7 +52,7 @@ class SurveyCardContainer extends DashboardItem { ), const SizedBox(height: 4), Text( - localizations.survey12MonthsInfo, + localizations.surveyCardInfo, textAlign: TextAlign.center, style: const TextStyle( color: Colors.black, diff --git a/recipients_app/lib/view/widgets/welcome/otp_input_page.dart b/recipients_app/lib/view/widgets/welcome/otp_input_page.dart index f5f369859..9c430a7da 100644 --- a/recipients_app/lib/view/widgets/welcome/otp_input_page.dart +++ b/recipients_app/lib/view/widgets/welcome/otp_input_page.dart @@ -51,10 +51,10 @@ class _OtpInputPageState extends State { context.read().resendVerificationCode(), child: Text( localizations.resendVerificationCode, - style: const TextStyle( - color: AppColors.primaryColor, - decoration: TextDecoration.underline, - ), + style: Theme.of(context).textTheme.headlineMedium!.copyWith( + color: AppColors.primaryColor, + decoration: TextDecoration.underline, + ), ), ), const SizedBox(height: 200), diff --git a/recipients_app/lib/view/widgets/welcome/phone_input_page.dart b/recipients_app/lib/view/widgets/welcome/phone_input_page.dart index d3b21af1d..dd10f1954 100644 --- a/recipients_app/lib/view/widgets/welcome/phone_input_page.dart +++ b/recipients_app/lib/view/widgets/welcome/phone_input_page.dart @@ -98,10 +98,10 @@ class _PhoneInputPageState extends State { ), inputDecoration: InputDecoration( labelText: localizations.phoneNumber, - labelStyle: const TextStyle( - color: AppColors.primaryColor, - fontSize: 18, - ), + labelStyle: Theme.of(context) + .textTheme + .headlineMedium! + .copyWith(color: AppColors.primaryColor), enabledBorder: const OutlineInputBorder( borderSide: BorderSide(color: AppColors.primaryColor),