150 lines
4.2 KiB
TypeScript
150 lines
4.2 KiB
TypeScript
'use client'
|
||
import React, { useState, useEffect } from 'react';
|
||
import { useQuery } from 'react-query';
|
||
import { fetchHardSkills, searchStudents } from '@/api/api';
|
||
import { Input, Button, Spin, List, Select, Card } from 'antd';
|
||
import { SearchOutlined } from '@ant-design/icons';
|
||
import style from './SearchResume.module.scss';
|
||
import { ResumeDataWithoutSkills } from '@/types/types';
|
||
|
||
const { Option } = Select;
|
||
|
||
const SearchResume: React.FC = () => {
|
||
const [year, setYear] = useState<number | undefined>();
|
||
const [time, setTime] = useState<string[]>([]);
|
||
const [hardskills, setHardskills] = useState<string[]>([]);
|
||
const [searchResults, setSearchResults] = useState<
|
||
ResumeDataWithoutSkills[] | null
|
||
>(null);
|
||
|
||
// Функция для формирования строки запроса
|
||
const buildQueryParams = () => {
|
||
const params = new URLSearchParams();
|
||
|
||
if (year !== undefined) {
|
||
params.append('year', year.toString());
|
||
}
|
||
|
||
if (time.length > 0) {
|
||
time.forEach(t => params.append('time', t));
|
||
}
|
||
|
||
if (hardskills.length > 0) {
|
||
hardskills.forEach(skill => params.append('hardskills', skill));
|
||
}
|
||
|
||
return params.toString();
|
||
};
|
||
|
||
const { data, error, isLoading, refetch } = useQuery<
|
||
ResumeDataWithoutSkills[]
|
||
>(
|
||
['searchStudents', buildQueryParams()],
|
||
() => {
|
||
const queryString = buildQueryParams();
|
||
return searchStudents(queryString);
|
||
},
|
||
{ enabled: false, refetchOnWindowFocus: false, retry: false }
|
||
);
|
||
|
||
const { data: hardSkills } = useQuery(
|
||
['hardSkills'],
|
||
() => fetchHardSkills(),
|
||
{
|
||
refetchOnWindowFocus: false,
|
||
retry: false,
|
||
}
|
||
);
|
||
|
||
// Используем useEffect для обновления searchResults, когда запрос завершен
|
||
useEffect(() => {
|
||
if (data) {
|
||
setSearchResults(data);
|
||
}
|
||
}, [data]);
|
||
|
||
const handleSearch = () => {
|
||
refetch();
|
||
};
|
||
|
||
return (
|
||
<div className={style.container}>
|
||
<div className={style.form}>
|
||
<Select
|
||
placeholder='Выберите Курс'
|
||
style={{ width: '100%', marginBottom: 20 }}
|
||
onChange={value => setYear(value)}
|
||
value={year}
|
||
>
|
||
<Option value={1}>1</Option>
|
||
<Option value={2}>2</Option>
|
||
<Option value={3}>3</Option>
|
||
<Option value={4}>4</Option>
|
||
</Select>
|
||
|
||
<Select
|
||
mode='multiple'
|
||
placeholder='Выберите занятость'
|
||
style={{ width: '100%', marginBottom: 20 }}
|
||
onChange={value => setTime(value)}
|
||
value={time}
|
||
>
|
||
<Option value='20'>20</Option>
|
||
<Option value='30'>30</Option>
|
||
<Option value='40'>40</Option>
|
||
</Select>
|
||
|
||
<Select
|
||
mode='multiple'
|
||
style={{ width: '100%', marginBottom: 20 }}
|
||
placeholder='Выбрать hardskills'
|
||
onChange={value => setHardskills(value)}
|
||
value={hardskills}
|
||
>
|
||
{hardSkills?.map(skill => (
|
||
<Option key={skill.Hard_skillID} value={skill.Title}>
|
||
{skill.Title}
|
||
</Option>
|
||
))}
|
||
</Select>
|
||
|
||
<Button type='primary' onClick={handleSearch} style={{ width: '100%' }} className={style.search_button}>
|
||
Поиск
|
||
</Button>
|
||
</div>
|
||
|
||
<div style={{ marginTop: 20, color: 'white' }}>
|
||
{isLoading && <Spin size='large' className={style.spin}/>}
|
||
{searchResults && searchResults.length > 0 ? (
|
||
<div className={style.card_wrapper}>
|
||
{searchResults.map((item: ResumeDataWithoutSkills) => (
|
||
<Card
|
||
key={item.Email}
|
||
title={item.Name}
|
||
className={style.card}
|
||
bordered={false}
|
||
style={{ marginBottom: 20 }}
|
||
>
|
||
<p className={style.item}>Тип: {item.Type}</p>
|
||
<p className={style.item}>Группа: {item.Group}</p>
|
||
<p className={style.item}>Занятость: {item.Time.join(', ')}</p>
|
||
<p className={style.item}>Soft Skills: {item.Soft_skills}</p>
|
||
<p className={style.item}>Номер телефона: {item.Phone_number}</p>
|
||
<p className={style.item}>Факультет: {item.Faculties}</p>
|
||
<p className={style.item}>
|
||
Ссылка: <a href={item.Link}>{item.Link}</a>
|
||
</p>
|
||
<p className={style.item}>Email: {item.Email}</p>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
) : (
|
||
!isLoading && <div className={style.empty}>Резюме не найдены</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default SearchResume;
|