Files
boluo-app-main/src/components/job-card/index.tsx
2025-03-31 22:34:22 +08:00

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);