112 lines
3.6 KiB
TypeScript
112 lines
3.6 KiB
TypeScript
import { Image } from '@tarojs/components';
|
|
|
|
import classNames from 'classnames';
|
|
import React, { useCallback } from 'react';
|
|
|
|
import { CertificationStatusIcon } from '@/components/certification-status';
|
|
import { PageUrl } from '@/constants/app';
|
|
import { CITY_CODE_TO_NAME_MAP, COUNTY_CODE_TO_NAME_MAP } from '@/constants/city';
|
|
import { CertificationStatusType } from '@/constants/company';
|
|
import { EMPLOY_TYPE_TITLE_MAP, EmployType } from '@/constants/job';
|
|
import { JobInfo } from '@/types/job';
|
|
import { LocationInfo } from '@/types/location';
|
|
import { getJobSalary, getJobTitle } from '@/utils/job';
|
|
import { calcDistance } from '@/utils/location';
|
|
import { navigateTo, redirectTo } from '@/utils/route';
|
|
|
|
import './index.less';
|
|
|
|
interface IProps {
|
|
data: JobInfo;
|
|
redirectOpen?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
const PREFIX = 'job-card';
|
|
const getCityDes = (location: LocationInfo) => {
|
|
if (!location) {
|
|
return '';
|
|
}
|
|
let des = CITY_CODE_TO_NAME_MAP.get(location.cityCode);
|
|
if (location.countyCode) {
|
|
des += `-${COUNTY_CODE_TO_NAME_MAP.get(location.countyCode)}`;
|
|
}
|
|
return des;
|
|
};
|
|
|
|
function JobCard(props: IProps) {
|
|
const { className, data, redirectOpen } = props;
|
|
const {
|
|
id,
|
|
tags = [],
|
|
employType = EmployType.All,
|
|
jobDescription,
|
|
sourceText,
|
|
publisher,
|
|
publisherAvatar,
|
|
jobLocation,
|
|
distance,
|
|
isAuthed = false,
|
|
} = data;
|
|
|
|
const handleClickCard = useCallback(() => {
|
|
if (redirectOpen) {
|
|
redirectTo(PageUrl.JobDetail, { id });
|
|
} else {
|
|
navigateTo(PageUrl.JobDetail, { id });
|
|
}
|
|
}, [id, redirectOpen]);
|
|
|
|
return (
|
|
<div className={classNames(`${PREFIX}__container`, className)} onClick={handleClickCard}>
|
|
<div className={`${PREFIX}__header`}>
|
|
<div className={`${PREFIX}__title`}>{getJobTitle(data)}</div>
|
|
<div className={`${PREFIX}__employment-type__wrapper`}>
|
|
<div className={`${PREFIX}__employment-type`}>{EMPLOY_TYPE_TITLE_MAP[employType]}</div>
|
|
</div>
|
|
{isAuthed && (
|
|
<CertificationStatusIcon
|
|
className={`${PREFIX}__certification-type`}
|
|
status={CertificationStatusType.Success}
|
|
small
|
|
/>
|
|
)}
|
|
</div>
|
|
<div className={`${PREFIX}__tags`}>
|
|
{tags.map((keyword: string, index) => (
|
|
<div className={`${PREFIX}__tag`} key={index}>
|
|
{keyword}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className={`${PREFIX}__salary`}>{getJobSalary(data) || '见描述'}</div>
|
|
<div className={`${PREFIX}__content`}>
|
|
<div className={`${PREFIX}__summary`}>{jobDescription || sourceText}</div>
|
|
<div className={`${PREFIX}__distance-wrapper`}>
|
|
<div className={`${PREFIX}__detailed-address`}>{jobLocation?.address}</div>
|
|
{distance && (
|
|
<>
|
|
<Image className={`${PREFIX}__distance-icon`} src={require('@/statics/svg/location.svg')} />
|
|
<div className={`${PREFIX}__distance`}>{calcDistance(distance)}</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className={`${PREFIX}__divider`} />
|
|
<div className={`${PREFIX}__footer`}>
|
|
<div className={`${PREFIX}__publisher`}>
|
|
<Image
|
|
mode="aspectFit"
|
|
className={`${PREFIX}__publisher-avatar`}
|
|
src={publisherAvatar || require('@/statics/svg/wechat.svg')}
|
|
/>
|
|
<div className={`${PREFIX}__publisher-name`}>{publisher}</div>
|
|
</div>
|
|
<div className={`${PREFIX}__city`}>{getCityDes(jobLocation)}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default React.memo(JobCard);
|