Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
156 changes: 156 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"react-dom": "^17.0.0",
"react-markdown": "^8.0.7",
"react-router-dom": "^6.17.0",
"uuid": "^9.0.1",
"vite": "^5.1.6",
"vite-tsconfig-paths": "^4.3.2"
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/Auth/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const Login = props => {
params.append('client_id', env.get('VITE_CLIENT').asString());
axios
.post(
`${env.get('VITE_AUTH').asString()}/auth/realms/${env
`${env.get('VITE_AUTH').asString()}/realms/${env
.get('VITE_REALM')
.asString()}/protocol/openid-connect/token`,
params,
Expand Down
3 changes: 3 additions & 0 deletions src/components/Dashboard/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import FormsSection from './ListSelections/FormsSection';
import EmptySection from './ListSelections/EmptySection';
import PatientTaskSection from './ListSelections/PatientTaskSection';
import MedicationsSection from './ListSelections/MedicationsSection';
import NotificationsSection from './ListSelections/NotificationsSection';

// Since we're using JS and can't use TS enums
const Section = Object.freeze({
Expand Down Expand Up @@ -79,6 +80,8 @@ const Dashboard = props => {
return <FormsSection client={props.client} />;
case Section.MEDICATIONS:
return <MedicationsSection client={props.client} />;
case Section.NOTIFICATIONS:
return <NotificationsSection />
default:
return <EmptySection />;
}
Expand Down
36 changes: 36 additions & 0 deletions src/components/Dashboard/ListSelections/NotificationsSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { memo, useContext, useEffect, useState } from 'react';
import useStyles from '../styles';
import { SettingsContext } from '../../../containers/ContextProvider/SettingsProvider';
import { EtasuStatusComponent } from '../../EtasuStatus/EtasuStatusComponent';
import axios from 'axios';

const NotificationsSection = () => {
const [globalState, _] = useContext(SettingsContext);
const classes = useStyles();
const [etasu, setEtasu] = useState([]);
useEffect(() => {
const patientFirstName = globalState.patient?.name?.at(0)?.given?.at(0);
const patientLastName = globalState.patient?.name?.at(0)?.family;
const patientDOB = globalState.patient?.birthDate;

const etasuUrl = `${globalState.remsAdminServer}/etasu/met/patient/${patientFirstName}/${patientLastName}/${patientDOB}`;
axios({
method: 'get',
url: etasuUrl
}).then((response) => {
setEtasu(response.data);
}, (error) =>{
console.error(error);
})
}, []);
return (
<div className={classes.dashboardArea}>
<h2 className={classes.elementHeader}>Notifications</h2>
{etasu.map((remsCase) => {
return <EtasuStatusComponent key = {remsCase.case_number} remsAdminResponseInit={remsCase} />
})}
</div>
);
};

export default memo(NotificationsSection);
44 changes: 44 additions & 0 deletions src/components/EtasuStatus/EtasuStatus.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { EtasuStatusButton } from './EtasuStatusButton.jsx';
import { EtasuStatusModal } from './EtasuStatusModal.jsx';
import { useState, useEffect, useContext } from 'react';
import { Card, Typography } from '@mui/material';
import { SettingsContext } from '../../containers/ContextProvider/SettingsProvider.jsx';
import axios from 'axios';
import { EtasuStatusComponent } from './EtasuStatusComponent.jsx';
import { getEtasu } from '../../util/util.js';

// converts code into etasu for the component to render
// simplifies usage for applications that only know the code, not the case they want to display
export const EtasuStatus = props => {
const [globalState, _] = useContext(SettingsContext);

const { code } =
props;
const [remsAdminResponse, setRemsAdminResponse] = useState({});
useEffect(() => getEtasuStatus(), [code]);
const getEtasuStatus = () => {
const patientFirstName = globalState.patient?.name?.at(0)?.given?.at(0);
const patientLastName = globalState.patient?.name?.at(0)?.family;
const patientDOB = globalState.patient?.birthDate;

console.log(
'get Etastu Status: ' +
patientFirstName +
' ' +
patientLastName +
' - ' +
patientDOB +
' - ' +
code
);
const etasuUrl = `${globalState.remsAdminServer}/etasu/met/patient/${patientFirstName}/${patientLastName}/${patientDOB}/drugCode/${code}`;
getEtasu(etasuUrl, setRemsAdminResponse);
};

return (
<>
{remsAdminResponse.case_number ? <EtasuStatusComponent remsAdminResponseInit={remsAdminResponse} /> : ""}
</>
);
};

17 changes: 17 additions & 0 deletions src/components/EtasuStatus/EtasuStatusButton.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.etasuButtonText {
margin-bottom: 0px;
font-weight: bold;
font-size: 14px;
}

.etasuButtonTimestamp {
margin: 0 auto;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 0.8rem;
}

.timestampString {
font-size: 0.7rem;
opacity: 0.8;
}

64 changes: 64 additions & 0 deletions src/components/EtasuStatus/EtasuStatusButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Button, Grid, Typography } from '@mui/material';
import ListIcon from '@mui/icons-material/List';
import './EtasuStatusButton.css';

export const EtasuStatusButton = props => {
const { baseColor, remsAdminResponse, handleOpenEtasuStatus, lastCheckedEtasuTime } =
props;
return (
<Grid item container flexDirection="column" alignItems="center">
<Button sx={buttonSx(baseColor)} variant="contained" onClick={handleOpenEtasuStatus}>
<ListIcon fontSize="large" />
<Typography className="etasuButtonText" component="p">
ETASU:
</Typography>
<Typography component="p">{remsAdminResponse?.status || 'Not Started'}</Typography>
</Button>
{renderTimestamp(lastCheckedEtasuTime)}
</Grid>
);
};

const buttonSx = baseColor => ({
backgroundColor: baseColor,
':hover': { filter: 'brightness(110%)', backgroundColor: baseColor },
flexDirection: 'column'
});

const renderTimestamp = checkedTime => {
return checkedTime ? (
<>
<Typography component="p" className="etasuButtonTimestamp">
{convertTimeDifference(checkedTime)}
</Typography>
<Typography component="p" className="etasuButtonTimestamp timestampString">
{new Date(checkedTime).toLocaleString()}
</Typography>
</>
) : (
<Typography>No medication selected</Typography>
);
};

const convertTimeDifference = start => {
const end = Date.now();
const difference = end - start;
const diffMin = difference / 60000;
let prefix = 'a long time';
if (diffMin < 1) {
prefix = 'a few seconds';
} else if (diffMin > 1 && diffMin < 2) {
prefix = 'a minute';
} else if (diffMin > 2 && diffMin < 60) {
prefix = `${Math.round(diffMin)} minutes`;
} else if (diffMin > 60 && diffMin < 120) {
prefix = 'an hour';
} else if (diffMin > 120 && diffMin < 1440) {
prefix = `${Math.round(diffMin / 60)} hours`;
} else if (diffMin > 1440 && diffMin < 2880) {
prefix = 'a day';
} else if (diffMin > 2880) {
prefix = `${Math.round(diffMin / 1440)} days`;
}
return `Last checked ${prefix} ago`;
};
Loading