@eureca/eureca-ui
Version:
UI component library of Eureca's user and admin apps
167 lines (146 loc) • 3.87 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { differenceInDays } from 'date-fns';
import { Typography, Box, useTheme, Link } from '@material-ui/core';
import { IconContext } from 'react-icons';
import { Flex } from '../Flex';
import { colors } from '../../theme/colors';
const styles = muiTheme => ({
box: {
cursor: 'pointer',
border: `1px solid ${colors.gray5}`,
boxSizing: 'border-box',
},
headerTypography: {
letterSpacing: 1,
color: colors.gray3,
textTransform: 'uppercase',
},
boldFont: {
fontWeight: muiTheme.typography.fontWeightBold,
},
divisor: {
border: `1px solid ${colors.gray5}`,
width: '100%',
margin: `${muiTheme.spacing(2)}px 0px`,
},
icon: {
marginRight: muiTheme.spacing(1),
fontSize: '1.125rem',
},
link: {
color: colors.green2,
letterSpacing: 0.5,
textDecoration: 'underline',
whiteSpace: 'nowrap',
},
});
const statusDecoder = {
feedback: 'Aguardando feedback',
feedbackReady: 'Acessar feedback',
confirmation: 'Confirme sua presença',
};
const dateDecoder = {
unavailable: 'Indisponível',
not_started: 'Fase não iniciada',
finished: 'Encerrada',
};
const ProgressCard = ({ title, icon, progress, date, status, active, onClick }) => {
const muiTheme = useTheme();
const style = styles(muiTheme);
function ProgressValue() {
let value = 0;
if (progress) {
value = progress <= 100 ? progress : 100;
}
return (
<Box ml={1}>
<Typography variant="body1" style={style.headerTypography}>
{`${value}%`}
</Typography>
</Box>
);
}
const statusText = name => (
<Link style={style.link}>
<Typography>{statusDecoder[name]}</Typography>
</Link>
);
function TrackStatus() {
let result;
if (!date) {
result = dateDecoder['unavailable'];
} else {
const remainingDays = differenceInDays(date, new Date());
remainingDays > 0
? (result = `Faltam ${remainingDays} dias para encerrar essa fase`)
: (result = dateDecoder.finished);
}
return (
<Typography
variant="body2"
style={{
fontWeight: 500,
color: !active && colors.gray3,
}}
>
{result}
</Typography>
);
}
return (
<Box
width={1}
p={2}
style={style.box}
bgcolor={active ? colors.white : colors.gray7}
onClick={onClick}
>
<Flex directionRow justifySpaceBetween alignCenter>
<Flex directionRow>
<IconContext.Provider
value={{
color: active ? colors.green1 : colors.gray3,
style: style.icon,
}}
>
{icon}
</IconContext.Provider>
<Typography variant="body1" style={style.headerTypography}>
{title}
</Typography>
</Flex>
<Flex directionRow>
<Typography variant="body1" style={{ ...style.headerTypography, ...style.boldFont }}>
Progresso:
</Typography>
<ProgressValue />
</Flex>
</Flex>
<div style={style.divisor} />
<Flex directionRow justifySpaceBetween alignCenter>
<TrackStatus />
{statusText(status)}
</Flex>
</Box>
);
};
ProgressCard.propTypes = {
title: PropTypes.string,
icon: PropTypes.object,
progress: PropTypes.number.isRequired,
date: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
status: PropTypes.oneOf(['feedback', 'feedbackReady', 'confirmation']),
active: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
};
ProgressCard.defaultProps = {
title: '',
icon: null,
progress: 0,
date: new Date(),
status: 'feedback',
active: false,
onClick: () => {},
};
export { ProgressCard };