Files
Tg-job/mtucijobsweb/fsd/widgets/Search/SearchWidget.tsx

176 lines
5.5 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 { searchJobs } from '@/api/api';
import { Input, Button, Spin, List, Select, Checkbox, InputNumber, Card } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import style from './SearchWidget.module.scss';
import { JobData } from '@/types/types';
import { skillsOptions } from '@/fsd/entities/Resume/data';
import { initThemeParams } from '@tma.js/sdk-react';
const { Option } = Select;
const SearchWidget: React.FC = () => {
const [query, setQuery] = useState('');
const [year, setYear] = useState<number | undefined>();
const [qualification, setQualification] = useState<boolean | undefined>();
const [time, setTime] = useState<string[]>([]);
const [salary, setSalary] = useState<number | undefined>();
const [hardskills, setHardskills] = useState<string[]>([]);
const [searchResults, setSearchResults] = useState<JobData[]>([]);
const [themeParams] = initThemeParams();
// Функция для формирования объекта параметров
const buildQueryParams = () => {
const params: any = {}; // Или укажите более точный тип, соответствующий JobsSearch
if (year !== undefined) {
params.year = year;
}
if (qualification !== undefined) {
params.qualification = qualification;
}
if (time.length > 0) {
params.time = time; // здесь может потребоваться изменить на массив строк
}
if (salary !== undefined) {
params.salary = salary;
}
if (hardskills.length > 0) {
params.hardskills = hardskills;
}
if (query) {
params.search = query;
}
return params; // Возвращаем объект вместо строки
};
// Вызов useQuery с объектом
const { data, error, isLoading, refetch } = useQuery<JobData[]>(
['searchJobs', buildQueryParams()],
() => {
const queryParams = buildQueryParams(); // Получаем объект параметров
return searchJobs(queryParams); // Передаём объект в функцию
},
{ enabled: false, refetchOnWindowFocus: false, retry: false }
);
// Используем useEffect для обновления searchResults, когда запрос завершен
useEffect(() => {
if (data) {
setSearchResults(data);
}
}, [data]);
const handleSearch = () => {
refetch();
};
if (isLoading) return <Spin size='large' className={style.spin} />;
if (error)
return <div className={style.error}>Ошибка при поиске вакансий</div>;
return (
<div className={style.container}>
<div className={style.form}>
<Input
placeholder='Поиск по названию вакансии или компании...'
value={query}
onChange={e => setQuery(e.target.value)}
prefix={<SearchOutlined />}
style={{ marginBottom: 20 }}
/>
<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>
<Checkbox
checked={qualification}
onChange={e => setQualification(e.target.checked)}
style={{ marginBottom: 20, color: themeParams.textColor }}
>
Требуется квалификация
</Checkbox>
<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>
<InputNumber
placeholder='Минимальная зарплата'
value={salary}
onChange={value => setSalary(value !== null ? value : undefined)}
style={{ width: '100%', marginBottom: 20 }}
/>
<Select
mode='multiple'
placeholder='Выберите hard skills'
style={{ width: '100%', marginBottom: 20 }}
onChange={value => setHardskills(value)}
value={hardskills}
options={skillsOptions.map(skill => ({ value: skill, label: skill }))}
/>
<Button type='primary' onClick={handleSearch} style={{ width: '100%' }}>
Поиск
</Button>
</div>
<div style={{ marginTop: 20 }}>
{isLoading && <Spin size='large' />}
{searchResults.length > 0 ? (
<div className={style.cardWrapper}>
{searchResults.map((item: JobData) => (
<Card
key={item.Email} // Предположим, что Email уникален для вакансий
title={item.Job_name}
bordered={false}
style={{ marginBottom: 20 }}
className={style.card}
>
<p>Год: {item.Year}</p>
<p>Квалификация: {item.Qualification ? 'Да' : 'Нет'}</p>
<p>Зарплата: {item.Salary}</p>
<p>Soft Skills: {item.Soft_skills}</p>
<p>Обязанности: {item.Responsibilities}</p>
<p>
Email: <a href={`mailto:${item.Email}`}>{item.Email}</a>
</p>
</Card>
))}
</div>
) : (
!isLoading && (
<div style={{ color: themeParams.textColor }}>
Вакансии не найдены
</div>
)
)}
</div>
</div>
);
};
export default SearchWidget;