From e0839938ddb3699aa51567f09a473012087104e6 Mon Sep 17 00:00:00 2001 From: S T Date: Tue, 19 Mar 2024 01:26:44 -0700 Subject: [PATCH] feat(tfi, poc): Provide Your Types of Financial Institutions - Skeleton; Point of Contact - Skeleton, Input Validation, Error Handling, Submission (#300) closes #284 closes #287 closes #297 closes #288 ## Changes - style(Fieldgroup): Adhere's to the 770px max-width with box-border (includes borders, margins and padding into the max-width) - style(SectionIntro): Adhere's to the 670px max-width with box-border (includes borders, margins and padding into the max-width) - feat(poc): Point of Contacts - Skeleton - feat(poc): Point of Contacts - Zod Schema - feat(tfi): Types of Financial Institutions - Skeleton Implemented - awaiting functionality - feat(vite proxy): add `v1/filing` as a vite proxy point. - feat(poc): Create a `submitPointOfContact` request for use on the Point of Contact form. - chore(FormMain): Created a `FormMain` component which is a wrapper component for `
`. ## Screenshots |Point of Contact|PoC Error Header|Types of Financial Institutions| |---|---|---| |Screenshot 2024-03-15 at 11 35 42 AM|Screenshot 2024-03-15 at 11 35 59 AM|Screenshot 2024-03-15 at 11 39 12 AM| ## How to Test **Pre-requisites** - Make sure to `yarn update`, wipe all Docker containers and Docker volumes, run `yarn seed`. - **Add `SBL_FILING_BASE_URL="http://localhost:8882"` to your `.env`.** **Test Set 0** - Code inspect the proxy changes - Ensure all previously create requests are functioning properly - Inspect the styling of `Fieldgroup` and ensure the 770px (48.125rem) limit is met (including borders, margins, etc). **Test Set 1** - If needed, `toggleRouting()` to disable enforced routing - Navigate to `http://localhost:8899/point-of-contact` to verify Point of Contact - Do not fill anything and hit **submit**. Double-check regex verification (ZIP code, phone number, email, etc) - Fill out everything properly and hit submit. Check in Network tab along (compare with the swagger docs) that the request is properly implemented. NOTE: Currently, the request is **not** working (backend problem). **Test Set 2** - If needed, `toggleRouting()` to disable enforced routing - Navigate to `http://localhost:8899/types-financial-institutions` to verify Types of Financial Institutions. No functionality at this moment. ## TODO - `submitPointOfContact` requires a corresponding `lei` and `filing_period`, so temporarily using **HARDCODED** values. - Types of Financial Institutions: Waiting on `Update Your Financial Institution` to be completed before further updates to the zod schema, input validation and error handling. ## Notes - Includes commits from 222: Update Your Financial Institution; wait till that PR is merged in before this one. - Currently, the `submitPointOfContact` request will return an `500 Internal Server Error`. This can be ignored, [see here](https://github.com/cfpb/sbl-frontend/pull/300#issuecomment-1999955629). --------- Co-authored-by: Meis --- ENV-GUIDE.md | 1 + src/App.tsx | 20 ++ src/api/requests/submitPointOfContact.ts | 19 ++ src/components/FieldGroup.tsx | 2 +- src/components/FormErrorHeader.tsx | 5 +- src/components/FormMain.tsx | 18 ++ src/components/FormWrapper.tsx | 4 +- src/components/InputEntry.tsx | 5 +- src/components/SectionIntro.tsx | 2 +- .../TypesFinancialInstitutionSection.tsx | 78 ++++++++ .../UpdateIdentifyingInformation.tsx | 8 +- .../Filing/UpdateFinancialProfile/types.ts | 54 ++--- src/pages/PointOfContact/index.tsx | 188 ++++++++++++++++++ src/pages/PointOfContact/states.json | 55 +++++ .../ProfileForm/CreateProfileForm/index.tsx | 105 +++++----- src/pages/ProfileForm/ProfileFormUtils.ts | 21 ++ src/pages/ProfileForm/Step1Form/Step1Form.tsx | 5 +- .../TypesFinancialInstitutions/index.tsx | 73 +++++++ src/types/formTypes.ts | 55 ++++- vite.config.ts | 14 +- 20 files changed, 637 insertions(+), 95 deletions(-) create mode 100644 src/api/requests/submitPointOfContact.ts create mode 100644 src/components/FormMain.tsx create mode 100644 src/pages/Filing/UpdateFinancialProfile/TypesFinancialInstitutionSection.tsx create mode 100644 src/pages/PointOfContact/index.tsx create mode 100644 src/pages/PointOfContact/states.json create mode 100644 src/pages/TypesFinancialInstitutions/index.tsx diff --git a/ENV-GUIDE.md b/ENV-GUIDE.md index ea106764e..20ae9f4b9 100644 --- a/ENV-GUIDE.md +++ b/ENV-GUIDE.md @@ -10,6 +10,7 @@ SBL_OIDC_AUTHORITY="http://localhost:8880/realms/regtech" SBL_OIDC_CLIENT_ID="regtech-client" SBL_OIDC_REDIRECT_URI="http://localhost:${SBL_DEV_PORT}/filing" SBL_REGTECH_BASE_URL="http://localhost:8881" +SBL_FILING_BASE_URL="http://localhost:8882" SBL_MAIL_BASE_URL="http://localhost:8765" ``` diff --git a/src/App.tsx b/src/App.tsx index 6abb31084..dabe12dce 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -44,6 +44,10 @@ const PaperworkNotice = lazy( async () => import('pages/Filing/PaperworkNotice'), ); const Summary = lazy(async () => import('pages/Summary/Summary')); +const PointOfContact = lazy(async () => import('pages/PointOfContact')); +const TypesFinancialInstitutions = lazy( + async () => import('pages/TypesFinancialInstitutions'), +); // allow developers to toggle routing in development const isRoutingEnabled = getIsRoutingEnabled(); @@ -237,6 +241,22 @@ export default function App(): ReactElement { } /> + + + + } + /> + + + + } + /> } /> => { + return request({ + // This will eventually be `/v1/filing/institutions/{lei}/filings/{period_name}/contact-info` + // CURRENTLY HARDCODED + url: `/v1/filing/institutions/123456789TESTBANK123/filings/2024/contact-info`, + method: 'put', + body: userProfileObject, + headers: { Authorization: `Bearer ${auth.user?.access_token}` }, + }); +}; + +export default submitPointOfContact; diff --git a/src/components/FieldGroup.tsx b/src/components/FieldGroup.tsx index 0ed929efe..a4f0a0f6f 100644 --- a/src/components/FieldGroup.tsx +++ b/src/components/FieldGroup.tsx @@ -6,7 +6,7 @@ interface FieldGroupProperties { function FieldGroup({ children }: FieldGroupProperties): JSX.Element { return ( -
+
{children}
); diff --git a/src/components/FormErrorHeader.tsx b/src/components/FormErrorHeader.tsx index cea505b38..d70f7f91f 100644 --- a/src/components/FormErrorHeader.tsx +++ b/src/components/FormErrorHeader.tsx @@ -20,6 +20,7 @@ function FormErrorHeader({ id, }: FormErrorHeaderProperties): JSX.Element | null { if (!errors || Object.keys(errors).length === 0) return null; + return (
@@ -76,7 +77,9 @@ function FormErrorHeader({ {`${ formFieldsHeaderError[ keyUsed as keyof typeof formFieldsHeaderError - ] + ] ?? + errors[keyUsed]?.message ?? + 'Missing entry' }${ // eslint-disable-next-line @typescript-eslint/no-magic-numbers typeof keyIndex === 'number' ? ` (${keyIndex + 1})` : '' diff --git a/src/components/FormMain.tsx b/src/components/FormMain.tsx new file mode 100644 index 000000000..f5b50b939 --- /dev/null +++ b/src/components/FormMain.tsx @@ -0,0 +1,18 @@ +import type { ReactNode } from 'react'; + +interface FormProperties { + children: ReactNode; +} + +/** + * + * @returns FormParagraph + */ +function FormMain({ + children, + className = '', +}: FormProperties & React.ComponentPropsWithoutRef<'form'>): JSX.Element { + return {children}; +} + +export default FormMain; diff --git a/src/components/FormWrapper.tsx b/src/components/FormWrapper.tsx index ff22dd9b6..db2539522 100644 --- a/src/components/FormWrapper.tsx +++ b/src/components/FormWrapper.tsx @@ -1,10 +1,10 @@ import type { ReactNode } from 'react'; -interface Properties { +interface FormWrapperProperties { children: ReactNode; } -function FormWrapper({ children }: Properties): JSX.Element { +function FormWrapper({ children }: FormWrapperProperties): JSX.Element { return (
diff --git a/src/components/InputEntry.tsx b/src/components/InputEntry.tsx index 5366f16c1..ccba12e48 100644 --- a/src/components/InputEntry.tsx +++ b/src/components/InputEntry.tsx @@ -4,8 +4,8 @@ import { forwardRef } from 'react'; import { Element } from 'react-scroll'; import InputErrorMessage from 'components/InputErrorMessage'; +import LabelOptional from 'components/LabelOptional'; import { Heading, TextInput } from 'design-system-react'; -import LabelOptional from './LabelOptional'; interface InputEntryProperties extends PropsWithoutRef { @@ -23,6 +23,7 @@ interface InputEntryProperties const InputEntry = forwardRef( ( { + className = '', id, errorMessage, label, @@ -38,7 +39,7 @@ const InputEntry = forwardRef( ) => { const handleError = Boolean(showError && errorMessage); return ( -
+