copied the code from the working repo
This commit is contained in:
149
mtucijobsweb2/fsd/widgets/SearchResume/SearchResume.tsx
Normal file
149
mtucijobsweb2/fsd/widgets/SearchResume/SearchResume.tsx
Normal file
@@ -0,0 +1,149 @@
|
||||
'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;
|
||||
Reference in New Issue
Block a user