diff --git a/src/App.jsx b/src/App.jsx index 5578cdf..8e00b55 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,7 +1,9 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { Route, Routes } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; // import NotFound404 from "./pages/not-found/not-found"; +import * as yup from "yup"; +import { useFormik } from "formik"; import HomePage from "./pages/home-page/home-page"; import RequestBuilder from "./pages/request-builder/request-builder"; import GlobalRoute from "./components/global-route/global-route"; @@ -9,11 +11,17 @@ import Success from "./components/success/success"; import FailureWindow from "./components/failure-window/failure-window"; import Window404 from "./components/404-window/404-window"; import { + formDataPost, getCategoriesRequest, getCityRequest, + getRequiredDataFromSpecRequest, + getRequiredDataRequest, getVacancyNamesRequest, + handleClearRequiredData, + handleClearSalaryData, } from "./services/dataSlice"; -/* eslint-disable react-hooks/exhaustive-deps */ +import { saveFormState } from "./services/formSlice"; +/* eslint-disable react-hooks/exhaustive-deps, react-redux/useSelector-prefer-selectors */ function App() { const dispatch = useDispatch(); // eslint-disable-next-line react-redux/useSelector-prefer-selectors @@ -25,6 +33,181 @@ function App() { dispatch(getCategoriesRequest()); }, []); + const formStateFromRedux = useSelector((state) => state.form.formState); + const baseDataFromRedux = useSelector((state) => state.data.baseData); + + const validationSchema = yup.object({ + vacancyNameField: yup.object().shape({ + name: yup.string().min(3).required(), + }), + specialisationField: yup.object().required(), + cityField: yup.object().required(), + salaryFromField: yup + .number() + .positive() + .min(1000) + .max(1000000000) + .integer() + .required(), + salaryToField: yup + .number() + .positive() + .min(1000) + .max(1000000000) + .integer() + .required(), + rewardField: yup + .number() + .positive() + .min(1000) + .max(1000000000) + .integer() + .required(), + employeeCountField: yup + .number() + .positive() + .min(1) + .max(1000) + .integer() + .required(), + }); + + const formik = useFormik({ + initialValues: formStateFromRedux || { + vacancyNameField: null, + specialisationField: null, + cityField: null, + grade: "", + expirience: "", + worktype: [], + employment: "", + registrationType: "", + salaryFromField: "", + salaryToField: "", + responsibilitiesCheckboxes: [], + responsibilitiesField: "", + requirementsCheckboxes: [], + requirementsField: "", + conditionsCheckbox: [], + conditionsField: "", + rewardRadio: 0, + rewardField: "", + employeeCountField: "", + recruiterCount: "", + rewardRadio3: 0, + additionalTasks: [], + whatNeedRadio: 0, + specialRequirementsField: "", + companyInfoSwitch: false, + }, + validationSchema, + onSubmit: (values) => { + console.log(JSON.stringify(values, null, 2)); + dispatch(formDataPost(values)); + }, + }); + + const [vacancyNameTemp, handleVacancyNameTemp] = useState({}); + const [cityTemp, handlecityTemp] = useState({}); + const [specialisationTemp, handleSpecialisationTemp] = useState({}); + useEffect( + () => () => { + const formState = formik.values; + // console.log(JSON.stringify(formState, null, 2)); + + const firstFieldHandler = () => { + dispatch( + getRequiredDataFromSpecRequest({ + specId: formState.vacancyNameField.id, + }), + ); + + const tmpSpecName = baseDataFromRedux.specialisationNames.find( + (item) => item.id === formState.vacancyNameField.id, + ); + const tmpSpec = baseDataFromRedux.specialisations.find( + (item) => item.id === tmpSpecName.specialisationsId, + ); + + formik.setFieldValue("specialisationField", { + id: tmpSpecName.id, + title: tmpSpecName.name, + specialisation: tmpSpec.name, + }); + }; + + if ( + formState.vacancyNameField !== null && + formState.cityField === null && + formState.vacancyNameField !== vacancyNameTemp + ) { + if (formState.specialisationField === null) { + if (formState.vacancyNameField.id !== undefined) { + firstFieldHandler(); + } + } else if ( + formState.vacancyNameField.id !== formState.specialisationField.id && + formState.vacancyNameField.id !== undefined + ) { + firstFieldHandler(); + } + } + /// ////////////////////////////////////////////// + + if ( + formState.cityField === null && + formState.specialisationField !== specialisationTemp + ) { + if (formState.vacancyNameField === null) { + if (formState.specialisationField !== null) { + dispatch( + getRequiredDataFromSpecRequest({ + specId: formState.specialisationField.id, + }), + ); + } + } else if ( + formState.vacancyNameField.name !== undefined && + formState.specialisationField !== null + ) { + dispatch( + getRequiredDataFromSpecRequest({ + specId: formState.specialisationField.id, + }), + ); + } + } + /// ////////////////////////////////////////////// + if ( + formState.cityField !== null && + formState.specialisationField !== null && + (formState.specialisationField !== specialisationTemp || + formState.cityField !== cityTemp) + ) { + dispatch( + getRequiredDataRequest({ + vacancyNameFieldId: formState.specialisationField.id, + cityId: formState.cityField.id, + }), + ); + } + /// ////////////////////////////////////////////// + if (formState.cityField === null) { + dispatch(handleClearSalaryData()); + } + + if (formState.specialisationField === null) { + dispatch(handleClearRequiredData()); + } + + dispatch(saveFormState(formik.values)); + handleSpecialisationTemp(formState.specialisationField); + handleVacancyNameTemp(formState.vacancyNameField); + handlecityTemp(formState.cityField); + }, + [formik], + ); + return ( // eslint-disable-next-line react/jsx-no-useless-fragment <> @@ -32,19 +215,19 @@ function App() {

