175 lines
6.4 KiB
TypeScript
175 lines
6.4 KiB
TypeScript
import { useCallback, useEffect, useState } from "react";
|
||
import styles from "./Campus.module.css";
|
||
import Banner from "@/components/Banner";
|
||
import Section from "@/components/layout/Section";
|
||
import { SearchOutlined, FilterOutlined, DownOutlined, RightOutlined } from "@ant-design/icons";
|
||
import { Empty, Select } from "antd";
|
||
import Pagination from "@/components/Pagination";
|
||
import { Link } from "react-router-dom";
|
||
import { debounce } from "@/utils";
|
||
|
||
type JobItem = {
|
||
id: number;
|
||
title: string;
|
||
content: string;
|
||
labels: string[];
|
||
}
|
||
|
||
export default function JoinCampus() {
|
||
const [searchValue, setSearchValue] = useState('');
|
||
|
||
// 职业类别 业务领域 所属板块
|
||
const [jobType, setJobType] = useState('');
|
||
const [jobTypeOptions, setJobTypeOptions] = useState([
|
||
{ label: "全部", value: "" },
|
||
{ label: "职业类别1", value: "1" },
|
||
{ label: "职业类别2", value: "2" },
|
||
{ label: "职业类别3", value: "3" },
|
||
]);
|
||
const [businessArea, setBusinessArea] = useState('');
|
||
const [businessAreaOptions, setBusinessAreaOptions] = useState([]);
|
||
const [businessPlate, setBusinessPlate] = useState('');
|
||
const [businessPlateOptions, setBusinessPlateOptions] = useState([]);
|
||
|
||
const [page, setPage] = useState(1);
|
||
const [size] = useState(9);
|
||
const [total, setTotal] = useState(1000);
|
||
|
||
|
||
const [jobList, setJobList] = useState<JobItem[]>([]);
|
||
|
||
const refreshData = useCallback(debounce(() => {
|
||
console.log('refreshData2');
|
||
setJobList([
|
||
{ id: 1, title: '职位1', content: '工作职责:1、为集团的各类投资项目提供法律支持,包括:组织外部律师进行尽职调查、审阅及起草交易文件、必要时参与法律谈判、提示法律风险等;2、协助完善集团本部的规章制度和合规体系;3、审阅集团各部门提交法务部审阅的日常业务法务部审阅的日常业务法务部审阅的日常业务', labels: ['标签1', '标签2'] },
|
||
{ id: 2, title: '职位2', content: '职位2内容', labels: ['标签1', '标签2'] },
|
||
{ id: 3, title: '职位3', content: '职位3内容', labels: ['标签1', '标签2'] },
|
||
])
|
||
}, 500), []);
|
||
|
||
useEffect(() => {
|
||
refreshData();
|
||
}, [searchValue, jobType, businessArea, businessPlate, page, size]);
|
||
|
||
const handleReset = useCallback(() => {
|
||
setSearchValue('');
|
||
setJobType('');
|
||
setBusinessArea('');
|
||
setBusinessPlate('');
|
||
setPage(1);
|
||
}, []);
|
||
|
||
return (
|
||
<div>
|
||
<Banner
|
||
title="招贤纳士"
|
||
titleSize="large"
|
||
showBreadcrumb={true}
|
||
breadcrumbItems={[{ label: '加入银泰', to: '/business' }, { label: '招贤纳士', to: '' }]}
|
||
backgroundImage={`/images/bg-overview.png`}
|
||
/>
|
||
|
||
<Section maskBackground="#FFFFFF">
|
||
<div className={styles.campusRow}>
|
||
<div className={styles.campusColLeft}>
|
||
<SearchInput value={searchValue} placeholder="搜索职位" onChange={setSearchValue} onEnter={refreshData} />
|
||
|
||
<SelectFormItem value={jobType} options={jobTypeOptions} label="职业类别" onChange={setJobType} />
|
||
<SelectFormItem value={businessArea} options={businessAreaOptions} label="业务领域" onChange={setBusinessArea} />
|
||
<SelectFormItem value={businessPlate} options={businessPlateOptions} label="所属板块" onChange={setBusinessPlate} />
|
||
|
||
<button className={styles.resetButton} onClick={handleReset}>重置</button>
|
||
</div>
|
||
<div className={styles.campusColRight}>
|
||
<div className={styles.jobList}>
|
||
{/* 没有数据时显示 */}
|
||
{jobList.length === 0 && (
|
||
<div className={styles.noData}>
|
||
<Empty description="暂无数据" />
|
||
</div>
|
||
)}
|
||
{jobList.map(item => (
|
||
<Link to={`/join/campus/detail/${item.id}`}>
|
||
<div key={item.id} className={styles.jobItem}>
|
||
<div className={styles.jobItemTitleRow}>
|
||
<div className={styles.jobItemTitle}>{item.title}</div>
|
||
<div className={styles.jobItemTitleRight}>查看详情 <RightOutlined /></div>
|
||
</div>
|
||
<div className={styles.jobItemLabels}>
|
||
{item.labels.map(label => (
|
||
<div key={label} className={styles.jobItemLabel}> • {label}</div>
|
||
))}
|
||
</div>
|
||
<div className={styles.jobItemContent}>{item.content}</div>
|
||
</div></Link>
|
||
))}
|
||
</div>
|
||
<Pagination total={total} size={size} page={page} onChange={setPage} />
|
||
</div>
|
||
</div>
|
||
</Section>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
|
||
type SearchInputProps = {
|
||
value: string;
|
||
placeholder: string;
|
||
onChange: (value: string) => void;
|
||
onEnter: () => void;
|
||
}
|
||
function SearchInput(
|
||
{ value, placeholder, onChange, onEnter }: SearchInputProps) {
|
||
return (
|
||
<div className={styles.searchInput}>
|
||
<label htmlFor="searchInput"><SearchOutlined className={styles.searchIcon} /></label>
|
||
<input
|
||
id="searchInput"
|
||
type="text"
|
||
placeholder={placeholder}
|
||
value={value}
|
||
onChange={e => onChange(e.target.value)}
|
||
onKeyDown={e => {
|
||
if (e.key === 'Enter') {
|
||
onEnter();
|
||
}
|
||
}}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
type SelectFormItemProps = {
|
||
value: string;
|
||
options: { label: string; value: string }[];
|
||
label: string;
|
||
onChange: (value: string) => void;
|
||
}
|
||
function SelectFormItem({ value, options, label, onChange }: SelectFormItemProps) {
|
||
return (
|
||
<div className={styles.selectFormItem}>
|
||
<label className={styles.selectFormItemLabel} htmlFor={`select-${label.replace(/\s/g, "-")}`}>{label}</label>
|
||
<div className={styles.selectFormItemBox}>
|
||
<Select
|
||
id={`select-${label.replace(/\s/g, "-")}`}
|
||
className={styles.selectFormItemSelect}
|
||
showSearch
|
||
placeholder="全部"
|
||
notFoundContent="无数据"
|
||
optionFilterProp="label"
|
||
filterOption={(input, opt) =>
|
||
(opt?.label ?? "").toString().toLowerCase().includes(input.toLowerCase())
|
||
}
|
||
options={options}
|
||
value={value}
|
||
onChange={v => onChange(v ?? "")}
|
||
prefix={<FilterOutlined className={styles.selectFilterIcon} />}
|
||
suffixIcon={<DownOutlined className={styles.selectDownIcon} />}
|
||
bordered={false}
|
||
/>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|