From 48409575a92300012a1454e900db4553bb4cc4be Mon Sep 17 00:00:00 2001 From: vasya Date: Sun, 5 Apr 2026 19:32:39 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D1=8E=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=87=D0=B0=D1=81=D1=82=D0=B8=20=D1=84=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Modules/Taxi/resources/assets/js/app.jsx | 6 + Modules/Taxi/resources/assets/sass/app.scss | 0 Modules/Taxi/resources/css/taxiHome.css | 44 ++ Modules/Taxi/resources/css/taxiOrder.css | 3 + .../Taxi/resources/js/components/TaxiHome.tsx | 387 +++++++++++ .../resources/js/components/TaxiOrder.tsx | 635 ++++++++++++++++++ .../Taxi/resources/js/page/taxiHomePage.tsx | 13 + .../Taxi/resources/js/page/taxiOrderPage.tsx | 37 + .../Taxi/resources/js/types/taxiOrderType.ts | 50 ++ Modules/Taxi/resources/views/.gitkeep | 0 Modules/Taxi/resources/views/index.blade.php | 7 + .../resources/views/layouts/master.blade.php | 31 + .../Taxi/resources/views/taxi_home.blade.php | 13 + .../Taxi/resources/views/taxi_order.blade.php | 13 + 14 files changed, 1239 insertions(+) create mode 100644 Modules/Taxi/resources/assets/js/app.jsx create mode 100644 Modules/Taxi/resources/assets/sass/app.scss create mode 100644 Modules/Taxi/resources/css/taxiHome.css create mode 100644 Modules/Taxi/resources/css/taxiOrder.css create mode 100644 Modules/Taxi/resources/js/components/TaxiHome.tsx create mode 100644 Modules/Taxi/resources/js/components/TaxiOrder.tsx create mode 100644 Modules/Taxi/resources/js/page/taxiHomePage.tsx create mode 100644 Modules/Taxi/resources/js/page/taxiOrderPage.tsx create mode 100644 Modules/Taxi/resources/js/types/taxiOrderType.ts create mode 100644 Modules/Taxi/resources/views/.gitkeep create mode 100644 Modules/Taxi/resources/views/index.blade.php create mode 100644 Modules/Taxi/resources/views/layouts/master.blade.php create mode 100644 Modules/Taxi/resources/views/taxi_home.blade.php create mode 100644 Modules/Taxi/resources/views/taxi_order.blade.php diff --git a/Modules/Taxi/resources/assets/js/app.jsx b/Modules/Taxi/resources/assets/js/app.jsx new file mode 100644 index 0000000..9645277 --- /dev/null +++ b/Modules/Taxi/resources/assets/js/app.jsx @@ -0,0 +1,6 @@ +import { createRoot } from 'react-dom/client'; +import MenuApp from './components/MenuApp.jsx'; // Создайте этот файл, если используете React + +const container = document.getElementById('root'); +const root = createRoot(container); +root.render(); diff --git a/Modules/Taxi/resources/assets/sass/app.scss b/Modules/Taxi/resources/assets/sass/app.scss new file mode 100644 index 0000000..e69de29 diff --git a/Modules/Taxi/resources/css/taxiHome.css b/Modules/Taxi/resources/css/taxiHome.css new file mode 100644 index 0000000..56b3ff5 --- /dev/null +++ b/Modules/Taxi/resources/css/taxiHome.css @@ -0,0 +1,44 @@ +table { + + & td { + padding: 5px; + } + & tr:nth-child(odd) { + background-color: #eeeeee; +} +} + +#taxi__order-create{ + padding: 10px; +} + +#taxi__home__filter-form{ + width: 20%; +} + +.taxi-btn{ + margin: 25px 0; +} + +.elem--title.el-title--big{ + padding: 7px; + margin: 50px 0 25px 0; + border-left: 5px solid #7864eb; + font-size: 1.3rem; + background: linear-gradient(90deg, rgb(237 234 255) 0%, rgb(255 255 255) 75%); + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + display: inline-block; + min-width: 400px; +} + +.form-field-block{ + display: flex; +} + +.taxi-orders__order-options{ + + & button { + margin: 10px 0; + } +} diff --git a/Modules/Taxi/resources/css/taxiOrder.css b/Modules/Taxi/resources/css/taxiOrder.css new file mode 100644 index 0000000..9f23b1d --- /dev/null +++ b/Modules/Taxi/resources/css/taxiOrder.css @@ -0,0 +1,3 @@ +.order-create__btn-block{ + margin: 20px 0; +} \ No newline at end of file diff --git a/Modules/Taxi/resources/js/components/TaxiHome.tsx b/Modules/Taxi/resources/js/components/TaxiHome.tsx new file mode 100644 index 0000000..62621eb --- /dev/null +++ b/Modules/Taxi/resources/js/components/TaxiHome.tsx @@ -0,0 +1,387 @@ +import { tr } from "date-fns/locale"; +import React, { useEffect, useState, useMemo, useContext } from "react"; +import { TaxiOrder_type, TaxiOrder_initial, TaxiOrder_fieldName, TaxiOrder_tableData } from '../types/taxiOrderType'; +import { differenceInDays } from 'date-fns'; +import { getCsrfToken } from "../../../../../resources/js/services/getCsrfService"; +import { Button, TextInput, Select, Option } from '@SharePoint/rencredit_uikit'; +import { EntityHistoryProps } from "../../../../../resources/js/components/entityHistory/EntityHistory"; +import { HistoryProvider, HistoryContext } from "../../../../../resources/js/contexts/HistoryContext"; +import { PopupContext } from "../../../../../resources/js/contexts/PopupContext"; +import { PreloaderContext } from "../../../../../resources/js/contexts/PreloaderContext"; +import api from "../../../../../resources/js/api"; + +type EmpSupervisorsData = { + emp_login: string, + emp_supervisor: string +} + +export default function TaxiHome () +{ + //Массив полей для отображения в таблицах с заяками. Учитывается, в том числе, порядок + const rqstTableFields = ['id', 'emp_login', 'emp_supervisor', 'emp_phone', 'taxi_date', 'taxi_time', 'taxi_address_from', 'taxi_address_to', 'cancel_rqst']; + //Формируем объект с полями для таблицы + const rqstTableHeaderFields: Record = Object.assign({}, ...rqstTableFields.map( field => {return {[field]: TaxiOrder_fieldName[field]}})); + const rqstTableHeader:string[] = Object.keys(TaxiOrder_fieldName).map(rqstFieldName => TaxiOrder_fieldName[rqstFieldName]); + const [ccEmp, setCcEmp] = useState([]); + //Стейт для руководителей сотрудников + const [empSupervisors, setEmpSupervisors] = useState([]); + const [allOrders, setAllOrders] = useState([]); + const [filterOrders, setFilterOrders] = useState([]); + const [startSearch, setStartSearch] = useState(false); + const [rqstNumber, setRqstNumber] = useState(''); + const [rqstTime, setRqstTime] = useState(''); + const [rqstLogin, setRqstLogin] = useState(''); + const [orderTimePeriods, setOrderTimePeriods] = useState<[{time_period: string}]>([{time_period: ''}]); + + const popupContext = useContext(PopupContext); + const preloaderContext = useContext(PreloaderContext); + + useEffect ( () => { + api.get('/taxi/getTimePeriods', + ).then(timePeriods_json => setOrderTimePeriods(timePeriods_json.data)); + + // fetch('/public/api/taxi/getTimePeriods', { + // method: 'GET', + // credentials: 'include', + // }).then(timePeriods_resp => timePeriods_resp.json().then( timePeriods_json => { + // setOrderTimePeriods(timePeriods_json); + // })); + + setTimeout(() => { + popupContext.addPopupArrTest([ + {message: 'для информации', timeOut: true, type: 'attention'} + ]) + popupContext.addPopupArrTest([ + {message: 'ошибка', timeOut: true, type: 'error'} + ]) + }, 1000); + console.log(Object.keys(TaxiOrder_fieldName)) + }, []) + + //ГАВРИЛОВ + //ЕСЛИ ОБЪЕКТ СО ЗНАЧЕНИЯМИ ДЛЯ ПОИСКА ПУСТОЙ - НЕ ВЫПОЛНЯЕМ ПОИСК, ВОЗВРАЩАЕМ ОПОВЕЩЕНИЕ О ПУСТЫХ УСЛОВИЯХ + const getFilterOrders = () => { + console.log(rqstTime) + console.log(rqstNumber) + console.log(rqstLogin) + setStartSearch(true); + // ГАВРИЛОВ. проверь + api.post('/taxi/getFilterOrders', { + id: rqstNumber, + taxi_time: rqstTime, + emp_login: rqstLogin + }).then(filterOrdersJson => { + setFilterOrders(filterOrdersJson.data); + }) + // fetch('/public/api/taxi/getFilterOrders', { + // credentials: 'include', + // method: 'POST', + // body: JSON.stringify({ + // id: rqstNumber, + // taxi_time: rqstTime, + // emp_login: rqstLogin + // }), + // headers: { + // 'content-type': 'application/json' + // } + // }).then(filterOrdersRqst => filterOrdersRqst.json()) + // .then(filterOrdersJson => { + // setFilterOrders(filterOrdersJson); + // }) + } + + const timePeriodOptions: Option[] = useMemo(() => { + return orderTimePeriods.map((time: {time_period: string}) => { + return { + caption: time.time_period, + value: time.time_period, + id: time.time_period + } + }) + }, [orderTimePeriods]) + + const empLoginOptions: Option[] = useMemo(() => { + return ccEmp.map((empLogin: string) => { + return { + caption: empLogin, + value: empLogin, + id: empLogin + } + }) + }, [ccEmp]) + + useEffect ( () => { + Promise.all( + [ + // fetch('/public/api/taxi/getEmpInfo', { + // credentials: 'include', + // method: 'GET', + // }).then( empInfo_resp => empInfo_resp.json() ), + api.get('taxi/getEmpInfo'), + api.get('taxi/getActiveOrders'), + // fetch('/public/api/taxi/getActiveOrders', { + // credentials: 'include', + // method: 'GET', + // }).then( allOrders_resp => allOrders_resp.json() ) + ] + ).then( + ([ + {data: empInfo_json}, + {data: allOrders_json} + ]) => { + setCcEmp(empInfo_json.map( (empInfoEl: {emp_login: String}) => empInfoEl.emp_login )); + setAllOrders(allOrders_json); + setEmpSupervisors(empInfo_json.map( (empInfoEl: {emp_login: String, emp_group: String}) => ({emp_login: empInfoEl.emp_login, emp_supervisor: empInfoEl.emp_group}) )); + } + ) + + }, []) + + const isReady = ccEmp.length > 0 && orderTimePeriods.length > 0; + + useEffect ( () => { + console.log(!isReady) + preloaderContext.setPreloaderVisible(!isReady) + // setPreloaderProp(!isReady); + // console.log(empSupervisors) + }, [isReady]) + + if (!ccEmp.length || !orderTimePeriods.length) { + //setIsReady(true); + return; + } else { + //setIsReady(false); + // console.log(allOrders); + console.log(ccEmp); + console.log(orderTimePeriods); + } + + // ГАВРИЛОВ. ОФОРМИ РЕЗУЛЬТАТЫ ПОИСКА. ПОСЛЕ ПОИСКА ПЛАВНО ОПУСКАЙ ДО ТАБЛИЦЫ РЕЗУЛЬТАТЫ ПОИСКА, ТАКЖЕ ВЫВЕДИ ЗОТЯ БЫ ТЕКСТ "РЕЗУЛЬТАТЫ ПОИСКА, СЕЙЧАС ЭТО ПРОСТО ТАБЛИЦА" + + //Гаврилов + //Реализовать подтягивание информации + //Реализовать переключение между БД (new and old Magic) + + //console.log(sanctumToken()) + + let newDate = new Date('2024-06-05'); + newDate.setHours(0, 0, 0); + + // function callHistory(entityId) { + // console.log(entityId) + + // return fakeObjArr; + // } + + + // let resultObj = { + // entityId: 1, + // entityProps: fakeObjArr + // } + + return ( +
+ */} + +
+
+ { + startSearch ? + + + + { + rqstTableHeader.map( (headEl, headElIndex) => + ) + } + + + + { + filterOrders.length ? + filterOrders.map( (rqstData: TaxiOrder_type, rqstIndex: number) => + + { + Object.keys(TaxiOrder_initial).map(initField => + ) + } + ) + : + + + } + +
+ {headEl} +
+ {initField == 'cancel_rqst' ? (rqstData[initField] ? 'Нет' : 'Да') : rqstData[initField]} +
Запросов не найдено
+ : '' + } +
+ + ) +} + + +function RqstTable(props: {allOrders: TaxiOrder_type[], rqstTableHeader: Record, empSupervisors: EmpSupervisorsData[]}){ + const historyContext = useContext(HistoryContext); + if (!historyContext) { + return null; + } + let newDate = new Date('2024-06-05'); + newDate.setHours(0, 0, 0); + return ( + props.allOrders.length ? + + + + { + Object.entries(props.rqstTableHeader).map((el, index) => + + ) + } + + + + + { + props.allOrders.map( (rqstData: TaxiOrder_type, rqstIndex: number) => + + { + Object.entries(props.rqstTableHeader).map( el => { + return ( + // Если поле - руководитель сотрудника - вычисляем значение, ориентируясь на список props.empSupervisors + el[0] === 'emp_supervisor' ? + + : + ) + }) + } + + + ) + } + +
{el[1]}Управление
{ props.empSupervisors.find(empData => empData.emp_login == rqstData.emp_login)?.emp_supervisor }{ rqstData[el[0]] } + {/* Можно взаимодействовать только с заявками на такси на сегодняшнюю, либо завтрашнюю дату */} + {differenceInDays(new Date(rqstData.taxi_date), new Date()) >= 0 && !rqstData.cancel_rqst ? + <> +
+ :
Нет активных заявок
+ ) +} diff --git a/Modules/Taxi/resources/js/components/TaxiOrder.tsx b/Modules/Taxi/resources/js/components/TaxiOrder.tsx new file mode 100644 index 0000000..aa0ac67 --- /dev/null +++ b/Modules/Taxi/resources/js/components/TaxiOrder.tsx @@ -0,0 +1,635 @@ +import React, { useEffect, useContext, useState, useMemo } from "react"; +import { TaxiOrder_type, TaxiOrder_initial } from '../types/taxiOrderType'; +import { addDays, format } from 'date-fns'; +import { getCsrfToken } from "../../../../../resources/js/services/getCsrfService"; +import { Button, TextInput, Select, Option } from '@SharePoint/rencredit_uikit'; +import FormValidErr, { FormValidErrObject } from "../../../../../resources/js/components/formValidErr/FormValidErr"; +import { PopupContext } from "../../../../../resources/js/contexts/PopupContext"; +import { EntityHistoryProps } from "../../../../../resources/js/components/entityHistory/EntityHistory"; +import { PreloaderContext } from "../../../../../resources/js/contexts/PreloaderContext"; + +//Гаврилов типы для пропсов? +// export default function TaxiOrder( {rqstId, setPreloaderProp}: {rqstId: number | undefined, setPreloaderProp: CallableFunction} ) +export default function TaxiOrder( {rqstId}: {rqstId: number | undefined} ) +{ + let newDate = new Date('2024-06-05'); + newDate.setHours(0, 0, 0); + let fakeObjArr: EntityHistoryProps[] = [ + { + changeAction: 'insert', + changeAuthor: 'login', + changeDate: newDate, + changeDetails: [ + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле2', + propValue: 'значение2' + } + ] + }, + { + changeAction: 'insert', + changeAuthor: 'login', + changeDate: new Date('2024-06-05'), + changeDetails: [ + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле2', + propValue: 'значение2' + } + ] + }, + { + changeAction: 'insert', + changeAuthor: 'login', + changeDate: new Date('2024-06-05'), + changeDetails: [ + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле', + propValue: 'значение' + }, + { + propName: 'поле2', + propValue: 'значение2' + } + ] + }, + { + changeAction: 'update', + changeAuthor: 'login2', + changeDate: new Date('2025-06-05'), + changeDetails: [ + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле5', + propValue: 'значение6' + } + ] + }, + { + changeAction: 'update', + changeAuthor: 'login2', + changeDate: new Date('2025-06-05'), + changeDetails: [ + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле3', + propValue: 'значение4' + }, + { + propName: 'поле5', + propValue: 'значение6' + } + ] + } + ]; + + const preloaderContext = useContext(PreloaderContext); + + //ГАВРИЛОВ ПОСТОЯННЫЙ ПЕРЕРЕНДЕРИНГ СПРОСИТЬ У САШИ. ЭЛЕМЕНТ НЕ МИГАЕТ В КОНСОЛИ, НО ПИШЕТ ПОСТОЯННО ПЕРЕРЕНДЕР + console.log('🔁 TaxiForm перерендерился!'); + interface UserData { + emp_id: number, + emp_address: string, + emp_lastname: string, + emp_name: string, + emp_surname: string, + emp_login: string | null + emp_phone: string, + //Все остальные поля объекта могут быть пустыми + [key: string]: unknown, + full_name: string, + }; + const UserData_initial: UserData = { + emp_id: 0, + emp_address: '', + emp_lastname: '', + emp_name: '', + emp_surname: '', + emp_login: '', + emp_phone: '', + full_name: '', + // _token: getCsrfToken() + }; + //Проверка загрузки необходимых для начала работ данных. После успешного получения всех данных происходит рендеринг + const [checkLoad, setCheckLoad] = useState( + { + ccEmp: false, + orderData: false, + checkEditOrderUserData: false, + getTimePeriods: false, + checkOfficeAddress: false, + } + ); + const todayDate = new Date(); + //Данные по всем пользователям + const [ccEmp, setCcEmp] = useState( [UserData_initial] ); + //Данные по редактируемому запросу (если вызвано редактирование) + const [orderData, setOrderData] = useState(TaxiOrder_initial); + //Данные по пользователю, чей запрос редактируется (если вызвано редактирование запроса) + const [editOrderUserData, setEditOrderUserData] = useState(UserData_initial); + //Данные по временным промежуткам + const [orderTimePeriods, setOrderTimePeriods] = useState< {time_period: string, is_morning_time: number}[] >( + [ {time_period: '', is_morning_time: 0} ] + ); + //Массив доступных для заказа такси дат для их дальнейшего преобразования в теги option селекта + const [dateOrderArr, setDateOrderArr] = useState( + [ + format(todayDate, "yyyy-MM-dd"), + format(addDays(todayDate, 1), "yyyy-MM-dd") + ] + ); + const popupContext = useContext(PopupContext); + useEffect ( () => { + setFormCreateVisible(true); + setFormCreateValidObj([{fieldName: 'testField', fieldErrors: ['errOne']}]); + console.log(popupContext) + // console.log() + // setTimeout(() => { + // popupContext.addPopupArrTest([ + // {message: 'для информации', timeOut: true, type: 'attention'} + // ]) + // }, 1000); + // setTimeout(() => { + // setPopupArrProp([ + // {message: 'для информации', timeOut: true, type: 'attention'}, + // ]) + // }, 1000); + // setTimeout(() => { + // setPopupArrProp([ + // {message: 'для информации', timeOut: false, type: 'info'}, + // ]) + // }, 2000); + // setTimeout(() => { + // setPopupArrProp([ + // {message: 'для информации', timeOut: false, type: 'info'}, + // ]) + // }, 3000); + // setPopupArrProp([ + // {message: 'для информации', timeOut: false, type: 'info'}, + // {message: 'успешно', timeOut: true, type: 'success'}, + // {message: 'ошибка', timeOut: true, type: 'error'}, + // {message: 'обратить внимание', timeOut: true, type: 'attention'} + // ]) + }, []) + + const [formCreateVisible, setFormCreateVisible] = useState(false); + const [formCreateValidErrObj, setFormCreateValidObj] = useState([{fieldName: null, fieldErrors: []}]) + + //ГАВРИЛОВ ДОБАВИТЬ ВСПЛЫВАЮЩЕЕ ОКНО ЕСЛИ ПРОИСХОДИТ НЕСООТВЕТСТВИЕ ВРЕМЕНИ И ДАТЫ ЗАКАЗА ТАКСИ? А НЕ ПРОСТО УДАЛЯТЬ ЗНАЧЕНИЕ ИЗ СОСЕДНЕГО ПОЛЯ? + + //Адреса офисов + const [officeAddressInfo, setOfficeAddressInfo] = useState< {place: string, address: string}[] >( + [ {place: '', address: ''} ] + ); + //Адрес офиса, где работает сотрудник. Определяется на этапе выбора логина + const [empOfficeAddress, setEmpOfficeAddress] = useState(null); + //const [orderTime, setOrderTime] = useState(null); + //const [orderDate, setOrderDate] = useState(null); + // const [orderAddressFrom, setOrderAddressFrom] = useState(null); + // const [orderAddressTo, setOrderAddressTo] = useState(null); + + function gotoHome() + { + document.location.href = '/public/taxi/home'; + } + + //Гаврилов. Не передаешь CSRF токен + //Отправка заказа на такси + function sendTaxiOrder () + { + console.log(orderData) + console.log(editOrderUserData) + //return + // setPreloaderProp(true, 'создаем заявку') + preloaderContext.setPreloaderVisible(true); + preloaderContext.setPreloaderText('создаем заявку'); + let popupType; + fetch('/public/api/taxi/' + (rqstId ? `editOrder/${rqstId}` : 'createRqst'), { + credentials: 'include', + method: (rqstId ? "PATCH" : "POST"), + body: JSON.stringify(orderData), + headers: { + 'content-type': 'application/json', + 'Accept': 'application/json' + } + }).then(result => { + preloaderContext.setPreloaderVisible(false); + // setPreloaderProp(false) + result.json().then(jsonResult => { + console.log(jsonResult) + if (!result.ok) { + //ГАВРИЛОВ здесь обработка ошибок валидации формы + if (result.status == 422) { + // setPopupArrProp( + // [ + // //ГАВРИЛОВ обработка ошибки + // {message: 'Произошла ошибка! Заявка не создана', type: 'error'}, + // ] + // ) + } else { + // setPopupArrProp( + // [ + // //ГАВРИЛОВ обработка ошибки + // {message: jsonResult.result_msg, type: 'error'}, + // ] + // ) + } + popupType = 'error' + } else { + popupType = 'success' + } + popupContext.addPopupArrTest( + [ + {message: jsonResult.message, type: popupType}, + ] + ) + }) + }) + } + +//Функция, собирающая нужный массив для формирования из него списка option для select +function transformToOptionsFunc ( + dataArr: T[], + dataKey?: keyof T +): Option[] { + let optionArr = dataArr.map(item => { + //Без проверки ниже, Typescript ругается на условный атрибут dataKey, который может отсутствовать, но при этом укаан как относящийся к Дженерику + const value = dataKey !== undefined + ? item[dataKey] + : item; + + return { + caption: String(value), + value: String(value), + id: String(value) + }; + }); + return optionArr; +} + + +/** + * Метод проверки соответствует ли дата и время заказа логике. Наприме, если дата заказа сегодняшняя - нельзя выбрать утренний промежуток времени + * @param orderTime время заказа такси + * @param orderDate дата заказа такси + * @returns результат проверки соответствия даты и времени заказа + */ +function checkTimeAndDate (orderTime: string|null, orderDate: string|null): boolean +{ + // console.log(orderTime) + // console.log(!orderTime) + // console.log(orderDate) + // console.log(!orderDate) + if (!orderTime || !orderDate) { + //console.log(1) + return true; + } + let isMorningTimeCheck = orderTimePeriods.filter( e => e.time_period == orderTime )[0].is_morning_time; + // console.log(isMorningTimeCheck) + //Если выбранная дата заказа больше текущей - заказ на завтра, можно выбирать любую дату + if (!(new Date(orderDate) > todayDate)) { + //console.log(2) + return !isMorningTimeCheck; + } + return true; +} + + // const ccEmpList: Option[] = useMemo(() => { + // return ccEmp.map(empData => { + // return { + // caption: empData.emp_login, + // value: empData.emp_login, + // id: empData.emp_login + // } + // }) + // }, [ccEmp]); + + // console.log(ccEmpList) + + + const ccEmpList = useMemo( () => { + return transformToOptionsFunc(ccEmp, 'emp_login'); + }, [ccEmp]); + + const orderDateList = useMemo( () => { + return transformToOptionsFunc(dateOrderArr); + }, [dateOrderArr]); + + const orderTimeList = useMemo( () => { + return transformToOptionsFunc(orderTimePeriods, 'time_period') + }, [orderTimePeriods]); + + //Загрузка данных для старта работ + useEffect ( () => { + //Получаем информацию по сотруднику при загрузке страницы + fetch('/public/api/taxi/getEmpInfo', { + credentials: 'include', + method: 'GET', + // headers: new Headers({ + // 'Authorization': `Bearer ${sanctumToken()}` + // }) + }).then(empInfo_resp => empInfo_resp.json().then(empInfo_json => { + console.log(empInfo_json) + console.log(editOrderUserData) + setCcEmp(empInfo_json); + setCheckLoad(loadObj => ( {...loadObj, ccEmp: true} )); + })); + //Получаем доступные временные промежутки для заказа такси + fetch('/public/api/taxi/getTimePeriods', { + method: 'GET', + credentials: 'include', + // headers: new Headers({ + // 'Authorization': `Bearer ${sanctumToken()}` + // }) + }).then(timePeriods_resp => timePeriods_resp.json().then(timePeriods_json => { + setOrderTimePeriods(timePeriods_json); + setCheckLoad(loadObj => ( {...loadObj, getTimePeriods: true} )); + })); + //ГАВРИЛОВ. ВЕЗДЕ В FETCH ЗАПРОСАХ ПЕРЕХВАТЫВАЙ ОШИБКИ И ВЫВОДИ СООБЩЕНИЯ ОБ ОШИБКЕ. НАПРИМЕМР С 401. В ЭТОМ СЛУЧАЕ НУЖНО ПЕРЕБРАСЫВАТЬ ПОЛЬЗОВАТЕЛЯ НА СТРАНИЦУ АУТЕНТИФИКАЦИИ + //Получае адреса всех офисов, куда могут заказываться такси? + fetch('/public/api/taxi/getOfficeAddress', { + method: 'GET', + credentials: 'include', + }).then(officeAddress_resp => {officeAddress_resp.json().then(officeAddress_json => { + setOfficeAddressInfo(officeAddress_json); + setCheckLoad(loadObj => ( {...loadObj, checkOfficeAddress: true} )); + })}); + //Если в пропсах передается rqstId, происходит редактирование заявки, а не создание новой - получаем данные по редактируемой заявке на такси + if (rqstId) { + fetch(`/public/api/taxi/getOrderById/${rqstId}`, { + method: 'GET', + credentials: 'include', + // headers: new Headers({ + // 'Authorization': `Bearer ${sanctumToken()}` + // }) + }).then(orderData_resp => orderData_resp.json().then( orderData_json => { + console.log(orderData_json) + setOrderData(orderData_json); + setCheckLoad(loadObj => ({...loadObj, orderData: true})); + })); + } + }, []) + + //гаврилов. Нужно ввести объект с данными по запросу и туда класть только нужные данные , а не все параметры пользователя. и тогда не нужно нигде проверять rqstId. Внизу в методе класть в этот объект все нужные параметры + + useEffect ( () => { + //Гаврилов. Причем тут проверка логина? Зачем она? + if (rqstId && orderData.emp_login) { + //Если передан id запроса на редактирование, устанавливаем значение с данными пользователя редактируемого запроса + fetch(`/public/api/taxi/getEmpInfo/${orderData.emp_login}`).then(userData_resp => userData_resp.json().then(userData_json => { + //гаврилов. Вот здесь нужно класть данные в orderData, а также заполнять адрес из и адрес куда + setEditOrderUserData(userData_json[0]); + //setOrderData(prevData => ({...prevData, userData_json[0]})); + //setEmpAddress(editOrderUserData['emp_address']); + setCheckLoad(loadObj => ( {...loadObj, checkEditOrderUserData: true} )); + //ГАВРИЛОВ. вынеси в отедльную функцию определение адреса офиса? + setEmpOfficeAddress(officeAddressInfo.filter(addressInfo => addressInfo.place == userData_json[0].emp_area)[0].address); + })); + } + }, [orderData.emp_login]) + + //Итоговая проверка все ли необходимые данные для рендеринга получены + const isReady = rqstId ? + checkLoad.ccEmp && checkLoad.checkEditOrderUserData && checkLoad.orderData && checkLoad.checkOfficeAddress && checkLoad.getTimePeriods + : checkLoad.ccEmp; + + //Регулировка видимости прелоадера в зависимости от того все ли данные для рендеринга получены или нет + useEffect ( () => { + //isReady ? setPreloaderProp(false) : setPreloaderProp(true); + isReady ? preloaderContext.setPreloaderVisible(false) : preloaderContext.setPreloaderVisible(true); + }, [isReady]) + + if (!isReady) { + return; + } + + return ( +
+ {/* */} +
+
+

{rqstId ? 'Редактирование' : 'Создание'} заявки на такси

+
+ {/* */} +
+ {/* ГАВРИЛОВ как защищаешься от csrf если комментируешь поле ниже? */} + {/* */} +
+ dateData.value === orderData.taxi_time) : null} + size = 'm' + onChange = {(_, sel:{caption:string, id:string, value:string}) => { + let selOrderTime = (sel ? sel.value : null); + setOrderData(prevData => ( {...prevData, taxi_time: selOrderTime} )); + //Проверяем относится ли выбранный промежуток времени заказа к утру или нет. Если выбран утренний промежуток, дата откуда - адрес сотрудника, адрес куда - офис, если выбран вечерний промежуток - наоборот + if (orderTimePeriods.filter( e => selOrderTime == e.time_period )[0].is_morning_time == 1) { + console.log(1) + setOrderData(prevData => ( {...prevData, taxi_address_from: editOrderUserData.emp_address, taxi_address_to: empOfficeAddress} )); + } else { + console.log(2) + console.log(empOfficeAddress) + setOrderData(prevData => ( {...prevData, taxi_address_from: empOfficeAddress, taxi_address_to: editOrderUserData.emp_address} )); + } + //Если проверка соответствия и времени заказа не выполняется, сбрасываем дату + if (!checkTimeAndDate(selOrderTime, orderData.taxi_date)) { + popupContext.addPopupArrTest( + [{message: 'Несоответствие времени и даты', type: 'error'}] + ) + setOrderData(prevData => ({...prevData, taxi_date: null})); + } + }} + /> +
+
+