388 lines
14 KiB
TypeScript
388 lines
14 KiB
TypeScript
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<keyof TaxiOrder_tableData, string> = 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<string[]>([]);
|
||
//Стейт для руководителей сотрудников
|
||
const [empSupervisors, setEmpSupervisors] = useState<EmpSupervisorsData[]>([]);
|
||
const [allOrders, setAllOrders] = useState<TaxiOrder_type[]>([]);
|
||
const [filterOrders, setFilterOrders] = useState<TaxiOrder_type[]>([]);
|
||
const [startSearch, setStartSearch] = useState<boolean>(false);
|
||
const [rqstNumber, setRqstNumber] = useState<string>('');
|
||
const [rqstTime, setRqstTime] = useState<string>('');
|
||
const [rqstLogin, setRqstLogin] = useState<string>('');
|
||
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<string>[] = 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<string>[] = 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 (
|
||
<div id='taxi-container'>
|
||
<Button
|
||
type = 'button'
|
||
text = 'Новая заявка'
|
||
onClick = {
|
||
() => document.location.href = 'createRqst'
|
||
}
|
||
className = "taxi-btn"
|
||
/>
|
||
<div className = "elem--title el-title--big">Активные заявки</div>
|
||
<div className='container__table-block' id='taxi__rqst--active'>
|
||
<HistoryProvider>
|
||
<RqstTable
|
||
allOrders={allOrders}
|
||
rqstTableHeader={rqstTableHeaderFields}
|
||
empSupervisors={empSupervisors}
|
||
/>
|
||
</HistoryProvider>
|
||
</div>
|
||
<div id="taxi__home__filter-form">
|
||
<div className = "elem--title el-title--big">Поиск заявки</div>
|
||
<form>
|
||
<input
|
||
type="hidden"
|
||
name="_token"
|
||
value={getCsrfToken()}
|
||
/>
|
||
<div>
|
||
<TextInput
|
||
labelText = 'Номер заявки'
|
||
value = {rqstNumber}
|
||
onChange = {(e: string) => setRqstNumber(e)}
|
||
/>
|
||
{/* <label htmlFor="">Номер заявки</label>
|
||
<input type="number" onChange={ e => {
|
||
setRqstNumber(e.target.value)
|
||
}}></input> */}
|
||
</div>
|
||
{/* <div>
|
||
<label htmlFor="">Дата с</label>
|
||
<input type="date" />
|
||
</div>
|
||
<div>
|
||
<label htmlFor="">Дата по</label>
|
||
<input type="date" />
|
||
</div> */}
|
||
<div>
|
||
<Select
|
||
labelText = "Время"
|
||
options = {timePeriodOptions}
|
||
size = '1'
|
||
onChange = { (e: string) => {
|
||
setRqstTime(e)
|
||
}}
|
||
/>
|
||
{/* <label htmlFor="">Время</label>
|
||
<select name="taxi_time" id="" onChange={ e => {
|
||
setRqstTime(e.target.value)
|
||
}}>
|
||
<option key='0' value=''></option>
|
||
{
|
||
orderTimePeriods.map( (timePeriodEl, timePeriodIndex ) =>
|
||
<option key={timePeriodIndex++} value={timePeriodEl.time_period}>{timePeriodEl.time_period}</option>
|
||
)
|
||
}
|
||
</select> */}
|
||
</div>
|
||
<div>
|
||
<Select
|
||
labelText = "Сотрудник"
|
||
options = {empLoginOptions}
|
||
size = '1'
|
||
onChange = { (e, selectedOption: {value: string}) => {
|
||
setRqstLogin(selectedOption.value)
|
||
}}
|
||
/>
|
||
{/* <label htmlFor="">Логин</label>
|
||
<select onChange={ e => setRqstLogin(e.target.value) }>
|
||
<option key="0" value=""></option>
|
||
{
|
||
ccEmp.map( (empDataEl: string, empDataIndex: number) =>
|
||
<option key={empDataIndex++} value={empDataEl}>{empDataEl}</option>
|
||
)
|
||
}
|
||
</select> */}
|
||
</div>
|
||
<Button
|
||
className = "taxi-btn"
|
||
type = 'button'
|
||
text = 'Искать'
|
||
onClick = { getFilterOrders }
|
||
size = 's'
|
||
ui = 'secondary'
|
||
/>
|
||
{/* <button type="button" onClick={getFilterOrders}>Искать</button> */}
|
||
</form>
|
||
</div>
|
||
<div id = "container__filter-rqst-table">
|
||
{
|
||
startSearch ?
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
{
|
||
rqstTableHeader.map( (headEl, headElIndex) =>
|
||
<th key={headElIndex} className = "table-header">
|
||
{headEl}
|
||
</th>)
|
||
}
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{
|
||
filterOrders.length ?
|
||
filterOrders.map( (rqstData: TaxiOrder_type, rqstIndex: number) =>
|
||
<tr key={rqstIndex}>
|
||
{
|
||
Object.keys(TaxiOrder_initial).map(initField =>
|
||
<td>
|
||
{initField == 'cancel_rqst' ? (rqstData[initField] ? 'Нет' : 'Да') : rqstData[initField]}
|
||
</td>)
|
||
}
|
||
</tr>)
|
||
: <tr>
|
||
<td>Запросов не найдено</td>
|
||
</tr>
|
||
}
|
||
</tbody>
|
||
</table>
|
||
: ''
|
||
}
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
|
||
function RqstTable(props: {allOrders: TaxiOrder_type[], rqstTableHeader: Record<keyof TaxiOrder_tableData, string>, 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 ?
|
||
<table className="taxi-orders">
|
||
<thead>
|
||
<tr>
|
||
{
|
||
Object.entries(props.rqstTableHeader).map((el, index) =>
|
||
<th key={index} className="table-header">{el[1]}</th>
|
||
)
|
||
}
|
||
<th className = "table-header">Управление</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{
|
||
props.allOrders.map( (rqstData: TaxiOrder_type, rqstIndex: number) =>
|
||
<tr key = {rqstIndex}>
|
||
{
|
||
Object.entries(props.rqstTableHeader).map( el => {
|
||
return (
|
||
// Если поле - руководитель сотрудника - вычисляем значение, ориентируясь на список props.empSupervisors
|
||
el[0] === 'emp_supervisor' ?
|
||
<td key={el[0]}>{ props.empSupervisors.find(empData => empData.emp_login == rqstData.emp_login)?.emp_supervisor }</td>
|
||
: <td key={el[0]}>{ rqstData[el[0]] }</td>
|
||
)
|
||
})
|
||
}
|
||
<td className="taxi-orders__order-options">
|
||
{/* Можно взаимодействовать только с заявками на такси на сегодняшнюю, либо завтрашнюю дату */}
|
||
{differenceInDays(new Date(rqstData.taxi_date), new Date()) >= 0 && !rqstData.cancel_rqst ?
|
||
<>
|
||
<Button
|
||
type = 'button'
|
||
onClick = { () => { document.location.href = `editOrder/${rqstData.id}` } }
|
||
text = {'Редактировать'}
|
||
ui = 'secondaryPurple'
|
||
/>
|
||
<Button
|
||
type = 'button'
|
||
onClick = { () => { document.location.href = `cancelRqst/${rqstData.id}` } }
|
||
text = {'Отменить'}
|
||
ui = 'secondaryPurple'
|
||
/>
|
||
<Button
|
||
type = 'button'
|
||
onClick = { () => { historyContext.getHistoryFromMagic('taxi', rqstData.id, TaxiOrder_fieldName) } }
|
||
text = {'История'}
|
||
ui = 'secondaryPurple'
|
||
/>
|
||
</>
|
||
: ""
|
||
}
|
||
</td>
|
||
</tr>
|
||
)
|
||
}
|
||
</tbody>
|
||
</table>
|
||
: <div>Нет активных заявок</div>
|
||
)
|
||
}
|