Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[User Profile] - Layout View - Submitted User Profile - Success/Failure #68

Merged
merged 41 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7bcf35f
chore: Set User Profile react-select element to not render control items
shindigira Sep 13, 2023
d861d3a
feat: Login - enabled automatic silent renew
shindigira Sep 14, 2023
9943ffa
chore: InputEntry - TypeScript adjustment
shindigira Sep 14, 2023
66f1d69
Merge branch 'main' of github.com:cfpb/sbl-frontend into 41-react-sel…
shindigira Sep 14, 2023
9b8365a
User Profile - Dropdown Indicator, refactor Step1Form
shindigira Sep 14, 2023
d0c3e67
chore: removed comment
shindigira Sep 15, 2023
e610fe8
Merge branch 'main' of github.com:cfpb/sbl-frontend into 41-react-sel…
shindigira Sep 18, 2023
e17a7e4
chore: renamed financial institutions names
shindigira Sep 18, 2023
c8a9655
feat: Implemented Dropdown from design-system-react
shindigira Sep 21, 2023
472a9d7
style: removed the dotted outline on the placeholder of the react-sel…
shindigira Sep 22, 2023
1ca028e
chore: added external state to Associated Institutions
shindigira Sep 22, 2023
eb9e004
chore: removed types.ts in root -- caused warnings
shindigira Sep 22, 2023
accd065
chore: updated yarn cache
shindigira Sep 22, 2023
4ecca3f
chore: updated yarn cache again
shindigira Sep 22, 2023
a0bad2b
Merge branch '41-react-select-dropdowns' of github.com:cfpb/sbl-front…
shindigira Sep 22, 2023
5f338d6
chore: updated yarn packages
shindigira Sep 23, 2023
0290178
chore: updated Step1Form type properties
shindigira Sep 25, 2023
6c0ad0c
chore: updated yarn cache
shindigira Sep 25, 2023
2ac0040
chore: differentiated between associated and all-fetched financial in…
shindigira Sep 25, 2023
03dc885
chore: updated yarn cache
shindigira Sep 25, 2023
223c174
style: aligned the Associated text more center relative to the checkb…
shindigira Sep 26, 2023
21ad746
chore: updated mock data for associated and dropdown financial instit…
shindigira Sep 26, 2023
0de7fb9
feat: added a user profile data setting to useProfileData
shindigira Sep 26, 2023
8d6452f
feat: the Associated Financial Institution state is now at the top level
shindigira Sep 26, 2023
e6ea01d
chore: Utilized the FiDataType to be used when react-hook-form checking
shindigira Sep 26, 2023
badd720
chore: moved the fiOptions to the mock data file
shindigira Sep 26, 2023
2b39bae
chore: checkmarking financial institutions now adds to the react-hook…
shindigira Sep 26, 2023
533159f
feat: places user profile data object on store for step2form
shindigira Sep 26, 2023
9ffdac2
chore: extra profile data on step2
shindigira Sep 26, 2023
568bdbb
chore: lei number in title -- react-select options
shindigira Sep 26, 2023
0605881
feat: on render of Step2, scroll to top
shindigira Sep 26, 2023
3a8e713
feat: Step2 draft complete
shindigira Sep 26, 2023
14f7e14
chore: useEffect scroll to top -- put on Step2 main area
shindigira Sep 26, 2023
5488afc
chore: added dotted underline for step2 links
shindigira Sep 26, 2023
57ab2be
feat: added Clear Form
shindigira Sep 27, 2023
4d5ee6a
fix: utilize the proper DSR branch
shindigira Sep 27, 2023
bed845d
resolved merge conflicts
shindigira Sep 27, 2023
cc25433
feat: implemented adjusted styles and success/failure states
shindigira Oct 9, 2023
e17e33a
chore: updated yarn cache
shindigira Oct 9, 2023
e4bf56b
chore: Associated Financial Information section does not appear if no…
shindigira Oct 9, 2023
cde31a4
chore: Step2Form error dependent on scenario
shindigira Oct 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,230 changes: 615 additions & 615 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@tanstack/react-query": "4.29.7",
"@tanstack/react-table": "^8.9.1",
"@trussworks/react-uswds": "^4.2.1",
"design-system-react": "cfpb/design-system-react#173-Dropdown-Update",
"design-system-react": "cfpb/design-system-react",
"immer": "^10.0.2",
"keycloak-js": "^21.1.1",
"less": "^4.1.3",
Expand Down
22 changes: 22 additions & 0 deletions src/components/FormParagraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
interface FormParagraphProperties {
children: string;
className?: string;
}

