207 lines
5.3 KiB
TypeScript
207 lines
5.3 KiB
TypeScript
'use client';
|
||
import { useMutation, useQuery } from 'react-query';
|
||
import { deleteJob, fetchJobs, updateJob } from '../../../api/api';
|
||
import { Card, Spin, Alert, Button, notification } from 'antd';
|
||
import { ExtendedJobData } from '@/types/types';
|
||
import { queryClient } from '@/fsd/app/provider/QueryClient';
|
||
import { useRouter } from 'next/navigation';
|
||
import style from './ViewVacansy.module.scss';
|
||
|
||
const ViewVacansy = () => {
|
||
const router = useRouter();
|
||
|
||
const { data, error, isLoading } = useQuery<ExtendedJobData[]>(
|
||
'jobs',
|
||
fetchJobs,
|
||
{
|
||
refetchOnWindowFocus: false,
|
||
retry: false,
|
||
}
|
||
);
|
||
|
||
const mutation = useMutation(deleteJob, {
|
||
onSuccess: () => {
|
||
// Обновление списка вакансий после удаления
|
||
queryClient.invalidateQueries('jobs');
|
||
},
|
||
});
|
||
|
||
const archiveMutation = useMutation(
|
||
(job: ExtendedJobData) =>
|
||
updateJob(job.JobID, {
|
||
...job,
|
||
Archive: !job.Archive,
|
||
Hardskills: [],
|
||
}),
|
||
{
|
||
onSuccess: () => {
|
||
queryClient.invalidateQueries('jobs');
|
||
},
|
||
onError: () => {
|
||
notification.error({
|
||
message: 'Ошибка',
|
||
description: 'Не удалось снять вакансию с публикации',
|
||
});
|
||
},
|
||
}
|
||
);
|
||
|
||
const handleArchive = (job: ExtendedJobData) => {
|
||
archiveMutation.mutate(job);
|
||
};
|
||
|
||
const handleDelete = (id: number) => {
|
||
mutation.mutate(id);
|
||
};
|
||
|
||
const handleClick = (id: number) => {
|
||
router.push(`/resume/${id}`);
|
||
};
|
||
|
||
const handleEdit = (id: number) => {
|
||
router.push(`/editvacansy/${id}`);
|
||
};
|
||
|
||
if (isLoading) return <Spin size='large' className={style.spin} />;
|
||
if (error) {
|
||
return <div className={style.empty}>Нет доступных вакансий</div>;
|
||
}
|
||
|
||
// Разделение данных на активные и архивные вакансии
|
||
const activeJobs = data?.filter(job => !job.Archive);
|
||
const archivedJobs = data?.filter(job => job.Archive);
|
||
console.log(activeJobs);
|
||
return (
|
||
<div style={{ padding: '20px' }}>
|
||
<h3 className={style.text}>Активные вакансии:</h3>
|
||
<div
|
||
className={style.card_wrapper}
|
||
style={{
|
||
display: 'grid',
|
||
gap: '20px',
|
||
gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
|
||
}}
|
||
>
|
||
{activeJobs?.map((job, index) => (
|
||
<Card
|
||
key={index}
|
||
title={job.Job_name}
|
||
bordered={false}
|
||
className={style.card}
|
||
>
|
||
{/* Контент вакансии */}
|
||
<p>
|
||
<strong>Название компании:</strong> {job.Company_name}
|
||
</p>
|
||
<p>
|
||
<strong>Курс:</strong> {job.Year}
|
||
</p>
|
||
|
||
<p>
|
||
<strong>Квалификация:</strong>{' '}
|
||
{job.Qualification ? 'Нужна' : 'Не нужна'}
|
||
</p>
|
||
<p>
|
||
<strong>Занятость (часов в неделю):</strong>{' '}
|
||
{job.Time.length > 1 ? job.Time.join(', ') : job.Time[0]}
|
||
</p>
|
||
<p>
|
||
<strong>Оклад:</strong> {job.Salary} ₽
|
||
</p>
|
||
<p>
|
||
<strong>Email:</strong> {job.Email}
|
||
</p>
|
||
<p>
|
||
<strong>Обязанности:</strong> {job.Responsibilities}
|
||
</p>
|
||
<div className={style.btn_group}>
|
||
<Button
|
||
onClick={() => handleEdit(job.JobID)}
|
||
className={style.btn}
|
||
>
|
||
Редактировать
|
||
</Button>
|
||
<Button
|
||
onClick={() => handleClick(job.JobID)}
|
||
className={style.btn}
|
||
>
|
||
Список резюме
|
||
</Button>
|
||
<Button onClick={() => handleArchive(job)} className={style.btn}>
|
||
Снять с публикации
|
||
</Button>
|
||
<Button
|
||
danger
|
||
onClick={() => handleDelete(job.JobID)}
|
||
className={style.btn}
|
||
>
|
||
Удалить
|
||
</Button>
|
||
</div>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
|
||
<h3 className={style.text}>Архив:</h3>
|
||
<div
|
||
className={style.card_wrapper}
|
||
style={{
|
||
display: 'grid',
|
||
gap: '20px',
|
||
gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
|
||
}}
|
||
>
|
||
{archivedJobs?.map((job, index) => (
|
||
<Card key={index} title={job.Job_name} bordered={false}>
|
||
{/* Контент вакансии */}
|
||
<p>
|
||
<strong>Курс:</strong> {job.Year}
|
||
</p>
|
||
<p>
|
||
<strong>Квалификация:</strong> {job.Qualification ? 'Yes' : 'No'}
|
||
</p>
|
||
<p>
|
||
<strong>Занятость:</strong>{' '}
|
||
{job.Time.length > 1 ? job.Time.join(', ') : job.Time[0]}
|
||
</p>
|
||
<p>
|
||
<strong>Оклад:</strong> ${job.Salary}
|
||
</p>
|
||
<p>
|
||
<strong>Email:</strong> {job.Email}
|
||
</p>
|
||
<p>
|
||
<strong>Archive:</strong> {job.Archive ? 'Yes' : 'No'}
|
||
</p>
|
||
<p>
|
||
<strong>Обязанности:</strong> {job.Responsibilities}
|
||
</p>
|
||
<div className={style.btn_group}>
|
||
<Button
|
||
onClick={() => handleEdit(job.JobID)}
|
||
className={style.btn}
|
||
>
|
||
Редактировать
|
||
</Button>
|
||
<Button
|
||
onClick={() => handleClick(job.JobID)}
|
||
className={style.btn}
|
||
>
|
||
Список резюме
|
||
</Button>
|
||
<Button onClick={() => handleArchive(job)} className={style.btn}>
|
||
Опубликовать
|
||
</Button>
|
||
<Button danger onClick={() => handleDelete(job.JobID)}>
|
||
Удалить
|
||
</Button>
|
||
</div>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default ViewVacansy;
|