From 213f2a8c88977da9ff653f66bb06f11443e7e9cb Mon Sep 17 00:00:00 2001 From: nicholashibbits1 <172406954+nicholashibbits1@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:29:07 -0600 Subject: [PATCH] Edm 363 update lce UI (#33304) * Align header for mobile | display result count beside to keyword suggestion * Align cancel icon styles with search input | reduce number of typeahed suggestions dipslayed * touchup styles | change license state if it differs from name selection * slot conditional alert into dropdown label * set state filter field to all when switching to certification category type * filter typeahead suggestions based on filter options * update filter options based on typeahead suggestion selected * rename functions more clearly | correct state managment for filters when clearing input * cleanup * update results to va-card component * enable routing for new lce result info page * align breadcrumbs with result details url * cleanup * delete unit test for unused component * update unit test for helper function --- src/applications/gi/components/Dropdown.jsx | 3 + .../gi/components/GiBillBreadcrumbs.jsx | 11 +- .../gi/components/LcKeywordSearch.jsx | 67 +++++--- .../LicenseCertificationResultInfo.jsx | 72 --------- .../components/LicenseCertificationSearch.jsx | 2 +- .../LicenseCertificationSearchForm.jsx | 147 ++++++++++++++---- .../LicenseCertificationSearchResult.jsx | 32 +--- .../LicenseCertificationSearchResults.jsx | 42 ++--- src/applications/gi/routes.jsx | 9 ++ src/applications/gi/sass/gi.scss | 31 ++-- ...censeCertificationResultInfo.unit.spec.jsx | 30 ---- .../gi/tests/utils/helpers.unit.spec.js | 14 +- src/applications/gi/utils/helpers.js | 2 +- 13 files changed, 240 insertions(+), 222 deletions(-) delete mode 100644 src/applications/gi/components/LicenseCertificationResultInfo.jsx delete mode 100644 src/applications/gi/tests/components/LicenseCertificationResultInfo.unit.spec.jsx diff --git a/src/applications/gi/components/Dropdown.jsx b/src/applications/gi/components/Dropdown.jsx index c7dfae991769..398d6205d730 100644 --- a/src/applications/gi/components/Dropdown.jsx +++ b/src/applications/gi/components/Dropdown.jsx @@ -18,6 +18,7 @@ const Dropdown = ({ value, visible, required, + children, }) => { if (!visible) { return null; @@ -28,6 +29,7 @@ const Dropdown = ({ ); @@ -91,6 +93,7 @@ Dropdown.propTypes = { visible: PropTypes.bool, onFocus: PropTypes.func, required: PropTypes.bool, + children: PropTypes.node, }; Dropdown.defaultProps = { diff --git a/src/applications/gi/components/GiBillBreadcrumbs.jsx b/src/applications/gi/components/GiBillBreadcrumbs.jsx index 2687bff5d3d3..1cca2ce8843d 100644 --- a/src/applications/gi/components/GiBillBreadcrumbs.jsx +++ b/src/applications/gi/components/GiBillBreadcrumbs.jsx @@ -11,6 +11,7 @@ const GiBillBreadcrumbs = () => { const compareMatch = useRouteMatch('/compare'); const lcMatch = useRouteMatch('/lc-search'); const lcResultsMatch = useRouteMatch('/lc-search/results'); + const lcResultInfoMatch = useRouteMatch('/lc-search/:type/:id'); const crumbLiEnding = giDocumentTitle(); const formatedProgramType = formatProgramType( ProgramsTypeMatch?.params?.programType, @@ -55,7 +56,7 @@ const GiBillBreadcrumbs = () => { if (lcMatch) { crumbs.push({ href: '/education/gi-bill-comparison-tool/lc-search', - label: 'Licensces and Certifications', + label: 'Licensces & Certifications', }); } if (lcResultsMatch) { @@ -64,6 +65,14 @@ const GiBillBreadcrumbs = () => { label: 'Search Results', }); } + if (lcResultInfoMatch) { + crumbs.push({ + href: `/education/gi-bill-comparison-tool/lc-search/results/${ + lcResultInfoMatch.params.type + }/${lcResultInfoMatch.params.id}`, + label: 'Result Details', + }); + } return (
{institution.name}
- - -{institution.phone}
- -
- {institution.physicalStreet}
-
- {institution.physicalCity}, {` `}
- {institution.physicalState} {` `}
- {institution.physicalZip}
-
- {institution.physicalCountry}
-
- - Print and fill out form Request for Reimbursement of Licensing or - Certification Test Fees - -
- - Link to VA Form 22-0803 - -
diff --git a/src/applications/gi/components/LicenseCertificationSearchForm.jsx b/src/applications/gi/components/LicenseCertificationSearchForm.jsx
index 32b9b465968e..46c5a16318d0 100644
--- a/src/applications/gi/components/LicenseCertificationSearchForm.jsx
+++ b/src/applications/gi/components/LicenseCertificationSearchForm.jsx
@@ -2,13 +2,17 @@ import React, { useEffect, useState } from 'react';
import ADDRESS_DATA from 'platform/forms/address/data';
import PropTypes from 'prop-types';
import Dropdown from './Dropdown';
-import { updateLcFilterDropdowns } from '../utils/helpers';
+import { handleUpdateLcFilterDropdowns } from '../utils/helpers';
import LcKeywordSearch from './LcKeywordSearch';
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
+const mappedStates = Object.entries(ADDRESS_DATA.states).map(state => {
+ return { optionValue: state[0], optionLabel: state[1] };
+});
+
export const dropdownSchema = [
{
label: 'category',
@@ -29,29 +33,40 @@ export const dropdownSchema = [
},
{
label: 'state',
- options: [
- { optionValue: 'all', optionLabel: 'All' },
- ...Object.entries(ADDRESS_DATA.states).map(state => {
- return { optionValue: state[0], optionLabel: state[1] };
- }),
- ],
+ options: [{ optionValue: 'all', optionLabel: 'All' }, ...mappedStates],
alt: 'state',
current: { optionValue: 'all', optionLabel: 'All' },
},
];
-const filterSuggestions = (suggestions, value) => {
- // add filter options as arg
+const filterSuggestions = (suggestions, value, filters) => {
+ const { type } = filters; // destructure state once it's added to the response
+
if (!value) {
return [];
}
return suggestions.filter(suggestion => {
- // TODO add logic to account for filterOptions
+ if (type !== suggestion.type && type !== 'all') return false;
+ // TODO add logic to account for state
+
return suggestion.name.toLowerCase().includes(value.toLowerCase());
});
};
+const resetStateDropdown = dropdowns => {
+ return dropdowns.map(dropdown => {
+ return dropdown.label === 'state'
+ ? {
+ ...dropdown,
+ current: dropdown.options.find(
+ option => option.optionValue === 'all',
+ ),
+ }
+ : dropdown;
+ });
+};
+
export default function LicenseCertificationSearchForm({
suggestions,
handleSearch,
@@ -59,22 +74,25 @@ export default function LicenseCertificationSearchForm({
const [dropdowns, setDropdowns] = useState(dropdownSchema);
const [name, setName] = useState('');
const [filteredSuggestions, setFilteredSuggestions] = useState(suggestions);
+ const [showStateAlert, setShowStateAlert] = useState(false);
useEffect(
() => {
- const newSuggestions = filterSuggestions(suggestions, name);
+ const newSuggestions = filterSuggestions(suggestions, name, {
+ type: dropdowns[0].current.optionValue,
+ });
if (name.trim() !== '') {
newSuggestions.unshift({
name,
- link: 'lce/', // verify link
- type: 'all', // verify type
+ link: 'lce/',
+ type: 'all',
});
}
setFilteredSuggestions(newSuggestions);
},
- [name],
+ [name, suggestions, dropdowns],
);
const handleReset = () => {
@@ -83,12 +101,53 @@ export default function LicenseCertificationSearchForm({
};
const handleChange = e => {
- const newDropdowns = updateLcFilterDropdowns(dropdowns, e.target);
- setDropdowns(newDropdowns);
+ const newDropdowns = handleUpdateLcFilterDropdowns(dropdowns, e.target);
+
+ if (newDropdowns[0].current.optionValue === 'certification') {
+ setDropdowns(resetStateDropdown);
+ }
+
+ setDropdowns(current => {
+ // update url params
+ return handleUpdateLcFilterDropdowns(current, e.target);
+ });
};
const onUpdateAutocompleteSearchTerm = value => {
- setName(value);
+ setName(value); // update url params
+ };
+
+ const onSelection = selection => {
+ const { type, state } = selection; // TODO ensure state is added to response object coming from BE
+
+ const updateDropdowns = dropdowns.map(dropdown => {
+ if (dropdown.label === 'state') {
+ return {
+ ...dropdown,
+ current: dropdown.options.find(option => {
+ return option.optionValue === state;
+ }),
+ };
+ }
+
+ return {
+ ...dropdown,
+ current: dropdown.options.find(option => {
+ return option.optionValue === type;
+ }),
+ };
+ });
+
+ if (type === 'license' && dropdowns[1].current.optionValue !== state) {
+ setShowStateAlert(true);
+ }
+
+ setDropdowns(updateDropdowns);
+ };
+
+ const handleClearInput = () => {
+ onUpdateAutocompleteSearchTerm('');
+ setShowStateAlert(false);
};
return (
@@ -105,28 +164,50 @@ export default function LicenseCertificationSearchForm({
selectClassName="lc-dropdown-filter"
required={dropdowns[0].label === 'category'}
/>
+
+