/**
*
* @returns FormParagraph
*/
function FormParagraph({ children, className }: FormParagraphProperties): JSX.Element {
return (
<p className={`max-w-[41.875rem] ${className}`}>
{children}
</p>
)
}

FormParagraph.defaultProps = {
className: ""
};

export default FormParagraph;
11 changes: 9 additions & 2 deletions src/pages/ProfileForm/ProfileForm.data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FiDataType } from 'pages/ProfileForm/types';
import type { FiDataType, FinancialInstitutionRS } from 'pages/ProfileForm/types';

const fiData: FiDataType[] = [
{
Expand Down Expand Up @@ -43,6 +43,13 @@ const afData: FiDataType[] = [
];


// react-select format
const fiOptions: FinancialInstitutionRS[] = fiData.map(object => ({
label: `${object.name} | ${object.lei}`,
value: object.lei,
}));


export default fiData;
export { fiData, afData };
export { afData, fiData, fiOptions };

Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import {
Checkbox
} from 'design-system-react';
import type { CheckedState, FiDataType } from 'pages/ProfileForm/types';
import { useEffect, useState } from 'react';
import type { FiDataChecked } from 'pages/ProfileForm/types';

interface AssociatedFinancialInstitutionProperties {
fiObject: FiDataType;
checked: boolean;
key: string;
fiObject: FiDataChecked;
onCheckHandler: () => void;
}

function AssociatedFinancialInstitution({ fiObject, onCheckHandler, checked, ...rest}: AssociatedFinancialInstitutionProperties): JSX.Element {
function AssociatedFinancialInstitution({ onCheckHandler, fiObject, ...rest}: AssociatedFinancialInstitutionProperties): JSX.Element {
return (
<div className="flex flex-row gap-1 mt-[0.9375em]" key={fiObject.lei}>
<Checkbox
Expand All @@ -24,7 +23,7 @@ function AssociatedFinancialInstitution({ fiObject, onCheckHandler, checked, ...
<p className='mb-[0.025rem]'>Agency Code: {fiObject.agencyCode}</p>
</div>
}
checked={checked}
checked={fiObject.checked}
name={fiObject.lei}
onChange={onCheckHandler}
{...rest}
Expand All @@ -38,34 +37,28 @@ AssociatedFinancialInstitution.defaultProps ={
};

interface AssociatedFinancialInstitutionsProperties {
fiData: FiDataType[];
handleCheckedState: (checkedState: CheckedState) => void
checkedListState: FiDataChecked[];
setCheckedListState: ( cbFunc: (prev: FiDataChecked[]) => FiDataChecked[]) => void
}

const emptyArray: FiDataType[] = [];
function AssociatedFinancialInstitutions({ checkedListState, setCheckedListState }: AssociatedFinancialInstitutionsProperties): JSX.Element {

function AssociatedFinancialInstitutions({ fiData = [], handleCheckedState }: AssociatedFinancialInstitutionsProperties): JSX.Element {
const formatCheckedState = (fiDataInput: FiDataType[]): CheckedState => Object.fromEntries(fiDataInput.map((object) => [object.lei, false]));
const [checkedListState, setCheckedListState] = useState<CheckedState>(formatCheckedState(fiData));

// Passes the checkboc state to the parent's callback
useEffect(() =>{
handleCheckedState(checkedListState)
},[handleCheckedState, checkedListState]);

return (
<div className="mb-[30px] mt-[30px]">
{fiData.map((fiObject: FiDataType) => {
{checkedListState.map((fiObject: FiDataChecked) => {
const onCheckHandler = (): void => {
setCheckedListState(previousState => ({
...previousState,
[fiObject.lei]: !previousState[fiObject.lei]
}))


setCheckedListState( (prev: FiDataChecked[]): FiDataChecked[] => {
return prev.map(obj => {
if (obj.lei !== fiObject.lei) return obj;
return {...fiObject,
checked: !fiObject.checked
};
});
})
};
return (
<AssociatedFinancialInstitution key={fiObject.lei} fiObject={fiObject} checked={Boolean(checkedListState[fiObject.lei])} onCheckHandler={onCheckHandler}/>
<AssociatedFinancialInstitution key={fiObject.lei} fiObject={fiObject} onCheckHandler={onCheckHandler}/>
)
})}

Expand Down
124 changes: 92 additions & 32 deletions src/pages/ProfileForm/Step1Form/Step1Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@

import { zodResolver } from "@hookform/resolvers/zod";
import useSblAuth from 'api/useSblAuth';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import type { SubmitHandler } from "react-hook-form";
import { useForm } from "react-hook-form";

import AssociatedFinancialInstitutions from './AssociatedFinancialInstitutions';
import NoDatabaseResultError from './NoDatabaseResultError';
import FormParagraph from "components/FormParagraph"

import {
Button
Button,
Link
} from 'design-system-react';
import { fiData, afData } from 'pages/ProfileForm/ProfileForm.data';
import type { CheckedState, ValidationSchema } from "pages/ProfileForm/types";
import fiData, { afData } from 'pages/ProfileForm/ProfileForm.data';
import type { FiDataChecked, FiDataType, FinancialInstitutionRS, ValidationSchema } from "pages/ProfileForm/types";
import { FormFields as formFields, validationSchema } from "pages/ProfileForm/types";
import InputEntry from "./InputEntry";
import Step1FormErrorHeader from "./Step1FormErrorHeader";
Expand All @@ -22,8 +24,7 @@ import Step1FormHeader from "./Step1FormHeader";
import useProfileForm from "store/useProfileForm";
import Step1FormDropdownContainer from "./Step1FormDropdownContainer";

import type { FinancialInstitution } from "../types";
import { fiOptions } from "../types";
import { fiOptions } from "../ProfileForm.data";

function Step1Form(): JSX.Element {
const auth = useSblAuth();
Expand All @@ -39,7 +40,7 @@ function Step1Form(): JSX.Element {
const {
register,
handleSubmit,
// setValue,
setValue,
trigger,
getValues,
formState: { errors },
Expand All @@ -51,37 +52,80 @@ function Step1Form(): JSX.Element {
const onSubmit: SubmitHandler<ValidationSchema> = (data) => {
console.log('data:', data);
}



console.log('form errors:', errors)
/* Selected State - Start */
// Associated Financial Institutions state
const formatDataCheckedState = (fiDataInput: FiDataType[]): FiDataChecked[] => fiDataInput.map((object) => ({...object, checked: false}));
const initialDataCheckedState = formatDataCheckedState(afData || []);
const [checkedListState, setCheckedListState] = useState<FiDataChecked[]>(initialDataCheckedState);

// Dropdown -- Financial Institutions state
const [selectedFI, setSelectedFI] = useState<FinancialInstitutionRS[]>([]);
/* Selected State - End */

// Formatting: Checkmarking either the Associated Financial Institutions or the Dropdown Financial Institutions, adds to the react-hook-form object
/* Format - Start */

const getFinancialInstitutionsFormData = (checkedListState: FiDataChecked[], selectedFI: FinancialInstitutionRS[], fiData: FiDataType[]): FiDataType[] => {
const newFinancialInstitutions: FiDataType[] = [];

checkedListState.forEach( (obj: FiDataChecked) => {
if (Boolean(obj.checked)) {
const fiDataObj: FiDataType = {
name: obj.name,
lei: obj.lei,
taxID: obj.taxID,
agencyCode: obj.agencyCode
};

newFinancialInstitutions.push(fiDataObj);
}
});

selectedFI.forEach( (objRS: FinancialInstitutionRS) => {
const found = fiData.find(obj => obj.lei === objRS.value);
if (found) {
newFinancialInstitutions.push(found);
}
} );

return newFinancialInstitutions;
}

useEffect(()=>{
setValue('financialInstitutions', getFinancialInstitutionsFormData(checkedListState, selectedFI, fiData));
},[checkedListState, selectedFI]);
/* Format - End */


// Post Submission -- then navigate to Step2
const setStep = useProfileForm((state) => state.setStep);
const setProfileData = useProfileForm((state) => state.setProfileData);

const onSubmitButtonAction = async (): Promise<void> => {
const passesValidation = await trigger();
if (passesValidation) {
// TODO: Post the submission
}
console.log("validationResult:", passesValidation)
// console.log("getValues:", getValues())
// console.log('onclick errors', errors);
const values = getValues();
if (values.firstName && values.lastName) {
setProfileData(getValues())
setStep(2)
}
}

const handleAFICheckedState = (checkedState: CheckedState): void => {
console.log('checkedState:', checkedState)
// Add to react-hook-form object
const currentFI = getValues().financialInstitutions;
// console.log(getValues())

// 'Clear Form' function
function clearForm(): void {
setValue('firstName', "");
setValue('lastName', "");
setSelectedFI([]);
setCheckedListState(initialDataCheckedState);
window.scrollTo({ top: 0, behavior: 'smooth' });
}

const [selected, setSelected] = useState<FinancialInstitution[]>();

return (
<div>
<div id="step1form">
<Step1FormHeader />
{ errors && Object.keys(errors).length > 0 ? <Step1FormErrorHeader errors={errors} /> : null}
<form
Expand All @@ -91,32 +135,40 @@ function Step1Form(): JSX.Element {
<InputEntry label={formFields.firstName} id="firstName" {...register('firstName')} errors={errors} isDisabled={false} />
<InputEntry label={formFields.lastName} id="lastName" {...register('lastName')} errors={errors} isDisabled={false} />
<InputEntry label={formFields.email} id="email" {...register('email')} errors={errors} isDisabled>
<p className="">Your email address is automatically pulled in from Login.gov.</p>
<FormParagraph>Your email address is automatically pulled in from <Link href="#">Login.gov</Link>.</FormParagraph>
</InputEntry>

<div className="mt-8 mb-9">
<h4 className="a-label a-label__heading">{formFields.financialInstitutions}</h4>
<p className="">Select the financial institution(s) that you are associated with.</p>
{afData ? <AssociatedFinancialInstitutions fiData={afData} handleCheckedState={handleAFICheckedState} /> : null}
<p className="">If you need to file for additional institutions not listed above, search and select the institutions you are associated with.</p>
<FormParagraph className="">The following institutions match your email domain. Select the available institutions you wish to file for. You may select more than one.</FormParagraph>
{afData
?
<>
<AssociatedFinancialInstitutions checkedListState={checkedListState} setCheckedListState={setCheckedListState} />
<FormParagraph>
If you need to file for additional institutions not listed above, search and select the institutions you are associated with.
</FormParagraph>
</>
:
null
}

{/* React-Select */}
<Step1FormDropdownContainer
error={errors.financialInstitutions ? errors.financialInstitutions.message : ""}
options={fiOptions}
id="financialInstitutions"
onChange={newSelected=>setSelected(newSelected)}
onChange={newSelected=>setSelectedFI(newSelected)} // TODO: use useCallback
label=""
labelClearAll = 'Clear All Selected Institutions'
isMulti
pillAlign="bottom"
placeholder=""
withCheckbox
showClearAllSelectedButton
showClearAllSelectedButton={false}
isClearable={false}
value={selected}
// menuIsOpen
value={selectedFI}
/>
{/* TODO: The below error occurs if the 'Get All Financial Instituions' fails or fetches empty data */}
{/* TODO: The below error occurs if the 'Get All Financial Instituions' fetch fails or fetches empty data */}
{errors.fiData ? <NoDatabaseResultError /> : null}

</div>
Expand All @@ -126,11 +178,19 @@ function Step1Form(): JSX.Element {
label="Submit"
aria-label="Submit User Profile"
size="default"
// type="submit"
>
Submit
</Button>

<div className='ml-[15px] inline-block pill clear-selected'>
<Button
label={"Clear form"}
onClick={clearForm}
appearance='warning'
asLink
/>
</div>


</form>
</div>
Expand Down
Loading
Loading