UNPKG

@eureca/eureca-ui

Version:

UI component library of Eureca's user and admin apps

232 lines (211 loc) 6.28 kB
import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { format } from 'date-fns'; import { ptBR } from 'date-fns/locale'; import { Box, Grid, Typography, useTheme } from '@material-ui/core/'; import { FiChevronLeft } from 'react-icons/fi'; import { useWindowSize } from '../../hooks/useWindowSizeSSR'; import { colors } from '../../theme/colors'; import { Flex } from '../Flex'; import { Avatar } from '../Avatar'; function MessageCard({ message = {}, isActive, onClick = () => {}, isMobile }) { const { title, date, sender } = message; return ( <Flex directionRow alignCenter justifySpaceBetween cursorPointer p={2} mb={[1, 0]} bgcolor={isActive ? colors.white : colors.gray5} style={{ border: isMobile ? `2px solid ${colors.gray5}` : `1px solid ${colors.white}`, borderRadius: isMobile ? 4 : 0, }} onClick={onClick} > <Box> <Box mb={1}> <Typography variant={isMobile ? 'h6' : 'body1'} style={{ color: isActive ? colors.gray2 : colors.gray3 }} > {title.length > 33 ? `${title.slice(0, 33)}...` : title} </Typography> </Box> <Typography variant="body2" style={{ fontSize: isMobile ? '.875rem' : '.625rem', color: colors.gray3, }} > {format(date, 'dd, MMMM, yyyy', { locale: ptBR })} </Typography> </Box> <Avatar name={sender.name} size={isMobile ? 48 : 36} src={sender.avatar} /> </Flex> ); } MessageCard.propTypes = { message: PropTypes.shape({ title: PropTypes.string, date: PropTypes.instanceOf(Date), sender: PropTypes.shape({ name: PropTypes.string, avatar: PropTypes.string, }), }), isActive: PropTypes.bool, onClick: PropTypes.func, isMobile: PropTypes.bool, }; function MessageHeader({ sender, date }) { return ( <Flex directionRow alignCenter> <Box mr={1}> <Avatar name={sender.name} src={sender.avatar} /> </Box> <Flex width={1} flexDirection={['column', 'row']} justifyContent={['initial', 'space-between']} > <Flex directionRow alignCenter> <Typography style={{ marginRight: 4 }}>{sender.name}</Typography> <Typography style={{ color: colors.gray3 }}>{`<${sender.email}>`}</Typography> </Flex> <Typography variant="body2" style={{ fontSize: '.875rem', lineHeight: 2, color: colors.gray3 }} > {format(date, 'dd, MMMM, yyyy', { locale: ptBR })} </Typography> </Flex> </Flex> ); } MessageHeader.propTypes = { sender: PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), name: PropTypes.string, email: PropTypes.string, avatar: PropTypes.string, }), date: PropTypes.object, }; function MessagePanel({ message }) { const { title = '', sender = {}, date = new Date(), body = '' } = message; const theme = useTheme(); return ( <Flex py={4} px={6} border={`1px solid ${colors.gray5}`} bgcolor={colors.white}> <Typography variant="body1">{title}</Typography> <MessageHeader sender={sender} date={date} /> <Typography style={{ fontSize: '.625rem', fontWeight: theme.typography.fontWeightLight, lineHeight: 2 }} > {body} </Typography> </Flex> ); } MessagePanel.propTypes = { message: PropTypes.object, title: PropTypes.string, sender: PropTypes.object, date: PropTypes.object, body: PropTypes.any, }; function MessagePanelMobile({ message, onClose }) { const { title = '', sender = {}, date = new Date(), body = '' } = message; const theme = useTheme(); return ( <Flex position="fixed" top={0} left={0} width={1} height={1} zIndex={999} px={2} pb={5} bgcolor={colors.white} border={`1px solid ${colors.gray5}`} > <Flex my={4} width={32} height={32} justifyCenter alignCenter cursorPointer onClick={onClose}> <FiChevronLeft size="32" /> </Flex> <Box px={2}> <Typography variant="body1" style={{ fontSize: '2rem', lineHeight: 1.5 }}> {title} </Typography> <Box mt={3} mb={3}> <MessageHeader sender={sender} date={date} /> </Box> </Box> <Typography variant="body1" style={{ fontWeight: theme.typography.fontWeightLight, overflowY: 'auto' }} > {body} </Typography> </Flex> ); } MessagePanelMobile.propTypes = { message: PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), title: PropTypes.string, sender: PropTypes.object, date: PropTypes.object, body: PropTypes.any, }), onClose: PropTypes.func, }; function Messages({ data = [], ...props }) { const theme = useTheme(); const size = useWindowSize(); const isMobile = size?.width < theme.breakpoints.values.sm; const [activeMessage, setActiveMessage] = useState(isMobile ? null : 0); const toggleMessage = index => setActiveMessage(index); useEffect(() => { setActiveMessage(isMobile ? null : 0); }, [isMobile]); return ( <Grid container style={{ overflow: 'hidden', borderRadius: 4 }} {...props}> <Grid item xs={12} sm={4}> {data.map((item, index) => { return ( <MessageCard key={item.id} message={item} isActive={index === activeMessage || isMobile} isMobile={isMobile} onClick={e => { e.stopPropagation(); toggleMessage(index); }} /> ); })} </Grid> {activeMessage !== null && ( <Grid item xs={12} sm={8}> {isMobile ? ( <MessagePanelMobile message={data[activeMessage]} onClose={() => setActiveMessage(null)} /> ) : ( <MessagePanel message={data[activeMessage]} /> )} </Grid> )} </Grid> ); } Messages.propTypes = { data: PropTypes.array, }; export { Messages };