Chapter 5: Putting It All Together

By following this guide we will
  • Build a component to display a patient’s health information and style it into a chart.
  • Display the information chart in the right panel of the dashboard for the patient that is selected on the left panel of the dashboard.

Building the PatientInfo component

Let’s build a component called PatientInfo to display patient information. The component should take in a patientId representing the patient whose information is to be displayed. We will use the connected components that we built in the previous chapter to show the patient’s Medications, Condition, Allergies, Vitals, and lab results in Fishbone format where there are two types of fishbones, BMP and CBC.

In src/components/PatientInfo/PatientInfo.tsx we have the following code:

src/components/PatientInfo/PatientInfo.tsx
1import React from "react";
2
3import Allergies from "../Allergies/Allergies";
4import Condition from "../Condition/Condition";
5import Fishbone from "../Fishbone/Fishbone";
6import Medications from "../Medications/Medications";
7import Vitals from "../Vitals/Vitals";
8
9interface Props {
10 patientId: string;
11}
12
13const PatientInfo: React.FC<Props> = ({ patientId }) => {
14 const baseClass = "patient-info";
15 const baseProps = {
16 baseClass,
17 patientId
18 };
19 return (
20 <div className={baseClass}>
21 <Medications {...baseProps} />
22 <Condition {...baseProps} />
23 <Allergies {...baseProps} />
24 <Vitals {...baseProps} />
25 <Fishbone {...baseProps} fishboneType="BMP" />
26 <Fishbone {...baseProps} fishboneType="CBC" />
27 </div>
28 );
29};
30
31export default PatientInfo;

Styling into a chart

We can style the patient information into a chart for easier readability. For this tutorial, we intend to style the chart as follows:

mockup

Let’s modify the code in PatientInfo.tsx to allow for this formatting.

src/components/PatientInfo/PatientInfo.tsx
1<div className={baseClass}>
2 <Medications {...baseProps} />
3 <div className="column">
4 <Condition {...baseProps} />
5 <Allergies {...baseProps} />
6 </div>
7 <Vitals {...baseProps} />
8 <h1>Labs</h1>
9 <Fishbone {...baseProps} fishboneType="BMP" />
10 <Fishbone {...baseProps} fishboneType="CBC" />
11</div>

Note that hospitals often still use older browsers such as Internet Explorer, so browser compatibility should be a consideration when styling components. We use display: flex instead of display: grid to accommodate Internet Explorer, even though the chart may be more intuitively seen as a grid.

In src/components/PatientInfo/patientInfo.scss we add the following code:

src/components/PatientInfo/patientInfo.scss
1$min-width-column: 350px;
2
3.patient-info {
4 display: flex;
5 flex-wrap: wrap;
6
7 h1 {
8 padding: 0px $spacing-large;
9 margin-top: $spacing-medium-large;
10 flex-basis: 100%;
11 }
12
13 .column {
14 flex: 1;
15 display: flex;
16 flex-direction: column;
17 min-width: $min-width-column;
18 }
19
20 &__vitals {
21 flex: 1;
22 min-width: $min-width-column;
23 }
24
25 &__fishbone {
26 flex: 1;
27 min-width: $min-width-column;
28 }
29
30 &__conditions.patient_medications {
31 flex-basis: 100%;
32 min-width: 900px;
33 }
34}

Displaying PatientInfo on the Dashboard

In Chapter 3, we built a PatientListLoader that can load a list of patients and allow the user to search for and select a patient. This was placed in a PanelBody on the left side of LeftPanelLayout. Meanwhile, the right side still shows the old PatientList component we built in Chapter 1. Let's replace that with our new PatientInfo component by updating the Dashboard with the following code:

src/components/Dashboard/Dashboard.tsx
1import PatientInfo from "../PatientInfo/PatientInfo";
2
3[code omitted]
4
5<LeftPanelLayout collapsible panelBody={<PanelBody />}>
6 {/* Spacer */}
7 <div style={{ height: 40 + 16 }}></div>
8
9 {patientId ? (
10 <PatientInfo patientId={patientId} />
11 ) : (
12 <div className="empty-no-patient">No patient ID selected.</div>
13 )}
14</LeftPanelLayout>;

Note that the spacer in line 7 is needed to adjust for occlusion by the AppHeader bar.

Remember to also replace the styling import in all.scss:

src/styles/all.scss
1@import "./_styles.scss"; // Global styles
2@import "./constants.scss"; // Presentation constants
3
4// Component styles:
5@import "../components/Dashboard/dashboard.scss";
6@import "../components/PanelBody/panelBody.scss";
7@import "../components/PatientListLoader/patientListLoader.scss";
8@import "../components/PatientMenuItem/patientMenuItem.scss";
9@import "../components/PatientInfo/patientInfo.scss";

At this point, since the PatientList component is no longer being used, you can delete the code for that component.

1rm -r src/components/PatientList

We now have an application where we can search and select a patient from a list of patients on the left side, and see the selected patient’s health information on the right side. If you select one of the patients whose data we uploaded in the prerequisites (e.g. Ezra452), you should see something like the following:

patient 360 lite app

box icon

Conclusion

In this chapter, we created a component to display a selected patient’s health information. Combining this component with the components we built in previous chapters, we now have a useful application that can search through a list of patients, identify each patient by name and date of birth, and display a selected patient’s health information.

In the next chapter, we will discuss the final step: deployment!