diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/formDefinitions.tsx b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/formDefinitions.tsx index e33adccd35..18779d10fe 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/formDefinitions.tsx +++ b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/formDefinitions.tsx @@ -11,6 +11,8 @@ export function getFormMap({ getValidationErrorMessage: (props: { type: "required" | "invalid"; label: string; + errorCode?: string; + fieldName?: string; }) => string; bankCountry?: string; }) { @@ -32,6 +34,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.beneficiaryAccountName?.type, label: props.text.beneficiaryAccountNameLabel, + errorCode: errors?.inputErrors?.beneficiaryAccountName?.errorCode, + fieldName: "beneficiaryAccountName", }), })} > @@ -50,6 +54,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankAccountType?.type, label: props.text.bankAccountTypeLabel, + errorCode: errors?.inputErrors?.bankAccountType?.errorCode, + fieldName: "bankAccountType", }), })} > @@ -77,6 +83,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankAccountNumber?.type, label: props.text.bankAccountNumberLabel, + errorCode: errors?.inputErrors?.bankAccountNumber?.errorCode, + fieldName: "bankAccountNumber", }), })} > @@ -97,6 +105,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankAccountNumber?.type, label: props.text.ibanLabel, + errorCode: errors?.inputErrors?.bankAccountNumber?.errorCode, + fieldName: "bankAccountNumber", }), })} > @@ -117,6 +127,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.swiftCode?.type, label: props.text.swiftCodeLabel, + errorCode: errors?.inputErrors?.swiftCode?.errorCode, + fieldName: "swiftCode", }), })} > @@ -152,6 +164,8 @@ export function getFormMap({ bankCountry, } ), + errorCode: errors?.inputErrors?.routingCode?.errorCode, + fieldName: "routingCode", }), })} > @@ -171,6 +185,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankName?.type, label: props.text.bankNameLabel, + errorCode: errors?.inputErrors?.bankName?.errorCode, + fieldName: "bankName", }), })} > @@ -189,6 +205,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.beneficiaryClassification?.type, label: props.text.classificationLabel, + errorCode: errors?.inputErrors?.beneficiaryClassification?.errorCode, + fieldName: "beneficiaryClassification", }), })} > @@ -222,6 +240,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.taxPayerId?.type, label: props.text.taxPayerIdLabel, + errorCode: errors?.inputErrors?.taxPayerId?.errorCode, + fieldName: "taxPayerId", }), })} >, @@ -240,6 +260,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.beneficiaryClassification?.type, label: props.text.classificationCPFLabel, + errorCode: errors?.inputErrors?.beneficiaryClassification?.errorCode, + fieldName: "beneficiaryClassification", }), })} > @@ -262,6 +284,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.patronymicName?.type, label: props.text.patronymicNameLabel, + errorCode: errors?.inputErrors?.patronymicName?.errorCode, + fieldName: "patronymicName", }), })} > @@ -280,6 +304,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.voCode?.type, label: props.text.voCodeLabel, + errorCode: errors?.inputErrors?.voCode?.errorCode, + fieldName: "voCode", }), })} > @@ -299,6 +325,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.agencyCode?.type, label: props.text.agencyCodeLabel, + errorCode: errors?.inputErrors?.agencyCode?.errorCode, + fieldName: "agencyCode", }), })} > @@ -318,6 +346,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankAddress?.type, label: props.text.bankAddressLabel, + errorCode: errors?.inputErrors?.bankAddress?.errorCode, + fieldName: "bankAddress", }), })} >, @@ -333,6 +363,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankCity?.type, label: props.text.bankCityLabel, + errorCode: errors?.inputErrors?.bankCity?.errorCode, + fieldName: "bankCity", }), })} >, @@ -348,6 +380,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankState?.type, label: props.text.bankStateLabel, + errorCode: errors?.inputErrors?.bankState?.errorCode, + fieldName: "bankState", }), })} >, @@ -363,6 +397,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankPostalCode?.type, label: props.text.bankPostalCodeLabel, + errorCode: errors?.inputErrors?.bankPostalCode?.errorCode, + fieldName: "bankPostalCode", }), })} >, @@ -382,6 +418,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.branchCode?.type, label: props.text.branchCodeLabel, + errorCode: errors?.inputErrors?.branchCode?.errorCode, + fieldName: "branchCode", }), })} > @@ -400,6 +438,8 @@ export function getFormMap({ helpText: getValidationErrorMessage({ type: errors?.inputErrors?.beneficiaryClassification?.type, label: props.text.classificationLabel, + errorCode: errors?.inputErrors?.beneficiaryClassification?.errorCode, + fieldName: "beneficiaryClassification", }), })} > diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form-view.tsx b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form-view.tsx index 806eaf1139..3819882246 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form-view.tsx +++ b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form-view.tsx @@ -32,6 +32,7 @@ export interface BankingInfoFormViewProps { inputErrors?: { [field: string]: { type: "required" | "invalid"; + errorCode?: string; }; }; }; @@ -105,6 +106,7 @@ export interface BankingInfoFormViewProps { generalTitle: string; generalDescription: string; }; + errorMessages?: { [field: string]: string }; }; refs: { formRef: any; diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form.tsx b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form.tsx index 2a674f973d..8d005baa3e 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form.tsx +++ b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/sqm-banking-info-form.tsx @@ -350,6 +350,197 @@ export class BankingInfoForm { */ @Prop() modalButtonText: string = "I understand, update my information"; + // ────────────────────────────────────────────────────────────────── + // Per-field validation error messages + // Each prop uses ICU select on {errorCode} to pick the right message. + // Error codes are short frontend keys mapped from the API error codes. + // The `other` branch displays the raw API message directly via {errorCode}, + // which is already human-readable English (e.g. "Invalid Routing Code"). + // ────────────────────────────────────────────────────────────────── + + /** + * Error messages for the beneficiary / account holder name field. + * Supports error codes: empty, invalidCharacters, numeric, tooLong, + * nonEnglish, businessNameMismatch, nameMismatch, businessPayeeMismatch, payeeMismatch + * @uiName Beneficiary account name error + * @uiWidget textArea + */ + @Prop() beneficiaryAccountNameError: string = + "{errorCode, select, empty {Account holder name is required} invalidCharacters {Account holder name contains invalid characters} numeric {Account holder name cannot be purely numeric} tooLong {Account holder name must be 70 characters or fewer} nonEnglish {Account holder name must contain only English characters for this currency} businessNameMismatch {Beneficiary name must match the name on your tax document} nameMismatch {Beneficiary name must match the name on your tax document} businessPayeeMismatch {Payee name must match the name on your tax document} payeeMismatch {Payee name must match the name on your tax document} other {{errorCode}}}"; + + /** + * Error messages for the bank account number / IBAN field. + * Supports error codes: empty, invalidUk, invalid, ibanEmpty, + * ibanAlphanumeric, ibanInvalid, ibanCountryMismatch + * @uiName Bank account number / IBAN error + * @uiWidget textArea + */ + @Prop() bankAccountNumberError: string = + "{errorCode, select, empty {Account number is required} invalidUk {Please enter a valid UK account number} invalid {Account number is invalid} ibanEmpty {IBAN is required} ibanAlphanumeric {IBAN must contain only letters and numbers} ibanInvalid {IBAN is invalid} ibanCountryMismatch {UK accounts must use an IBAN starting with GB} other {{errorCode}}}"; + + /** + * Error messages for the routing code / sort code / BSB field. + * Supports error codes: invalidBsb, invalidSortCode, empty, invalid + * @uiName Routing code error + * @uiWidget textArea + */ + @Prop() routingCodeError: string = + "{errorCode, select, invalidBsb {Please enter a valid BSB number} invalidSortCode {Please enter a valid sort code} empty {Routing number is required} invalid {Routing number is invalid} other {{errorCode}}}"; + + /** + * Error messages for the SWIFT / BIC code field. + * Supports error codes: empty, alphanumeric, invalid + * @uiName SWIFT code error + * @uiWidget textArea + */ + @Prop() swiftCodeError: string = + "{errorCode, select, empty {SWIFT/BIC code is required} alphanumeric {SWIFT/BIC code must contain only letters and numbers} invalid {SWIFT/BIC code is invalid} other {{errorCode}}}"; + + /** + * Error messages for the bank account type field. + * Supports error codes: empty + * @uiName Bank account type error + * @uiWidget textArea + */ + @Prop() bankAccountTypeError: string = + "{errorCode, select, empty {Bank account type is required} other {{errorCode}}}"; + + /** + * Error messages for the bank name field. + * Supports error codes: empty + * @uiName Bank name error + * @uiWidget textArea + */ + @Prop() bankNameError: string = + "{errorCode, select, empty {Bank name is required} other {{errorCode}}}"; + + /** + * Error messages for the tax payer ID / classification entity field. + * Supports error codes: empty, emptyAr, emptyKr, alphanumeric, alphanumericAr, + * alphanumericKr, invalid, invalidAr, invalidKr, invalidKzt, cnpjTooShort, cpfTooShort + * @uiName Tax payer ID error + * @uiWidget textArea + */ + @Prop() taxPayerIdError: string = + "{errorCode, select, empty {Tax payer ID is required} emptyAr {CUIT/CUIL is required} emptyKr {Classification ID is required} alphanumeric {Tax payer ID must contain only letters and numbers} alphanumericAr {CUIT/CUIL must contain only letters and numbers} alphanumericKr {Classification ID must contain only letters and numbers} invalid {Tax payer ID is invalid} invalidAr {CUIT/CUIL must be 11 characters} invalidKr {Classification ID length is invalid} invalidKzt {Tax payer ID must be 12 characters for KZT} cnpjTooShort {CNPJ must be at least 14 characters} cpfTooShort {CPF must be at least 11 characters} other {{errorCode}}}"; + + /** + * Error messages for the patronymic name field. + * Supports error codes: empty, alphanumeric + * @uiName Patronymic name error + * @uiWidget textArea + */ + @Prop() patronymicNameError: string = + "{errorCode, select, empty {Patronymic name is required} alphanumeric {Patronymic name must contain only letters and numbers} other {{errorCode}}}"; + + /** + * Error messages for the VO code field. + * Supports error codes: empty, alphanumeric + * @uiName VO code error + * @uiWidget textArea + */ + @Prop() voCodeError: string = + "{errorCode, select, empty {VO code is required} alphanumeric {VO code must contain only letters and numbers} other {{errorCode}}}"; + + /** + * Error messages for the agency code field. + * Supports error codes: empty, alphanumeric, tooShort + * @uiName Agency code error + * @uiWidget textArea + */ + @Prop() agencyCodeError: string = + "{errorCode, select, empty {Agency code is required} alphanumeric {Agency code must contain only letters and numbers} tooShort {Agency code must be at least 5 characters} other {{errorCode}}}"; + + /** + * Error messages for the bank address field. + * Supports error codes: empty + * @uiName Bank address error + * @uiWidget textArea + */ + @Prop() bankAddressError: string = + "{errorCode, select, empty {Bank address is required} other {{errorCode}}}"; + + /** + * Error messages for the bank city field. + * Supports error codes: empty + * @uiName Bank city error + * @uiWidget textArea + */ + @Prop() bankCityError: string = + "{errorCode, select, empty {Bank city is required} other {{errorCode}}}"; + + /** + * Error messages for the bank province/state field. + * Supports error codes: empty + * @uiName Bank province/state error + * @uiWidget textArea + */ + @Prop() bankStateError: string = + "{errorCode, select, empty {Bank province/state is required} other {{errorCode}}}"; + + /** + * Error messages for the bank postal code field. + * Supports error codes: empty + * @uiName Bank postal code error + * @uiWidget textArea + */ + @Prop() bankPostalCodeError: string = + "{errorCode, select, empty {Bank postal code is required} other {{errorCode}}}"; + + /** + * Error messages for the branch code field. + * Supports error codes: invalid + * @uiName Branch code error + * @uiWidget textArea + */ + @Prop() branchCodeError: string = + "{errorCode, select, invalid {Branch code is invalid} other {{errorCode}}}"; + + /** + * Error messages for the branch name field. + * Supports error codes: empty + * @uiName Branch name error + * @uiWidget textArea + */ + @Prop() branchNameError: string = + "{errorCode, select, empty {Branch name is required} other {{errorCode}}}"; + + /** + * Error messages for the classification code field. + * Supports error codes: empty, invalidKzt + * @uiName Classification code error + * @uiWidget textArea + */ + @Prop() classificationCodeError: string = + "{errorCode, select, empty {Classification code is required} invalidKzt {Classification code must be exactly 2 characters} other {{errorCode}}}"; + + /** + * Error messages for the PayPal email field. + * Supports error codes: empty, unsupportedCurrency, invalidEmail, verificationIncomplete + * @uiName PayPal email error + * @uiWidget textArea + */ + @Prop() paypalEmailError: string = + "{errorCode, select, empty {PayPal email is required} unsupportedCurrency {PayPal is not supported for this currency} invalidEmail {Please enter a valid email address} verificationIncomplete {PayPal verification is not complete} other {{errorCode}}}"; + + /** + * Error messages for the payment threshold field. + * Supports error codes: empty, invalid + * @uiName Payment threshold error + * @uiWidget textArea + */ + @Prop() paymentThresholdError: string = + "{errorCode, select, empty {Payment threshold is required} invalid {Payment threshold is invalid} other {{errorCode}}}"; + + /** + * Error messages for the payment day field. + * Supports error codes: empty, invalid + * @uiName Payment day error + * @uiWidget textArea + */ + @Prop() paymentDayError: string = + "{errorCode, select, empty {Payment day is required} invalid {Payment day must be the 1st or the 15th} other {{errorCode}}}"; + /** * @undocumented * @uiType object @@ -373,6 +564,28 @@ export class BankingInfoForm { loadingErrorAlertDescription: props.loadingErrorAlertDescription, loadingErrorAlertHeader: props.loadingErrorAlertHeader, }, + errorMessages: { + beneficiaryAccountName: props.beneficiaryAccountNameError, + bankAccountNumber: props.bankAccountNumberError, + routingCode: props.routingCodeError, + swiftCode: props.swiftCodeError, + bankAccountType: props.bankAccountTypeError, + bankName: props.bankNameError, + taxPayerId: props.taxPayerIdError, + patronymicName: props.patronymicNameError, + voCode: props.voCodeError, + agencyCode: props.agencyCodeError, + bankAddress: props.bankAddressError, + bankCity: props.bankCityError, + bankState: props.bankStateError, + bankPostalCode: props.bankPostalCodeError, + branchCode: props.branchCodeError, + branchName: props.branchNameError, + beneficiaryClassification: props.classificationCodeError, + paypalEmailAddress: props.paypalEmailError, + paymentThreshold: props.paymentThresholdError, + paymentDay: props.paymentDayError, + }, }; } @@ -389,10 +602,32 @@ export class BankingInfoForm { function getValidationErrorMessage({ type, label, + errorCode, + fieldName, }: { type: "required" | "invalid"; label: string; + errorCode?: string; + fieldName?: string; }) { + // If we have a specific error code from the API, try to use + // the per-field ICU error message template for a rich message + if (type === "invalid" && errorCode && fieldName) { + const errorTemplate = props.text.errorMessages?.[fieldName]; + if (errorTemplate) { + return intl.formatMessage( + { + id: `fieldError-${fieldName}-${errorCode}`, + defaultMessage: errorTemplate, + }, + { + errorCode, + fieldName: label, + } + ); + } + } + if (type === "required") { return intl.formatMessage( { @@ -525,6 +760,8 @@ export class BankingInfoForm { helpText: getValidationErrorMessage({ type: errors?.inputErrors?.bankCountry?.type, label: props.text.bankLocationLabel, + errorCode: errors?.inputErrors?.bankCountry?.errorCode, + fieldName: "bankCountry", }), })} > @@ -578,6 +815,8 @@ export class BankingInfoForm { helpText: getValidationErrorMessage({ type: errors?.inputErrors?.paymentThreshold?.type, label: props.text.paymentThresholdSelectLabel, + errorCode: errors?.inputErrors?.paymentThreshold?.errorCode, + fieldName: "paymentThreshold", }), })} > @@ -601,6 +840,8 @@ export class BankingInfoForm { helpText: getValidationErrorMessage({ type: errors?.inputErrors?.paymentDay?.type, label: props.text.paymentDaySelectLabel, + errorCode: errors?.inputErrors?.paymentDay?.errorCode, + fieldName: "paymentDay", }), })} > @@ -629,6 +870,10 @@ export class BankingInfoForm { type: props.states.formState?.errors?.inputErrors ?.paypalEmailAddress?.type, label: props.text.payPalInputLabel, + errorCode: + props.states.formState?.errors?.inputErrors + ?.paypalEmailAddress?.errorCode, + fieldName: "paypalEmailAddress", }), })} > diff --git a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/useBankingInfoForm.tsx b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/useBankingInfoForm.tsx index 09a1cb7bfd..108c0c832e 100644 --- a/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/useBankingInfoForm.tsx +++ b/packages/mint-components/src/components/tax-and-cash/sqm-banking-info-form/useBankingInfoForm.tsx @@ -49,6 +49,129 @@ const ACH_PAYMENT_METHOD = 3; const WIRE_PAYMENT_METHOD = 5; const PAYPAL_PAYMENT_METHOD = 7; +/** + * Maps GraphQL validation error field names to form field names. + * + * The Impact API returns UpperCamelCase field names (e.g. `BankAccountNumber`). + * The GraphQL layer in `UserServiceImpl.java` converts these to lowerCamelCase + * via `CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, errorDto.field)`. + * + * Most converted field names already match the form field names exactly + * (e.g. `bankAccountNumber`, `swiftCode`, `routingCode`). Only entries + * where the GraphQL field name differs from the form field name need + * to be listed here. + */ +const API_FIELD_TO_FORM_FIELD: Record = { + // bankProvinceState → form uses bankState + bankProvinceState: "bankState", +}; + +/** + * Maps Impact API error code paths (from validationErrors[].errorPath) to short, + * readable frontend error codes used in the ICU select props. + * + * The Impact API returns a stable dot-delimited error path (e.g. + * "withdrawal.settings.error.routingcode") alongside the human-readable message. + * The GraphQL layer exposes this as `errorPath`. The keys below match those paths + * to short frontend codes used in the ICU `{errorCode, select, ...}` props. + */ +const API_ERROR_PATH_TO_FRONTEND: Record = { + // Beneficiary account name + "withdrawal.settings.error.empty_beneficiaryname": "empty", + "withdrawal.settings.error.invalid_character_beneficiaryname": + "invalidCharacters", + "withdrawal.settings.error.numeric_beneficiaryname": "numeric", + "withdrawal_settings.error.beneficiaryname.size": "tooLong", + "withdrawal.settings.error.non_english_beneficiaryname": "nonEnglish", + "withdrawal_settings.error.business_beneficiaryname_match": + "businessNameMismatch", + "withdrawal_settings.error.beneficiaryname_match": "nameMismatch", + "withdrawal_settings.error.business_checkpayeename_match": + "businessPayeeMismatch", + "withdrawal_settings.error.checkpayeename_match": "payeeMismatch", + + // Bank account number + "withdrawal.settings.error.accountnumber.empty": "empty", + "withdrawal.settings.error.accountnumber.uk": "invalidUk", + "withdrawal.settings.error.bankaccount.invalid": "invalid", + + // IBAN + "withdrawal.settings.error.iban": "ibanEmpty", + "withdrawal.settings.error.iban.alphanumeric": "ibanAlphanumeric", + "withdrawal.settings.error.iban.invalid": "ibanInvalid", + "withdrawal.settings.error.iban.uk.country.mismatch": "ibanCountryMismatch", + + // Routing code + "withdrawal.settings.error.bsbNumber": "invalidBsb", + "withdrawal.settings.error.sortcode": "invalidSortCode", + "withdrawal.settings.error.routingNumber": "empty", + "withdrawal.settings.error.routingcode": "invalid", + + // SWIFT / BIC + "withdrawal.settings.error.bic": "empty", + "withdrawal.settings.error.bic.alphanumeric": "alphanumeric", + "withdrawal.settings.error.bic.invalid": "invalid", + + // Bank account type + "global.error.invalid.accounttype": "empty", + + // Bank name + "withdrawal.settings.error.bankName": "empty", + + // Tax payer ID + "withdrawal.settings.error.taxPayerId": "empty", + "withdrawal.settings.error.taxPayerId.ar": "emptyAr", + "withdrawal.settings.error.taxPayerId.kr": "emptyKr", + "withdrawal.settings.error.taxPayerId.alphanumeric": "alphanumeric", + "withdrawal.settings.error.taxPayerId.alphanumeric.ar": "alphanumericAr", + "withdrawal.settings.error.taxPayerId.alphanumeric.kr": "alphanumericKr", + "withdrawal.settings.error.taxPayerId.invalid": "invalid", + "withdrawal.settings.error.taxPayerId.invalid.ar": "invalidAr", + "withdrawal.settings.error.taxPayerId.invalid.kr": "invalidKr", + "withdrawal.settings.error.taxPayerId.invalid.kzt": "invalidKzt", + "withdrawal.settings.error.taxPayerId.cnpj": "cnpjTooShort", + "withdrawal.settings.error.taxPayerId.cpf": "cpfTooShort", + + // Patronymic name + "withdrawal.settings.error.patronymicName": "empty", + "withdrawal.settings.error.patronymicName.alphanumeric": "alphanumeric", + + // VO code + "withdrawal.settings.error.voCode": "empty", + "withdrawal.settings.error.voCode.alphanumeric": "alphanumeric", + + // Agency code + "withdrawal.settings.error.agencyCode": "empty", + "withdrawal.settings.error.agencyCode.alphanumeric": "alphanumeric", + "withdrawal.settings.error.agencyCode.length": "tooShort", + + // Bank address fields + "withdrawal.settings.error.bankAddress": "empty", + "withdrawal.settings.error.bankCity": "empty", + "withdrawal.settings.error.bankProvinceState": "empty", + "withdrawal.settings.error.bankPostalCode": "empty", + + // Branch code / name + "withdrawal.settings.error.branchCode": "invalid", + "withdrawal.settings.error.branchName": "empty", + + // Classification code + "withdrawal.settings.error.classificationCode.invalid": "empty", + "withdrawal.settings.error.classificationCode.invalid.kzt": "invalidKzt", + + // PayPal + "payment.error.email": "empty", + "payment.error.paypal_not_supported": "unsupportedCurrency", + "payment.error.email.invalid": "invalidEmail", + "payment.error.paypal_verification_incomplete": "verificationIncomplete", + + // Payment schedule + "payment.error.no_threshold": "empty", + "payment.error.invalid_threshold": "invalid", + "payment.error.no_dayOfMonth": "empty", + "payment.error.invalid_dayOfMonth": "invalid", +}; + export type BankingInfoFormData = { // Fields that are auto-filled bankCountry?: string; @@ -101,7 +224,11 @@ export function getFormInputs({ bitset, formMap }) { type SetImpactPublisherWithdrawalSettingsResult = { setImpactPublisherWithdrawalSettings: { success: boolean; - validationErrors: { field: string; message: string }[]; + validationErrors: { + field: string; + message: string; + errorPath: string; + }[]; }; }; type SetImpactPublisherWithdrawalSettingsInput = { @@ -120,7 +247,11 @@ type UpdateImpactPublisherWithdrawalSettingsInput = type UpdateImpactPublisherWithdrawalSettingsResult = { updateImpactPublisherWithdrawalSettings: { success: boolean; - validationErrors: { field: string; message: string }[]; + validationErrors: { + field: string; + message: string; + errorPath: string; + }[]; }; }; @@ -135,6 +266,7 @@ const SAVE_WITHDRAWAL_SETTINGS = gql` validationErrors { field message + errorPath } } } @@ -151,6 +283,7 @@ const UPDATE_WITHDRAWAL_SETTINGS = gql` validationErrors { field message + errorPath } } } @@ -390,11 +523,15 @@ export function useBankingInfoForm( const mappedValidationErrors = validationErrors?.reduce( (agg, error) => { + const formField = + API_FIELD_TO_FORM_FIELD[error.field] || error.field; + const errorCode = + API_ERROR_PATH_TO_FRONTEND[error.errorPath] || error.errorPath; return { ...agg, - - [error.field]: { + [formField]: { type: "invalid", + errorCode, }, }; },