diff --git a/client/src/pages/patients/PatientRegistationAccordion.module.css b/client/src/pages/patients/PatientRegistationAccordion.module.css index 14922a32..e416a442 100644 --- a/client/src/pages/patients/PatientRegistationAccordion.module.css +++ b/client/src/pages/patients/PatientRegistationAccordion.module.css @@ -1,12 +1,11 @@ .control { - background-color: var(--mantine-color-gray-6); font-weight: 600; - - &[data-active] { - background-color: white; - } } .label { + display: flex; + align-items: center; + justify-content: space-between; font-size: 1.5rem; + margin-right: 1rem; } diff --git a/client/src/pages/patients/PatientRegistration.jsx b/client/src/pages/patients/PatientRegistration.jsx index 46225133..f2f08f07 100644 --- a/client/src/pages/patients/PatientRegistration.jsx +++ b/client/src/pages/patients/PatientRegistration.jsx @@ -10,15 +10,7 @@ import { useQuery } from '@tanstack/react-query'; import LifelineAPI from './LifelineAPI.js'; import PatientRegistrationAccordion from './PatientRegistrationAccordion'; -const TABS = [ - 'patientData', - 'contactData', - 'medicalData', - 'healthcareChoices', - 'codeStatus', -]; - -const ERROR_SECTION_MAP = { +const FORM_TABS = { patientData: 'Patient Data', contactData: 'Emergency Contact', medicalData: 'Medical Information', @@ -32,13 +24,20 @@ const ERROR_SECTION_MAP = { */ export default function PatientRegistration() { const [loading, setLoading] = useState(false); - const [active, setActive] = useState(0); const [initialMedicalData, setInitialMedicalData] = useState({}); - const [initialHospitalData, setInitialHospitalData] = useState({}); - const [initialPhysicianData, setInitialPhysicianData] = useState({}); + const [initialHospitalData, setInitialHospitalData] = useState(''); + const [initialPhysicianData, setInitialPhysicianData] = useState(''); const [openedSection, setOpenedSection] = useState('patientData'); const [opened, { open, close }] = useDisclosure(false); + const [showCheck, setShowCheck] = useState({ + patientData: false, + contactData: false, + medicalData: false, + healthcareChoices: false, + codeStatus: false, + }); + const [visitedSections, setVisitedSections] = useState({ patientData: true, contactData: false, @@ -168,15 +167,11 @@ export default function PatientRegistration() { }), }); - setInitialHospitalData({ - id: hospital ? hospital.id : '', - name: hospital ? hospital.name : '', - }); + setInitialHospitalData(hospital ? hospital.name : ''); - setInitialPhysicianData({ - id: physician ? physician.id : '', - name: physician ? `${physician.firstName} ${physician.lastName}` : '', - }); + setInitialPhysicianData( + physician ? `${physician.firstName} ${physician.lastName}` : '', + ); const patientData = { firstName, @@ -251,7 +246,7 @@ export default function PatientRegistration() { const unvisited = Object.entries(visitedSections) .filter(([_, visited]) => !visited) - .map(([section]) => ERROR_SECTION_MAP[section]); + .map(([section]) => FORM_TABS[section]); if (unvisited.length > 0) { setUnvisitedSections(unvisited); @@ -324,7 +319,7 @@ export default function PatientRegistration() { let errorSections = []; errorSets.forEach((key) => { - errorSections.push(ERROR_SECTION_MAP[key]); + errorSections.push(FORM_TABS[key]); }); showErrorNotification( @@ -343,6 +338,10 @@ export default function PatientRegistration() { showSuccessNotification( 'Patient basic information has been successfully registered.', ); + setShowCheck((prevShowCheck) => ({ + ...prevShowCheck, + patientData: true, + })); return; } @@ -355,6 +354,10 @@ export default function PatientRegistration() { showSuccessNotification( 'Patient basic information has been successfully updated.', ); + setShowCheck((prevShowCheck) => ({ + ...prevShowCheck, + patientData: true, + })); return; } throw new Error('Failed to update patient.'); @@ -382,6 +385,10 @@ export default function PatientRegistration() { showSuccessNotification( 'Patient information has been successfully updated.', ); + setShowCheck((prevShowCheck) => ({ + ...prevShowCheck, + [Object.keys(data)[0]]: true, + })); return; } if (res.status === StatusCodes.BAD_REQUEST) { @@ -403,25 +410,11 @@ export default function PatientRegistration() { * @param {string} value */ async function handleAccordionChange(value) { - value === null - ? navigate('', { replace: true }) - : navigate(`#${value}`, { replace: true }); - - setVisitedSections((prevVisitedSections) => ({ - ...prevVisitedSections, - [value]: true, - })); - - if (!openedSection) { - setOpenedSection(value); - setActive(TABS.indexOf(value)); - return; - } - - if (TABS.indexOf(value) < active) { - setOpenedSection(value); - setActive(TABS.indexOf(value)); + if (value === null) { + navigate('', { replace: true }); return; + } else { + navigate(`#${value}`, { replace: true }); } let errorFieldCount = 0; @@ -437,7 +430,11 @@ export default function PatientRegistration() { if (errorFieldCount === 0) { setOpenedSection(value); - setActive(TABS.indexOf(value)); + + setVisitedSections((prevVisitedSections) => ({ + ...prevVisitedSections, + [value]: true, + })); if (openedSection === 'patientData') { const patientData = { @@ -479,6 +476,7 @@ export default function PatientRegistration() { initialHospitalData={initialHospitalData} initialPhysicianData={initialPhysicianData} openedSection={openedSection} + showCheck={showCheck} handleAccordionChange={handleAccordionChange} /> diff --git a/client/src/pages/patients/PatientRegistrationAccordion.jsx b/client/src/pages/patients/PatientRegistrationAccordion.jsx index 1f3f50af..3dda2994 100644 --- a/client/src/pages/patients/PatientRegistrationAccordion.jsx +++ b/client/src/pages/patients/PatientRegistrationAccordion.jsx @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import { Accordion, TextInput, Select, InputBase } from '@mantine/core'; import { DateInput } from '@mantine/dates'; +import { IconCircleCheck } from '@tabler/icons-react'; import { IMaskInput } from 'react-imask'; import MedicalDataSearch from './inputs/MedicalDataSearch'; import HealthcareChoicesSearch from './inputs/HealthcareChoicesSearch'; @@ -10,13 +11,37 @@ import classes from './PatientRegistationAccordion.module.css'; const PatientRegistrationAccordionProps = { form: PropTypes.object.isRequired, - openedSection: PropTypes.string, - handleAccordionChange: PropTypes.func.isRequired, initialMedicalData: PropTypes.object, initialHospitalData: PropTypes.object, initialPhysicianData: PropTypes.object, + openedSection: PropTypes.string, + showCheck: PropTypes.object.isRequired, + handleAccordionChange: PropTypes.func.isRequired, +}; + +const FORM_SELECT_ENUM_VALUES = { + language: [ + 'CANTONESE', + 'ENGLISH', + 'MANDARIN', + 'RUSSIAN', + 'SPANISH', + 'TAGALOG', + ], + gender: ['FEMALE', 'MALE', 'TRANS_MALE', 'TRANS_FEMALE', 'OTHER', 'UNKNOWN'], + relationship: ['SPOUSE', 'PARENT', 'CHILD', 'SIBLING', 'OTHER', 'UNKNOWN'], + codeStatus: ['COMFORT', 'DNR', 'DNI', 'DNR_DNI', 'FULL'], }; +/** + * Converts a string to title case + * @param {string} string + * @returns {string} + */ +function toTitleCase(string) { + return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); +} + /** * Patient Registration Accordion component * @param {PropTypes.InferProps} props @@ -27,6 +52,7 @@ export default function PatientRegistrationAccordion({ initialHospitalData, initialPhysicianData, openedSection, + showCheck, handleAccordionChange, }) { return ( @@ -38,7 +64,12 @@ export default function PatientRegistrationAccordion({ classNames={classes} > - ① Basic Information + + ① Basic Information{' '} + {showCheck['patientData'] ? ( + + ) : null} + ({ + value, + label: toTitleCase(value), + }))} searchable key={form.key('patientData.gender')} {...form.getInputProps('patientData.gender')} @@ -80,14 +107,10 @@ export default function PatientRegistrationAccordion({ label="Language" placeholder="Select Language" withAsterisk - data={[ - 'CANTONESE', - 'ENGLISH', - 'MANDARIN', - 'RUSSIAN', - 'SPANISH', - 'TAGALOG', - ]} + data={FORM_SELECT_ENUM_VALUES.language.map((value) => ({ + value, + label: toTitleCase(value), + }))} searchable key={form.key('patientData.language')} {...form.getInputProps('patientData.language')} @@ -106,7 +129,12 @@ export default function PatientRegistrationAccordion({ - ② Emergency Contact + + ② Emergency Contact{' '} + {showCheck['contactData'] ? ( + + ) : null} + ({ + value, + label: toTitleCase(value), + }))} searchable key={form.key('contactData.relationship')} {...form.getInputProps('contactData.relationship')} @@ -159,7 +183,12 @@ export default function PatientRegistrationAccordion({ - ③ Medical Information + + ③ Medical Information{' '} + {showCheck['medicalData'] ? ( + + ) : null} + {Object.keys(form.getValues().medicalData).map((category) => { return ( @@ -175,7 +204,12 @@ export default function PatientRegistrationAccordion({ - ④ Healthcare Choices + + ④ Healthcare Choices{' '} + {showCheck['healthcareChoices'] ? ( + + ) : null} + - ⑤ Advanced Directive + + ⑤ Advanced Directive{' '} + {showCheck['codeStatus'] ? ( + + ) : null} +