feat: first commit
This commit is contained in:
111
src/components/job-card/index.tsx
Normal file
111
src/components/job-card/index.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user