Skip to content
Closed
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
51 changes: 51 additions & 0 deletions src/components/EtasuStatus/EtasuStatus.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { EtasuStatusButton } from './EtasuStatusButton.jsx';
import { EtasuStatusModal } from './EtasuStatusModal.jsx';
import { useState, useEffect } from 'react';
import { Card, Typography } from '@mui/material';

export const EtasuStatus = props => {
const { etasuUrl, request, remsAdminResponse, getEtasuStatus, lastCheckedEtasuTime } =
props;
const [showEtasuStatus, setShowEtasuStatus] = useState(false);

useEffect(() => getEtasuStatus(), [request.id, etasuUrl]);

const handleCloseEtasuStatus = () => {
setShowEtasuStatus(false);
};

const handleOpenEtasuStatus = () => {
setShowEtasuStatus(true);
};

return (
<Card variant="outlined" sx={{ padding: 2 }}>
<Typography variant="h6" align="center" mb={2}>
{remsAdminResponse?.drugName}
</Typography>
<EtasuStatusButton
baseColor={getStatusColor(remsAdminResponse?.status)}
remsAdminResponse={remsAdminResponse}
handleOpenEtasuStatus={handleOpenEtasuStatus}
lastCheckedEtasuTime={lastCheckedEtasuTime}
/>
<EtasuStatusModal
callback={getEtasuStatus}
remsAdminResponse={remsAdminResponse}
update={showEtasuStatus}
onClose={handleCloseEtasuStatus}
/>
</Card>
);
};

export const getStatusColor = status => {
switch (status) {
case 'Approved':
return 'green';
case 'Pending':
return '#f0ad4e';
default:
return '#0c0c0c';
}
};
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`;
};
33 changes: 33 additions & 0 deletions src/components/EtasuStatus/EtasuStatusModal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.renew-icon{
cursor: pointer;
margin-left: 15px;
margin-right: 15px;
}

.refresh{
cursor: pointer;
margin-left: 15px;
margin-right: 15px;
animation-name: spin;
animation-duration: 500ms;
animation-iteration-count: 2;
animation-timing-function: ease-in-out;
}

.status-icon{
width: 100%;
height:5px;
}

.bundle-entry{
margin: 5px;
}

@keyframes spin {
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
}
101 changes: 101 additions & 0 deletions src/components/EtasuStatus/EtasuStatusModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Box, Grid, IconButton, Modal, Tooltip, List, ListItem, ListItemIcon, ListItemText } from '@mui/material';
import AutorenewIcon from '@mui/icons-material/Autorenew';
import { useState, useEffect } from 'react';
import { getStatusColor } from './EtasuStatus';
import './EtasuStatusModal.css';
import CheckCircle from '@mui/icons-material/CheckCircle';
import Close from '@mui/icons-material/Close';

const getIdText = remsAdminResponse => remsAdminResponse?.case_number || 'N/A';

export const EtasuStatusModal = props => {
const { callback, onClose, remsAdminResponse, update } = props;
const [spin, setSpin] = useState(false);
const color = getStatusColor(remsAdminResponse?.status);

useEffect(() => {
if (update) {
setSpin(true);
callback();
}
}, [update]);

return (
<Modal open={update} onClose={onClose}>
<Box sx={modalStyle}>
<div>
<h1>REMS Status</h1>
<div className="status-icon" style={{ backgroundColor: color }}></div>
<Grid container columns={12}>
<Grid item xs={10}>
<div className="bundle-entry">
Case Number: {getIdText(remsAdminResponse)}
</div>
<div className="bundle-entry">Status: {remsAdminResponse.status || 'N/A'}</div>
</Grid>
<Grid item xs={2}>
<div className="bundle-entry">
<Tooltip title="Refresh">
<IconButton onClick={callback} data-testid="refresh">
<AutorenewIcon
data-testid="icon"
className={spin === true ? 'refresh' : 'renew-icon'}
onAnimationEnd={() => setSpin(false)}
/>
</IconButton>
</Tooltip>
</div>
</Grid>
</Grid>
<div>
<br></br>
<h3>ETASU</h3>
<Box sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>
{remsAdminResponse ? (
<List>
{remsAdminResponse?.metRequirements?.map((metRequirements) => (
<ListItem
disablePadding
key={metRequirements.metRequirementId}
data-testid="etasu-item"
>
<ListItemIcon>
{metRequirements.completed ? (
<CheckCircle color="success" />
) : (
<Close color="warning" />
)}
</ListItemIcon>
{metRequirements.completed ? (
<ListItemText primary={metRequirements.requirementName} />
) : (
<ListItemText
primary={metRequirements.requirementName}
secondary={metRequirements.requirementDescription}
/>
)}
</ListItem>
))}
</List>
) : (
'Not Available'
)}
</Box>
</div>
</div>
</Box>
</Modal>
);
};

const modalStyle = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '1px solid #000',
boxShadow: 24,
p: 4
};
Loading