department-of-veterans-affairs/vets-website

View on GitHub
src/applications/toe/config/form.js

Summary

Maintainability
F
1 wk
Test Coverage
import React from 'react';
import { createSelector } from 'reselect';
import { Link } from 'react-router';

import fullSchema1990e from 'vets-json-schema/dist/22-1990E-schema.json';
import commonDefinitions from 'vets-json-schema/dist/definitions.json';

import * as address from 'platform/forms/definitions/address';
import bankAccountUI from 'platform/forms/definitions/bankAccount';
import currentOrPastDateUI from 'platform/forms-system/src/js/definitions/currentOrPastDate';
import emailUI from 'platform/forms-system/src/js/definitions/email';
import environment from 'platform/utilities/environment';
import get from 'platform/utilities/data/get';
import ReviewCardField from 'platform/forms-system/src/js/components/ReviewCardField';
import { VA_FORM_IDS } from 'platform/forms/constants';
import FormFooter from 'platform/forms/components/FormFooter';

import constants from 'vets-json-schema/dist/constants.json';
import * as BUCKETS from 'site/constants/buckets';
import * as ENVIRONMENTS from 'site/constants/environments';

import manifest from '../manifest.json';

import ConfirmationPage from '../containers/ConfirmationPage';
import IntroductionPage from '../containers/IntroductionPage';

import ApplicantIdentityView from '../components/ApplicantIdentityView';
import ApplicantInformationReviewPage from '../components/ApplicantInformationReviewPage';
import CustomEmailField from '../components/CustomEmailField';
import DirectDepositViewField from '../components/DirectDepositViewField';
import EmailViewField from '../components/EmailViewField';
import FirstSponsorRadioGroup from '../components/FirstSponsorRadioGroup';
import FirstSponsorReviewPage from '../components/FirstSponsorReviewPage';
import GetHelp from '../components/GetHelp';
import GoToYourProfileLink from '../components/GoToYourProfileLink';
import LearnMoreAboutMilitaryBaseTooltip from '../components/LearnMoreAboutMilitaryBaseTooltip';
import MailingAddressViewField from '../components/MailingAddressViewField';
import SelectedSponsorsReviewPage from '../components/SelectedSponsorsReviewPage';
import SponsorCheckboxGroup from '../components/SponsorsCheckboxGroup';
import Sponsors from '../components/Sponsors';
import SponsorsSelectionHeadings from '../components/SponsorsSelectionHeadings';
import YesNoReviewField from '../components/YesNoReviewField';
import preSubmitInfo from '../components/preSubmitInfo';
import DuplicateContactInfoModal from '../components/DuplicateContactInfoModal';

import {
  addWhitespaceOnlyError,
  isOnlyWhitespace,
  prefillTransformer,
  applicantIsaMinor,
} from '../helpers';

import { transformTOEForm } from '../utils/form-submit-transform';

import { phoneSchema, phoneUISchema } from '../schema';
import {
  isValidPhoneField,
  validateAccountNumber,
  validateEmail,
  validateRoutingNumber,
} from '../utils/validation';
import { formFields } from '../constants';
import ObfuscateReviewField from '../ObfuscateReviewField';

const { date, email } = commonDefinitions;
const contactMethods = ['Email', 'Home Phone', 'Mobile Phone', 'Mail'];
const checkImageSrc = (() => {
  const bucket = environment.isProduction()
    ? BUCKETS[ENVIRONMENTS.VAGOVPROD]
    : BUCKETS[ENVIRONMENTS.VAGOVSTAGING];

  return `${bucket}/img/check-sample.png`;
})();

