Merge branch 'testeA'

pull/1/head
adriano 2022-03-30 11:10:01 -03:00
commit 083e1aeaac
34 changed files with 2202 additions and 278 deletions

View File

@ -1,7 +1,65 @@
import { Request, Response } from "express";
import AppError from "../errors/AppError";
import { getIO } from "../libs/socket";
import DeleteSchedulingNotifyService from "../services/SchedulingNotifyServices/DeleteSchedulingNotifyService";
import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService";
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
// const test = await ListSchedulingNotifyContactService('5517988310949','2022-03-18','2022-03-19');
// const test = await ListSchedulingNotifyContactService('','2022-03-18','2022-03-19');
// const test = await ListSchedulingNotifyContactService('5517988310949');
// console.log('$$$$$$$$$$$$$$$$$$$$$$$$$$ test:\n', test)
type IndexQuery = {
contactNumber: string;
startDate: string;
endDate: string;
};
export const reportScheduleNotifyByDateStartDateEnd = async (req: Request, res: Response): Promise<Response> => {
const { contactNumber, startDate, endDate } = req.query as IndexQuery
const data_query = await ListSchedulingNotifyContactService(contactNumber, startDate, endDate);
// console.group('DATA QUERY SCHEDULE:\n',data_query)
return res.status(200).json(data_query);
};
export const createOrUpdateScheduleNotify = async (req: Request, res: Response): Promise<Response> => {
const scheduleData = req.body;
console.log(' +++++++++++ scheduleData: ', scheduleData)
const schedulingNotifyCreate = await CreateSchedulingNotifyService(
{
schedulingNotifyId: scheduleData.schedulingNotifyId,
ticketId: scheduleData.ticketId,
statusChatEndId: scheduleData.statusChatEndId,
schedulingDate: scheduleData.schedulingDate,
schedulingTime: scheduleData.schedulingTime,
message: scheduleData.message
}
)
// console.group(':::::::::::::::::: DATA schedulingNotifyCreate:\n',schedulingNotifyCreate)
// const io = getIO();
// io.emit("schedulingNotify", {action: "update", schedulingNotifyCreate });
return res.status(200).json(schedulingNotifyCreate);
};
export const remove = async ( req: Request, res: Response ): Promise<Response> => {
@ -13,3 +71,4 @@ export const remove = async ( req: Request, res: Response ): Promise<Response> =
return res.status(200).send();
};

View File

@ -0,0 +1,12 @@
import { Request, Response } from "express";
import AppError from "../errors/AppError";
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
export const show = async (req: Request, res: Response): Promise<Response> => {
const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({ searchParam: "", pageNumber: "1" });
return res.status(200).json(statusChatEnd);
};

View File

@ -11,7 +11,8 @@ import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService
import CreateSchedulingNotifyService from "../services/SchedulingNotifyServices/CreateSchedulingNotifyService";
import ListSchedulingNotifyContactService from "../services/SchedulingNotifyServices/ListSchedulingNotifyContactService";
import {isScheduling} from "../helpers/CheckSchedulingReminderNotify"
@ -33,7 +34,7 @@ interface TicketData {
}
import ListScheduleService from "../services/ScheduleService/ListScheduleService";
import ListStatusChatEndService from "../services/StatusChatEndService/ListStatusChatEndService";
export const index = async (req: Request, res: Response): Promise<Response> => {
const {
@ -93,18 +94,14 @@ export const show = async (req: Request, res: Response): Promise<Response> => {
const contact = await ShowTicketService(ticketId);
const { schedules, count, hasMore } = await ListScheduleService({ searchParam: "", pageNumber: "1" });
const { statusChatEnd, count, hasMore } = await ListStatusChatEndService({ searchParam: "", pageNumber: "1" });
//////////////////
const schedulesContact = await ListSchedulingNotifyContactService(contact.contact.number);
/////////////////
// console.log('############### schedulesContact: ', schedulesContact)
// console.log('############### contact.contact.number: ',contact.contact.number)
// return res.status(200).json(contact);
return res.status(200).json({contact, schedules, schedulesContact});
return res.status(200).json({contact, statusChatEnd, schedulesContact});
};
@ -139,14 +136,27 @@ export const update = async ( req: Request, res: Response ): Promise<Response> =
}
///////////////////////////////
// lembrete
const scheduleData = JSON.parse(schedulingNotifyData)
// lembrete // agendamento
if( scheduleData.statusChatEndId === '2' || scheduleData.statusChatEndId === '3'){
console.log('*** schedulingDate: ', scheduleData.schedulingDate)
console.log('*** schedulingTime: ', scheduleData.schedulingTime)
if(isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)){
console.log('*** É AGENDAMENTO!')
}
else{
console.log('*** É LEMBRETE!')
}
if( scheduleData.scheduleId === '2'){
const schedulingNotifyCreate = await CreateSchedulingNotifyService(
{
ticketId: scheduleData.ticketId,
scheduleId: scheduleData.scheduleId,
statusChatEndId: scheduleData.statusChatEndId,
schedulingDate: scheduleData.schedulingDate,
schedulingTime: scheduleData.schedulingTime,
message: scheduleData.message

View File

@ -12,7 +12,7 @@ import UserQueue from "../models/UserQueue";
import QuickAnswer from "../models/QuickAnswer";
import SchedulingNotify from "../models/SchedulingNotify";
import Schedule from "../models/Schedule";
import StatusChatEnd from "../models/StatusChatEnd";
// eslint-disable-next-line
@ -35,7 +35,7 @@ const models = [
QuickAnswer,
SchedulingNotify,
Schedule,
StatusChatEnd,
];
sequelize.addModels(models);

View File

@ -0,0 +1,11 @@
import { QueryInterface, DataTypes } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.renameTable("Schedules", "StatusChatEnd");
},
down: (queryInterface: QueryInterface) => {
return queryInterface.renameTable("StatusChatEnd", "Schedules");
}
};

View File

@ -0,0 +1,11 @@
import { QueryInterface, DataTypes } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.renameColumn("SchedulingNotifies", "scheduleId", "statusChatEndId");
},
down: (queryInterface: QueryInterface) => {
return queryInterface.renameColumn("SchedulingNotifies", "statusChatEndId", "scheduleId");
}
};

View File

@ -0,0 +1,11 @@
import { QueryInterface, DataTypes } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.renameTable("StatusChatEnd", "StatusChatEnds");
},
down: (queryInterface: QueryInterface) => {
return queryInterface.renameTable("StatusChatEnds", "StatusChatEnd");
}
};

View File

@ -0,0 +1,23 @@
import { QueryInterface, DataTypes } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.changeColumn("SchedulingNotifies", "statusChatEndId", {
type: DataTypes.INTEGER,
references: { model: "StatusChatEnds", key: "id" },
onUpdate: "CASCADE",
onDelete: "CASCADE",
allowNull: false
});
},
down: (queryInterface: QueryInterface) => {
return queryInterface.changeColumn("SchedulingNotifies", "statusChatEndId", {
type: DataTypes.INTEGER,
references: { model: "Schedules", key: "id" },
onUpdate: "CASCADE",
onDelete: "CASCADE",
allowNull: false
});
}
};

View File

