Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge PR 205 #206

Merged
merged 21 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4c0d1d8
feat: Добавлено удаление вакансии с сайта
n1k-deco Nov 10, 2023
b40a907
fix: частично поправил странику модуль ShelterOwnerProfile и ProfileS…
Nov 11, 2023
f0be697
Тест для Коли
n1k-deco Nov 14, 2023
4a33e09
feat: добавил ссылку-кнопку на переход в личный кабинет
Nov 14, 2023
2b92363
тест вакансий
n1k-deco Nov 15, 2023
fa28a28
chore: merge from dev
Nov 16, 2023
f6953ce
feat: сверстал страницу в 6.2.1.2
Nov 16, 2023
6ecc6c6
Merge branch 'dev' into feat/shelter-owner-layout-6.2.1.2-6.2.1.8
Nov 17, 2023
4fdfad8
feat: добавил оболочку и настроил роуты на страницу редактирования пр…
Nov 17, 2023
10426f1
feat: добавлена кнопка материальной помощи и подключения платежей
n1k-deco Nov 17, 2023
626e62b
Merge pull request #201 from Lapkipomoshi/dev_n1k
n1k-deco Nov 17, 2023
210a51a
Merge pull request #202 from Lapkipomoshi/dev_n1k_fixBags
n1k-deco Nov 17, 2023
19721cb
Merge branch 'dev' into dev_n1k
n1k-deco Nov 22, 2023
260ce34
feat: реализовано удаления \ редактирование вакансий
n1k-deco Nov 22, 2023
1678b1b
Merge branch 'dev' into dev_n1k
n1k-deco Nov 22, 2023
d02bb54
Merge pull request #203 from Lapkipomoshi/dev_n1k
nickoff Nov 22, 2023
2618d71
feat: начало работы над страницей редактирования приюта
Nov 22, 2023
7fd26a9
fix: fix merge conflict
Nov 22, 2023
50b776a
Merge pull request #204 from Lapkipomoshi/feat/shelter-owner-layout-6…
n1k-deco Dec 2, 2023
53f8858
feat: подключение платежа и правки баг-репортов
n1k-deco Dec 4, 2023
8f3e8ed
Merge pull request #205 from Lapkipomoshi/dev_n1k
nickoff Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.details-card__title {
margin: 0;
margin-bottom: 16px;
padding: 0;
}
4 changes: 2 additions & 2 deletions src/components/DetailsCard/svg/PlusMinus.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.plus-minus {
width: 32px;
height: 32px;
width: 29px;
height: 29px;
}

