From 4c0d1d8c370a76e2fc71ed98001075222fb1cef9 Mon Sep 17 00:00:00 2001 From: nikita Date: Fri, 10 Nov 2023 23:29:13 +0300 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=D0=B0=D0=BA=D0=B0=D0=BD=D1=81=D0=B8=D0=B8?= =?UTF-8?q?=20=D1=81=20=D1=81=D0=B0=D0=B9=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/VacancyCard/VacancyCard.jsx | 58 ++++++++++++++++-- src/components/VacancyCard/VacancyCard.scss | 59 +++++++++++++++++++ .../ShelterVacancies/ShelterVacancies.jsx | 11 +++- src/modules/ShelterVacancies/VacancyList.jsx | 3 +- .../AddVacancyForm/AddVacancyForm.jsx | 20 +++---- .../components/AddVacancyForm/constants.js | 23 ++------ 6 files changed, 138 insertions(+), 36 deletions(-) diff --git a/src/components/VacancyCard/VacancyCard.jsx b/src/components/VacancyCard/VacancyCard.jsx index ac33293e..96df06df 100644 --- a/src/components/VacancyCard/VacancyCard.jsx +++ b/src/components/VacancyCard/VacancyCard.jsx @@ -1,11 +1,35 @@ -import React from 'react'; +import React, { useState } from 'react'; import { useOutletContext } from 'react-router-dom'; import './VacancyCard.scss'; import EditIcon from '../../images/EditIcon/EditIcon'; import DeleteIcon from '../../images/DeleteIcon/DeleteIcon'; +import { Button } from '../../ui'; -const VacancyCard = ({ title, salary, schedule, description, education, isLoading }) => { +const VacancyCard = ({ id, title, salary, schedule, description, education, isLoading, onDelete }) => { const { isOwner } = useOutletContext(); + const [isModalOpen, setModalOpen] = useState(false); + + const handleDelete = async () => { + try { + const token = localStorage.getItem('access'); + const response = await fetch(`http://194.58.109.129/api/v1/my-shelter/vacancies/${id}`, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }); + + if (!response.ok) { + throw new Error('Ошибка при удалении вакансии'); + } + onDelete(id); + } catch (error) { + throw new Error('Ошибка при удалении вакансии'); + } finally { + setModalOpen(false); + } + }; if (isLoading) { return null; @@ -22,8 +46,7 @@ const VacancyCard = ({ title, salary, schedule, description, education, isLoadin - {/* TODO DeleteIcon функционал реализую в след PR */} - @@ -33,8 +56,33 @@ const VacancyCard = ({ title, salary, schedule, description, education, isLoadin

{`График работы: ${schedule.map((item) => { return item.name; }).join(', ')}`}

{`Образование: ${education.name}`}

{`Обязанности: ${description}`}

+ + {isModalOpen && ( +
+
+
+
+
Вы уверены, что хотите удалить вакансию?
+
Все данные о вакансии будут удалены
+
+
+ + +
+
+
+
+ )} ); }; -export default VacancyCard; +export default VacancyCard; \ No newline at end of file diff --git a/src/components/VacancyCard/VacancyCard.scss b/src/components/VacancyCard/VacancyCard.scss index 4b00fed7..7934f631 100644 --- a/src/components/VacancyCard/VacancyCard.scss +++ b/src/components/VacancyCard/VacancyCard.scss @@ -3,3 +3,62 @@ @import url('./vacancy-card/__text/vacancy-card__text.css'); @import url('./vacancy-card/__title-container/vacancy-card__title-container.scss'); @import url('./vacancy-card/__icon-button/vacancy-card__icon-button.scss'); +$images-path: '../../images'; + +.wrapper__del { + padding: 100px; + width: 621px; +} + +.modal { + &__del { + gap: 40px; + + &-title { + text-align: center; + width: 100%; + } + + &-descr { + text-align: center; + width: 100%; + } + + &-text { + display: flex; + flex-direction: column; + gap: 26px; + width: 600px; + } + } + + &__btn-del { + display: flex; + gap: 20px; + + &-left { + display: flex; + gap: 8px; + } + } +} + +.modal__esc { + background-image: url('#{$images-path}/icons/ic_button_close.svg'); + background-size: contain; + border: none; + width: 40px; + height: 40px; + background-color: rgba(0, 0, 0, 0); + padding: 0; + margin: 0; + transition: opacity 0.2s; + position: absolute; + top: 36px; + right: 57px; + + &:hover { + opacity: 0.6; + cursor: pointer; + } +} diff --git a/src/modules/ShelterVacancies/ShelterVacancies.jsx b/src/modules/ShelterVacancies/ShelterVacancies.jsx index 9948554b..f2152b73 100644 --- a/src/modules/ShelterVacancies/ShelterVacancies.jsx +++ b/src/modules/ShelterVacancies/ShelterVacancies.jsx @@ -12,10 +12,8 @@ const message = 'Вакансия успешно добавлена!'; const ShelterVacancies = () => { const [infoTooltipOpen, setInfoTooltipOpen] = useState(false); - const [vacanciesList, setVacanciesList] = useState([]); const [isOpenVacancyForm, setIsOpenVacancyForm] = useState(false); - const [isLoading, setIsLoading] = useState(true); const { shelter, isOwner } = useOutletContext(); @@ -49,6 +47,13 @@ const ShelterVacancies = () => { setInfoTooltipOpen(false); }; + const handleDeleteVacancy = (id) => { + const updatedVacancies = vacanciesList.filter((vacancy) => { + return vacancy.id !== id; + }); + setVacanciesList(updatedVacancies); + }; + const handleSubmit = () => { setIsOpenVacancyForm(false); setInfoTooltipOpen(true); @@ -83,7 +88,7 @@ const ShelterVacancies = () => {

Всего вакансий: {vacanciesList.length}

- + {isOpenVacancyForm && }
diff --git a/src/modules/ShelterVacancies/VacancyList.jsx b/src/modules/ShelterVacancies/VacancyList.jsx index 5b368dd2..8e4e867a 100644 --- a/src/modules/ShelterVacancies/VacancyList.jsx +++ b/src/modules/ShelterVacancies/VacancyList.jsx @@ -2,7 +2,7 @@ import React from 'react'; import VacancyCard from '../../components/VacancyCard/VacancyCard'; import './ShelterVacancies.scss'; -const VacancyList = ({ vacancies, isLoading }) => { +const VacancyList = ({ vacancies, isLoading, onDelete }) => { if (!vacancies.length) { return

У приюта нет активных вакансий

; } @@ -20,6 +20,7 @@ const VacancyList = ({ vacancies, isLoading }) => { salary={card.salary} schedule={card.schedule} description={card.description} + onDelete={onDelete} /> ); })} diff --git a/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.jsx b/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.jsx index 34c55766..4adba477 100644 --- a/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.jsx +++ b/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.jsx @@ -56,6 +56,15 @@ const AddVacancyForm = ({ onChange, onSubmitSuccess }) => { }); }; + const handleSelectChange = (id, selected) => { + setFormValues((prevValues) => { + return { + ...prevValues, + [id]: selected, + }; + }); + }; + useEffect(() => { setFormValues((prevValues) => { return { @@ -70,7 +79,7 @@ const AddVacancyForm = ({ onChange, onSubmitSuccess }) => { const fetchOptions = async () => { const fetchedShiftOptions = await getShiftOptions(); const fetchedEducationOptions = await getEducationOptions(); - const fetchedSalaryOptions = await getSalaryOptions(); + const fetchedSalaryOptions = getSalaryOptions(); if (fetchedShiftOptions) { setShiftOptions(fetchedShiftOptions); } @@ -84,15 +93,6 @@ const AddVacancyForm = ({ onChange, onSubmitSuccess }) => { fetchOptions(); }, []); - const handleSelectChange = (id, selected) => { - setFormValues((prevValues) => { - return { - ...prevValues, - [id]: selected, - }; - }); - }; - return (
diff --git a/src/modules/ShelterVacancies/components/AddVacancyForm/constants.js b/src/modules/ShelterVacancies/components/AddVacancyForm/constants.js index 4ea6e284..777faedc 100644 --- a/src/modules/ShelterVacancies/components/AddVacancyForm/constants.js +++ b/src/modules/ShelterVacancies/components/AddVacancyForm/constants.js @@ -11,7 +11,6 @@ export const fetchDataFromBackend = async (url) => { const data = await response.json(); return data; } catch (error) { - // console.error('Error fetching data from backend:', error); return null; } }; @@ -26,21 +25,11 @@ export const getEducationOptions = async () => { return fetchDataFromBackend(url); }; -export const getSalaryOptions = async () => { - const url = `${baseUrl}/v1/vacancies`; - const data = await fetchDataFromBackend(url); - if (!data) { - return []; - } - - const salarySet = new Set(); - data.forEach((item) => { - if (item.is_ndfl === 'ndfl') { - salarySet.add({ name: 'с НДФЛ', slug: 'ndfl' }); - } else if (item.is_ndfl === 'no_ndfl') { - salarySet.add({ name: 'На руки', slug: 'no_ndfl' }); - } - }); +export const getSalaryOptions = () => { + const salaryOptions = [ + { name: 'с НДФЛ', slug: 'ndfl' }, + { name: 'На руки', slug: 'no_ndfl' }, + ]; - return Array.from(salarySet); + return salaryOptions; }; \ No newline at end of file From f0be697e1c874abdc4217c321209eb19ec432916 Mon Sep 17 00:00:00 2001 From: nikita Date: Tue, 14 Nov 2023 14:52:21 +0300 Subject: [PATCH 2/5] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=9A=D0=BE=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditVacancyForm/EditVacancyForm.jsx | 64 +++++++++++++++++++ src/components/VacancyCard/VacancyCard.jsx | 29 +++++++-- .../ShelterVacancies/ShelterVacancies.jsx | 4 +- src/modules/ShelterVacancies/VacancyList.jsx | 4 +- 4 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx diff --git a/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx b/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx new file mode 100644 index 00000000..fd55b6af --- /dev/null +++ b/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx @@ -0,0 +1,64 @@ +import React, { useState, useEffect } from 'react'; +import '../../../modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss'; +import DeclarationInput from '../../../ui/DeclarationInput/DeclarationInput'; +import Select from '../../../ui/Select/Select'; +import { getEducationOptions } from '../../../modules/ShelterVacancies/components/AddVacancyForm/constants'; + +const EditVacancyForm = ({ initialValues }) => { + const [formData, setFormData] = useState(initialValues); + const [educationOptions, setEducationOptions] = useState([]); + + useEffect(() => { + const fetchEducationOptions = async () => { + try { + const options = await getEducationOptions(); + setEducationOptions(options); + } catch (error) { + console.error('Ошибка загрузки опций образования:', error); + } + }; + + fetchEducationOptions(); + }, []); + + const handleInputChange = (name, value) => { + setFormData({ + ...formData, + [name]: value, + }); + }; + + const handleSelectChange = (name, selectedValue) => { + setFormData({ + ...formData, + [name]: selectedValue, + }); + }; + + return ( + + { handleInputChange('title', e.target.value); } }} + type='text' name='position' required /> + +
+ { handleInputChange('salary', e.target.value); } }} + type='number' name='salaryInput' required placeholder='₽' + /> + +
+
+
+ + + {/* */} + + ); }; diff --git a/src/components/VacancyCard/VacancyCard.jsx b/src/components/VacancyCard/VacancyCard.jsx index 430ee1a8..e5a367a1 100644 --- a/src/components/VacancyCard/VacancyCard.jsx +++ b/src/components/VacancyCard/VacancyCard.jsx @@ -5,42 +5,28 @@ import EditIcon from '../../images/EditIcon/EditIcon'; import DeleteIcon from '../../images/DeleteIcon/DeleteIcon'; import { Button } from '../../ui'; import EditVacancyForm from './EditVacancyForm/EditVacancyForm'; +import { deleteVacancy } from '../../modules/ShelterVacancies/components/AddVacancyForm/constants'; -const VacancyCard = ({ id, title, salary, schedule, description, education, isLoading, onDelete }) => { +// eslint-disable-next-line +const VacancyCard = ({ id, title, salary, schedule, description, education, is_ndfl, isLoading, onDelete }) => { const { isOwner } = useOutletContext(); const [isModalOpen, setIsModalOpen] = useState(false); + const [isEditFormOpen, setIsEditFormOpen] = useState(false); + // eslint-disable-next-line + const convertedIsNdfl = is_ndfl === 'ndfl' ? { slug: 'ndfl', name: 'с НДФЛ' } : { slug: 'no_ndfl', name: 'на руки' }; - const [formValues, setFormValues] = useState({ - title, - salary, - education, - }); - - console.log('Значение education в VacancyCard:', education); - - const handleEditFormChange = (field, value) => { + const handleEditFormToggle = () => { // eslint-disable-next-line - setFormValues(prevValues => ({ - ...prevValues, - [field]: value, - })); + setIsEditFormOpen(prevState => !prevState); }; const handleDelete = async () => { try { - const token = localStorage.getItem('access'); - const response = await fetch(`http://194.58.109.129/api/v1/my-shelter/vacancies/${id}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - }); + const isDeleted = await deleteVacancy(id); - if (!response.ok) { - throw new Error('Ошибка при удалении вакансии'); + if (isDeleted) { + onDelete(id); } - onDelete(id); } catch (error) { throw new Error('Ошибка при удалении вакансии'); } finally { @@ -59,7 +45,7 @@ const VacancyCard = ({ id, title, salary, schedule, description, education, isLo {isOwner && ( <> - - - )} - - -
    - {shelter.address} - {`${shelter.working_from_hour} - ${shelter.working_to_hour}`} - {shelter.phone_number} - {shelter.email} - {shelter.web_site && ( - - - {shelter.web_site} - - - )} -
    - {shelter.ok_page && ( - - одноклассники - + {isOwner && ( + <> + {/* TODO ведет на 6.2.1.4 в фигме, оно пока не реализовано */} + + + + {/* TODO при нажатии попап как на 6.2.1.3 в фигме, попап не сверстан */} + + )} +
    - {shelter.vk_page && ( - - вконтакте - +
      + {shelter.address} + {`${shelter.working_from_hour} - ${shelter.working_to_hour}`} + {shelter.phone_number} + {shelter.email} + {shelter.web_site && ( + + + {shelter.web_site} + + )} +
      + {shelter.ok_page && ( + + одноклассники + + )} - {shelter.telegram && ( - - телеграм - - )} -
      -
    + {shelter.vk_page && ( + + вконтакте + + )} + + {shelter.telegram && ( + + телеграм + + )} + +
+ - -

Описание

-

- {shelter.description} -

+

Описание

+

+ {shelter.description} +

- {isOwner && } + {isOwner && } -

- Собрано денег за всё время: {shelter.money_collected} -

-

- Забрали животных за всё время: {shelter.animals_adopted} -

+

+ Собрано денег за всё время: {shelter.money_collected} +

+

+ Забрали животных за всё время: {shelter.animals_adopted} +

+ + {isOwner && ( +
+

+ Подключить платежную систему +

+ +
+ )} ); }; diff --git a/src/modules/AboutShelter/AboutShelter.scss b/src/modules/AboutShelter/AboutShelter.scss index 53b8b19d..dbcea5ae 100644 --- a/src/modules/AboutShelter/AboutShelter.scss +++ b/src/modules/AboutShelter/AboutShelter.scss @@ -12,3 +12,14 @@ @import url('./styles/shelter-info/__link/shelter-info__link.css'); @import url('./styles/shelter-info/__icons/shelter-info__icons.css'); @import url('./styles/shelter-info/__icon/shelter-info__icon.css'); + +.shelter-section__about { + display: flex; + gap: 44px; +} + +.shelter-section__bottom { + display: flex; + gap: 16px; + flex-direction: column; +} \ No newline at end of file diff --git a/src/modules/HelpToShelter/HelpToShelter.css b/src/modules/HelpToShelter/HelpToShelter.css index 08eb34c5..33a50622 100644 --- a/src/modules/HelpToShelter/HelpToShelter.css +++ b/src/modules/HelpToShelter/HelpToShelter.css @@ -1,2 +1,16 @@ -@import url('./help-to-shelter/__title/help-to-shelter__title.css'); -@import url('./help-to-shelter/__button/help-to-shelter__button.css'); \ No newline at end of file +.help-to-shelter { + gap: 40px; +} + +.help-to-shelter__mat { + display: flex; + flex-direction: column; + max-width: 528px; + gap: 32px; +} + +.help-to-shelter__nonmat { + display: flex; + flex-direction: column; + gap: 32px; +} \ No newline at end of file diff --git a/src/modules/HelpToShelter/HelpToShelter.jsx b/src/modules/HelpToShelter/HelpToShelter.jsx index 69f93abc..64e8e513 100644 --- a/src/modules/HelpToShelter/HelpToShelter.jsx +++ b/src/modules/HelpToShelter/HelpToShelter.jsx @@ -1,14 +1,38 @@ import React from 'react'; +import { useOutletContext } from 'react-router-dom'; import './HelpToShelter.css'; -import Button from '../../ui/Button/Button'; +import { Button } from '../../ui'; +import DeclarationInput from '../../ui/DeclarationInput/DeclarationInput'; +import * as regex from '../../utils/regex'; +import * as errorMessage from '../../utils/errorMessage'; +import useInput from '../../hooks/useInput'; const HelpToShelter = () => { + const materialAid = useInput('', { notEmpty: true, maxLength: 12, regex: regex.NUMBER }, errorMessage.DONATION_AMOUNT); + const { isOwner, isAuth, isShelterOwner } = useOutletContext(); + return (
-

Материальная помощь

- -

Нематериальная помощь

- + { !isOwner && ( +
+

Материальная помощь

+ { (isShelterOwner || isAuth) && (isAuth || isShelterOwner) && ( + + )} + +
+ )} +
+

Нематериальная помощь

+ +
); }; diff --git a/src/modules/HelpToShelter/help-to-shelter/__button/help-to-shelter__button.css b/src/modules/HelpToShelter/help-to-shelter/__button/help-to-shelter__button.css deleted file mode 100644 index e79773ef..00000000 --- a/src/modules/HelpToShelter/help-to-shelter/__button/help-to-shelter__button.css +++ /dev/null @@ -1,3 +0,0 @@ -.help-to-shelter__button { - margin: 0 auto 40px 0; -} \ No newline at end of file diff --git a/src/modules/HelpToShelter/help-to-shelter/__title/help-to-shelter__title.css b/src/modules/HelpToShelter/help-to-shelter/__title/help-to-shelter__title.css deleted file mode 100644 index fc9d56af..00000000 --- a/src/modules/HelpToShelter/help-to-shelter/__title/help-to-shelter__title.css +++ /dev/null @@ -1,3 +0,0 @@ -.help-to-shelter__title { - margin-bottom: 24px; -} \ No newline at end of file diff --git a/src/pages/ShelterPage/ShelterPage.jsx b/src/pages/ShelterPage/ShelterPage.jsx index 0381a8c3..d74098eb 100644 --- a/src/pages/ShelterPage/ShelterPage.jsx +++ b/src/pages/ShelterPage/ShelterPage.jsx @@ -14,6 +14,8 @@ const ShelterPage = () => { const currentUser = useContext(CurrentUserContext); const isOwner = currentUser?.own_shelter?.id === Number(id); + const isAuth = currentUser?.status === 'user'; + const isShelterOwner = currentUser?.status === 'shelter_owner'; useEffect(() => { shelterApi @@ -33,7 +35,7 @@ const ShelterPage = () => {
- + ); diff --git a/src/pages/ShelterPage/styles/shelter-section/shelter-section.css b/src/pages/ShelterPage/styles/shelter-section/shelter-section.css index ab6bf835..679a3e3b 100644 --- a/src/pages/ShelterPage/styles/shelter-section/shelter-section.css +++ b/src/pages/ShelterPage/styles/shelter-section/shelter-section.css @@ -1,7 +1,7 @@ .shelter-section { display: flex; width: 1440px; - min-height: 625px; + /* min-height: 625px; */ padding: 0 0 80px 132px; flex-direction: column; background-color: var(--color-background-base); diff --git a/src/utils/errorMessage.js b/src/utils/errorMessage.js index ee5782f5..2838adfe 100644 --- a/src/utils/errorMessage.js +++ b/src/utils/errorMessage.js @@ -118,3 +118,9 @@ export const VACANCY_DESCRIPTION = { TOO_LONG: tooLong, INVALID: invalidSymbol, }; + +// сумма пожертвования +export const DONATION_AMOUNT = { + TOO_LONG: tooLong, + NOT_FOUND: 'Введите сумму пожертвования', +}; \ No newline at end of file From 260ce34e227374bd413f13369a3b7c51deb5faa9 Mon Sep 17 00:00:00 2001 From: nikita Date: Wed, 22 Nov 2023 19:36:18 +0300 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20\=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=BA=D0=B0=D0=BD=D1=81=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditVacancyForm/EditActionButtons.jsx | 74 ++++++++++--------- .../EditVacancyForm/EditVacancyForm.jsx | 50 ++++++------- src/components/VacancyCard/VacancyCard.jsx | 45 ++++++++--- .../vacancy-card__icon-button.scss | 9 ++- .../vacancy-card__title-container.scss | 1 + src/images/icons/ic_button_close_editForm.svg | 3 + src/modules/PetModule/PetModule.jsx | 3 +- .../ShelterVacancies/ShelterVacancies.jsx | 44 ++++++++++- src/modules/ShelterVacancies/VacancyList.jsx | 5 +- .../AddVacancyForm/AddVacancyForm.jsx | 8 +- .../AddVacancyForm/AddVacancyForm.scss | 47 +++++++++--- .../components/FormActionButtons.jsx | 8 +- .../components/FormTextarea.jsx | 4 +- .../AddVacancyForm/components/api.js | 20 ----- .../AddVacancyForm/components/apiEdit.js | 20 ----- .../AddVacancyForm/components/vacanciesAPI.js | 56 ++++++++++++++ .../components/AddVacancyForm/constants.js | 21 ------ src/ui/Button/Button.scss | 24 ++++++ 18 files changed, 283 insertions(+), 159 deletions(-) create mode 100644 src/images/icons/ic_button_close_editForm.svg delete mode 100644 src/modules/ShelterVacancies/components/AddVacancyForm/components/api.js delete mode 100644 src/modules/ShelterVacancies/components/AddVacancyForm/components/apiEdit.js create mode 100644 src/modules/ShelterVacancies/components/AddVacancyForm/components/vacanciesAPI.js diff --git a/src/components/VacancyCard/EditVacancyForm/EditActionButtons.jsx b/src/components/VacancyCard/EditVacancyForm/EditActionButtons.jsx index 717447c5..d436ed1b 100644 --- a/src/components/VacancyCard/EditVacancyForm/EditActionButtons.jsx +++ b/src/components/VacancyCard/EditVacancyForm/EditActionButtons.jsx @@ -1,44 +1,44 @@ import React, { useState } from 'react'; import { Button } from '../../../ui'; -import updateDataWithToken from '../../../modules/ShelterVacancies/components/AddVacancyForm/components/apiEdit'; -import { deleteVacancy } from '../../../modules/ShelterVacancies/components/AddVacancyForm/constants'; import DeleteIcon from '../../../images/DeleteIcon/DeleteIcon'; +import { updateVacancy, deleteVacancy } from '../../../modules/ShelterVacancies/components/AddVacancyForm/components/vacanciesAPI'; -const EditActionButtons = ({ id, formData, isSubmitButtonDisabled, onSubmitSuccess, onDelete }) => { +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 = { - // eslint-disable-next-line id: formData.id, - // eslint-disable-next-line position: formData.title, salary: formData.salary, - is_ndfl: (() => { - if (Array.isArray(formData.is_ndfl)) { - // Если это массив строк, объединяем его в одну строку - return formData.is_ndfl.join(''); - // eslint-disable-next-line - } else if (typeof formData.is_ndfl === 'object' && formData.is_ndfl !== null) { - // Если это объект, используем его поле slug - return formData.is_ndfl.slug || ''; - } else { - // Если это не массив и не объект, оставляем без изменений - return formData.is_ndfl || ''; - } - })(), - // eslint-disable-next-line - schedule: formData.schedule.map(item => item.slug), - education: formData.education, + is_ndfl: getFormattedValue(formData.is_ndfl), + schedule: formattedSchedule, + education: getFormattedValue(formData.education), description: formData.description, }; - // eslint-disable-next-line - console.log('Данные в форме:', updateFormData); - await updateDataWithToken(token, updateFormData, updateFormData.id); + await updateVacancy(token, updateFormData, updateFormData.id); onSubmitSuccess(); + onClose(); } catch (error) { throw new Error('Network response was not ok'); } @@ -46,24 +46,32 @@ const EditActionButtons = ({ id, formData, isSubmitButtonDisabled, onSubmitSucce const handleDelete = async () => { try { - const isDeleted = await deleteVacancy(id); - + const isDeleted = await deleteVacancy(formData.id); if (isDeleted) { - onDelete(id); + onDelete(formData.id); } } catch (error) { throw new Error('Ошибка при удалении вакансии'); } finally { setIsModalOpen(false); + onClose(); } }; + if (isLoading) { + return null; + } + return ( -
- - +
+
+ + +
{isModalOpen && (
@@ -93,4 +101,4 @@ const EditActionButtons = ({ id, formData, isSubmitButtonDisabled, onSubmitSucce ); }; -export default EditActionButtons; +export default EditActionButtons; \ No newline at end of file diff --git a/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx b/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx index 84e24e10..c8fc59be 100644 --- a/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx +++ b/src/components/VacancyCard/EditVacancyForm/EditVacancyForm.jsx @@ -1,5 +1,6 @@ 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'; @@ -10,7 +11,7 @@ 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, onSubmitSuccess }) => { +const EditVacancyForm = ({ id, title, salary, education, schedule, is_ndfl, description, onDelete, onClose, onSubmitSuccess, isLoading }) => { const [formData, setFormData] = useState({ id: id || '', title: title || '', @@ -34,7 +35,6 @@ const EditVacancyForm = ({ id, title, salary, education, schedule, is_ndfl, desc ...prevData, [field]: value, })); - // onFieldChange(field, value); }; const handleDescriptionChange1 = (evt) => { @@ -50,36 +50,38 @@ const EditVacancyForm = ({ id, title, salary, education, schedule, is_ndfl, desc useEffect(() => { const fetchOptions = async () => { - try { - const [salaryOpts, educationOpts, shiftOpts] = await Promise.all([ - getSalaryOptions(), - getEducationOptions(), - getShiftOptions(), - ]); - setSalaryOptions(salaryOpts); - setEducationOptions(educationOpts); + const shiftOpts = await getShiftOptions(); + const educationOpts = await getEducationOptions(); + const salaryOpts = getSalaryOptions(); + if (shiftOpts) { setShiftOptions(shiftOpts); - } catch (error) { - throw new Error('Network response was not ok'); + } + if (educationOpts) { + setEducationOptions(educationOpts); + } + if (salaryOpts) { + setSalaryOptions(salaryOpts); } }; - fetchOptions(); }, []); - useEffect(() => { - // eslint-disable-next-line - console.log('Загруженные данные в форму для редактирования:', formData); - }, [formData]); - return ( -
+ +
+ +
{ handleInputChange('title', e.target.value); } }} type='text' name='position' required /> -
+
{ handleInputChange('salary', e.target.value); } }} @@ -94,7 +96,7 @@ const EditVacancyForm = ({ id, title, salary, education, schedule, is_ndfl, desc initialValues={formData.is_ndfl} />
-
+
-
+
@@ -126,4 +126,4 @@ const AddVacancyForm = ({ onChange, onSubmitSuccess }) => { ); }; -export default AddVacancyForm; +export default AddVacancyForm; \ No newline at end of file diff --git a/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss b/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss index 92fe583e..3b6917e8 100644 --- a/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss +++ b/src/modules/ShelterVacancies/components/AddVacancyForm/AddVacancyForm.scss @@ -1,21 +1,41 @@ -.add-vacancy-form__flex-container { - display: flex; - gap: 16px; - justify-content: space-between; -} +$images-path: '../../../../images'; -.add-vacancy-form__container { +.vacancy-form { margin-top: 36px; width: 576px; + + &__container { + display: flex; + gap: 16px; + justify-content: space-between; + } + + &__edit { + display: flex; + gap: 12px; + margin-bottom: 36px; + + &-btn { + background-image: url('#{$images-path}/icons/ic_button_close_editForm.svg'); + background-size: contain; + border: none; + width: 20px; + height: 20px; + background-color: rgba(0, 0, 0, 0); + padding: 0; + margin: 0; + cursor: pointer; + } + } } -.add-shelter-form__submit-buttons { +.shelter-form__submit-buttons { display: flex; gap: 32px; margin-top: 40px; } -.add-vacancy-form__description { +.vacancy-form__description { width: 100%; height: 120px; margin: 0; @@ -34,6 +54,15 @@ } } -.add-vacancy-form__desctioption-title { +.vacancy-form__desctioption-title { margin-bottom: 10px; } + +.btn-edit { + display: flex; + gap: 76px; + + &__buttons { + font-size: 16px; + } +} diff --git a/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormActionButtons.jsx b/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormActionButtons.jsx index b1ebf820..bc06e576 100644 --- a/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormActionButtons.jsx +++ b/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormActionButtons.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Button from '../../../../../ui/Button/Button'; -import sendDataWithToken from './api'; +import { sendVacancy } from './vacanciesAPI'; const FormActionButtons = ({ isSubmitButtonDisabled, onClick, onSubmitSuccess, formValues }) => { const handleSubmit = async () => { @@ -21,7 +21,7 @@ const FormActionButtons = ({ isSubmitButtonDisabled, onClick, onSubmitSuccess, f description: formattedDescription, }; - await sendDataWithToken(token, formData); + await sendVacancy(token, formData); onSubmitSuccess(); } catch (error) { throw new Error('Network response was not ok'); @@ -29,7 +29,7 @@ const FormActionButtons = ({ isSubmitButtonDisabled, onClick, onSubmitSuccess, f }; return ( -
+
@@ -38,4 +38,4 @@ const FormActionButtons = ({ isSubmitButtonDisabled, onClick, onSubmitSuccess, f ); }; -export default FormActionButtons; +export default FormActionButtons; \ No newline at end of file diff --git a/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormTextarea.jsx b/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormTextarea.jsx index d44c7728..2f90af29 100644 --- a/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormTextarea.jsx +++ b/src/modules/ShelterVacancies/components/AddVacancyForm/components/FormTextarea.jsx @@ -8,9 +8,9 @@ const FormTextarea = ({ jobDescriptionInput, handleDescriptionChange, initialVal }, [initialValues]); return ( <> -

Обязанности*

+

Обязанности*