@ -3,7 +3,7 @@ import { QueryInterface } from "sequelize";
module.exports = {
up: (queryInterface: QueryInterface) => {
return queryInterface.bulkInsert(
"Schedules",
"StatusChatEnd",
[
{
name: "SEM RETORNO DO CLIENTE",
@ -21,6 +21,6 @@ module.exports = {
},
down: (queryInterface: QueryInterface) => {
return queryInterface.bulkDelete("Schedules", {});
return queryInterface.bulkDelete("StatusChatEnd", {});
}
};

View File

@ -0,0 +1,11 @@
export const isScheduling = (schedulingDate:string, schedulingTime:string) => {
if (schedulingDate === schedulingTime){
return false
}
return true
}

View File

@ -10,7 +10,7 @@ import {
BelongsTo
} from "sequelize-typescript";
import Schedule from "./Schedule";
import StatusChatEnd from "./StatusChatEnd";
import Ticket from "./Ticket";
@Table
@ -20,12 +20,12 @@ import {
@Column
id: number;
@ForeignKey(() => Schedule)
@ForeignKey(() => StatusChatEnd)
@Column
scheduleId: number;
statusChatEndId: number;
@BelongsTo(() => Schedule)
schedule: Schedule;
@BelongsTo(() => StatusChatEnd)
statusChatEnd: StatusChatEnd;
@ForeignKey(() => Ticket)

View File

@ -12,7 +12,7 @@ import {
import SchedulingNotify from "./SchedulingNotify";
@Table
class Schedule extends Model<Schedule> {
class StatusChatEnd extends Model<StatusChatEnd> {
@PrimaryKey
@AutoIncrement
@Column
@ -31,5 +31,5 @@ import {
SchedulingNotifies: SchedulingNotify[];
}
export default Schedule;
export default StatusChatEnd;

View File

@ -7,4 +7,8 @@ const schedulingNotifiyRoutes = Router();
schedulingNotifiyRoutes.delete("/schedule/:scheduleId", isAuth, SchedulingNotifyController.remove);
schedulingNotifiyRoutes.post("/schedule", isAuth, SchedulingNotifyController.createOrUpdateScheduleNotify);
schedulingNotifiyRoutes.get("/schedules", isAuth, SchedulingNotifyController.reportScheduleNotifyByDateStartDateEnd);
export default schedulingNotifiyRoutes;

View File

@ -12,6 +12,7 @@ import queueRoutes from "./queueRoutes";
import quickAnswerRoutes from "./quickAnswerRoutes";
import reportRoutes from "./reportRoutes";
import schedulingNotifiyRoutes from "./SchedulingNotifyRoutes";
import statusChatEndRoutes from "./statusChatEndRoutes";
const routes = Router();
@ -27,8 +28,8 @@ routes.use(whatsappSessionRoutes);
routes.use(queueRoutes);
routes.use(quickAnswerRoutes);
routes.use(schedulingNotifiyRoutes)
routes.use(schedulingNotifiyRoutes);
routes.use(reportRoutes);
routes.use(statusChatEndRoutes);
export default routes;

View File

@ -0,0 +1,10 @@
import { Router } from "express";
import isAuth from "../middleware/isAuth";
import * as StatusChatEnd from "../controllers/StatusChatEndController";
const statusChatEndRoutes = Router();
statusChatEndRoutes.get("/statusChatEnd", isAuth, StatusChatEnd.show);
export default statusChatEndRoutes;

View File

@ -3,35 +3,88 @@ import SchedulingNotify from "../../models/SchedulingNotify";
interface Request {
schedulingNotifyId?: string,
ticketId: string,
scheduleId: string,
statusChatEndId: string,
schedulingDate: string,
schedulingTime: string,
message: string
}
const CreateSchedulingNotifyService = async (
{
ticketId,
scheduleId,
schedulingDate,
schedulingTime,
message
}: Request): Promise<SchedulingNotify> => {
}
const schedulingNotify = await SchedulingNotify.create(
{
ticketId,
scheduleId,
schedulingDate,
schedulingTime,
message
const CreateSchedulingNotifyService = async ({
schedulingNotifyId = '',
ticketId,
statusChatEndId,
schedulingDate,
schedulingTime,
message
}: Request): Promise<SchedulingNotify> => {
let schedulingNotify = null;
if(schedulingNotifyId){
console.log('000000000000000000000000000 ATUALIZOU!')
})
schedulingNotify = await SchedulingNotify.findOne({ where: { id: schedulingNotifyId } });
if(schedulingNotify){
try{
await schedulingNotify.update({ statusChatEndId, schedulingDate, schedulingTime, message});
}catch(err){
throw new AppError("ERR_NO_SCHEDULING_NOTIFY_FOUND", 404);
}
//await scheduleNotify.reload({attributes: ["id", "name"]});
}
}
if(!schedulingNotify){
console.log('111111111111111111111111111 criou!')
schedulingNotify = await SchedulingNotify.create(
{
ticketId,
statusChatEndId,
schedulingDate,
schedulingTime,
message
})
}
return schedulingNotify
}
// const CreateSchedulingNotifyService = async ({ ticketId, statusChatEndId, schedulingDate, schedulingTime, message }: Request): Promise<SchedulingNotify> => {
// const schedulingNotify = await SchedulingNotify.create(
// {
// ticketId,
// statusChatEndId,
// schedulingDate,
// schedulingTime,
// message
// })
// return schedulingNotify
// }
export default CreateSchedulingNotifyService

View File

@ -1,5 +1,6 @@
import AppError from "../../errors/AppError";
import SchedulingNotify from "../../models/SchedulingNotify";
import { getIO } from "../../libs/socket";
const DeleteSchedulingNotifyService = async (id: string | number): Promise<void> => {
@ -9,9 +10,15 @@ const DeleteSchedulingNotifyService = async (id: string | number): Promise<void>
if (!schedulingNotify) {
throw new AppError("ERR_NO_SCHEDULING_NOTIFY_FOUND", 404);
return
}
await schedulingNotify.destroy();
const io = getIO();
io.emit("schedulingNotify", {action: "delete", schedulingNotifyId: id});
};
export default DeleteSchedulingNotifyService;

View File

@ -4,31 +4,134 @@ import SchedulingNotify from "../../models/SchedulingNotify";
import { Op, where, Sequelize } from "sequelize";
import AppError from "../../errors/AppError";
const ListSchedulingNotifyContactService = async (contactNumber: string): Promise<SchedulingNotify[]> => {
const ListSchedulingNotifyContactService = async (contactNumber: string = '', startDate: string='', endDate: string=''): Promise<SchedulingNotify[]> => {
let where_clause = {}
let where_clause_notify = {}
let nameNumber = {
[Op.or]: [
{
name: Sequelize.where(
Sequelize.fn("LOWER", Sequelize.col("name")),
"LIKE",
`%${contactNumber.toLowerCase().trim()}%`
)
},
{ number: { [Op.like]: `%${contactNumber.toLowerCase().trim()}%` } }
]
}
if (contactNumber.trim().length>0 && startDate.trim().length>0 && endDate.trim().length>0){
where_clause = nameNumber
where_clause_notify = {
schedulingTime: {
[Op.gte]: startDate+' 00:00:00.000000',
[Op.lte]: endDate +' 23:59:59.999999'
},
}
}
else if (contactNumber.trim().length==0 && startDate.trim().length>0 && endDate.trim().length>0){
where_clause = {}
where_clause_notify = {
schedulingDate: {
[Op.gte]: startDate+' 00:00:00.000000',
[Op.lte]: endDate +' 23:59:59.999999'
},
}
}
else if (contactNumber.trim().length==0 && startDate.trim().length>0 && endDate.trim().length==0){
where_clause = {}
where_clause_notify = {
schedulingDate: {
[Op.gte]: startDate+' 00:00:00.000000',
[Op.lte]: startDate +' 23:59:59.999999'
},
}
}
else if (contactNumber.trim().length==0 && startDate.trim().length==0 && endDate.trim().length>0){
where_clause = {}
where_clause_notify = {
schedulingDate: {
[Op.gte]: endDate+' 00:00:00.000000',
[Op.lte]: endDate +' 23:59:59.999999'
},
}
}
else if (contactNumber.trim().length>0 && startDate.trim().length>0 && endDate.trim().length==0){
where_clause = nameNumber
where_clause_notify = {
schedulingDate: {
[Op.gte]: startDate+' 00:00:00.000000',
[Op.lte]: startDate +' 23:59:59.999999'
},
}
}
else if (contactNumber.trim().length>0 && startDate.trim().length==0 && endDate.trim().length>0){
where_clause = nameNumber
where_clause_notify = {
schedulingDate: {
[Op.gte]: endDate+' 00:00:00.000000',
[Op.lte]: endDate +' 23:59:59.999999'
},
}
}
else if(contactNumber.trim().length>0){
where_clause = nameNumber
}
const ticket = await SchedulingNotify.findAll({
raw: true,
where: where_clause_notify,
attributes:['id', [Sequelize.fn("DATE_FORMAT",Sequelize.col("schedulingDate"),"%d/%m/%Y %H:%i:%s"),"schedulingDate"],
attributes:['id', 'ticketId','statusChatEndId', [Sequelize.fn("DATE_FORMAT",Sequelize.col("schedulingDate"),"%d/%m/%Y %H:%i:%s"),"schedulingDate"],
[Sequelize.fn("DATE_FORMAT",Sequelize.col("schedulingTime"),"%d/%m/%Y %H:%i:%s"),"schedulingTime"], 'message'],
include: [
{
model: Ticket,
{
model: Ticket,
required:true,
attributes: [],
include: [
{
model: Contact,
where:{
number: contactNumber,
},
attributes: ['name', 'number']
model: Contact,
where: where_clause,
attributes: ['name', 'number', 'profilePicUrl']
},
]
},
],
order: [["id", "DESC"]]
});

View File

@ -32,13 +32,13 @@ interface Request {
const whereCondition = {
[Op.and]: [
{
"$schedulingDate$": Sequelize.where(Sequelize.fn("date", Sequelize.col("schedulingDate")), `${date.trim()}`)
"$schedulingTime$": Sequelize.where(Sequelize.fn("date", Sequelize.col("schedulingTime")), `${date.trim()}`)
},
{
"$schedulingDate$": Sequelize.where(Sequelize.fn("hour", Sequelize.col("schedulingDate")), `${hour.trim()}`)
"$schedulingTime$": Sequelize.where(Sequelize.fn("hour", Sequelize.col("schedulingTime")), `${hour.trim()}`)
},
{
"$schedulingDate$": Sequelize.where(Sequelize.fn("minute", Sequelize.col("schedulingDate")), `${minute.trim()}`)
"$schedulingTime$": Sequelize.where(Sequelize.fn("minute", Sequelize.col("schedulingTime")), `${minute.trim()}`)
}
]
};

View File

@ -1,5 +1,5 @@
import { Sequelize } from "sequelize";
import Schedule from "../../models/Schedule";
import StatusChatEnd from "../../models/StatusChatEnd";
interface Request {
searchParam?: string;
@ -7,7 +7,7 @@ interface Request {
}
interface Response {
schedules: Schedule[];
statusChatEnd: StatusChatEnd[];
count: number;
hasMore: boolean;
}
@ -23,7 +23,7 @@ interface Request {
const limit = 20;
const offset = limit * (+pageNumber - 1);
const { count, rows: schedules } = await Schedule.findAndCountAll({
const { count, rows: statusChatEnd } = await StatusChatEnd.findAndCountAll({
where: whereCondition,
attributes: ['id', 'name'],
limit,
@ -31,10 +31,10 @@ interface Request {
order: [["id", "ASC"]]
});
const hasMore = count > offset + schedules.length;
const hasMore = count > offset + statusChatEnd.length;
return {
schedules,
statusChatEnd,
count,
hasMore
};

View File

@ -1,4 +1,4 @@
import { subHours, subMinutes } from "date-fns";
import { subHours, subMinutes, subSeconds } from "date-fns";
import { Op } from "sequelize";
import Contact from "../../models/Contact";
import Ticket from "../../models/Ticket";

View File

@ -8,29 +8,19 @@ import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import PropTypes from 'prop-types';
import Box from '@mui/material/Box';
import SelectField from "../../Report/SelectField";
import SelectField from "../../Report/SelectField";
import DatePicker from '../../Report/DatePicker'
import TimerPickerSelect from '../TimerPickerSelect'
import TextareaAutosize from '@mui/material/TextareaAutosize';
// import { subHours } from "date-fns";
import { subHours, addDays, subDays} from "date-fns";
import TextFieldSelectHourBefore from '@mui/material/TextField';
import MenuItem from '@mui/material/MenuItem';
import {
IconButton,
Paper,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from "@material-ui/core";
import { DeleteOutline } from "@material-ui/icons";
import { toast } from "react-toastify"; import api from "../../../services/api";
import toastError from "../../../errors/toastError";
import ConfirmationModal from "../../ConfirmationModal";
import api from "../../../services/api";
import toastError from "../../../errors/toastError";
const reducer = (state, action) => {
@ -106,20 +96,17 @@ Item.propTypes = {
const Modal = (props) => {
// const [clientSchedules, dispatch] = useReducer(reducer, []);
const [selectedSchedule, setSelectedSchedule] = useState(null);
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
// const [selectedSchedule, setSelectedSchedule] = useState(null);
const [open, setOpen] = useState(true);
const [scroll, /*setScroll*/] = useState('body');
const [scheduleId, setScheduling] = useState(null)
const [statusChatEndId, setStatusChatEnd] = useState(null)
const [startDate, setDatePicker] = useState(new Date())
const [timerPicker, setTimerPicker] = useState(new Date())
const [textArea1, setTextArea1] = useState()
const [data] = useState(props.schedules)
const [textArea1, setTextArea1] = useState()
const [schedulesContact, dispatch] = useReducer(reducer, []);
const [currencyHourBefore, setCurrency] = useState(null);
const [currenciesTimeBefore, setCurrenciesTimeBefore] = useState(null);
const handleCancel = (event, reason) => {
@ -129,7 +116,6 @@ const Modal = (props) => {
setOpen(false);
};
useEffect(() => {
@ -161,23 +147,18 @@ const Modal = (props) => {
}
const handleCloseConfirmationModal = () => {
setConfirmModalOpen(false);
setSelectedSchedule(null);
};
const handleDeleteSchedule = async (scheduleId) => {
try {
await api.delete(`/schedule/${scheduleId}`);
toast.success(("Lembrete deletado com sucesso!"));
dispatch({ type: "DELETE_SCHEDULE", payload: scheduleId });
} catch (err) {
toastError(err);
}
setSelectedSchedule(null);
};
// const handleDeleteSchedule = async (scheduleId) => {
// try {
// await api.delete(`/schedule/${scheduleId}`);
// toast.success(("Lembrete/Agendamento deletado com sucesso!"));
// dispatch({ type: "DELETE_SCHEDULE", payload: scheduleId });
// } catch (err) {
// toastError(err);
// }
// setSelectedSchedule(null);
// };
// Get from child 2
const datePickerValue = (data) => {
@ -195,53 +176,108 @@ const timerPickerValue = (data) => {
}
const dateCurrentFormated = (dateF=null) => {
let date =null
if(dateF){
date = new Date(dateF)
}
else{
date = new Date();
}
let day = date.getDate().toString().padStart(2, '0');
let month = (date.getMonth()+1).toString().padStart(2, '0');
let year = date.getFullYear();
return `${year}-${month}-${day}`
}
const handleChatEnd = (event, reason) => {
let dataSendServer = {'scheduleId': scheduleId}
let dataSendServer = {'statusChatEndId': statusChatEndId}
if (reason && reason === "backdropClick")
return;
if (scheduleId === '2'){
if (statusChatEndId === '2' || statusChatEndId === '3'){
console.log('Entrou! textArea1: ', textArea1)
if( startDate.trim().length === 0){
if(textArea1 && textArea1.trim().length<5){
alert('Mensagem muito curta!')
alert('Selecione uma data atual ou futura!')
return
}
else if(textArea1 && textArea1.trim().length<5){
alert('Mensagem muito curta!')
return
}
else if(!textArea1){
alert('Defina uma mensagem para enviar para o cliente!')
return
}
else if(formatedFullCurrentDate()===startDate){
if((new Date(timerPicker).getHours() < new Date().getHours() && new Date(timerPicker).getMinutes() <= new Date().getMinutes()) ||
else if(formatedFullCurrentDate()===startDate &&
((new Date(timerPicker).getHours() < new Date().getHours() && new Date(timerPicker).getMinutes() <= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() === new Date().getHours() && new Date(timerPicker).getMinutes() <= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() < new Date().getHours() && new Date(timerPicker).getMinutes() >= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() < new Date().getHours)){
(new Date(timerPicker).getHours() < new Date().getHours))){
alert('Horário menor ou igual horário atual!')
return
}
return
}
else if((new Date(timerPicker).getHours() > 20 && new Date(timerPicker).getMinutes() > 0) ||
(new Date(timerPicker).getHours() < 6)){
alert('Horário comercial inválido!\n Selecione um horário de lembrete válido entre às 06:00 e 20:00')
return
}
dataSendServer = {
'scheduleId': scheduleId,
'schedulingDate': startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`)),
'schedulingTime': startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`)),
'message': textArea1
let dateSendMessage = startDate
let timeBefore = formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))
if(statusChatEndId === '3'){
if(!currencyHourBefore){
alert('Para agendamentos do dia corrente, essa funcionalidade atende a agendeamentos com no mínimo 2 horas adiantado a partir da hora atual!')
return
}
timeBefore = currencyHourBefore
let sendMessageDayBefore = currenciesTimeBefore.filter(i => i.label.indexOf('24 HORAS ANTES DO HORÁRIO DO AGENDAMENTO') >= 0);
if(sendMessageDayBefore.length > 0 && timeBefore === formatedTimeHour(timerPicker))
{
console.log('ENVIAR MENSAGEM UM DIA ANTES!')
console.log('MENSAGEM SERÁ ENVIA NO DIA: ', dateCurrentFormated( new Date(subDays(new Date(startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))), 1))))
dateSendMessage = dateCurrentFormated( new Date(subDays(new Date(startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))), 1)))
}
console.log('AGENDAMENTO ENVIO MENSAGEM1: ', `${dateSendMessage} ${timeBefore}:00` )
} else if (statusChatEndId === '2'){
console.log('AGENDAMENTO ENVIO MENSAGEM2: ', startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`)) )
}
}
dataSendServer = {
'statusChatEndId': statusChatEndId,
'schedulingDate': startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}`))+':00',
'schedulingTime': `${dateSendMessage} ${timeBefore}:00`,
'message': textArea1
}
}
props.func(dataSendServer)
@ -249,6 +285,98 @@ const timerPickerValue = (data) => {
};
useEffect(()=>{
const hoursBeforeAvalible = (timer) =>{
let hours = []
let hour = 1
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>> startDate: ', startDate )
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>> dateCurrentFormated: ', dateCurrentFormated() )
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>> startDate: ',typeof(startDate) )
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>> startDate: ',(startDate) )
if(typeof(startDate)==='string' && startDate.trim().length>0 && startDate === dateCurrentFormated()){
console.log('HOJE++++')
while(subHours(timer, hour).getHours()>=6 &&
subHours(timer, hour).getHours()>=new Date().getHours() &&
subHours(timer, hour).getHours()<=20){
console.log('******** TIMER: ', formatedTimeHour(subHours(timer,hour)))
hours.push({value: formatedTimeHour(subHours(timer,hour)), label: `${hour} HORA ANTES DO HORÁRIO DO AGENDAMENTO`})
hour++;
}
if(hours.length>1){
console.log('entrou----------------------: ', hours.length)
hours.pop()
setCurrency(hours[0].value)
}
else{
setCurrency(null)
}
}
else{
while(subHours(timer, hour).getHours()>=6 && subHours(timer, hour).getHours()<=20){
console.log('******** another day TIMER: ', formatedTimeHour(subHours(timer,hour)))
hours.push(
{value: formatedTimeHour(subHours(timer,hour)),
label: `${hour} HORA ANTES DO HORÁRIO DO AGENDAMENTO`})
hour++;
}
if(hours.length>0){
console.log('entrou----------------------: ', hours.length)
setCurrency(hours[0].value)
}
else{
setCurrency(null)
}
}
if(new Date(startDate) > addDays(new Date(), 1) ){
hours.push({value: formatedTimeHour(timerPicker) , label: `24 HORAS ANTES DO HORÁRIO DO AGENDAMENTO`})
console.log('#subDays: ', dateCurrentFormated( new Date(subDays(new Date(startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))), 1))))
}
console.log('hourshourshourshourshourshourshourshourshourshourshourshours ', hours)
return {time: hours, hour:hour}
}
console.log('===================================== addDays: ', addDays(new Date(), 1))
setCurrenciesTimeBefore(hoursBeforeAvalible(timerPicker).time)
},[timerPicker, startDate])
const descriptionElementRef = useRef(null);
useEffect(() => {
if (open) {
@ -263,17 +391,29 @@ const timerPickerValue = (data) => {
// Get from child 1
const textFieldSelect = (data) => {
console.log('textFieldSelect: ',data);
setScheduling(data)
setStatusChatEnd(data)
}
const handleChange = (event) => {
setTextArea1(event.target.value);
};
const handleChangeHourBefore = (event) => {
console.log('textFihandleChangeHourBefore: ',event.target.value);
// var matchedTime = currenciesTimeBefore.filter(i => i.label.indexOf('24 HORAS ANTES DO HORÁRIO DO AGENDAMENTO') >= 0);
// console.log('textFihandleChangeHourBefore matchedTime: ',matchedTime);
setCurrency(event.target.value);
};
@ -319,8 +459,9 @@ const handleChange = (event) => {
<SelectField func={textFieldSelect}
emptyField={false}
textBoxFieldSelected={'1'}
header={'Opções de encerramento do atendimento'}
currencies={data.map((obj)=>{
currencies={props.statusChatEnd.map((obj)=>{
return {'value': obj.id, 'label': obj.name}
})}/>
@ -329,7 +470,7 @@ const handleChange = (event) => {
</Box>
{scheduleId==='2' &&
{statusChatEndId==='2' &&
<Item>
@ -337,9 +478,9 @@ const handleChange = (event) => {
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)' }}>
<Item><DatePicker func={datePickerValue} minDate = {true} title={'Data do lembrete'}/></Item>
<Item><DatePicker func={datePickerValue} minDate={true} startEmpty={true} title={'Data'}/></Item>
<Item><TimerPickerSelect func={timerPickerValue} title={'Hora do lembrete'}/></Item>
<Item><TimerPickerSelect func={timerPickerValue} title={'Hora'}/></Item>
</Box>
@ -351,7 +492,7 @@ const handleChange = (event) => {
aria-label="minimum height"
minRows={3}
value={textArea1}
placeholder={'Mensagem para lembrar cliente'}
placeholder={'Mensagem de envio para cliente'}
onChange={ handleChange}
style={{ width: '100%' }}
/>
@ -359,72 +500,69 @@ const handleChange = (event) => {
</Box>
</Item>
}
}
{schedulesContact.length>0 &&
{statusChatEndId==='3' &&
<Item>
<Item>
<span>Agendamento</span>
<ConfirmationModal
title={selectedSchedule && `Deletar lembrete do dia ${selectedSchedule.schedulingTime.split(' ')[0]} ${selectedSchedule.schedulingTime.split(' ')[1]} ?`}
open={confirmModalOpen}
onClose={handleCloseConfirmationModal}
onConfirm={() => handleDeleteSchedule(selectedSchedule.id)}
>
<span>Deseja realmente deletar esse Lembrete? </span>
</ConfirmationModal>
<span>Lembrete</span>
<Paper variant="outlined">
<Table size="small">
<TableHead>
<TableRow>
<TableCell align="center">
Data
</TableCell>
<TableCell align="center">
Hora
</TableCell>
<TableCell align="center">
Mensagem
</TableCell>
<TableCell align="center">
Deletar
</TableCell>
</TableRow>
</TableHead>
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)' }}>
<TableBody>
<>
{schedulesContact.map((scheduleData, index) => (
<TableRow key={scheduleData.id}>
<TableCell align="center">{scheduleData.schedulingDate.split(' ')[0]}</TableCell>
<TableCell align="center">{scheduleData.schedulingTime.split(' ')[1]}</TableCell>
<TableCell align="center">{scheduleData.message}</TableCell>
<Item><DatePicker func={datePickerValue} minDate={true} startEmpty={true} title={'Data'}/></Item>
<Item><TimerPickerSelect func={timerPickerValue} title={'Hora'}/></Item>
</Box>
<TableCell align="center">
<IconButton
size="small"
onClick={() => {
setSelectedSchedule(scheduleData);
setConfirmModalOpen(true);
}}
>
<DeleteOutline />
</IconButton>
</TableCell>
</TableRow>
))}
</>
</TableBody>
</Table>
</Paper>
</Item>}
<Box sx={{display: 'flex', flexDirection: 'column' }}>
<Item>
{currencyHourBefore && startDate && typeof(startDate)==='string' && startDate.trim().length > 0 && currenciesTimeBefore.length > 0 &&
<TextFieldSelectHourBefore
id="outlined-select-currency"
disabled={startDate.length>0 ? false : true}
select
label="Enviar mensagem para o cliente"
value={currencyHourBefore}
size="small"
onChange={handleChangeHourBefore}
>
{currenciesTimeBefore.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextFieldSelectHourBefore>
}
</Item>
<Item>
<TextareaAutosize
aria-label="minimum height"
minRows={3}
value={textArea1}
placeholder={'Mensagem de envio para o cliente'}
onChange={ handleChange}
style={{ width: '100%' }}
/>
</Item>
</Box>
</Item>
}
{schedulesContact.length>0 &&
<div></div>
}
</Box>

View File

@ -0,0 +1,105 @@
import React, { Fragment, useState, useEffect } from "react";
import DateFnsUtils from '@date-io/date-fns'; // choose your lib
import {
KeyboardDatePicker,
MuiPickersUtilsProvider,
} from '@material-ui/pickers';
import ptBrLocale from "date-fns/locale/pt-BR";
function formatDateDatePicker(data){
return String(new Date(data).getFullYear())+'-'+
String(new Date(data).getMonth() + 1).padStart(2,'0')+'-'+
String(new Date(data).getDate()).padStart(2,'0')
}
function formatDate(strDate){
const date = strDate.split(' ')[0].split('/')
const time = strDate.split(' ')[1]
return `${date[2]}-${date[1]}-${date[0]} ${time}`
}
function ResponsiveDatePickers(props) {
const [selectedDate, handleDateChange] = useState(new Date(formatDate(props.schedulingDate)));
useEffect(()=>{
if( !selectedDate ){
props.func('');
}
else{
props.func(formatDateDatePicker(selectedDate));
}
}, [selectedDate, props])
return (
<Fragment>
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={ptBrLocale}>
<KeyboardDatePicker
// autoOk
variant="inline"
inputVariant="outlined"
label={props.title}
minDate={props.minDate? new Date() : false}
format="dd/MM/yyyy"
value={selectedDate}
InputAdornmentProps={{ position: "start" }}
onChange={date => handleDateChange(date)}
/>
</MuiPickersUtilsProvider>
</Fragment>
);
}
export default ResponsiveDatePickers;
/*import * as React from 'react';
import TextField from '@mui/material/TextField';
import AdapterDateFns from '@mui/lab/AdapterDateFns';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import DesktopDatePicker from '@mui/lab/DesktopDatePicker';
import Stack from '@mui/material/Stack';
const ResponsiveDatePickers = (props) => {
const [value, setValue] = React.useState(new Date());
props.func(value);
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={1}>
<DesktopDatePicker
label={props.title}
value={value}
minDate={new Date('2017-01-01')}
onChange={(newValue) => {setValue(newValue)}}
renderInput={(params) => <TextField {...params} />}
/>
</Stack>
</LocalizationProvider>
);
}
export default ResponsiveDatePickers*/

View File

@ -0,0 +1,93 @@
// import React, { useState } from "react";
// import { DateTimePicker, KeyboardDateTimePicker } from "@material-ui/pickers";
// function InlineDateTimePickerDemo(props) {
// const [selectedDate, handleDateChange] = useState(new Date("2018-01-01T00:00:00.000Z"));
// return (
// <>
// <DateTimePicker
// variant="inline"
// label="Basic example"
// value={selectedDate}
// onChange={handleDateChange}
// />
// <KeyboardDateTimePicker
// variant="inline"
// ampm={false}
// label="With keyboard"
// value={selectedDate}
// onChange={handleDateChange}
// onError={console.log}
// disablePast
// format="yyyy/MM/dd HH:mm"
// />
// </>
// );
// }
// export default InlineDateTimePickerDemo;
import React, { Fragment, useState, useEffect } from "react";
// import TextField from '@mui/material/TextField';
import DateFnsUtils from '@date-io/date-fns';
import {
TimePicker,
MuiPickersUtilsProvider,
} from '@material-ui/pickers';
import ptBrLocale from "date-fns/locale/pt-BR";
function formatDate(strDate){
const date = strDate.split(' ')[0].split('/')
const time = strDate.split(' ')[1]
return `${date[2]}-${date[1]}-${date[0]} ${time}`
}
const ResponsiveTimePickers = (props) => {
const [value, setValue] = useState(new Date(new Date(formatDate(props.schedulingDate))));
// props.func(value);
useEffect(()=>{
props.func(value);
}, [value, props])
return (
<Fragment>
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={ptBrLocale}>
<TimePicker
variant="outline"
label={props.title}
value={value}
ampm={false}
onChange={(newValue) => {
setValue(newValue);
}}
// Ativar se necessario
// renderInput={(params) => <TextField {...params} />}
/>
</MuiPickersUtilsProvider>
</Fragment>
);
}
export default ResponsiveTimePickers

View File

@ -0,0 +1,630 @@
import React, { useState, useEffect, useRef, useReducer } from 'react';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import PropTypes from 'prop-types';
import Box from '@mui/material/Box';
import SelectField from "../Report/SelectField";
import DatePicker from './DatePicker2'
import TimerPickerSelect from './TimerPickerSelect2'
import TextareaAutosize from '@mui/material/TextareaAutosize';
import { subHours, addDays, subDays} from "date-fns";
import TextFieldSelectHourBefore from '@mui/material/TextField';
import MenuItem from '@mui/material/MenuItem';
import api from "../../services/api";
import toastError from "../../errors/toastError";
const reducer = (state, action) => {
if (action.type === "LOAD_SCHEDULES") {
const schedulesContact = action.payload;
const newSchedules= [];
schedulesContact.forEach((schedule) => {
const scheduleIndex = state.findIndex((s) => s.id === schedule.id);
if (scheduleIndex !== -1) {
state[scheduleIndex] = schedule;
} else {
newSchedules.push(schedule);
}
});
return [...state, ...newSchedules];
}
if (action.type === "DELETE_SCHEDULE") {
const scheduleId = action.payload;
const scheduleIndex = state.findIndex((q) => q.id === scheduleId);
if (scheduleIndex !== -1) {
state.splice(scheduleIndex, 1);
}
return [...state];
}
if (action.type === "RESET") {
return [];
}
};
const 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,
]),
};
const Modal = (props) => {
// const [selectedSchedule, setSelectedSchedule] = useState(null);
// const [confirmModalOpen, setConfirmModalOpen] = useState(false);
const [open, setOpen] = useState(true);
const [scroll, /*setScroll*/] = useState('body');
const [statusChatEndId, setStatusChatEnd] = useState(props.rowData.statusChatEndId)
const [startDate, setDatePicker] = useState(props.rowData.schedulingTime ? new Date(props.rowData.schedulingTime) : new Date())
const [timerPicker, setTimerPicker] = useState(new Date())
const [textArea1, setTextArea1] = useState(props.rowData.message)
const [schedulesContact, dispatch] = useReducer(reducer, []);
const [currencyHourBefore, setCurrency] = useState(props.rowData.schedulingTime.split(' ')[1].slice(0,5));
const [currenciesTimeBefore, setCurrenciesTimeBefore] = useState(null);
const [currencyHourBeforeAux, ] = useState(props.rowData.schedulingTime.split(' ')[1].slice(0,5));
if(schedulesContact){}
const handleCancel = (event, reason) => {
if (reason && reason === "backdropClick")
return;
setOpen(false);
};
useEffect(() => {
(async () => {
try {
const { data } = await api.get("/tickets/" + props.rowData.ticketId);
dispatch({ type: "LOAD_SCHEDULES", payload: data.schedulesContact });
} catch (err) {
toastError(err);
}
})();
}, [props]);
function formatedTimeHour(timer){
return `${timer.getHours().toString().padStart(2, '0')}:${timer.getMinutes().toString().padStart(2, '0')}`
}
function formatedFullCurrentDate(){
let dateCurrent = new Date()
let day = dateCurrent.getDate().toString().padStart(2, '0');
let month = (dateCurrent.getMonth()+1).toString().padStart(2, '0');
let year = dateCurrent.getFullYear();
return `${year}-${month}-${day}`;
}
// const handleCloseConfirmationModal = () => {
// setConfirmModalOpen(false);
// setSelectedSchedule(null);
// };
// const handleDeleteSchedule = async (scheduleId) => {
// try {
// await api.delete(`/schedule/${scheduleId}`);
// toast.success(("Lembrete/Agendamento deletado com sucesso!"));
// dispatch({ type: "DELETE_SCHEDULE", payload: scheduleId });
// } catch (err) {
// toastError(err);
// }
// setSelectedSchedule(null);
// };
// Get from child 2
const datePickerValue = (data) => {
setDatePicker(data)
}
// Get from child 3
const timerPickerValue = (data) => {
setTimerPicker(data)
}
const dateCurrentFormated = (dateF=null) => {
let date =null
if(dateF){
date = new Date(dateF)
}
else{
date = new Date();
}
let day = date.getDate().toString().padStart(2, '0');
let month = (date.getMonth()+1).toString().padStart(2, '0');
let year = date.getFullYear();
return `${year}-${month}-${day}`
}
const handleChatEnd = (event, reason) => {
let dataSendServer = {'statusChatEndId': statusChatEndId}
if (reason && reason === "backdropClick")
return;
if (statusChatEndId === '2'|| statusChatEndId === '3'){
if(textArea1 && textArea1.trim().length<5){
alert('Mensagem muito curta!')
return
}
else if(!textArea1){
alert('Defina uma mensagem para enviar para o cliente!')
return
}
else if(formatedFullCurrentDate()===startDate &&
((new Date(timerPicker).getHours() < new Date().getHours() && new Date(timerPicker).getMinutes() <= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() === new Date().getHours() && new Date(timerPicker).getMinutes() <= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() < new Date().getHours() && new Date(timerPicker).getMinutes() >= new Date().getMinutes()) ||
(new Date(timerPicker).getHours() < new Date().getHours))){
alert('Horário menor ou igual horário atual!')
return
}
else if((new Date(timerPicker).getHours() > 20 && new Date(timerPicker).getMinutes() > 0) ||
(new Date(timerPicker).getHours() < 6)){
alert('Horário comercial inválido!\n Selecione um horário de lembrete válido entre às 06:00 e 20:00')
return
}
let dateSendMessage = startDate
let timeBefore = formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))
if(statusChatEndId === '3'){
if(!currencyHourBefore){
alert('Para agendamentos do dia corrente, essa funcionalidade atende a agendeamentos com no mínimo 2 horas adiantado a partir da hora atual!')
return
}
timeBefore = currencyHourBefore
let sendMessageDayBefore = currenciesTimeBefore.filter(i => i.label.indexOf('24 HORAS ANTES DO HORÁRIO DO AGENDAMENTO') >= 0);
if(sendMessageDayBefore.length > 0 && timeBefore === formatedTimeHour(timerPicker))
{
dateSendMessage = dateCurrentFormated( new Date(subDays(new Date(startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}:00`))), 1)))
}
} else if (statusChatEndId === '2'){
}
dataSendServer = {
'schedulingNotifyId': props.rowData.id,
'statusChatEndId': statusChatEndId,
'schedulingDate': startDate+' '+formatedTimeHour(new Date(`${startDate} ${timerPicker.getHours()}:${timerPicker.getMinutes()}`))+':00',
'schedulingTime': `${dateSendMessage} ${timeBefore}:00`,
'message': textArea1
}
const formatDateTimeBrazil = (dateTime) => {
let date = dateTime.split(' ')[0]
let time = dateTime.split(' ')[1]
date = date.split('-')
return `${date[2]}/${date[1]}/${date[0]} ${time}`
}
props.rowData['statusChatEndId'] = statusChatEndId
props.rowData['schedulingDate'] = formatDateTimeBrazil(`${dataSendServer['schedulingDate']}`)
props.rowData['schedulingTime'] = formatDateTimeBrazil(`${dataSendServer['schedulingTime']}`)
props.rowData['message'] = textArea1
}
props.func(dataSendServer, props.rowData)
setOpen(false);
};
useEffect(()=>{
const selectedTimeOld = (_hours) => {
let selectedOld = _hours.filter((h)=>(h.value===currencyHourBeforeAux))[0]
if(selectedOld){
return selectedOld
}
return null
}
const hoursBeforeAvalible = (timer) =>{
let hours = []
let hour = 1
if(typeof(startDate)==='string' && startDate.trim().length>0 && startDate === dateCurrentFormated()){
while(subHours(timer, hour).getHours()>=6 &&
subHours(timer, hour).getHours()>=new Date().getHours() &&
subHours(timer, hour).getHours()<=20){
hours.push({value: formatedTimeHour(subHours(timer,hour)), label: `${hour} HORA ANTES DO HORÁRIO DO AGENDAMENTO`})
hour++;
}
if(hours.length>1){
hours.pop()
let selectedOld = selectedTimeOld(hours)
setCurrency(selectedOld ? selectedOld.value : hours[0].value)
}
else{
setCurrency(null)
}
}
else{
while(subHours(timer, hour).getHours()>=6 && subHours(timer, hour).getHours()<=20){
hours.push(
{value: formatedTimeHour(subHours(timer,hour)),
label: `${hour} HORA ANTES DO HORÁRIO DO AGENDAMENTO`})
hour++;
}
if(hours.length>0){
let selectedOld = selectedTimeOld(hours)
setCurrency(selectedOld ? selectedOld.value : hours[0].value)
//if(contador>1)
// setCurrency( hours[0].value)
}
else{
setCurrency(null)
}
}
if(new Date(startDate) > addDays(new Date(), 1) ){
hours.push({value: formatedTimeHour(timerPicker) , label: `24 HORAS ANTES DO HORÁRIO DO AGENDAMENTO`})
let selectedOld = selectedTimeOld(hours)
if(selectedOld)
setCurrency(selectedOld.value)
}
return {time: hours, hour:hour}
}
setCurrenciesTimeBefore(hoursBeforeAvalible(timerPicker).time)
},[timerPicker, startDate, currencyHourBeforeAux])
const descriptionElementRef = useRef(null);
useEffect(() => {
if (open) {
const { current: descriptionElement } = descriptionElementRef;
if (descriptionElement !== null) {
descriptionElement.focus();
}
}
}, [open]);
// Get from child 1
const textFieldSelect = (data) => {
setStatusChatEnd(data)
}
const handleChange = (event) => {
setTextArea1(event.target.value);
};
const handleChangeHourBefore = (event) => {
setCurrency(event.target.value);
};
return (
<Dialog
open={open}
onClose={handleCancel}
// fullWidth={true}
// maxWidth={true}
disableEscapeKeyDown
scroll={scroll}
aria-labelledby="scroll-dialog-title"
aria-describedby="scroll-dialog-description"
>
<DialogTitle id="scroll-dialog-title">{props.modal_header}</DialogTitle>
<DialogContent dividers={scroll === 'body'}>
<DialogContentText
id="scroll-dialog-description"
ref={descriptionElementRef}
tabIndex={-1}
>
</DialogContentText>
<Box
sx={{
width: 500,
height: '100%',
// backgroundColor: 'primary.dark',
// '&:hover': {backgroundColor: 'primary.main', opacity: [0.9, 0.8, 0.7],},
}}>
<Box sx={{
display: 'grid',
}}>
<Item>
<SelectField func={textFieldSelect}
emptyField={false}
textBoxFieldSelected={`${props.rowData.statusChatEndId}`}
header={'Opções lembrete/agendamento'}
currencies={props.statusChatEnd.map((obj)=>{
return {'value': obj.id, 'label': obj.name}
})}/>
</Item>
</Box>
{statusChatEndId==='2' &&
<Item>
<span>Lembrete</span>
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)' }}>
<Item>
<DatePicker
func={datePickerValue}
minDate={true}
schedulingDate={props.rowData.schedulingDate}
title={'Data'}/>
</Item>
<Item>
<TimerPickerSelect
func={timerPickerValue}
schedulingDate={props.rowData.schedulingDate}
title={'Hora'}/>
</Item>
</Box>
<Box sx={{display: 'flex', flexDirection: 'column' }}>
<Item>
<TextareaAutosize
aria-label="minimum height"
minRows={3}
value={textArea1}
placeholder={'Mensagem de envio para cliente'}
onChange={ handleChange}
style={{ width: '100%' }}
/>
</Item>
</Box>
</Item>
}
{statusChatEndId==='3' &&
<Item>
<span>Agendamento</span>
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)' }}>
<Item>
<DatePicker
func={datePickerValue}
minDate={true}
schedulingDate={props.rowData.schedulingDate}
title={'Data'}/>
</Item>
<Item>
<TimerPickerSelect
func={timerPickerValue}
schedulingDate={props.rowData.schedulingDate}
title={'Hora'}/>
</Item>
</Box>
<Box sx={{display: 'flex', flexDirection: 'column' }}>
<Item>
{currencyHourBefore && startDate && typeof(startDate)==='string' && startDate.trim().length > 0 && currenciesTimeBefore.length > 0 &&
<TextFieldSelectHourBefore
id="outlined-select-currency"
disabled={startDate.length>0 ? false : true}
select
label="Enviar mensagem para cliente"
value={currencyHourBefore}
size="small"
onChange={handleChangeHourBefore}
>
{currenciesTimeBefore.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextFieldSelectHourBefore>
}
</Item>
<Item>
<TextareaAutosize
aria-label="minimum height"
minRows={3}
value={textArea1}
placeholder={'Mensagem de envio para cliente'}
onChange={ handleChange}
style={{ width: '100%' }}
/>
</Item>
</Box>
</Item>
}
</Box>
</DialogContent>
<DialogActions>
<div style={{marginRight:'50px'}}>
<Button onClick={handleCancel}>Cancelar</Button>
</div>
<Button onClick={handleChatEnd}>Ok</Button>
</DialogActions>
</Dialog>
);
}
export default Modal

View File

@ -22,13 +22,28 @@ function formatDateDatePicker(data){
}
function ResponsiveDatePickers(props) {
const [selectedDate, handleDateChange] = useState(new Date());
const [selectedDate, handleDateChange] = useState(props.startEmpty? null : new Date());
// props.func(formatDateDatePicker(selectedDate));
//////////////////////////
useEffect(() => {
if (props.reset) {
handleDateChange(null)
props.setReset(false)
}
}, [props.reset, props.setReset, props])
/////////////////////////
useEffect(()=>{
props.func(formatDateDatePicker(selectedDate));
if( !selectedDate ){
props.func('');
}
else{
props.func(formatDateDatePicker(selectedDate));
}
}, [selectedDate, props])
@ -37,15 +52,17 @@ function ResponsiveDatePickers(props) {
<Fragment>
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={ptBrLocale}>
<KeyboardDatePicker
autoOk
// autoOk
variant="inline"
inputVariant="outlined"
label={props.title}
minDate={props.minDate? new Date() : false}
format="dd/MM/yyyy"
value={selectedDate}
value={selectedDate}
InputAdornmentProps={{ position: "start" }}
onChange={date => handleDateChange(date)}
/>
</MuiPickersUtilsProvider>
</Fragment>

View File

@ -1,77 +1,88 @@
import { useState, useEffect} from 'react';
import MaterialTable from 'material-table';
import Modal from '../Modal'
import { useState, useEffect } from 'react';
import MaterialTable from 'material-table';
import Modal from '../Modal'
import { render } from '@testing-library/react';
import React from 'react';
import React from 'react';
const MTable = (props) => {
const [selectedRow, setSelectedRow] = useState(null);
const MTable = (props) => {
const [selectedRow, setSelectedRow] = useState(null);
//const dataLoad = props.data.map((dt) => { return { ...dt }});
const dataLoad = props.data.map(({user, ...others})=>({...others, 'user': user ? user : {name: 'Aguardando atendente', email:''}}));
const dataLoad = props.data.map(({ user, ...others }) => ({ ...others, 'user': user ? user : { name: 'Aguardando atendente', email: '' } }));
const columnsLoad = props.columns.map((column) => { return { ...column } });
const columnsLoad = props.columns.map((column) => { return { ...column }});
useEffect(() => {
console.log(`You have clicked the button ${selectedRow} times`)
},[selectedRow]);
return (
<MaterialTable
title= {props.table_title}
columns={columnsLoad}
data={dataLoad}
maxWidth={true}
console.log(`You have clicked the button ${selectedRow} times`)
onRowClick={(evt, selectedRow) => {
}, [selectedRow]);
console.log(selectedRow.tableData.id);
console.log(selectedRow);
console.log(selectedRow.messages);
setSelectedRow(selectedRow.tableData.id)
return (
if(props.hasChild) {
render(<Modal data={selectedRow.messages}
hasChild={false}
modal_header={'Chat do atendimento pelo Whatsapp'}
user={selectedRow.user.name}
clientContactNumber={selectedRow.contact.number}/>)
}
console.log('props.hasChild: ', props.hasChild)
<MaterialTable
title={props.table_title}
columns={columnsLoad}
data={dataLoad}
//evt.stopPropagation()
}
}
options={{
search: true,
selection: false,
paging: false,
padding: 'dense',
sorting: true ? props.hasChild: false,
//loadingType: 'linear',
searchFieldStyle: {
width: 300,
},
rowStyle: rowData => ({
fontSize: 12,
backgroundColor: selectedRow === rowData.tableData.id ? '#ec5114' : '#FFF'
})
}}
/>
);
maxWidth={true}
onRowClick={(evt, selectedRow) => {
};
if(props.removeClickRow){
return
}
console.log(selectedRow.tableData.id);
console.log(selectedRow);
console.log(selectedRow.messages);
setSelectedRow(selectedRow.tableData.id)
export default React.memo(MTable)
if (props.hasChild) {
render(<Modal data={selectedRow.messages}
hasChild={false}
modal_header={'Chat do atendimento pelo Whatsapp'}
user={selectedRow.user.name}
clientContactNumber={selectedRow.contact.number} />)
}
console.log('props.hasChild: ', props.hasChild)
//evt.stopPropagation()
}
}
options={{
search: true,
selection: false,
paging: false,
padding: 'dense',
sorting: true ? props.hasChild : false,
//loadingType: 'linear',
searchFieldStyle: {
width: 300,
},
pageSize: 20,
headerStyle: {
position: "sticky",
top: "0"
},
maxBodyHeight: "400px",
rowStyle: rowData => ({
fontSize: 12,
backgroundColor: selectedRow === rowData.tableData.id ? '#ec5114' : '#FFF'
})
}}
/>
);
};
export default React.memo(MTable)

View File

@ -7,9 +7,15 @@ import TextField from '@mui/material/TextField';
const SelectTextFields = (props) => {
const [currency, setCurrency] = useState(props.emptyField ? '0' : '1');
// const [currency, setCurrency] = useState(props.emptyField ? '0' : '1');
if(props.emptyField){
const [currency, setCurrency] = useState(props.textBoxFieldSelected ? props.textBoxFieldSelected: '0');
// const [currency, setCurrency] = useState(props.textBoxFieldSelected);
if(!props.textBoxFieldSelected){
props.currencies.push({ 'value': 0, 'label': ''})
}

View File

@ -83,7 +83,7 @@ const Ticket = () => {
const [contact, setContact] = useState({});
const [ticket, setTicket] = useState({});
const [schedule, setSchedule] = useState({})
const [statusChatEnd, setStatusChatEnd] = useState({})
useEffect(() => {
setLoading(true);
@ -101,7 +101,7 @@ const Ticket = () => {
setContact(data.contact.contact);
setTicket(data.contact);
setSchedule(data.schedules)
setStatusChatEnd(data.statusChatEnd)
setLoading(false);
} catch (err) {
@ -172,7 +172,7 @@ const Ticket = () => {
/>
</div>
<div className={classes.ticketActionButtons}>
<TicketActionButtons ticket={ticket} schedule={schedule}/>
<TicketActionButtons ticket={ticket} statusChatEnd={statusChatEnd}/>
</div>
</TicketHeader>
<ReplyMessageProvider>

View File

@ -27,7 +27,7 @@ const useStyles = makeStyles(theme => ({
},
}));
const TicketActionButtons = ({ ticket, schedule }) => {
const TicketActionButtons = ({ ticket, statusChatEnd }) => {
const classes = useStyles();
const history = useHistory();
const [anchorEl, setAnchorEl] = useState(null);
@ -64,7 +64,7 @@ const TicketActionButtons = ({ ticket, schedule }) => {
render(<Modal
modal_header={'Finalização de Atendimento'}
func={chatEndVal}
schedules={schedule}
statusChatEnd={statusChatEnd}
ticketId={ticket.id}
/>)

View File

@ -9,7 +9,9 @@ import Divider from "@material-ui/core/Divider";
import { Badge } from "@material-ui/core";
import DashboardOutlinedIcon from "@material-ui/icons/DashboardOutlined";
import ReportOutlinedIcon from "@material-ui/icons/ReportOutlined";
import ReportOutlinedIcon from "@material-ui/icons/ReportOutlined";
import SendOutlined from '@material-ui/icons/SendOutlined';
//import ReportOutlined from "@bit/mui-org.material-ui-icons.report-outlined";
@ -89,6 +91,11 @@ const MainListItems = (props) => {
to="/contacts"
primary={i18n.t("mainDrawer.listItems.contacts")}
icon={<ContactPhoneOutlinedIcon />}
/>
<ListItemLink
to="/schedulesReminder"
primary="Lembretes"
icon={<SendOutlined />}
/>
<ListItemLink
to="/quickAnswers"

View File

@ -17,7 +17,7 @@ const reducerQ = (state, action) =>{
if(action.type === 'LOAD_QUERY'){
console.log('----------------action.payload: ', action.payload)
const queries = action.payload
const newQueries = []
@ -234,19 +234,19 @@ const Report = () => {
// Get from child 1
const datePicker1Value = (data) => {
console.log('DATE1: ',(data));
setDatePicker1(data)
}
// Get from child 2
const datePicker2Value = (data) => {
console.log('DATE2: ',(data));
setDatePicker2(data)
}
// Get from child 3
const textFieldSelectUser = (data) => {
console.log('textField: ',data);
setUser(data)
}
@ -266,8 +266,8 @@ const textFieldSelectUser = (data) => {
return {'value': obj.id, 'label': obj.name}
})}/></Item>
<Item><DatePicker1 func={datePicker1Value} minDate={false} title={'Data inicio'}/></Item>
<Item><DatePicker2 func={datePicker2Value} minDate={false} title={'Data fim'}/></Item>
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={'Data inicio'}/></Item>
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'}/></Item>
<Item sx={{ gridColumn: '4 / 5' }}>
{/* <Button size="small" variant="contained" onClick={()=>{handleQuery()}}>GO</Button>*/}
@ -282,7 +282,8 @@ const textFieldSelectUser = (data) => {
<Item sx={{ gridColumn: '1', gridRow: 'span 1' }}>
<MTable data={query}
columns={columnsData}
hasChild={true}
hasChild={true}
removeClickRow={false}
table_title={'Relatório de atendimento por atendentes'}/>
</Item>

View File

@ -0,0 +1,586 @@
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,
},
rowStyle: {
fontSize: 12,
}
}}
/>
</Item>
</Box>
</MainContainer>
)
};
export default SchedulesReminder;

View File

@ -6,6 +6,7 @@ import LoggedInLayout from "../layout";
import Dashboard from "../pages/Dashboard/";
import Report from "../pages/Report/";
import SchedulesReminder from "../pages/SchedulesReminder/";
import Tickets from "../pages/Tickets/";
import Signup from "../pages/Signup/";
@ -19,8 +20,7 @@ import Queues from "../pages/Queues/";
import { AuthProvider } from "../context/Auth/AuthContext";
import { WhatsAppsProvider } from "../context/WhatsApp/WhatsAppsContext";
import Route from "./Route";
//import { Report } from "@material-ui/icons";
//console.log('---AuthProvider: ',AuthProvider)
@ -58,9 +58,13 @@ const Routes = () => {
component={Report}
isPrivate
/>
<Route exact path="/contacts" component={Contacts} isPrivate />
<Route exact path="/schedulesReminder" component={SchedulesReminder} isPrivate />
<Route exact path="/users" component={Users} isPrivate />
<Route
exact