+
diff --git a/src/index.css b/src/index.css
index 813fe488e..fd77363a2 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,7 +1,17 @@
-@tailwind base;
+/* @tailwind base; */
@tailwind components;
@tailwind utilities;
+/* Modified from cf.gov for tailwind use, see:
+https://github.com/search?q=org%3Acfpb+max-width%3A+41.875rem%3B&type=code&p=1
+https://v1.tailwindcss.com/docs/adding-base-styles#using-css */
+
+@layer components {
+ .row dd, .row dt, .row h3, .row h4, .row h5, .row h6, .row li, .row p, .row label {
+ max-width: 41.875rem;
+ }
+}
+
.auth-action .a-btn {
font-weight: 600;
color: #43484e;
@@ -23,6 +33,11 @@
}
/* Checkbox Border error styling - workaround */
-.m-form-field__checkbox.error-checkbox .a-label:before, .m-form-field__radio .a-label:before {
+.m-form-field__checkbox.error-checkbox .a-label::before, .m-form-field__radio .a-label::before {
@apply !border-errorColor !border-2
+}
+
+/* Workaround for styling the institution details on Profile-Form */
+.m-form-field__checkbox .invisible::before {
+ visibility: hidden;
}
\ No newline at end of file
diff --git a/src/pages/Filing/FilingHome.tsx b/src/pages/Filing/FilingHome.tsx
index 035eecebd..60ddbd2f9 100644
--- a/src/pages/Filing/FilingHome.tsx
+++ b/src/pages/Filing/FilingHome.tsx
@@ -15,6 +15,7 @@ import type { ReactElement } from 'react';
import { Link as RouterLink } from "react-router-dom";
import './FilingHome.less';
import ProcessStep from './ProcessStep';
+import { sblHelpLink, gleifLink } from 'utils/common';
function Home(): ReactElement {
const auth = useSblAuth();
@@ -55,7 +56,7 @@ function Home(): ReactElement {
>
In order to begin using the filing platform you must have a Legal
Entity Identifier (LEI) for your financial institution. Visit the{' '}
-
Global LEI Foundation (GLEIF) website for
+
Global LEI Foundation (GLEIF) website for
more information on how to obtain an LEI.
@@ -105,7 +106,7 @@ function Home(): ReactElement {
>
Find answers to frequently asked questions
,
-
+
Submit a question
,
]}
diff --git a/src/pages/Filing/ViewUserProfile/index.tsx b/src/pages/Filing/ViewUserProfile/index.tsx
index 7ecac4278..d6ba2c21d 100644
--- a/src/pages/Filing/ViewUserProfile/index.tsx
+++ b/src/pages/Filing/ViewUserProfile/index.tsx
@@ -7,6 +7,7 @@ import useSblAuth from '../../../api/useSblAuth';
import CrumbTrail from '../../../components/CrumbTrail';
import AssociatedInstitutions from './AssociatedInstitutions';
import UserInformation from './UserInformation';
+import { sblHelpLink } from 'utils/common';
export default function ViewUserProfile(): JSX.Element {
const auth = useSblAuth();
diff --git a/src/pages/ProfileForm/ProfileFormUtils.ts b/src/pages/ProfileForm/ProfileFormUtils.ts
index 6316f1a1c..d81edd48f 100644
--- a/src/pages/ProfileForm/ProfileFormUtils.ts
+++ b/src/pages/ProfileForm/ProfileFormUtils.ts
@@ -1,4 +1,9 @@
-import type { ValidationSchema, FormattedUserProfileObjectType } from './types';
+import type {
+ InstitutionDetailsApiType,
+ InstitutionDetailsApiCheckedType,
+ ValidationSchema,
+ FormattedUserProfileObjectType
+} from 'pages/ProfileForm/types';
export const formatUserProfileObject = (
userProfileObject: ValidationSchema,
@@ -7,3 +12,13 @@ export const formatUserProfileObject = (
last_name: userProfileObject.lastName,
leis: userProfileObject.financialInstitutions.map(object => object.lei),
});
+
+export const formatDataCheckedState = (
+ fiDataInput: InstitutionDetailsApiType[] = [],
+): InstitutionDetailsApiCheckedType[] =>
+ fiDataInput.map(object => ({ ...object, checked: false }));
+
+export default {
+ formatUserProfileObject,
+ formatDataCheckedState
+}
diff --git a/src/pages/ProfileForm/Step1Form/AssociatedFinancialInstitutions.tsx b/src/pages/ProfileForm/Step1Form/AssociatedFinancialInstitutions.tsx
index 584418d10..00cdb6300 100644
--- a/src/pages/ProfileForm/Step1Form/AssociatedFinancialInstitutions.tsx
+++ b/src/pages/ProfileForm/Step1Form/AssociatedFinancialInstitutions.tsx
@@ -1,14 +1,15 @@
-import { Checkbox, Link } from 'design-system-react';
+import { Checkbox, Link, Paragraph } from 'design-system-react';
import FormParagraph from 'components/FormParagraph';
+import InputErrorMessage from 'components/InputErrorMessage';
+import { sblHelpLink } from 'utils/common';
-import type { FiDataChecked } from 'pages/ProfileForm/types';
+import type { InstitutionDetailsApiCheckedType } from 'pages/ProfileForm/types';
import useProfileForm from 'store/useProfileForm';
interface AssociatedFinancialInstitutionProperties {
key: string;
- isFirst: boolean;
- fiObject: FiDataChecked;
+ fiObject: InstitutionDetailsApiCheckedType;
onCheckHandler: () => void;
hasError: boolean;
}
@@ -16,29 +17,18 @@ interface AssociatedFinancialInstitutionProperties {
function AssociatedFinancialInstitution({
onCheckHandler,
fiObject,
- isFirst,
hasError,
...rest
}: AssociatedFinancialInstitutionProperties &
JSX.IntrinsicElements['input']): JSX.Element {
return (
-
+
- {fiObject.name}
- LEI: {fiObject.lei}
- Tax ID: {fiObject.tax_id}
- {fiObject.rssd_id ? (
-
- RSS ID: {fiObject.rssd_id}
-
- ) : null}
+
}
checked={fiObject.checked}
@@ -46,15 +36,32 @@ function AssociatedFinancialInstitution({
onChange={onCheckHandler}
{...rest}
/>
+
+ LEI: {fiObject.lei}
+ TIN: {fiObject.tax_id}
+ {fiObject.rssd_id ? (
+
+ RSSD ID: {fiObject.rssd_id}
+
+ ) : null}
+
+ }
+ />
);
}
interface AssociatedFinancialInstitutionsProperties {
errors: object;
- checkedListState: FiDataChecked[];
+ checkedListState: InstitutionDetailsApiCheckedType[];
setCheckedListState: (
- callbackFunction: (previous: FiDataChecked[]) => FiDataChecked[],
+ callbackFunction: (
+ previous: InstitutionDetailsApiCheckedType[],
+ ) => InstitutionDetailsApiCheckedType[],
) => void;
}
@@ -67,40 +74,49 @@ function AssociatedFinancialInstitutions({
return (
<>
-
- The following financial institution is associated with your email
- domain. Check the box if you are authorized to file for this
- institution.
-
-
+
+
+ The following financial institutions are associated with your email
+ domain. Select the financial institutions you are authorized to file
+ for.
+
+
- {checkedListState.map((fiObject: FiDataChecked, index: number) => {
+ {checkedListState.map((fiObject: InstitutionDetailsApiCheckedType) => {
const onCheckHandler = (): void => {
- setCheckedListState((previous: FiDataChecked[]): FiDataChecked[] =>
- previous.map(object => {
- if (object.lei !== fiObject.lei) return object;
- return { ...fiObject, checked: !fiObject.checked };
- }),
+ setCheckedListState(
+ (
+ previous: InstitutionDetailsApiCheckedType[],
+ ): InstitutionDetailsApiCheckedType[] =>
+ previous.map((object: InstitutionDetailsApiCheckedType) => {
+ if (object.lei !== fiObject.lei) return object;
+ return { ...fiObject, checked: !fiObject.checked };
+ }),
);
};
return (
);
})}
+ {errors.financialInstitutions ? (
+
+ {errors.financialInstitutions.message}
+
+ ) : null}
{enableMultiselect ? null : (
-
- If you are authorized to file for an institution that is not listed,
- please complete this form and then contact our support staff{' '}
- contact our support staff to complete your user
- profile.
-
+
+
+ If you are authorized to file for an institution that is not listed
+ above, please{' '}
+ contact our support staff.
+
+
)}
>
);
diff --git a/src/pages/ProfileForm/Step1Form/InputEntry.tsx b/src/pages/ProfileForm/Step1Form/InputEntry.tsx
index 86967344c..07ab4371f 100644
--- a/src/pages/ProfileForm/Step1Form/InputEntry.tsx
+++ b/src/pages/ProfileForm/Step1Form/InputEntry.tsx
@@ -2,6 +2,7 @@ import type { ReactNode } from 'react';
import { forwardRef } from 'react';
import { Element } from 'react-scroll';
+import { TextInput, Heading } from 'design-system-react';
import InputErrorMessage from 'components/InputErrorMessage';
interface InputEntryProperties
@@ -10,35 +11,50 @@ interface InputEntryProperties
label: string;
errors: object;
isDisabled: boolean;
+ isLast: boolean;
+ hideInput: boolean;
children?: ReactNode;
}
const InputEntry = forwardRef
(
(
- { id, errors, label, isDisabled = false, children, ...properties },
+ {
+ id,
+ errors,
+ label,
+ isDisabled = false,
+ hideInput = false,
+ isLast = false,
+ children,
+ ...properties
+ },
reference,
) => (
-
+
-
- {label}
+
+
+ {label}
+
{children}
- {/* TODO: Replace this item with DSR equivalent : https://github.com/cfpb/sbl-frontend/issues/97 */}
-
- {/* TODO: Replace this item with DSR equivalent : https://github.com/cfpb/sbl-frontend/issues/97 */}
+ {/* TODO: Will put in a prop to style the email input as a regular text */}
+ {/* https://github.com/cfpb/sbl-frontend/issues/156 */}
+
+
+
{errors[id] ? (
{errors[id].message}
diff --git a/src/pages/ProfileForm/Step1Form/NoDatabaseResultError.tsx b/src/pages/ProfileForm/Step1Form/NoDatabaseResultError.tsx
index e1fd67846..a7f0b5b5b 100644
--- a/src/pages/ProfileForm/Step1Form/NoDatabaseResultError.tsx
+++ b/src/pages/ProfileForm/Step1Form/NoDatabaseResultError.tsx
@@ -1,19 +1,21 @@
-import ErrorIcon from 'components/ErrorIcon';
-import { Link } from 'design-system-react';
+import { Link, AlertFieldLevel } from 'design-system-react';
+import { sblHelpLink } from 'utils/common';
function NoDatabaseResultError(): JSX.Element {
return (
-
-
-
-
- The financial institution/LEI you searched for was not found in our
- database. If you recently registered for an LEI with GLEIF, your
- registration may still be in process. If you need further assistance
- please submit a technical question to our help
- desk.
-
-
+
+
+ The financial institution/LEI you searched for was not found in our
+ database. If you recently registered for an LEI with GLEIF, your
+ registration may still be in process. If you need further assistance
+ please submit a technical question{' '}
+ to our help desk.
+ >
+ }
+ status='error'
+ />
);
}
diff --git a/src/pages/ProfileForm/Step1Form/Step1Form.tsx b/src/pages/ProfileForm/Step1Form/Step1Form.tsx
index 921b051e6..75e39357e 100644
--- a/src/pages/ProfileForm/Step1Form/Step1Form.tsx
+++ b/src/pages/ProfileForm/Step1Form/Step1Form.tsx
@@ -5,16 +5,15 @@ import useSblAuth from 'api/useSblAuth';
import { useEffect, useState } from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form';
-import { Element } from 'react-scroll';
+import { Element, scroller } from 'react-scroll';
import { useNavigate } from 'react-router-dom';
import AssociatedFinancialInstitutions from './AssociatedFinancialInstitutions';
import NoDatabaseResultError from './NoDatabaseResultError';
import FormParagraph from 'components/FormParagraph';
import FieldGroup from 'components/FieldGroup';
-import InputErrorMessage from 'components/InputErrorMessage';
-import { Button, Link } from 'design-system-react';
+import { Button, Link, Paragraph, Heading } from 'design-system-react';
import { fiOptions, fiData } from 'pages/ProfileForm/ProfileForm.data';
import type {
@@ -31,13 +30,16 @@ import InputEntry from './InputEntry';
import Step1FormErrorHeader from './Step1FormErrorHeader';
import Step1FormHeader from './Step1FormHeader';
-import { useQuery, useQueryClient } from '@tanstack/react-query';
+import { useQuery } from '@tanstack/react-query';
import useProfileForm from 'store/useProfileForm';
import Step1FormDropdownContainer from './Step1FormDropdownContainer';
import fetchInstitutions from 'api/fetchInstitutions';
import submitUserProfile from 'api/submitUserProfile';
-import { formatUserProfileObject } from 'pages/ProfileForm/ProfileFormUtils';
+import {
+ formatUserProfileObject,
+ formatDataCheckedState,
+} from 'pages/ProfileForm/ProfileFormUtils';
function Step1Form(): JSX.Element {
/* Initial- Fetch all institutions */
@@ -45,13 +47,16 @@ function Step1Form(): JSX.Element {
const email = auth.user?.profile.email;
// eslint-disable-next-line unicorn/prefer-string-slice
- const emailDomain = email?.substring(email.lastIndexOf('@')+1);
- const { isLoading, isError, data: afData} = useQuery({
- queryKey: [`fetch-institutions-${emailDomain}`, emailDomain],
+ const emailDomain = email?.substring(email.lastIndexOf('@') + 1);
+ const {
+ isLoading,
+ isError,
+ data: afData,
+ } = useQuery({
+ queryKey: [`fetch-institutions-${emailDomain}`, emailDomain],
queryFn: async () => fetchInstitutions(auth, emailDomain),
enabled: !!emailDomain,
});
-
const defaultValues: ValidationSchema = {
firstName: '',
@@ -79,10 +84,6 @@ function Step1Form(): JSX.Element {
/* Selected State - Start */
// Associated Financial Institutions state
- const formatDataCheckedState = (
- fiDataInput: InstitutionDetailsApiType[] = [],
- ): InstitutionDetailsApiCheckedType[] =>
- fiDataInput.map(object => ({ ...object, checked: false }));
const [checkedListState, setCheckedListState] = useState<
InstitutionDetailsApiCheckedType[]
>([]);
@@ -98,20 +99,19 @@ function Step1Form(): JSX.Element {
// Formatting: Checkmarking either the Associated Financial Institutions or the Dropdown Financial Institutions, adds to the react-hook-form object
/* Format - Start */
-
const getFinancialInstitutionsFormData = (
- checkedListState: InstitutionDetailsApiCheckedType[],
+ checkedListStateArray: InstitutionDetailsApiCheckedType[],
): InstitutionDetailsApiType[] => {
const newFinancialInstitutions: InstitutionDetailsApiType[] = [];
- checkedListState.forEach((object: InstitutionDetailsApiCheckedType) => {
+ for (const object of checkedListStateArray) {
if (object.checked) {
const foundObject: InstitutionDetailsApiType = afData?.find(
institutionsObject => object.lei === institutionsObject.lei,
);
newFinancialInstitutions.push(foundObject);
}
- });
+ }
// TODO: Added multiselected to list of selected institutions
@@ -131,11 +131,30 @@ function Step1Form(): JSX.Element {
}, [checkedListState, selectedFI]);
/* Format - End */
- // Post Submission
- const setStep = useProfileForm(state => state.setStep);
- const setProfileData = useProfileForm(state => state.setProfileData);
+ const navigate = useNavigate();
+
const enableMultiselect = useProfileForm(state => state.enableMultiselect);
const isSalesforce = useProfileForm(state => state.isSalesforce);
+
+ // 'Clear Form' function
+ function clearForm(): void {
+ setValue('firstName', '');
+ setValue('lastName', '');
+ setSelectedFI([]);
+ setCheckedListState([]);
+ window.scrollTo({ top: 0, behavior: 'smooth' });
+ }
+
+ // Used for smooth scrolling to the Step1FormErrorHeader upon error
+ const scrollToErrorForm = (): void => {
+ scroller.scrollTo('step1FormErrorHeader', {
+ duration: 375,
+ smooth: true,
+ offset: -25, // Scrolls to element 25 pixels above the element
+ });
+ };
+
+ // Post Submission
const onSubmitButtonAction = async (): Promise
=> {
// TODO: Handle error UX on submission failure or timeout
const userProfileObject = getValues();
@@ -152,70 +171,80 @@ function Step1Form(): JSX.Element {
// https://github.com/cfpb/sbl-frontend/issues/135
await auth.signinSilent();
window.location.href = '/landing';
+ // navigate('/landing')
+ } else {
+ // on errors scroll to Step1FormErrorHeader
+ scrollToErrorForm();
}
};
- const navigate = useNavigate();
-
- // 'Clear Form' function
- function clearForm(): void {
- setValue('firstName', '');
- setValue('lastName', '');
- setSelectedFI([]);
- setCheckedListState(initialDataCheckedState);
- window.scrollTo({ top: 0, behavior: 'smooth' });
- }
-
+ // Based on useQuery states
if (!auth.user?.access_token) return <>Login first!>;
if (isLoading) return <>Loading Institutions!>;
if (isError) return <>Error on loading institutions!>;
return (