const formConfig = {
  rootUrl: manifest.rootUrl,
  urlPrefix: '/',
  submitUrl: `${environment.API_URL}/meb_api/v0/forms_submit_claim`,
  // submit: () =>
  //   Promise.resolve({ attributes: { confirmationNumber: '123123123' } }),
  transformForSubmit: transformTOEForm,
  trackingPrefix: 'toe-',
  // Fix double headers (only show v3)
  v3SegmentedProgressBar: true,
  introduction: IntroductionPage,
  confirmation: ConfirmationPage,
  formId: VA_FORM_IDS.FORM_22_1990EMEB,
  title: 'Apply to use transferred education benefits',
  subTitle:
    'Equal to VA Form 22-1990e (Application for Family Member to Use Transferred Benefits)',
  saveInProgress: {
    // messages: {
    //   inProgress: 'Your survivor dependent benefits application (22-1990E) is in progress.',
    //   expired: 'Your saved survivor dependent benefits application (22-1990E) has expired. If you want to apply for survivor dependent benefits, please start a new application.',
    //   saved: 'Your survivor dependent benefits application has been saved.',
    // },
  },
  version: 0,
  prefillEnabled: true,
  prefillTransformer,
  savedFormMessages: {
    notFound: 'Please start over to apply for survivor dependent benefits.',
    noAuth:
      'Please sign in again to continue your application for survivor dependent benefits.',
  },
  defaultDefinitions: {},
  footerContent: FormFooter,
  getHelp: GetHelp,
  preSubmitInfo,
  chapters: {
    applicantInformationChapter: {
      title: 'Your information',
      pages: {
        applicantInformation: {
          title: 'Your information',
          path: 'applicant-information',
          subTitle: 'Your information',
          CustomPageReview: ApplicantInformationReviewPage,
          instructions:
            'This is the personal information we have on file for you.',
          uiSchema: {
            'view:applicantInformation': {
              'ui:description': (
                <>
                  <ApplicantIdentityView />
                </>
              ),
            },
            'view:dateOfBirthUnder18Alert': {
              'ui:description': (
                <va-alert
                  background-only
                  close-btn-aria-label="Close notification"
                  show-icon
                  status="warning"
                  visible
                >
                  <>
                    Since you’re under 18 years old, a parent or guardian will
                    have to sign this application when you submit it.
                  </>
                </va-alert>
              ),
              'ui:options': {
                hideIf: formData => {
                  // If formData is empty, hide the alert
                  if (!formData) {
                    return true;
                  }

                  // Use applicantIsaMinor to determine if the alert should be hidden
                  return !applicantIsaMinor(formData);
                },
              },
            },
            [formFields.parentGuardianSponsor]: {
              'ui:title': 'Parent / Guardian signature',
              'ui:options': {
                hideIf: formData => {
                  // If formData is empty, hide the field
                  if (!formData) {
                    return true;
                  }

                  return !applicantIsaMinor(formData);
                },
              },
              'ui:required': formData => {
                // If formData is empty, the field is not required
                if (!formData) {
                  return false;
                }

                return applicantIsaMinor(formData);
              },
              'ui:validations': [
                (errors, field) => {
                  addWhitespaceOnlyError(
                    field,
                    errors,
                    'Please enter a parent/guardian signature',
                  );
                  if (field && field.length > 46) {
                    errors.addError('Signature must be 46 characters or less');
                  }
                },
              ],
              'ui:errorMessages': {
                required: 'Please enter a parent/guardian signature',
              },
            },
            [formFields.highSchoolDiploma]: {
              'ui:options': {
                hideIf: formData => {
                  if (!formData || !formData.toeHighSchoolInfoChange) {
                    return true;
                  }

                  return !applicantIsaMinor(formData);
                },
              },
              'ui:required': formData => {
                return (
                  formData.toeHighSchoolInfoChange &&
                  applicantIsaMinor(formData)
                );
              },
              'ui:title':
                'Did you earn a high school diploma or equivalency certificate?',
              'ui:widget': 'radio',
            },
            [formFields.highSchoolDiplomaDate]: {
              'ui:options': {
                hideIf: formData => {
                  if (!formData || !formData.toeHighSchoolInfoChange) {
                    return true;
                  }

                  return !(
                    applicantIsaMinor(formData) &&
                    formData[formFields.highSchoolDiploma] === 'Yes'
                  );
                },
              },
              'ui:required': formData => {
                return (
                  formData.toeHighSchoolInfoChange &&
                  applicantIsaMinor(formData) &&
                  formData[formFields.highSchoolDiploma] === 'Yes'
                );
              },
              ...currentOrPastDateUI(
                'When did you earn your high school diploma or equivalency certificate?',
              ),
            },
          },
          schema: {
            type: 'object',
            required: [
              formFields.highSchoolDiploma,
              formFields.highSchoolDiplomaDate,
            ],
            properties: {
              'view:dateOfBirthUnder18Alert': {
                type: 'object',
                properties: {},
              },
              'view:applicantInformation': {
                type: 'object',
                properties: {},
              },
              [formFields.parentGuardianSponsor]: {
                type: 'string',
              },
              [formFields.highSchoolDiploma]: {
                type: 'string',
                enum: ['Yes', 'No'],
              },
              [formFields.highSchoolDiplomaDate]: date,
            },
          },
        },
      },
    },
    sponsorInformationChapter: {
      title: 'Sponsor information',
      pages: {
        sponsorSelection: {
          title: 'Choose your sponsors',
          path: 'sponsor-selection',
          CustomPageReview: SelectedSponsorsReviewPage,
          depends: formData => formData.sponsors?.sponsors?.length,
          uiSchema: {
            'view:listOfSponsors': {
              'ui:description': (
                <>
                  <SponsorsSelectionHeadings />
                  <Sponsors />
                </>
              ),
            },
            [formFields.selectedSponsors]: {
              'ui:field': SponsorCheckboxGroup,
              'ui:required': formData => !!formData.sponsors?.sponsors?.length,
              'ui:options': {
                hideIf: formData =>
                  formData.fetchedSponsorsComplete &&
                  !formData.sponsors?.sponsors?.length,
                keepInPageOnReview: true,
              },
              items: {
                'ui:title': 'sponsor items',
              },
            },
            'view:additionalInfo': {
              'ui:description': (
                <va-additional-info
                  trigger="Which sponsor should I choose?"
                  class="vads-u-margin-bottom--4"
                >
                  <p className="vads-u-margin-y--0">
                    You will only receive a decision for the sponsor(s) you
                    select. VA will review your eligibility for each selection.
                    For any sponsors you do not select, you may impact your
                    ability to use those benefits in the future. You can reapply
                    for those sponsors using this application.
                  </p>
                </va-additional-info>
              ),
            },
          },
          schema: {
            type: 'object',
            properties: {
              'view:listOfSponsors': {
                type: 'object',
                properties: {},
              },
              [formFields.selectedSponsors]: {
                type: 'array',
                minItems: 1,
                items: {
                  type: 'string',
                },
              },
              'view:additionalInfo': {
                type: 'object',
                properties: {},
              },
            },
          },
        },
        firstSponsorSelection: {
          title: 'Choose your first sponsor',
          path: 'first-sponsor',
          CustomPageReview: FirstSponsorReviewPage,
          depends: formData => formData.selectedSponsors?.length > 1,
          uiSchema: {
            'view:subHeadings': {
              'ui:description': (
                <>
                  <h3>Choose your first sponsor</h3>
                  <p>
                    You can only use one sponsor’s benefits at a time. Because
                    you selected more than one sponsor, you must choose which
                    benefits to use first.
                  </p>
                </>
              ),
            },
            [formFields.firstSponsor]: {
              'ui:title':
                'Which sponsor’s benefits would you like to use first?',
              'ui:widget': FirstSponsorRadioGroup,
              'ui:errorMessages': {
                required: 'Please select a sponsor',
              },
            },
            'view:firstSponsorAdditionalInfo': {
              'ui:description': (
                <va-additional-info
                  trigger="Which sponsor should I use first?"
                  class="vads-u-margin-bottom--4"
                >
                  <p className="vads-u-margin-top--0">
                    Though unlikely, you may need to consider differences in the
                    amount of benefits each sponsor offers and when they expire.
                    Benefits from other sponsors can be used after your first
                    sponsor’s benefits expire.
                  </p>
                  <p className="vads-u-margin-bottom--0">
                    If you choose “I’m not sure,” or if there are additional
                    things to consider regarding your sponsors, a VA
                    representative will reach out to help you decide.
                  </p>
                </va-additional-info>
              ),
            },
          },
          schema: {
            type: 'object',
            required: [formFields.firstSponsor],
            properties: {
              'view:subHeadings': {
                type: 'object',
                properties: {},
              },
              [formFields.firstSponsor]: {
                type: 'string',
              },
              'view:firstSponsorAdditionalInfo': {
                type: 'object',
                properties: {},
              },
            },
          },
        },
        highSchool: {
          title: 'Verify your high school education',
          path: 'high-school',
          depends: formData =>
            applicantIsaMinor(formData) && !formData.toeHighSchoolInfoChange,
          uiSchema: {
            'view:subHeadings': {
              'ui:description': (
                <>
                  <va-alert
                    close-btn-aria-label="Close notification"
                    status="info"
                    visible
                  >
                    <h3 slot="headline">We need additional information</h3>
                    <div>
                      Since you are under 18 years old, please include
                      information about your high school education.
                    </div>
                  </va-alert>
                  <h3>Verify your high school education</h3>
                </>
              ),
            },
            [formFields.highSchoolDiplomaLegacy]: {
              'ui:title':
                'Did you earn a high school diploma or equivalency certificate?',
              'ui:widget': 'radio',
            },
          },
          schema: {
            type: 'object',
            required: [formFields.highSchoolDiplomaLegacy],
            properties: {
              'view:subHeadings': {
                type: 'object',
                properties: {},
              },
              [formFields.highSchoolDiplomaLegacy]: {
                type: 'string',
                enum: ['Yes', 'No'],
              },
            },
          },
        },
        highSchoolGraduationDate: {
          title: 'Verify your high school graduation date',
          path: 'high-school-completion',
          depends: formData =>
            applicantIsaMinor(formData) &&
            formData[formFields.highSchoolDiplomaLegacy] === 'Yes' &&
            !formData.toeHighSchoolInfoChange,
          uiSchema: {
            'view:subHeadings': {
              'ui:description': (
                <>
                  <va-alert
                    close-btn-aria-label="Close notification"
                    status="info"
                    visible
                  >
                    <h3 slot="headline">We need additional information</h3>
                    <div>
                      Since you are under 18 years old and indicated that you
                      earned a high school diploma, please verify your high
                      school graduation date.
                    </div>
                  </va-alert>
                  <h3>Verify your high school graduation date</h3>
                </>
              ),
            },
            [formFields.highSchoolDiplomaDateLegacy]: {
              ...currentOrPastDateUI(
                'When did you earn your high school diploma or equivalency certificate?',
              ),
            },
          },
          schema: {
            type: 'object',
            required: [formFields.highSchoolDiplomaDateLegacy],
            properties: {
              'view:subHeadings': {
                type: 'object',
                properties: {},
              },
              [formFields.highSchoolDiplomaDateLegacy]: date,
            },
          },
        },
      },
    },
    contactInformationChapter: {
      title: 'Contact information',
      pages: {
        contactInformation: {
          title: 'Phone numbers and email address',
          path: 'phone-email',
          uiSchema: {
            'view:subHeadings': {
              'ui:description': (
                <>
                  <h3>Review your phone numbers and email address</h3>
                  <div className="meb-list-label">
                    <strong>We’ll use this information to:</strong>
                  </div>
                  <ul>
                    <li>
                      Contact you if we have questions about your application
                    </li>
                    <li>Tell you important information about your benefits</li>
                  </ul>
                  <p>
                    We have this contact information on file for you. If you
                    notice any errors, please correct them now. Any updates you
                    make will change the information for your education benefits
                    only.
                  </p>
                  <p>
                    <strong>Note:</strong> If you want to make changes to your
                    contact information for other VA benefits,{' '}
                    <GoToYourProfileLink text="update your information on your profile" />
                    .
                  </p>
                </>
              ),
            },
            [formFields.viewPhoneNumbers]: {
              'ui:description': (
                <>
                  <h4 className="form-review-panel-page-header vads-u-font-size--h5 toe-review-page-only">
                    Phone numbers and email addresss
                  </h4>
                  <p className="toe-review-page-only">
                    If you’d like to update your phone numbers and email
                    address, please edit the form fields below.
                  </p>
                </>
              ),
              [formFields.mobilePhoneNumber]: phoneUISchema('mobile'),
              [formFields.phoneNumber]: phoneUISchema('home'),
            },
            [formFields.email]: {
              'ui:options': {
                hideLabelText: true,
                showFieldLabel: false,
                viewComponent: EmailViewField,
              },
              email: {
                ...emailUI('Email address'),
                'ui:validations': [validateEmail],
                'ui:widget': CustomEmailField,
              },
              confirmEmail: {
                ...emailUI('Confirm email address'),
                'ui:options': {
                  ...emailUI()['ui:options'],
                  hideOnReview: true,
                },
              },
              'ui:validations': [
                (errors, field) => {
                  if (
                    field?.email?.toLowerCase() !==
                    field?.confirmEmail?.toLowerCase()
                  ) {
                    errors.confirmEmail?.addError(
                      'Sorry, your emails must match',
                    );
                  }
                },
              ],
            },
            'view:confirmDuplicateData': {
              'ui:description': DuplicateContactInfoModal,
            },
          },
          schema: {
            type: 'object',
            properties: {
              'view:subHeadings': {
                type: 'object',
                properties: {},
              },
              [formFields.viewPhoneNumbers]: {
                type: 'object',
                properties: {
                  [formFields.mobilePhoneNumber]: phoneSchema(),
                  [formFields.phoneNumber]: phoneSchema(),
                },
              },
              [formFields.email]: {
                type: 'object',
                required: [formFields.email, 'confirmEmail'],
                properties: {
                  email,
                  confirmEmail: email,
                },
              },
              'view:confirmDuplicateData': {
                type: 'object',
                properties: {},
              },
            },
          },
        },
        mailingAddress: {
          title: 'Mailing address',
          path: 'mailing-address',
          uiSchema: {
            'view:subHeadings': {
              'ui:description': (
                <>
                  <h3>Review your mailing address</h3>
                  <p>
                    We’ll send any important information about your application
                    to this address.
                  </p>
                  <p>
                    We have this mailing address on file for you. If you notice
                    any errors, please correct them now. Any updates you make
                    will change the information for your education benefits
                    only.
                  </p>
                  <p>
                    <strong>Note:</strong> If you want to make changes to your
                    contact information for other VA benefits,{' '}
                    <GoToYourProfileLink text="update your information on your profile" />
                    .
                  </p>
                </>
              ),
            },
            [formFields.viewMailingAddress]: {
              'ui:description': (
                <>
                  <h4 className="form-review-panel-page-header vads-u-font-size--h5 toe-review-page-only">
                    Mailing address
                  </h4>
                  <p className="toe-review-page-only">
                    If you’d like to update your mailing address, please edit
                    the form fields below.
                  </p>
                </>
              ),
              livesOnMilitaryBase: {
                'ui:title': (
                  <span id="LiveOnMilitaryBaseTooltip">
                    I live on a United States military base outside of the
                    country
                  </span>
                ),
                'ui:reviewField': YesNoReviewField,
              },
              livesOnMilitaryBaseInfo: {
                'ui:description': LearnMoreAboutMilitaryBaseTooltip(),
              },
              [formFields.address]: {
                ...address.uiSchema('', false, null, true),
                country: {
                  'ui:title': 'Country',
                  'ui:required': formData =>
                    !formData['view:mailingAddress'].livesOnMilitaryBase,
                  'ui:disabled': formData =>
                    formData['view:mailingAddress'].livesOnMilitaryBase,
                  'ui:options': {
                    updateSchema: (formData, schema, uiSchema) => {
                      const countryUI = uiSchema;
                      const addressFormData = get(
                        ['view:mailingAddress', 'address'],
                        formData,
                      );
                      const livesOnMilitaryBase = get(
                        ['view:mailingAddress', 'livesOnMilitaryBase'],
                        formData,
                      );
                      if (livesOnMilitaryBase) {
                        countryUI['ui:disabled'] = true;
                        const USA = {
                          value: 'USA',
                          label: 'United States',
                        };
                        addressFormData.country = USA.value;
                        return {
                          enum: [USA.value],
                          enumNames: [USA.label],
                          default: USA.value,
                        };
                      }
                      countryUI['ui:disabled'] = false;
                      return {
                        type: 'string',
                        enum: constants.countries.map(country => country.value),
                        enumNames: constants.countries.map(
                          country => country.label,
                        ),
                      };
                    },
                  },
                },
                street: {
                  'ui:title': 'Street address',
                  'ui:errorMessages': {
                    required: 'Please enter your full street address',
                  },
                  'ui:validations': [
                    (errors, field) => {
                      if (isOnlyWhitespace(field)) {
                        errors.addError(
                          'Please enter your full street address',
                        );
                      }
                    },
                  ],
                },
                city: {
                  'ui:errorMessages': {
                    required: 'Please enter a valid city',
                  },
                  'ui:validations': [
                    (errors, field) => {
                      if (isOnlyWhitespace(field)) {
                        errors.addError('Please enter a valid city');
                      }
                    },
                  ],
                  'ui:options': {
                    replaceSchema: formData => {
                      if (
                        formData['view:mailingAddress']?.livesOnMilitaryBase
                      ) {
                        return {
                          type: 'string',
                          title: 'APO/FPO',
                          enum: ['APO', 'FPO'],
                        };
                      }

                      return {
                        type: 'string',
                        title: 'City',
                      };
                    },
                  },
                },
                state: {
                  'ui:required': formData =>
                    formData['view:mailingAddress']?.livesOnMilitaryBase ||
                    formData['view:mailingAddress']?.address?.country === 'USA',
                },
                postalCode: {
                  'ui:errorMessages': {
                    required: 'Zip code must be 5 digits',
                  },
                  'ui:options': {
                    replaceSchema: formData => {
                      if (
                        formData['view:mailingAddress']?.address?.country !==
                        'USA'
                      ) {
                        return {
                          title: 'Postal Code',
                          type: 'string',
                        };
                      }

                      return {
                        title: 'Zip code',
                        type: 'string',
                      };
                    },
                  },
                },
              },
              'ui:options': {
                hideLabelText: true,
                showFieldLabel: false,
                viewComponent: MailingAddressViewField,
              },
            },
          },
          schema: {
            type: 'object',
            properties: {
              'view:subHeadings': {
                type: 'object',
                properties: {},
              },
              'view:mailingAddress': {
                type: 'object',
                properties: {
                  livesOnMilitaryBase: {
                    type: 'boolean',
                  },
                  livesOnMilitaryBaseInfo: {
                    type: 'object',
                    properties: {},
                  },
                  [formFields.address]: {
                    ...address.schema(fullSchema1990e, true),
                  },
                },
              },
            },
          },
        },
        preferredContactMethod: {
          title: 'Contact preferences',
          path: 'preferred-contact-method',
          uiSchema: {
            'view:contactMethodIntro': {
              'ui:description': (
                <>
                  <h3 className="toe-form-page-only">
                    Choose your contact method for follow-up questions
                  </h3>
                </>
              ),
            },
            [formFields.contactMethod]: {
              'ui:title':
                'How should we contact you if we have questions about your application?',
              'ui:widget': 'radio',
              'ui:errorMessages': {
                required: 'Please select at least one way we can contact you.',
              },
              'ui:options': {
                updateSchema: (() => {
                  const filterContactMethods = createSelector(
                    form =>
                      form[formFields.viewPhoneNumbers][
                        formFields.mobilePhoneNumber
                      ]?.phone,
                    form =>
                      form[formFields.viewPhoneNumbers][formFields.phoneNumber]
                        ?.phone,
                    (mobilePhoneNumber, homePhoneNumber) => {
                      const invalidContactMethods = [];
                      if (!mobilePhoneNumber) {
                        invalidContactMethods.push('Mobile Phone');
                      }
                      if (!homePhoneNumber) {
                        invalidContactMethods.push('Home Phone');
                      }

                      return {
                        enum: contactMethods.filter(
                          method => !invalidContactMethods.includes(method),
                        ),
                      };
                    },
                  );

                  return form => filterContactMethods(form);
                })(),
              },
            },
            [formFields.viewReceiveTextMessages]: {
              'ui:description': (
                <>
                  <div className="toe-form-page-only">
                    <h3>Choose how you want to get notifications</h3>
                    <p>
                      We recommend that you opt into text message notifications
                      about your benefits. These include notifications that
                      prompt you to verify your enrollment so you’ll receive
                      your education payments. This is an easy way to verify
                      your monthly enrollment.
                    </p>
                    <div className="meb-list-label">
                      <strong>What to know about text notifications:</strong>
                    </div>
                    <ul>
                      <li>We’ll send you 2 messages per month.</li>
                      <li>Message and data rates may apply.</li>
                      <li>If you want to opt out, text STOP.</li>
                      <li>If you need help, text HELP.</li>
                    </ul>
                    <p>
                      <a
                        href="https://www.va.gov/privacy-policy/digital-notifications-terms-and-conditions/"
                        rel="noopener noreferrer"
                        target="_blank"
                      >
                        Read our text notifications terms and conditions
                      </a>
                    </p>
                    <p>
                      <a
                        href="https://www.va.gov/privacy-policy/"
                        rel="noopener noreferrer"
                        target="_blank"
                      >
                        Read our privacy policy
                      </a>
                    </p>
                    <p>
                      <strong>Note</strong>: At this time, we can only send text
                      messages to U.S. mobile phone numbers.
                    </p>
                  </div>
                </>
              ),
              'view:noMobilePhoneAlert': {
                'ui:description': (
                  <va-alert
                    background-only
                    close-btn-aria-label="Close notification"
                    show-icon
                    status="warning"
                    visible
                  >
                    <div>
                      <p className="vads-u-margin-y--0">
                        We can’t send you text message notifications because we
                        don’t have a mobile phone number on file for you
                      </p>

                      <Link
                        aria-label="Go back and add a mobile phone number"
                        to={{
                          pathname: 'phone-email',
                          search: '?redirect',
                        }}
                      >
                        <va-button
                          uswds
                          onClick={() => {}}
                          secondary
                          text="Go back and add a mobile phone number"
                        />
                      </Link>
                    </div>
                  </va-alert>
                ),
                'ui:options': {
                  hideIf: formData => {
                    return !!formData['view:phoneNumbers']?.mobilePhoneNumber
                      ?.phone;
                  },
                },
              },
              [formFields.receiveTextMessages]: {
                'ui:title':
                  'Would you like to receive text message notifications about your education benefits?',
                'ui:widget': 'radio',
                'ui:validations': [
                  (errors, field, formData) => {
                    const isYes = field.slice(0, 4).includes('Yes');
                    const phoneExist = !!formData[formFields.viewPhoneNumbers]
                      .mobilePhoneNumber.phone;
                    const { isInternational } = formData[
                      formFields.viewPhoneNumbers
                    ].mobilePhoneNumber;

                    if (isYes) {
                      if (!phoneExist) {
                        errors.addError(
                          "You can't select that response because we don't have a mobile phone number on file for you.",
                        );
                      } else if (isInternational) {
                        errors.addError(
                          "You can't select that response because you have an international mobile phone number",
                        );
                      }
                    }
                  },
                ],
              },
            },
            'view:internationalTextMessageAlert': {
              'ui:description': (
                <va-alert status="warning">
                  <>
                    You can’t choose to get text notifications because you have
                    an international mobile phone number. At this time, we can
                    send text messages about your education benefits only to
                    U.S. mobile phone numbers.
                  </>
                </va-alert>
              ),
              'ui:options': {
                hideIf: formData =>
                  (formData[formFields.viewReceiveTextMessages][
                    formFields.receiveTextMessages
                  ] &&
                    !formData[formFields.viewReceiveTextMessages][
                      formFields.receiveTextMessages
                    ]
                      .slice(0, 4)
                      .includes('Yes')) ||
                  !isValidPhoneField(
                    formData[formFields.viewPhoneNumbers][
                      formFields.mobilePhoneNumber
                    ],
                  ) ||
                  !formData[formFields.viewPhoneNumbers][
                    formFields.mobilePhoneNumber
                  ]?.isInternational,
              },
            },
            'view:emailOnFileWithSomeoneElse': {
              'ui:description': (
                <va-alert status="warning">
                  <>
                    You can’t choose to get email notifications because your
                    email is on file for another person with education benefits.
                    You will not be able to take full advantage of VA’s
                    electronic notifications and enrollment verifications
                    available. If you cannot, certain electronic services will
                    be limited or unavailable.
                    <br />
                    <br />
                    <a
                      target="_blank"
                      href="https://www.va.gov/education/verify-school-enrollment"
                      rel="noreferrer"
                    >
                      Learn more about the Enrollment Verifications
                    </a>
                  </>
                </va-alert>
              ),
              'ui:options': {
                hideIf: formData => {
                  const isNo = formData[
                    'view:receiveTextMessages'
                  ]?.receiveTextMessages
                    ?.slice(0, 3)
                    ?.includes('No,');
                  const noDuplicates = formData?.duplicateEmail?.some(
                    entry => entry?.dupe === false,
                  );

                  // Return true if isNo is false OR noDuplicates is not false
                  return (
                    !formData?.toeDupContactInfoCall || (!isNo || noDuplicates)
                  );
                },
              },
            },
            'view:mobilePhoneOnFileWithSomeoneElse': {
              'ui:description': (
                <va-alert status="warning">
                  <>
                    You can’t choose to get text notifications because your
                    mobile phone number is on file for another person with
                    education benefits. You will not be able to take full
                    advantage of VA’s electronic notifications and enrollment
                    verifications available. If you cannot, certain electronic
                    services will be limited or unavailable.
                    <br />
                    <br />
                    <a
                      target="_blank"
                      href="https://www.va.gov/education/verify-school-enrollment"
                      rel="noreferrer"
                    >
                      Learn more about the Enrollment Verifications
                    </a>
                  </>
                </va-alert>
              ),
              'ui:options': {
                hideIf: formData => {
                  const isYes = formData[
                    'view:receiveTextMessages'
                  ]?.receiveTextMessages
                    ?.slice(0, 4)
                    ?.includes('Yes');
                  const noDuplicates = formData?.duplicatePhone?.some(
                    entry => entry?.dupe === false,
                  );
                  const mobilePhone =
                    formData[(formFields?.viewPhoneNumbers)]?.[
                      formFields?.mobilePhoneNumber
                    ]?.phone;

                  // Return true if isYes is false, noDuplicates is true, or mobilePhone is undefined
                  return (
                    !formData?.toeDupContactInfoCall ||
                    (!isYes || noDuplicates || !mobilePhone)
                  );
                },
              },
            },
          },
          schema: {
            type: 'object',
            properties: {
              'view:contactMethodIntro': {
                type: 'object',
                properties: {},
              },
              [formFields.contactMethod]: {
                type: 'string',
                enum: contactMethods,
              },
              [formFields.viewReceiveTextMessages]: {
                type: 'object',
                required: [formFields.receiveTextMessages],
                properties: {
                  'view:noMobilePhoneAlert': {
                    type: 'object',
                    properties: {},
                  },
                  [formFields.receiveTextMessages]: {
                    type: 'string',
                    enum: [
                      'Yes, send me text message notifications',
                      'No, just send me email notifications',
                    ],
                  },
                },
              },
              'view:internationalTextMessageAlert': {
                type: 'object',
                properties: {},
              },
              'view:emailOnFileWithSomeoneElse': {
                type: 'object',
                properties: {},
              },
              'view:mobilePhoneOnFileWithSomeoneElse': {
                type: 'object',
                properties: {},
              },
              'view:duplicateEmailAndPhoneAndNoHomePhone': {
                type: 'object',
                properties: {},
              },
            },
            required: [formFields.contactMethod],
          },
        },
      },
    },
    bankAccountInfoChapter: {
      title: 'Direct deposit',
      pages: {
        directDeposit: {
          path: 'direct-deposit',
          title: 'Direct deposit',
          uiSchema: {
            title: 'direct deposit',
            'ui:title': (
              <h4 className="vads-u-font-size--h5 vads-u-margin-top--0">
                Direct deposit information
              </h4>
            ),
            'ui:field': ReviewCardField,
            'ui:options': {
              editTitle: 'Direct deposit information',
              hideLabelText: true,
              itemName: 'account information',
              itemNameAction: 'Update',
              reviewTitle: 'Direct deposit information',
              showFieldLabel: false,
              viewComponent: DirectDepositViewField,
              volatileData: true,
            },
            'ui:description': (
              <p>
                We make payments only through direct deposit, also called
                electronic funds transfer (EFT).
              </p>
            ),
            [formFields.bankAccount]: {
              ...bankAccountUI,
              'ui:order': ['accountType', 'routingNumber', 'accountNumber'],
              routingNumber: {
                ...bankAccountUI.routingNumber,
                'ui:errorMessages': {
                  pattern: 'Please enter a valid 9-digit routing number',
                },
                'ui:reviewField': ObfuscateReviewField,
                'ui:validations': [validateRoutingNumber],
              },
              accountNumber: {
                ...bankAccountUI.accountNumber,
                'ui:errorMessages': {
                  pattern:
                    'Please enter a valid 5-17 digit bank account number',
                },
                'ui:reviewField': ObfuscateReviewField,
                'ui:title': 'Bank account number',
                'ui:validations': [validateAccountNumber],
              },
            },
            'view:learnMore': {
              'ui:description': (
                <va-additional-info
                  key="learn-more-btn"
                  trigger="Where can I find these numbers?"
                >
                  <img
                    key="check-image-src"
                    style={{ marginTop: '0.625rem' }}
                    src={checkImageSrc}
                    alt="Example of a check showing where the account and routing numbers are"
                  />
                  <br />
                  <br />

                  <p key="learn-more-description">
                    The bank routing number is the first 9 digits on the bottom
                    left corner of a printed check. Your account number is the
                    second set of numbers on the bottom of a printed check, just
                    to the right of the bank routing number.
                  </p>
                  <br />
                  <p key="learn-more-additional">
                    If you don’t have a printed check, you can sign in to your
                    online banking institution for this information
                  </p>
                </va-additional-info>
              ),
            },
          },
          schema: {
            type: 'object',
            properties: {
              bankAccount: {
                type: 'object',
                required: [
                  formFields.accountType,
                  formFields.accountNumber,
                  formFields.routingNumber,
                ],
                properties: {
                  accountNumber: {
                    type: 'string',
                    pattern: '^[*a-zA-Z0-9]{5,17}$',
                  },
                  accountType: {
                    type: 'string',
                    enum: ['checking', 'savings'],
                  },
                  routingNumber: {
                    type: 'string',
                    pattern: '^[\\d*]{5}\\d{4}$',
                  },
                },
              },
              'view:learnMore': {
                type: 'object',
                properties: {},
              },
            },
          },
        },
      },
    },
  },
};

export default formConfig;