Загрузка..

) : ( - }> + }> } /> } + element={} /> } + element={} /> } + element={} /> } /> } /> diff --git a/src/components/global-route/global-route.jsx b/src/components/global-route/global-route.jsx index 314f10c..8621f2b 100644 --- a/src/components/global-route/global-route.jsx +++ b/src/components/global-route/global-route.jsx @@ -4,13 +4,13 @@ import styles from "./global-route.module.scss"; import AppHeader from "../app-header/app-header"; import Footer from "../footer/footer"; import Popup from "../popup/popup"; - -function GlobalRoute() { +/* eslint-disable react/prop-types */ +function GlobalRoute({ formik }) { const location = useLocation(); const currentRoute = location.pathname; return ( - <> +
@@ -21,7 +21,7 @@ function GlobalRoute() {
- + ); } diff --git a/src/components/popup/popup.jsx b/src/components/popup/popup.jsx index e9dd785..568c894 100644 --- a/src/components/popup/popup.jsx +++ b/src/components/popup/popup.jsx @@ -3,8 +3,9 @@ import { Button } from "@mui/material"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import styles from "./popup.module.scss"; -import { handleModal } from "../../services/modalSlice"; +import { handleModal, handleSuccess } from "../../services/modalSlice"; +/* eslint-disable react-hooks/exhaustive-deps */ function Popup() { const dispatch = useDispatch(); // eslint-disable-next-line react-redux/useSelector-prefer-selectors @@ -15,6 +16,8 @@ function Popup() { const requestedDataFromRedux = useSelector( (state) => state.data.requestedData, ); + // eslint-disable-next-line react-redux/useSelector-prefer-selectors + const isSuccess = useSelector((state) => state.modal.isSuccess); const navigate = useNavigate(); const handleClose = () => { @@ -31,6 +34,14 @@ function Popup() { return () => document.removeEventListener("keydown", onEsc); }); + React.useEffect(() => { + if (isSuccess) { + handleClose(); + navigate("/success"); + dispatch(handleSuccess(false)); + } + }, [isSuccess]); + // данные с formSlice.js const arrOfRespCheckboxesId = formStateFromRedux.responsibilitiesCheckboxes.map(Number); @@ -381,10 +392,11 @@ function Popup() {