UNPKG

@krowdy-ui/views

Version:

React components that implement Google's Material Design.

603 lines (583 loc) 19.1 kB
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import React from 'react'; import PropTypes from 'prop-types'; import XDate from 'xdate'; import { Typography, Button, Grid, Divider, List, ListItem, ListItemText, Chip, Paper, ListItemAvatar, Avatar } from '@krowdy-ui/core'; import BusinessIcon from '@material-ui/icons/Business'; import { withStyles } from '@krowdy-ui/styles'; import clsx from 'clsx'; import keyBy from '../utils/keyBy'; import { AccessTimeThin as AccessTimeThinIcon, AddCircleOutlinedThin as AddCircleOutlinedThinIcon, ComputerThin as ComputerThinIcon, DressHookThin as DressHookIcon, DriveEtaOutlinedThin as DriveEtaOutlinedThinIcon, EmojiPeopleOutlinedThin as EmojiPeopleOutlinedThinIcon, LanguageThin as LanguageThinIcon, PayrollThin as PayrollThinIcon, PetsOutlinedThin as PetsOutlinedThinIcon, TrainingThin as TrainingThinIcon } from '@krowdy-ui/icons'; export const styles = theme => ({ avatar: { backgroundColor: 'transparent', color: theme.palette.secondary[200], height: 26, width: 26 }, benefitList: { display: 'grid', gap: theme.spacing(1), gridTemplateColumns: '1fr', [theme.breakpoints.up('sm')]: { gridTemplateColumns: '1fr 1fr' } }, btnPostular: {}, chips: { '&:nth-last-child(1)': { marginRight: 0 }, margin: '5px 5px 5px 0', maxWidth: '100%' }, contentCompany: { '& > a': { marginLeft: theme.spacing(1) }, alignItems: 'flex-end', display: 'flex', [theme.breakpoints.down('xs')]: { alignItems: 'center' } }, contentCompanyLogo: { '& > img': { display: 'block', width: '100%' }, alignItems: 'center', backgroundColor: theme.palette.secondary[10] || '#F2F4F7', border: '1px solid rgb(234, 234, 234)', borderRadius: 6, display: 'flex', height: 47, justifyContent: 'center', width: 47 }, contentJobDetail: { '& > *': { margin: theme.spacing(2, 0) }, [theme.breakpoints.down('xs')]: { marginLeft: theme.spacing(2), marginRight: theme.spacing(2), paddingBottom: theme.spacing(5) }, backgroundColor: 'white', margin: theme.spacing(0, 5), padding: theme.spacing(1.5), width: '100%' }, contentOptions: { '& > div': { alignItems: 'center', color: theme.palette.primary.main, display: 'flex' }, display: 'flex', flexWrap: 'wrap' }, contentTitle: { display: 'flex' }, custom: { backgroundColor: 'white', bottom: 0, display: 'none', flex: '1 1 0', left: 0, position: 'fixed', right: 0, width: '100%', zIndex: 1 }, defaultBtnPostular: { [theme.breakpoints.down('xs')]: { backgroundColor: 'white', bottom: 0, flex: '1 1 0', left: 0, padding: theme.spacing(2), position: 'fixed', right: 0, width: '100%', zIndex: 1 }, '& button': { [theme.breakpoints.down('xs')]: { width: '100%' } }, alignItems: 'flex-end', display: 'flex', flex: '1 0 1', flexDirection: 'column' }, descriptionEmpty: { '& > img': { maxWidth: '100%' }, alignItems: 'center', display: 'flex', flexDirection: 'column' }, fixedCard: { [theme.breakpoints.down('xs')]: { '& $custom': { display: 'block' }, '& $defaultBtnPostular': { display: 'none' } } }, gridDescription: { '@media (min-width: 767px)': { marginTop: theme.spacing(7.5) }, marginTop: theme.spacing(3.5) }, headerJob: { display: 'flex', flexDirection: 'column', [theme.breakpoints.up('sm')]: { flexDirection: 'row' } }, headerLeft: { flex: '1' }, iconCompany: { // color: '#595959' color: theme.palette.secondary[200] || '#99A9C2' }, iconDetail: { marginRight: theme.spacing(1) }, itemList: { '& > div': { fontWeight: 'normal', wordBreak: 'break-word' }, display: 'list-item', fontSize: '.8rem', fontWeight: 'bold', padding: theme.spacing(.75), wordBreak: 'break-word' }, itemOptions: { marginRight: theme.spacing(2.5), marginTop: theme.spacing(1) }, list: { display: 'block', listStyleType: 'disc', margin: 0, paddingLeft: theme.spacing(5) }, listCompetitions: { display: 'list-item', fontSize: '.8rem', fontWeight: 'normal', padding: theme.spacing(.75), wordBreak: 'break-word' }, listItem: { border: `1px solid ${theme.palette.secondary[50]}`, borderRadius: theme.shape.borderRadius, padding: theme.spacing(1.5) }, listItemAvatar: { minWidth: 36 }, sectionInformation: { margin: theme.spacing(5, 0) }, seeMoreCompany: { color: theme.palette.primary.main, cursor: 'pointer', fontSize: '.8rem', marginLeft: theme.spacing(1.25) }, subTitle: { color: theme.palette.grey[600], fontSize: 10, marginTop: theme.spacing(1), textAlign: 'center', width: 145 }, svgIcon: { color: theme.palette.secondary[200] }, textDescription: { fontSize: '.8rem', marginTop: theme.spacing(1.5), wordBreak: 'break-word' }, textDetail: { fontSize: '.8rem' }, textEndJob: { fontSize: 12, marginTop: theme.spacing(.5), paddingRight: theme.spacing(.5) }, titleCompany: { '&.no-visible': { fontSize: '1rem' }, fontSize: '1.4rem', fontWeight: 'bold', lineHeight: 1, marginLeft: theme.spacing(1) }, titleJob: { // '&:first-letter': { // textTransform: 'uppercase' // }, fontSize: '2.5rem', // textTransform : 'lowercase', [theme.breakpoints.down('xs')]: { fontSize: 44 }, wordBreak: 'break-word' }, titleSection: { fontSize: '1.2rem' } }); const Div = _ref => { let { children } = _ref, props = _objectWithoutPropertiesLoose(_ref, ["children"]); return /*#__PURE__*/React.createElement("div", props, children); }; var _ref2 = /*#__PURE__*/React.createElement(Divider, null); var _ref3 = /*#__PURE__*/React.createElement("img", { alt: "without-description", src: "//s3.amazonaws.com/cdn.krowdy.com/media/images/empty-job.png" }); var _ref4 = /*#__PURE__*/React.createElement(Typography, { align: "center", color: "info", variant: "body3" }, "Sin descripci\xF3n"); var _ref5 = /*#__PURE__*/React.createElement(Divider, null); var _ref6 = /*#__PURE__*/React.createElement(Divider, null); const JobDetail = props => { const { hiddenButton, jobId, classes, title, competencies = [], closed, description, basicEdition, benefits = [], userInJob = false, company = {}, detailJob = [], expirationDate, disabledPerson: { visible: visibleDisabled, accepted: acceptedDisabled } = {}, requirements = [], onClickPostulation = () => {}, onViewCompany, visibleInformation = false, variant, fixedCard, fixedCardCustomComponent, fixedCardCustomStyle = {}, customTitleButton, subTitle, isPreview, hiddenHeaderJob } = props; const [imageFailed, setImageFailed] = React.useState(false); React.useEffect(() => { setImageFailed(false); }, [jobId]); let timeToDown, isFinalized; if (expirationDate) { const expDate = new XDate(expirationDate); // DEVUELVE 2019-12-29 10:38:20 const expDateFormat = new XDate(expDate.getFullYear(), expDate.getMonth(), expDate.getDate()); // DEVUELVE 2019-12-29 const today = new XDate(); // DEVUELVE 2019-12-30 10:38:20 const todayFormat = new XDate(today.getFullYear(), today.getMonth(), today.getDate()); // DEVUELVE 2019-12-30 timeToDown = todayFormat.diffDays(expDateFormat); isFinalized = expirationDate ? new XDate().getTime() >= new XDate(Number(expirationDate)).getTime() : false; } const renderItemRequirement = requirement => { switch (requirement.title.toLowerCase()) { case 'carreras': return requirement.value.map((career, indexCareer) => /*#__PURE__*/React.createElement(Chip // className={classes.requirementsChip} , { className: classes.chips, color: "primary", key: `career-${indexCareer}`, label: career, size: "small", variant: "outlined" })); case 'idioma': return requirement.value.map((idioma, indexIdioma) => /*#__PURE__*/React.createElement(Typography // className={classes.requirementsSubtitle} // component='span' , { key: `idioma-${indexIdioma}` }, idioma)); default: return requirement.value; } }; const handleErrorImage = () => { setImageFailed(true); }; const CustomComponent = React.useMemo(() => fixedCardCustomComponent ? fixedCardCustomComponent : 'div', [fixedCardCustomComponent]); const iconByTitle = React.useMemo(() => keyBy([{ icon: /*#__PURE__*/React.createElement(LanguageThinIcon, { className: classes.svgIcon }), title: 'Trabajo remoto' }, { icon: /*#__PURE__*/React.createElement(PayrollThinIcon, { className: classes.svgIcon }), title: 'Planilla' }, { icon: /*#__PURE__*/React.createElement(AddCircleOutlinedThinIcon, { className: classes.svgIcon }), title: 'Seguro de Salud' }, { icon: /*#__PURE__*/React.createElement(AccessTimeThinIcon, { className: classes.svgIcon }), title: 'Horario flexible' }, { icon: /*#__PURE__*/React.createElement(ComputerThinIcon, { className: classes.svgIcon }), title: 'Computadora' }, { icon: /*#__PURE__*/React.createElement(TrainingThinIcon, { className: classes.svgIcon }), title: 'Capacitaciones' }, { icon: /*#__PURE__*/React.createElement(DressHookIcon, { className: classes.svgIcon }), title: 'Vestimenta informal' }, { icon: /*#__PURE__*/React.createElement(DriveEtaOutlinedThinIcon, { className: classes.svgIcon }), title: 'Estacionamiento' }, { icon: /*#__PURE__*/React.createElement(EmojiPeopleOutlinedThinIcon, { className: classes.svgIcon }), title: 'Actividades recreativas' }, { icon: /*#__PURE__*/React.createElement(PetsOutlinedThinIcon, { className: classes.svgIcon }), title: 'Empresa pet friendly' }], 'title'), [classes.svgIcon]); const ContainerRoot = React.useMemo(() => isPreview ? Div : Paper, [isPreview]); const basicEditionFiltered = React.useMemo(() => !basicEdition ? null : basicEdition.filter(({ visible, description }) => visible && description), [basicEdition]); const filteredBenefits = React.useMemo(() => benefits.filter(({ title }) => title), [benefits]); return /*#__PURE__*/React.createElement(ContainerRoot, { className: classes.contentJobDetail, variant: variant }, !hiddenHeaderJob && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Grid, { container: true }, /*#__PURE__*/React.createElement(Grid, { item: true, xs: 12 }, /*#__PURE__*/React.createElement("div", { className: classes.headerJob }, /*#__PURE__*/React.createElement("div", { className: classes.headerLeft }, /*#__PURE__*/React.createElement(Typography, { className: classes.titleJob, variant: "h1" }, title)), !isPreview ? /*#__PURE__*/React.createElement("div", { className: clsx(fixedCard && classes.fixedCard) }, /*#__PURE__*/React.createElement("div", { className: classes.defaultBtnPostular }, !hiddenButton && /*#__PURE__*/React.createElement(Button, { color: "primary", disabled: isFinalized === undefined ? closed : isFinalized || closed, onClick: onClickPostulation, size: "large", variant: "contained" }, customTitleButton ? customTitleButton : closed || isFinalized ? 'Finalizado' : userInJob ? 'Ver postulación' : 'Postular'), subTitle ? /*#__PURE__*/React.createElement(Typography, { className: classes.subTitle }, subTitle) : null, isFinalized === undefined ? null : timeToDown > 0 && timeToDown <= 14 ? /*#__PURE__*/React.createElement(Typography, { className: classes.textEndJob, component: "span" }, "Finaliza ", `en ${timeToDown} día${timeToDown === 1 ? '' : 's'}`, ".") : timeToDown === 0 && !isFinalized ? /*#__PURE__*/React.createElement(Typography, { className: classes.textEndJob, variant: "subtitle2" }, "Finaliza hoy") : null), /*#__PURE__*/React.createElement(CustomComponent, { className: classes.custom, style: fixedCardCustomStyle }, fixedCard)) : null))), /*#__PURE__*/React.createElement(Grid, { item: true, xs: 12 }, /*#__PURE__*/React.createElement("div", { className: classes.contentCompany }, /*#__PURE__*/React.createElement("div", { className: classes.contentCompanyLogo }, company.company_logo && visibleInformation && !imageFailed ? /*#__PURE__*/React.createElement("img", { alt: "company logo", onError: handleErrorImage, src: company.company_logo }) : /*#__PURE__*/React.createElement(BusinessIcon, { className: classes.iconCompany })), !visibleInformation ? /*#__PURE__*/React.createElement(Typography, { className: `${classes.titleCompany} no-visible` }, "Confidencial") : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, { className: classes.titleCompany }, company.company_name), onViewCompany && !isPreview ? /*#__PURE__*/React.createElement(Typography, { className: classes.seeMoreCompany, onClick: onViewCompany }, "Ver m\xE1s") : null))), description ? /*#__PURE__*/React.createElement(Grid, { item: true }, typeof description === 'object' ? description : /*#__PURE__*/React.createElement(Typography, { className: classes.textDescription, component: "div", dangerouslySetInnerHTML: { __html: description }, variant: "body3" })) : null, /*#__PURE__*/React.createElement(Grid, { className: classes.contentOptions, item: true, xs: 12 }, detailJob.map(({ icon, text }, index) => /*#__PURE__*/React.createElement("div", { className: classes.itemOptions, key: `option-${index}` }, /*#__PURE__*/React.createElement(Typography, { className: classes.iconDetail }, icon), /*#__PURE__*/React.createElement(Typography, { className: classes.textDetail, color: "body", variant: "h6" }, text))))), filteredBenefits.length ? /*#__PURE__*/React.createElement(React.Fragment, null, !hiddenHeaderJob && _ref2, /*#__PURE__*/React.createElement("section", { className: classes.sectionInformation }, /*#__PURE__*/React.createElement(Typography, { className: classes.titleSection, variant: "h5" }, "Beneficios"), /*#__PURE__*/React.createElement(List, { className: classes.benefitList }, filteredBenefits.map(({ title }, index) => /*#__PURE__*/React.createElement(ListItem, { className: classes.listItem, key: `benefit-${index}` }, /*#__PURE__*/React.createElement(ListItemAvatar, { className: classes.listItemAvatar }, /*#__PURE__*/React.createElement(Avatar, { className: classes.avatar }, iconByTitle[title] ? iconByTitle[title].icon : /*#__PURE__*/React.createElement(LanguageThinIcon, { className: classes.svgIcon }))), /*#__PURE__*/React.createElement(ListItemText, { primary: title, primaryTypographyProps: { variant: 'body2' } })))))) : null, !basicEditionFiltered ? null : /*#__PURE__*/React.createElement(Grid, { className: classes.gridDescription, item: true, xs: 12 }, basicEditionFiltered.length > 0 ? basicEditionFiltered.map((item, key) => /*#__PURE__*/React.createElement("section", { className: classes.sectionInformation, key: `information-${key}` }, /*#__PURE__*/React.createElement(Typography, { className: classes.titleSection, variant: "h4" }, item.title), item.description ? /*#__PURE__*/React.createElement(Typography, { className: classes.textDescription, component: "div", dangerouslySetInnerHTML: { __html: item.description }, variant: "body2" }) : null)) : hiddenHeaderJob ? null : /*#__PURE__*/React.createElement("div", { className: classes.descriptionEmpty }, _ref3, _ref4)), competencies.length ? /*#__PURE__*/React.createElement(React.Fragment, null, _ref5, /*#__PURE__*/React.createElement("section", { className: classes.sectionInformation }, /*#__PURE__*/React.createElement(Typography, { className: classes.titleSection, variant: "h5" }, "Competencias"), /*#__PURE__*/React.createElement(List, { className: classes.list }, competencies.map((competency, index) => /*#__PURE__*/React.createElement(ListItem, { className: classes.listCompetitions, key: `competency-${index}` }, competency.title))))) : null, requirements.length || visibleDisabled ? /*#__PURE__*/React.createElement(React.Fragment, null, _ref6, /*#__PURE__*/React.createElement("section", { className: classes.sectionInformation }, /*#__PURE__*/React.createElement(Typography, { className: classes.titleSection, variant: "h5" }, "Requerimientos"), /*#__PURE__*/React.createElement(List, { className: classes.list }, requirements.map((requirement, index) => /*#__PURE__*/React.createElement(ListItem, { className: classes.itemList, key: `requirement-${index}` }, requirement.title, /*#__PURE__*/React.createElement("div", null, renderItemRequirement(requirement)))), visibleDisabled ? /*#__PURE__*/React.createElement(ListItem, { className: classes.itemList }, "Apto para discapacitados", /*#__PURE__*/React.createElement("div", null, acceptedDisabled ? 'Si' : 'No')) : null))) : null); }; process.env.NODE_ENV !== "production" ? JobDetail.propTypes = { basicEdition: PropTypes.array, benefits: PropTypes.array, /** * Override or extend the styles applied to the component. * See [CSS API](#css) below for more details. */ classes: PropTypes.object, closed: PropTypes.bool, company: PropTypes.object, competencies: PropTypes.array, customTitleButton: PropTypes.string, description: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), // _id detailJob: PropTypes.array, disabledPerson: PropTypes.object, expirationDate: PropTypes.string, fixedCard: PropTypes.node, fixedCardCustomComponent: PropTypes.node, fixedCardCustomStyle: PropTypes.object, hiddenButton: PropTypes.bool, hiddenHeaderJob: PropTypes.bool, isPreview: PropTypes.bool, jobId: PropTypes.string, onClickPostulation: PropTypes.func, // status: PropTypes.string onViewCompany: PropTypes.func, requirements: PropTypes.array, subTitle: PropTypes.string, title: PropTypes.string, userInJob: PropTypes.bool, variant: PropTypes.string, visibleInformation: PropTypes.bool } : void 0; JobDetail.muiName = 'JobDetail'; export default withStyles(styles, { name: 'KrowdyJobDetail' })(JobDetail);