Files
Tg-job/mtucijobsweb2/fsd/widgets/SearchResume/SearchResume.tsx

150 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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;