594 lines
14 KiB
JavaScript
594 lines
14 KiB
JavaScript
import React, { useState, useEffect, useReducer} from "react";
|
|
import MainContainer from "../../components/MainContainer";
|
|
import api from "../../services/api";
|
|
|
|
//import { data } from '../../components/Report/MTable/data';
|
|
import DatePicker1 from '../../components/Report/DatePicker'
|
|
import DatePicker2 from '../../components/Report/DatePicker'
|
|
//import { Button } from "@material-ui/core";
|
|
|
|
import PropTypes from 'prop-types';
|
|
import Box from '@mui/material/Box';
|
|
|
|
|
|
|
|
import SearchIcon from "@material-ui/icons/Search";
|
|
import TextField from "@material-ui/core/TextField";
|
|
import InputAdornment from "@material-ui/core/InputAdornment";
|
|
import Button from "@material-ui/core/Button";
|
|
|
|
import MaterialTable from 'material-table';
|
|
|
|
import Delete from '@material-ui/icons/Delete';
|
|
import Edit from '@material-ui/icons/Edit';
|
|
|
|
|
|
import { render } from '@testing-library/react';
|
|
|
|
// import Modal from "../../../..ChatEnd/ModalChatEnd";
|
|
import Modal from "../../components/ModalUpdateScheduleReminder";
|
|
|
|
import openSocket from "socket.io-client";
|
|
|
|
|
|
|
|
|
|
import { toast } from "react-toastify";
|
|
import toastError from "../../errors/toastError";
|
|
import ConfirmationModal from "../../components/ConfirmationModal";
|
|
|
|
|
|
|
|
const reducerQ = (state, action) =>{
|
|
|
|
if(action.type === 'LOAD_QUERY'){
|
|
|
|
|
|
const queries = action.payload
|
|
const newQueries = []
|
|
|
|
queries.forEach((query) => {
|
|
|
|
const queryIndex = state.findIndex((q) => q.id === query.id)
|
|
|
|
if(queryIndex !== -1){
|
|
state[queryIndex] = query
|
|
}
|
|
else{
|
|
newQueries.push(query)
|
|
}
|
|
|
|
})
|
|
|
|
return [...state, ...newQueries]
|
|
}
|
|
|
|
|
|
|
|
// if (action.type === "UPDATE_SCHEDULING") {
|
|
|
|
// const scheduling = action.payload;
|
|
// const schedulingIndex = state.findIndex((u) => u.id === +scheduling.id);
|
|
|
|
//
|
|
|
|
// if (schedulingIndex !== -1) {
|
|
// state[schedulingIndex] = scheduling;
|
|
// return [...state];
|
|
// } else {
|
|
// return [scheduling, ...state];
|
|
// }
|
|
// }
|
|
|
|
if (action.type === "DELETE_SCHEDULING") {
|
|
|
|
const scheduleId = action.payload;
|
|
|
|
const scheduleIndex = state.findIndex((u) => u.id === scheduleId);
|
|
|
|
if (scheduleIndex !== -1) {
|
|
state.splice(scheduleIndex, 1);
|
|
}
|
|
return [...state];
|
|
|
|
}
|
|
|
|
// if (action.type === "DELETE_QUEUE") {
|
|
// const queueId = action.payload;
|
|
// const queueIndex = state.findIndex((q) => q.id === queueId);
|
|
// if (queueIndex !== -1) {
|
|
// state.splice(queueIndex, 1);
|
|
// }
|
|
// return [...state];
|
|
// }
|
|
|
|
|
|
|
|
if (action.type === "RESET") {
|
|
return [];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// const reducer = (state, action) => {
|
|
|
|
// if (action.type === "LOAD_STATUS_CHAT_END") {
|
|
// const users = action.payload;
|
|
// const newUsers = [];
|
|
|
|
// users.forEach((user) => {
|
|
// const userIndex = state.findIndex((u) => u.id === user.id);
|
|
// if (userIndex !== -1) {
|
|
// state[userIndex] = user;
|
|
// } else {
|
|
// newUsers.push(user);
|
|
// }
|
|
// });
|
|
|
|
// return [...state, ...newUsers];
|
|
// }
|
|
|
|
// if (action.type === "RESET") {
|
|
// return [];
|
|
// }
|
|
// };
|
|
|
|
|
|
|
|
|
|
function Item(props) {
|
|
const { sx, ...other } = props;
|
|
return (
|
|
<Box
|
|
sx={{
|
|
bgcolor: (theme) => (theme.palette.mode === 'dark' ? '#101010' : '#fff'),
|
|
color: (theme) => (theme.palette.mode === 'dark' ? 'grey.300' : 'grey.800'),
|
|
border: '1px solid',
|
|
borderColor: (theme) =>
|
|
theme.palette.mode === 'dark' ? 'grey.800' : 'grey.300',
|
|
p: 1,
|
|
m: 1,
|
|
borderRadius: 2,
|
|
fontSize: '0.875rem',
|
|
fontWeight: '700',
|
|
...sx,
|
|
}}
|
|
{...other}
|
|
/>
|
|
);
|
|
}
|
|
|
|
Item.propTypes = {
|
|
sx: PropTypes.oneOfType([
|
|
PropTypes.arrayOf(
|
|
PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool]),
|
|
),
|
|
PropTypes.func,
|
|
PropTypes.object,
|
|
]),
|
|
};
|
|
|
|
|
|
|
|
// let columnsData = [
|
|
|
|
// { title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} style={{width: 40, borderRadius: '50%'}}/> },
|
|
|
|
// { title: 'Nome', field: 'ticket.contact.name' },
|
|
// { title: 'Contato', field: 'ticket.contact.number' },
|
|
// { title: 'schedulingTime', field: 'schedulingTime' },
|
|
// { title: 'schedulingDate', field: 'schedulingDate' },
|
|
// { title: 'message', field: 'message' },
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
const SchedulesReminder = () => {
|
|
|
|
|
|
|
|
//--------
|
|
const [searchParam] = useState("");
|
|
const [loading, setLoading] = useState(null);
|
|
//const [hasMore, setHasMore] = useState(false);
|
|
const [pageNumber, setPageNumber] = useState(1);
|
|
// const [users, dispatch] = useReducer(reducer, []);
|
|
//const [columns, setColums] = useState([])
|
|
const [startDate, setDatePicker1] = useState(new Date())
|
|
const [endDate, setDatePicker2] = useState(new Date())
|
|
|
|
const [query, dispatchQ] = useReducer(reducerQ, [])
|
|
const [contactNumber, setContactNumber] = useState("");
|
|
|
|
const [resetChild, setReset] = useState(false)
|
|
|
|
const [selectedSchedule, setSelectedSchedule] = useState(null);
|
|
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
|
|
const [dataRows, setData] = useState([]);
|
|
|
|
const [statusEndChat, setStatusEndChat] = useState(null)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
|
|
|
socket.on("schedulingNotify", (data) => {
|
|
|
|
|
|
|
|
setLoading(true);
|
|
|
|
// if (data.action === "update" || data.action === "create") {
|
|
|
|
//
|
|
|
|
// // dispatchQ({ type: "UPDATE_SCHEDULING", payload: data.schedulingNotifyCreate });
|
|
// }
|
|
|
|
if (data.action === "delete") {
|
|
|
|
dispatchQ({ type: "DELETE_SCHEDULING", payload: +data.schedulingNotifyId });
|
|
//handleDeleteRows(data.schedulingNotifyId)
|
|
}
|
|
|
|
setLoading(false);
|
|
|
|
|
|
});
|
|
|
|
return () => {
|
|
socket.disconnect();
|
|
};
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
// dispatch({ type: "RESET" });
|
|
dispatchQ({ type: "RESET" })
|
|
|
|
setPageNumber(1);
|
|
}, [searchParam]);
|
|
|
|
|
|
//natalia
|
|
useEffect(() => {
|
|
// setLoading(true);
|
|
|
|
const delayDebounceFn = setTimeout(() => {
|
|
|
|
const fetchStatusChatEnd = async () => {
|
|
try {
|
|
const statusChatEndLoad = await api.get("/statusChatEnd", {
|
|
params: { searchParam, pageNumber },
|
|
});
|
|
|
|
// dispatch({ type: "LOAD_STATUS_CHAT_END", payload: statusChatEndLoad.data });
|
|
|
|
|
|
|
|
|
|
// setStatusEndChat(statusChatEndLoad.data.filter(status => (status.id == '2' || status.id == '3')))
|
|
|
|
setStatusEndChat(statusChatEndLoad.data.filter(status => (`${status.id}` === '2' || `${status.id}` === '3')))
|
|
|
|
|
|
//setHasMore(data.hasMore);
|
|
// setLoading(false);
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
};
|
|
|
|
fetchStatusChatEnd();
|
|
|
|
}, 500);
|
|
return () => clearTimeout(delayDebounceFn);
|
|
}, [searchParam, pageNumber]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
setLoading(true);
|
|
|
|
const delayDebounceFn = setTimeout(() => {
|
|
|
|
const fetchQueries = async () => {
|
|
try {
|
|
|
|
const dataQuery = await api.get("/schedules/", {params: {contactNumber, startDate, endDate },});
|
|
|
|
dispatchQ({ type: "RESET" })
|
|
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
|
|
setLoading(false);
|
|
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
};
|
|
|
|
fetchQueries();
|
|
|
|
}, 500);
|
|
return () => clearTimeout(delayDebounceFn);
|
|
|
|
}, [contactNumber, startDate, endDate]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if(!loading){
|
|
|
|
|
|
|
|
setData(query.map(({ scheduleReminder, ...others }) => (
|
|
{ ...others, 'scheduleReminder': `${others.statusChatEndId}` === '3' ? 'Agendamento' : 'Lembrete' }
|
|
)))
|
|
}
|
|
|
|
}, [loading, query])
|
|
|
|
|
|
// Get from child 1
|
|
const datePicker1Value = (data) => {
|
|
|
|
setDatePicker1(data)
|
|
}
|
|
|
|
// Get from child 2
|
|
const datePicker2Value = (data) => {
|
|
|
|
setDatePicker2(data)
|
|
}
|
|
|
|
|
|
|
|
const handleSearch = (event) => {
|
|
setContactNumber(event.target.value.toLowerCase());
|
|
};
|
|
|
|
const handleClear = () => {
|
|
|
|
setContactNumber('')
|
|
|
|
setReset(true)
|
|
|
|
}
|
|
|
|
const handleCloseConfirmationModal = () => {
|
|
setConfirmModalOpen(false);
|
|
|
|
setSelectedSchedule(null);
|
|
};
|
|
|
|
|
|
// const handleDeleteRows = (id) => {
|
|
|
|
// let _data = [...dataRows];
|
|
|
|
// _data.forEach(rd => {
|
|
// _data = _data.filter(t => t.id !== id);
|
|
// });
|
|
// setData(_data);
|
|
|
|
// };
|
|
|
|
|
|
const handleDeleteSchedule = async (scheduleId) => {
|
|
try {
|
|
await api.delete(`/schedule/${scheduleId}`);
|
|
toast.success(("Lembrete/Agendamento deletado com sucesso!"));
|
|
//handleDeleteRows(scheduleId)
|
|
} catch (err) {
|
|
toastError(err);
|
|
}
|
|
|
|
setSelectedSchedule(null);
|
|
};
|
|
|
|
|
|
|
|
const handleUpdateSchedule = async (scheduleData, rowsDataNew) => {
|
|
try {
|
|
|
|
await api.post("/schedule", scheduleData);
|
|
toast.success(("Lembrete/Agendamento atualizado com sucesso!"));
|
|
//////////////////
|
|
|
|
const dataUpdate = [...dataRows];
|
|
const index = rowsDataNew.tableData['id'];
|
|
dataUpdate[index] = rowsDataNew;
|
|
|
|
setData([...dataUpdate].map(({ scheduleReminder, ...others }) => (
|
|
{ ...others, 'scheduleReminder': `${others.statusChatEndId}` === '3' ? 'Agendamento' : 'Lembrete' }
|
|
)));
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
|
} catch (err) {
|
|
toastError(err);
|
|
}
|
|
//
|
|
setSelectedSchedule(null);
|
|
};
|
|
|
|
|
|
const chatEndVal = (data, rowsDataNew) => {
|
|
|
|
if(data){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handleUpdateSchedule(data, rowsDataNew)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
const handleModal = (rowData) => {
|
|
|
|
// NATY
|
|
|
|
render(<Modal
|
|
modal_header={'Editar Lembrete/Agendamentos'}
|
|
func={chatEndVal}
|
|
statusChatEnd={statusEndChat}
|
|
// textBoxFieldSelected={'2'}
|
|
rowData={rowData}
|
|
/>)
|
|
|
|
};
|
|
|
|
return (
|
|
|
|
|
|
<MainContainer>
|
|
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
|
|
|
<Item>
|
|
<TextField
|
|
placeholder='Numero/Nome...'
|
|
type="search"
|
|
value={contactNumber}
|
|
onChange={handleSearch}
|
|
InputProps={{
|
|
startAdornment: (
|
|
<InputAdornment position="start">
|
|
<SearchIcon style={{ color: "gray" }} />
|
|
</InputAdornment>
|
|
),
|
|
}}
|
|
/>
|
|
</Item>
|
|
|
|
|
|
|
|
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={'Data inicio'}/></Item>
|
|
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={true} reset={resetChild} setReset={setReset} title={'Data fim'}/></Item>
|
|
|
|
<Item sx={{ gridColumn: '4 / 5' }}>
|
|
{/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/}
|
|
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
onClick={(e) => handleClear()}
|
|
>
|
|
{"CLEAR"}
|
|
</Button>
|
|
</Item>
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
<Box sx={{
|
|
display: 'grid',
|
|
}}>
|
|
|
|
<Item sx={{ gridColumn: '1', gridRow: 'span 1' }}>
|
|
|
|
|
|
<ConfirmationModal
|
|
title={selectedSchedule && `Deletar ${''+selectedSchedule.statusChatEndId === '2' ? 'lembrete' : 'agendamento'} do dia ${selectedSchedule.schedulingDate.split(' ')[0]} ${selectedSchedule.schedulingDate.split(' ')[1]} ?`}
|
|
open={confirmModalOpen}
|
|
onClose={handleCloseConfirmationModal}
|
|
onConfirm={() => handleDeleteSchedule(selectedSchedule.id)}
|
|
>
|
|
<span>Deseja realmente deletar esse lembrete/agendamento ? </span>
|
|
</ConfirmationModal>
|
|
|
|
<MaterialTable
|
|
title="Lembretes/Agendamentos"
|
|
columns={
|
|
[
|
|
|
|
{ title: 'Foto', field: 'ticket.contact.profilePicUrl', render: rowData => <img src={rowData['ticket.contact.profilePicUrl']} alt="imagem de perfil do whatsapp" style={{width: 40, borderRadius: '50%'}}/> },
|
|
{ title: 'Nome', field: 'ticket.contact.name' },
|
|
{ title: 'Contato', field: 'ticket.contact.number' },
|
|
{ title: 'Lemb/Agen', field: 'scheduleReminder'},
|
|
{ title: 'Envio', field: 'schedulingTime' },
|
|
{ title: 'Data', field: 'schedulingDate' },
|
|
{ title: 'Mensagem', field: 'message', width: "80%" },
|
|
|
|
]
|
|
}
|
|
data={dataRows}
|
|
// icons={tableIcons}
|
|
|
|
actions={[
|
|
{
|
|
icon: Edit,
|
|
tooltip: 'Editar',
|
|
onClick: (event, rowData) => {
|
|
|
|
setSelectedSchedule(rowData);
|
|
handleModal(rowData)
|
|
}
|
|
|
|
},
|
|
{
|
|
icon: Delete,
|
|
tooltip: 'Deletar',
|
|
onClick: (event, rowData) => {
|
|
|
|
setSelectedSchedule(rowData);
|
|
setConfirmModalOpen(true);
|
|
}
|
|
// onClick: handleDeleteRows
|
|
}
|
|
]}
|
|
|
|
options={
|
|
{
|
|
search: true,
|
|
selection: false,
|
|
paging: false,
|
|
padding: 'dense',
|
|
sorting: true,
|
|
//loadingType: 'linear',
|
|
searchFieldStyle: {
|
|
width: 300,
|
|
},
|
|
|
|
pageSize: 20,
|
|
headerStyle: {
|
|
position: "sticky",
|
|
top: "0"
|
|
},
|
|
maxBodyHeight: "400px",
|
|
|
|
rowStyle: {
|
|
fontSize: 12,
|
|
}
|
|
|
|
}}
|
|
/>
|
|
|
|
|
|
</Item>
|
|
|
|
</Box>
|
|
</MainContainer>
|
|
)
|
|
|
|
|
|
};
|
|
|
|
export default SchedulesReminder;
|