.plus-minus line {
Expand Down
52 changes: 26 additions & 26 deletions src/components/ProfileSheltersBlock/ProfileSheltersBlock.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import './ProfileSheltersBlock.scss';
import ShelterCard from '../ShelterCard/ShelterCard';
import Button from '../../ui/Button/Button';
import CardsSlider from '../CardsSlider/CardsSlider';

const ProfileSheltersBlock = ({ shelters, sheltersTitle, owner }) => {
const ProfileSheltersBlock = ({ myShelters, sheltersTitle }) => {
const navigate = useNavigate();

return (
<div className='profile-shelters'>
{shelters && shelters.length !== 0 &&
{myShelters && myShelters.length !== 0 &&
<div className='profile-shelters__container'>
<h3 className='profile-shelters__title standard-font standard-font_type_h3'>{sheltersTitle}</h3>

<div className='profile-shelters__shelters'>
<CardsSlider modifier='profile'>
<ul className='profile-shelters__shelters-container'>
{shelters.map((shelter) => {
return (
<li key={shelter.id}>
<ShelterCard
id={shelter.id}
name={shelter.name}
address={shelter.address}
workingFromHour={shelter.working_from_hour}
workingToHour={shelter.working_to_hour}
workingHours={shelter.working_hours}
logo={shelter.logo}
profileImage={shelter.profile_image}
/>
</li>
);
})}
</ul>
</CardsSlider>

{owner && <Button link to='/'>Перейти в приют</Button>}
<ul className='profile-shelters__shelters-container'>
{myShelters.map((shelter) => {
return (
<li key={shelter.id}>
<ShelterCard
id={shelter.id}
name={shelter.name}
address={shelter.address}
workingFromHour={shelter.working_from_hour}
workingToHour={shelter.working_to_hour}
workingHours={shelter.working_hours}
logo={shelter.logo}
profileImage={shelter.profile_image}
/>
</li>
);
})}
</ul>
{myShelters && <Button onClick={
() => {return navigate('my-shelter');}
}>Перейти в приют</Button>}
</div>
</div>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.profile-shelters__shelters {
display: flex;
flex-direction: column;
align-items: center;
}

.profile-shelters__container {
Expand Down
104 changes: 104 additions & 0 deletions src/components/VacancyCard/EditVacancyForm/EditActionButtons.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React, { useState } from 'react';
import { Button } from '../../../ui';
import DeleteIcon from '../../../images/DeleteIcon/DeleteIcon';
import { updateVacancy, deleteVacancy } from '../../../modules/ShelterVacancies/components/AddVacancyForm/components/vacanciesAPI';

const EditActionButtons = ({ formData, isSubmitButtonDisabled, onDelete, onClose, onSubmitSuccess, isLoading }) => {
const [isModalOpen, setIsModalOpen] = useState(false);

const handleSubmit = async () => {
try {
const token = localStorage.getItem('access');

const getFormattedValue = (value) => {
if (Array.isArray(value)) {
return value.join('');
}
if (typeof value === 'object' && value !== null) {
return value.slug || '';
}
return value || '';
};

const formattedSchedule = formData.schedule.map((item) => {
if (typeof item === 'object' && item !== null && item.slug) {
return item.slug;
}
return item;
});

const updateFormData = {
id: formData.id,
position: formData.title,
salary: formData.salary,
is_ndfl: getFormattedValue(formData.is_ndfl),
schedule: formattedSchedule,
education: getFormattedValue(formData.education),
description: formData.description,
};
await updateVacancy(token, updateFormData, updateFormData.id);
onSubmitSuccess();
onClose();
} catch (error) {
throw new Error('Network response was not ok');
}
};

const handleDelete = async () => {
try {
const isDeleted = await deleteVacancy(formData.id);
if (isDeleted) {
onDelete(formData.id);
}
} catch (error) {
throw new Error('Ошибка при удалении вакансии');
} finally {
setIsModalOpen(false);
onClose();
}
};

if (isLoading) {
return null;
}

return (
<div className='shelter-form__submit-buttons'>
<div className='btn-edit'>
<Button className='btn-edit__buttons' disabled={isSubmitButtonDisabled} onClick={handleSubmit}>
Сохранить изменения
</Button>
<Button className='btn-edit__buttons' theme='transparent' onClick={() => { setIsModalOpen(true); }}>
Удалить вакансию
</Button>
</div>

{isModalOpen && (
<div className='modal-overlay'>
<div className='wrapper wrapper__del'>
<div className='modal modal__del'>
<div className='modal__del-text'>
<div className='modal__title modal__del-title standard-font standard-font_type_h3'>Вы уверены, что хотите удалить вакансию?</div>
<div className='modal__descr modal__del-descr standard-font standard-font_type_h3'>Все данные о вакансии будут удалены</div>
</div>
<div className='modal__btn-del'>
<Button className='modal__btn-del-left' theme='accent' onClick={handleDelete}>
<DeleteIcon />
Да, удалить вакансию
</Button>
<Button theme='transparent' onClick={() => { setIsModalOpen(false); }}>Отменить удаление</Button>
</div>
<button
type='button'
className='modal__esc'
onClick={() => { setIsModalOpen(false); }}
/>
</div>
</div>
</div>
)}
</div>
);
};

export default EditActionButtons;
127 changes: 127 additions & 0 deletions src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import React, { useState, useEffect } from 'react';
import '../../../modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss';
import { Button } from '../../../ui';
import DeclarationInput from '../../../ui/DeclarationInput/DeclarationInput';
import Select from '../../../ui/Select/Select';
import FormTextarea from '../../../modules/ShelterVacancies/components/AddVacancyForm/components/FormTextarea';
import useInput from '../../../hooks/useInput';
import EditActionButtons from './EditActionButtons';
import * as regex from '../../../utils/regex';
import * as errorMessage from '../../../utils/errorMessage';
import { getEducationOptions, getShiftOptions, getSalaryOptions } from '../../../modules/ShelterVacancies/components/AddVacancyForm/constants';

// eslint-disable-next-line
const EditVacancyForm = ({ id, title, salary, education, schedule, is_ndfl, description, onDelete, onClose, onSubmitSuccess, isLoading }) => {
const [formData, setFormData] = useState({
id: id || '',
title: title || '',
salary: salary || '',
education: education || '',
schedule: schedule || '',
// eslint-disable-next-line
is_ndfl: is_ndfl || '',
description: description || '',
});

const [educationOptions, setEducationOptions] = useState([]);
const [shiftOptions, setShiftOptions] = useState([]);
const [salaryOptions, setSalaryOptions] = useState([]);

const jobDescriptionInput = useInput('', { notEmpty: true, maxLength: 3000, regex: regex.TEXT }, errorMessage.VACANCY_DESCRIPTION);

const handleInputChange = (field, value) => {
// eslint-disable-next-line
setFormData((prevData) => ({
...prevData,
[field]: value,
}));
};

const handleDescriptionChange1 = (evt) => {
jobDescriptionInput.onChange(evt);

setFormData((prevData) => {
return {
...prevData,
description: evt.target.value,
};
});
};

useEffect(() => {
const fetchOptions = async () => {
const shiftOpts = await getShiftOptions();
const educationOpts = await getEducationOptions();
const salaryOpts = getSalaryOptions();
if (shiftOpts) {
setShiftOptions(shiftOpts);
}
if (educationOpts) {
setEducationOptions(educationOpts);
}
if (salaryOpts) {
setSalaryOptions(salaryOpts);
}
};
fetchOptions();
}, []);

return (
<form className='vacancy-form'>
<div className='vacancy-form__edit' >
<button
type='button'
className='vacancy-form__edit-btn'
onClick={onClose}
/>
<Button theme='tertiary' onClick={onClose}>Отменить редактирование вакансии</Button>
</div>
<DeclarationInput
caption='Название вакансии*'
inputState={{ value: formData.title, onChange: (e) => { handleInputChange('title', e.target.value); } }}
type='text' name='position' required />

<div className='vacancy-form__container'>
<DeclarationInput
caption='Заработная плата*'
inputState={{ value: formData.salary, onChange: (e) => { handleInputChange('salary', e.target.value); } }}
type='number' name='salaryInput' required placeholder='₽'
/>
<Select
label='Тип оплаты*'
onChange={handleInputChange}
options={salaryOptions}
id='is_ndfl'
isMulti={false}
initialValues={formData.is_ndfl}
/>
</div>
<div className='vacancy-form__container'>
<Select
label='График работы*'
id='schedule'
isMulti
onChange={handleInputChange}
options={shiftOptions}
initialValues={formData.schedule}
/>
<Select
label='Образование*'
id='education'
isMulti={false}
onChange={handleInputChange}
options={educationOptions}
initialValues={formData.education}
/>
</div>
<FormTextarea
jobDescriptionInput={jobDescriptionInput}
handleDescriptionChange={handleDescriptionChange1}
initialValues={formData.description}
/>
<EditActionButtons formData={formData} onDelete={onDelete} onSubmitSuccess={onSubmitSuccess} onClose={onClose} isLoading={isLoading} />
</form>
);
};

export default EditVacancyForm;
Loading
Loading