Tabs and Manager list fix some functions
WIP Project stop by order chefpull/14/head^2
parent
3c43d78cfc
commit
4c24f81336
|
@ -1,9 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { BadgeComponentStyled } from "./BadgeComponent.style";
|
import { BadgeComponentStyled } from "./BadgeComponent.style";
|
||||||
|
|
||||||
const BadgeComponent = ({ counter, position, top, left, right, bottom }) => {
|
const BadgeComponent = ({ counter,fontSize, position, top, left, right, bottom,bgcolor }) => {
|
||||||
return (
|
return (
|
||||||
<BadgeComponentStyled position={position} top={top} left={left} right={right} bottom={bottom}>
|
<BadgeComponentStyled position={position} top={top} left={left} right={right} bottom={bottom} fontSize={fontSize} bgcolor={bgcolor}>
|
||||||
{counter}
|
{counter}
|
||||||
</BadgeComponentStyled>
|
</BadgeComponentStyled>
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,8 +15,8 @@ export const BadgeComponentStyled = styled.span`
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
width: 21px;
|
width: 21px;
|
||||||
height: 21px;
|
height: 21px;
|
||||||
font-size: 16px;
|
font-size: ${({ fontSize }) => (fontSize ? fontSize : "16px")};
|
||||||
color: ${color.pricinpal.blanco};
|
color: ${color.pricinpal.blanco};
|
||||||
background-color: ${color.status.yes};
|
background-color: ${({ bgcolor }) => (bgcolor ? bgcolor : color.status.yes)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { color } from "../../../../style/varibles";
|
||||||
|
|
||||||
const InputComponentStyled = styled.input`
|
const InputComponentStyled = styled.input`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: transparent;
|
background: ${color.complement.azulOscuro};
|
||||||
border: none;
|
border: none;
|
||||||
color: ${color.complement.azulCielo};
|
color: ${color.complement.azulCielo};
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -88,13 +88,9 @@ const Ticket = () => {
|
||||||
setDrawerOpen(false);
|
setDrawerOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const style ={
|
|
||||||
height: "fit-content",
|
|
||||||
width: "100%",
|
|
||||||
position: "relative",
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className="test" style={style} >
|
<div className="test" >
|
||||||
<TicketHeader loading={loading}>
|
<TicketHeader loading={loading}>
|
||||||
<div>
|
<div>
|
||||||
<TicketInfo contact={contact} ticket={ticket} onClick={handleDrawerOpen} />
|
<TicketInfo contact={contact} ticket={ticket} onClick={handleDrawerOpen} />
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import styled from "styled-components";
|
||||||
|
import { color } from "../../style/varibles";
|
||||||
|
|
||||||
|
export const TicketStyled = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
background-color: ${color.status.no};
|
||||||
|
`;
|
|
@ -8,7 +8,7 @@ import { i18n } from "../../../../../translate/i18n";
|
||||||
import api from "../../../../../services/api";
|
import api from "../../../../../services/api";
|
||||||
import { AuthContext } from "../../../../../context/Auth/AuthContext";
|
import { AuthContext } from "../../../../../context/Auth/AuthContext";
|
||||||
import toastError from "../../../../../errors/toastError";
|
import toastError from "../../../../../errors/toastError";
|
||||||
import Btn from "../../../../Base/Btn/Btn"
|
import Btn from "../../../../Base/Btn/Btn";
|
||||||
import {
|
import {
|
||||||
TicketDateStyled,
|
TicketDateStyled,
|
||||||
TicketImgStyled,
|
TicketImgStyled,
|
||||||
|
@ -24,7 +24,6 @@ const TicketListItem = ({ tickets }) => {
|
||||||
const [loading, setLoading] = React.useState(false);
|
const [loading, setLoading] = React.useState(false);
|
||||||
const isMounted = React.useRef(true);
|
const isMounted = React.useRef(true);
|
||||||
const { user } = React.useContext(AuthContext);
|
const { user } = React.useContext(AuthContext);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
isMounted.current = false;
|
isMounted.current = false;
|
||||||
|
@ -32,7 +31,7 @@ const TicketListItem = ({ tickets }) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleAcepptTicket = async (id) => {
|
const handleAcepptTicket = async (id) => {
|
||||||
setLoading(true)
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
await api.put(`/tickets/${id}`, {
|
await api.put(`/tickets/${id}`, {
|
||||||
status: "open",
|
status: "open",
|
||||||
|
@ -54,10 +53,14 @@ const TicketListItem = ({ tickets }) => {
|
||||||
const handleSelectTicket = (id) => {
|
const handleSelectTicket = (id) => {
|
||||||
history.push(`/tickets/${id}`);
|
history.push(`/tickets/${id}`);
|
||||||
};
|
};
|
||||||
if (loading) return <LoadingScreen />;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={tickets.id}>
|
<React.Fragment key={tickets.id}>
|
||||||
<TicketListItemStyled queuecolor={tickets.queue} onClick={()=>handleSelectTicket(tickets.id)}>
|
<TicketListItemStyled
|
||||||
|
queuecolor={tickets.queue}
|
||||||
|
onClick={() => handleSelectTicket(tickets.id)}
|
||||||
|
>
|
||||||
{tickets.contact.profilePicUrl ? (
|
{tickets.contact.profilePicUrl ? (
|
||||||
<TicketImgStyled src={tickets.contact.profilePicUrl} alt={tickets.id} />
|
<TicketImgStyled src={tickets.contact.profilePicUrl} alt={tickets.id} />
|
||||||
) : (
|
) : (
|
||||||
|
@ -86,7 +89,13 @@ const TicketListItem = ({ tickets }) => {
|
||||||
)}
|
)}
|
||||||
</TicketDateStyled>
|
</TicketDateStyled>
|
||||||
{tickets.status === "pending" ? (
|
{tickets.status === "pending" ? (
|
||||||
<Btn text="Aceitar" bgcolor={color.complement.azulCielo} fontcolor={color.pricinpal.blanco} fontSize="12px"/>
|
<Btn
|
||||||
|
onClick={() => handleAcepptTicket(tickets.id)}
|
||||||
|
text="Aceitar"
|
||||||
|
bgcolor={color.complement.azulCielo}
|
||||||
|
fontcolor={color.pricinpal.blanco}
|
||||||
|
fontSize="12px"
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import React from "react";
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "socket.io-client";
|
||||||
|
|
||||||
|
import LoadingScreen from "../../../LoadingScreen/LoadingScreen";
|
||||||
|
|
||||||
import TicketListStyled from "./TicketsList.style";
|
import TicketListStyled from "./TicketsList.style";
|
||||||
import useTickets from "../../../../hooks/useTickets";
|
import useTickets from "../../../../hooks/useTickets";
|
||||||
import TicketListItem from "../TicketsList/TicketListItem/TicketListItem";
|
import TicketListItem from "../TicketsList/TicketListItem/TicketListItem";
|
||||||
|
@ -94,10 +96,14 @@ const reducer = (state, action) => {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCount }) => {
|
const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCount, valueTab }) => {
|
||||||
const [pageNumber, setPageNumber] = React.useState(1);
|
const [pageNumber, setPageNumber] = React.useState(1);
|
||||||
const [ticketsList, dispatch] = React.useReducer(reducer, []);
|
const [ticketsList, dispatch] = React.useReducer(reducer, []);
|
||||||
const { user } = React.useContext(AuthContext);
|
const { user } = React.useContext(AuthContext);
|
||||||
|
React.useEffect(() => {
|
||||||
|
dispatch({ type: "RESET" });
|
||||||
|
setPageNumber(1);
|
||||||
|
}, [status, searchParam, dispatch, showAll, selectedQueueIds]);
|
||||||
const { tickets, loading } = useTickets({
|
const { tickets, loading } = useTickets({
|
||||||
pageNumber,
|
pageNumber,
|
||||||
searchParam,
|
searchParam,
|
||||||
|
@ -105,10 +111,13 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou
|
||||||
showAll,
|
showAll,
|
||||||
queueIds: JSON.stringify(selectedQueueIds),
|
queueIds: JSON.stringify(selectedQueueIds),
|
||||||
});
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
dispatch({ type: "RESET" });
|
if (typeof updateCount === "function") {
|
||||||
setPageNumber(1);
|
updateCount(ticketsList.length);
|
||||||
}, [status, searchParam, dispatch, showAll, selectedQueueIds]);
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ticketsList]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!status && !searchParam) return;
|
if (!status && !searchParam) return;
|
||||||
|
@ -116,7 +125,7 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou
|
||||||
type: "LOAD_TICKETS",
|
type: "LOAD_TICKETS",
|
||||||
payload: tickets,
|
payload: tickets,
|
||||||
});
|
});
|
||||||
}, [tickets, searchParam]);
|
}, [tickets, status, searchParam]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
||||||
|
@ -162,6 +171,8 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou
|
||||||
|
|
||||||
socket.on("appMessage", (data) => {
|
socket.on("appMessage", (data) => {
|
||||||
if (data.action === "create" && shouldUpdateTicket(data.ticket)) {
|
if (data.action === "create" && shouldUpdateTicket(data.ticket)) {
|
||||||
|
// console.log('((((((((((((((((((( DATA.MESSAGE: ', data.message)
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "UPDATE_TICKET_UNREAD_MESSAGES",
|
type: "UPDATE_TICKET_UNREAD_MESSAGES",
|
||||||
// payload: data.ticket,
|
// payload: data.ticket,
|
||||||
|
@ -185,13 +196,16 @@ const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCou
|
||||||
}, [status, showAll, user, selectedQueueIds]);
|
}, [status, showAll, user, selectedQueueIds]);
|
||||||
|
|
||||||
if (loading) return <TicketsListSkeleton />;
|
if (loading) return <TicketsListSkeleton />;
|
||||||
|
|
||||||
|
if (status === valueTab)
|
||||||
return (
|
return (
|
||||||
<TicketListStyled>
|
<TicketListStyled>
|
||||||
{ticketsList.map((ticket) => (
|
{ticketsList.map((ticket) => (
|
||||||
<TicketListItem tickets={ticket} status={status} key={ticket.id} />
|
<TicketListItem tickets={ticket} key={ticket.id} />
|
||||||
))}
|
))}
|
||||||
</TicketListStyled>
|
</TicketListStyled>
|
||||||
);
|
);
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TicketsList;
|
export default TicketsList;
|
||||||
|
|
|
@ -2,24 +2,25 @@ import React from "react";
|
||||||
|
|
||||||
import TicketsManagerStyled from "./TicketsManager.style";
|
import TicketsManagerStyled from "./TicketsManager.style";
|
||||||
import TicketsTabs from "./TicketsTabs/TicketsTabs";
|
import TicketsTabs from "./TicketsTabs/TicketsTabs";
|
||||||
|
|
||||||
|
import TicketSearch from "../TicketSearch/TicketSearch";
|
||||||
import TicketsList from "./TicketsList/TicketsList";
|
import TicketsList from "./TicketsList/TicketsList";
|
||||||
import NewTicketModal from "../../NewTicketModal";
|
import NewTicketModal from "../../NewTicketModal";
|
||||||
import useTickets from "../../../hooks/useTickets";
|
|
||||||
import { AuthContext } from "../../../context/Auth/AuthContext";
|
import { AuthContext } from "../../../context/Auth/AuthContext";
|
||||||
import TicketSearch from "../TicketSearch/TicketSearch";
|
|
||||||
|
|
||||||
const TicketsManager = () => {
|
const TicketsManager = () => {
|
||||||
const [valueTab, setValueTab] = React.useState("open");
|
const [valueTab, setValueTab] = React.useState("open");
|
||||||
const [searchParam, setSearchParam] = React.useState("");
|
const [searchParam, setSearchParam] = React.useState("");
|
||||||
const [spinning, setSpinning] = React.useState(false);
|
const [spinning, setSpinning] = React.useState(false);
|
||||||
const [newTicketModalOpen, setNewTicketModalOpen] = React.useState(false);
|
const [newTicketModalOpen, setNewTicketModalOpen] = React.useState(false);
|
||||||
|
const [openCount, setOpenCount] = React.useState(0);
|
||||||
|
const [pendingCount, setPendingCount] = React.useState(0);
|
||||||
|
const [closedCount, setClosedCount] = React.useState(0);
|
||||||
const [showAllTickets, setShowAllTickets] = React.useState(false);
|
const [showAllTickets, setShowAllTickets] = React.useState(false);
|
||||||
const { user } = React.useContext(AuthContext);
|
const { user } = React.useContext(AuthContext);
|
||||||
const userQueueIds = user.queues.map((q) => q.id);
|
const userQueueIds = user.queues.map((q) => q.id);
|
||||||
const [selectedQueueIds, setSelectedQueueIds] = React.useState(userQueueIds || []);
|
const [selectedQueueIds, setSelectedQueueIds] = React.useState(userQueueIds || []);
|
||||||
const { tickets } = useTickets({
|
|
||||||
searchParam
|
|
||||||
});
|
|
||||||
|
|
||||||
let searchTimeout;
|
let searchTimeout;
|
||||||
const handleSearch = (e) => {
|
const handleSearch = (e) => {
|
||||||
|
@ -47,23 +48,47 @@ const TicketsManager = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TicketsManagerStyled>
|
<TicketsManagerStyled>
|
||||||
<TicketsTabs tickets={tickets} setValueTab={setValueTab} valueTab={valueTab} />
|
<TicketsTabs
|
||||||
|
setValueTab={setValueTab}
|
||||||
|
valueTab={valueTab}
|
||||||
|
count={{ openCount, pendingCount, closedCount }}
|
||||||
|
/>
|
||||||
|
|
||||||
<TicketSearch
|
<TicketSearch
|
||||||
spinning={spinning}
|
spinning={spinning}
|
||||||
handleSearch={handleSearch}
|
handleSearch={handleSearch}
|
||||||
setNewTicketModalOpen={setNewTicketModalOpen}
|
setNewTicketModalOpen={setNewTicketModalOpen}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TicketsList
|
<TicketsList
|
||||||
|
status="open"
|
||||||
|
updateCount={(v) => setOpenCount(v)}
|
||||||
showAll={showAllTickets}
|
showAll={showAllTickets}
|
||||||
status={valueTab}
|
|
||||||
selectedQueueIds={selectedQueueIds}
|
selectedQueueIds={selectedQueueIds}
|
||||||
searchParam={searchParam}
|
searchParam={searchParam}
|
||||||
|
valueTab={valueTab}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TicketsList
|
||||||
|
status="pending"
|
||||||
|
updateCount={(v) => setPendingCount(v)}
|
||||||
|
selectedQueueIds={selectedQueueIds}
|
||||||
|
searchParam={searchParam}
|
||||||
|
valueTab={valueTab}
|
||||||
|
/>
|
||||||
|
<TicketsList
|
||||||
|
status="closed"
|
||||||
|
updateCount={(v) => setClosedCount(v)}
|
||||||
|
selectedQueueIds={selectedQueueIds}
|
||||||
|
searchParam={searchParam}
|
||||||
|
valueTab={valueTab}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<NewTicketModal
|
<NewTicketModal
|
||||||
modalOpen={newTicketModalOpen}
|
modalOpen={newTicketModalOpen}
|
||||||
onClose={(e) => setNewTicketModalOpen(false)}
|
onClose={(e) => setNewTicketModalOpen(false)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</TicketsManagerStyled>
|
</TicketsManagerStyled>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { TicketsTabStyled } from "./TicketsTab.style";
|
import { TicketsTabStyled } from "./TicketsTab.style";
|
||||||
|
import { color } from "../../../../../style/varibles";
|
||||||
|
|
||||||
const TicketsTab = ({ text, id, setValueTab, valueTab }) => {
|
import BadgeComponent from "../../../../Base/Badge/BadgeComponent";
|
||||||
|
|
||||||
|
const TicketsTab = ({ text, id, setValueTab, valueTab, count }) => {
|
||||||
const [active, setActive] = React.useState(false);
|
const [active, setActive] = React.useState(false);
|
||||||
|
|
||||||
const handleClick = ({ target }) => {
|
const handleClick = ({ target }) => {
|
||||||
|
@ -11,6 +14,7 @@ const TicketsTab = ({ text, id, setValueTab, valueTab }) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
valueTab === id ? setActive(true) : setActive(false);
|
valueTab === id ? setActive(true) : setActive(false);
|
||||||
}, [valueTab, id]);
|
}, [valueTab, id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TicketsTabStyled
|
<TicketsTabStyled
|
||||||
id={id}
|
id={id}
|
||||||
|
@ -19,6 +23,18 @@ const TicketsTab = ({ text, id, setValueTab, valueTab }) => {
|
||||||
className={active ? "active" : ""}
|
className={active ? "active" : ""}
|
||||||
>
|
>
|
||||||
{text}
|
{text}
|
||||||
|
{id !== "open" ? (
|
||||||
|
<BadgeComponent
|
||||||
|
counter={count}
|
||||||
|
position="absolute"
|
||||||
|
right="4px"
|
||||||
|
top="6px"
|
||||||
|
fontSize="12px"
|
||||||
|
bgcolor={id === "pending" ? color.status.warning : color.status.no}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
</TicketsTabStyled>
|
</TicketsTabStyled>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,32 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import TicketsTab from "../TicketsTabs/TicketsTab/TicketsTab";
|
||||||
import { TicketTabsStyled } from "./TicketsTabs.style";
|
import { TicketTabsStyled } from "./TicketsTabs.style";
|
||||||
|
|
||||||
import TicketsTab from "./TicketsTab/TicketsTab";
|
const TicketsTabs = ({ setValueTab, valueTab, count }) => {
|
||||||
|
|
||||||
const TicketsTabs = ({ tickets, setValueTab, valueTab }) => {
|
|
||||||
|
|
||||||
if (!setValueTab) return null;
|
|
||||||
return (
|
return (
|
||||||
<TicketTabsStyled>
|
<TicketTabsStyled>
|
||||||
<TicketsTab text="Aberto" id="open" setValueTab={setValueTab} valueTab={valueTab} />
|
<TicketsTab
|
||||||
<TicketsTab text="Aguardando" id="pending" setValueTab={setValueTab} valueTab={valueTab} />
|
text="Aberto"
|
||||||
<TicketsTab text="Fechado" id="closed" setValueTab={setValueTab} valueTab={valueTab} />
|
id="open"
|
||||||
|
setValueTab={setValueTab}
|
||||||
|
valueTab={valueTab}
|
||||||
|
count={count.openCount}
|
||||||
|
/>
|
||||||
|
<TicketsTab
|
||||||
|
text="Aguardando"
|
||||||
|
id="pending"
|
||||||
|
setValueTab={setValueTab}
|
||||||
|
valueTab={valueTab}
|
||||||
|
count={count.pendingCount}
|
||||||
|
/>
|
||||||
|
<TicketsTab
|
||||||
|
text="Fechado"
|
||||||
|
id="closed"
|
||||||
|
setValueTab={setValueTab}
|
||||||
|
valueTab={valueTab}
|
||||||
|
count={count.closedCount}
|
||||||
|
/>
|
||||||
</TicketTabsStyled>
|
</TicketTabsStyled>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,101 +3,89 @@ import MainContainer from "../../components/MainContainer";
|
||||||
import api from "../../services/api";
|
import api from "../../services/api";
|
||||||
import SelectField from "../../components/Report/SelectField";
|
import SelectField from "../../components/Report/SelectField";
|
||||||
//import { data } from '../../components/Report/MTable/data';
|
//import { data } from '../../components/Report/MTable/data';
|
||||||
import DatePicker1 from '../../components/Report/DatePicker'
|
import DatePicker1 from "../../components/Report/DatePicker";
|
||||||
import DatePicker2 from '../../components/Report/DatePicker'
|
import DatePicker2 from "../../components/Report/DatePicker";
|
||||||
import MTable from "../../components/Report/MTable";
|
import MTable from "../../components/Report/MTable";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from "prop-types";
|
||||||
import Box from '@mui/material/Box';
|
import Box from "@mui/material/Box";
|
||||||
import { AuthContext } from "../../context/Auth/AuthContext";
|
import { AuthContext } from "../../context/Auth/AuthContext";
|
||||||
import { Can } from "../../components/Can";
|
import { Can } from "../../components/Can";
|
||||||
|
|
||||||
import { Button } from "@material-ui/core";
|
import { Button } from "@material-ui/core";
|
||||||
|
|
||||||
import ReportModal from "../../components/ReportModal";
|
import ReportModal from "../../components/ReportModal";
|
||||||
import MaterialTable from 'material-table';
|
import MaterialTable from "material-table";
|
||||||
|
|
||||||
import LogoutIcon from '@material-ui/icons/CancelOutlined';
|
import LogoutIcon from "@material-ui/icons/CancelOutlined";
|
||||||
|
|
||||||
import { CSVLink } from "react-csv";
|
import { CSVLink } from "react-csv";
|
||||||
|
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "socket.io-client";
|
||||||
|
|
||||||
const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }]
|
const report = [
|
||||||
|
{ value: "1", label: "Atendimento por atendentes" },
|
||||||
|
{ value: "2", label: "Usuários online/offline" },
|
||||||
|
];
|
||||||
|
|
||||||
let columns = [
|
let columns = [
|
||||||
{
|
{
|
||||||
key: 'ticket.whatsapp.name',
|
key: "ticket.whatsapp.name",
|
||||||
label: 'Loja',
|
label: "Loja",
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: "id",
|
||||||
label: 'id Mensagem',
|
label: "id Mensagem",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'ticket.id',
|
key: "ticket.id",
|
||||||
label: 'id Conversa',
|
label: "id Conversa",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'ticket.contact.name',
|
key: "ticket.contact.name",
|
||||||
label: 'Cliente',
|
label: "Cliente",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
key: 'ticket.user.name',
|
key: "ticket.user.name",
|
||||||
label: 'Atendente',
|
label: "Atendente",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'body',
|
key: "body",
|
||||||
label: 'Mensagem',
|
label: "Mensagem",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'fromMe',
|
key: "fromMe",
|
||||||
label: 'Sentido',
|
label: "Sentido",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'createdAt',
|
key: "createdAt",
|
||||||
label: 'Criada',
|
label: "Criada",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ticket.contact.number',
|
key: "ticket.contact.number",
|
||||||
label: 'Telefone cliente',
|
label: "Telefone cliente",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ticket.queue.name',
|
key: "ticket.queue.name",
|
||||||
label: 'Fila',
|
label: "Fila",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ticket.status',
|
key: "ticket.status",
|
||||||
label: 'Status',
|
label: "Status",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ticket.statusChatEnd',
|
key: "ticket.statusChatEnd",
|
||||||
label: 'Status de encerramento',
|
label: "Status de encerramento",
|
||||||
}
|
},
|
||||||
|
];
|
||||||
]
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const reducerQ = (state, action) => {
|
const reducerQ = (state, action) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (action.type === "DELETE_USER_STATUS") {
|
if (action.type === "DELETE_USER_STATUS") {
|
||||||
|
|
||||||
const userId = action.payload;
|
const userId = action.payload;
|
||||||
|
|
||||||
//console.log('Entrou no delete user status userId: ', userId)
|
//console.log('Entrou no delete user status userId: ', userId)
|
||||||
|
@ -113,115 +101,90 @@ const reducerQ = (state, action) => {
|
||||||
return [...state];
|
return [...state];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.type === "LOAD_QUERY") {
|
||||||
|
const queries = action.payload;
|
||||||
if (action.type === 'LOAD_QUERY') {
|
const newQueries = [];
|
||||||
|
|
||||||
|
|
||||||
const queries = action.payload
|
|
||||||
const newQueries = []
|
|
||||||
|
|
||||||
queries.forEach((query) => {
|
queries.forEach((query) => {
|
||||||
|
const queryIndex = state.findIndex((q) => q.id === query.id);
|
||||||
const queryIndex = state.findIndex((q) => q.id === query.id)
|
|
||||||
|
|
||||||
if (queryIndex !== -1) {
|
if (queryIndex !== -1) {
|
||||||
state[queryIndex] = query
|
state[queryIndex] = query;
|
||||||
|
} else {
|
||||||
|
newQueries.push(query);
|
||||||
}
|
}
|
||||||
else {
|
});
|
||||||
newQueries.push(query)
|
|
||||||
|
return [...state, ...newQueries];
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return [...state, ...newQueries]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (action.type === "UPDATE_STATUS_ONLINE") {
|
if (action.type === "UPDATE_STATUS_ONLINE") {
|
||||||
|
let onlineUser = action.payload;
|
||||||
let onlineUser = action.payload
|
let index = -1;
|
||||||
let index = -1
|
|
||||||
|
|
||||||
// console.log('sssssssssstate: ', state, ' | ONLINE USERS: onlineUser.userId ', onlineUser.userId)
|
// console.log('sssssssssstate: ', state, ' | ONLINE USERS: onlineUser.userId ', onlineUser.userId)
|
||||||
|
|
||||||
if (onlineUser.sumOpen || onlineUser.sumClosed) {
|
if (onlineUser.sumOpen || onlineUser.sumClosed) {
|
||||||
index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)))
|
index = state.findIndex(
|
||||||
}
|
(e) =>
|
||||||
else {
|
(onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) ||
|
||||||
index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`)
|
(onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log(' *********************** index: ', index)
|
//console.log(' *********************** index: ', index)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
|
|
||||||
// console.log('ENTROU NO INDEX')
|
// console.log('ENTROU NO INDEX')
|
||||||
|
|
||||||
|
|
||||||
if (!("statusOnline" in state[index])) {
|
if (!("statusOnline" in state[index])) {
|
||||||
state[index].statusOnline = onlineUser
|
state[index].statusOnline = onlineUser;
|
||||||
|
} else if ("statusOnline" in state[index]) {
|
||||||
|
state[index].statusOnline["status"] = onlineUser.status;
|
||||||
}
|
}
|
||||||
else if ("statusOnline" in state[index]) {
|
|
||||||
state[index].statusOnline['status'] = onlineUser.status
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ("onlineTime" in onlineUser) {
|
if ("onlineTime" in onlineUser) {
|
||||||
|
|
||||||
if ("sumOnlineTime" in state[index]) {
|
if ("sumOnlineTime" in state[index]) {
|
||||||
state[index].sumOnlineTime['sum'] = (onlineUser.onlineTime).split(" ")[1]
|
state[index].sumOnlineTime["sum"] = onlineUser.onlineTime.split(" ")[1];
|
||||||
}
|
} else if (!("sumOnlineTime" in state[index])) {
|
||||||
else if (!("sumOnlineTime" in state[index])) {
|
state[index].sumOnlineTime = {
|
||||||
state[index].sumOnlineTime = { userId: onlineUser.userId, sum: (onlineUser.onlineTime).split(" ")[1] }
|
userId: onlineUser.userId,
|
||||||
|
sum: onlineUser.onlineTime.split(" ")[1],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (onlineUser.sumOpen) {
|
if (onlineUser.sumOpen) {
|
||||||
|
|
||||||
if ("sumOpen" in state[index]) {
|
if ("sumOpen" in state[index]) {
|
||||||
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1 | state[index].sumOpen["count"]: ', state[index].sumOpen['count'], ' | onlineUser.sumOpen.count: ', onlineUser.sumOpen.count)
|
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1 | state[index].sumOpen["count"]: ', state[index].sumOpen['count'], ' | onlineUser.sumOpen.count: ', onlineUser.sumOpen.count)
|
||||||
state[index].sumOpen['count'] = onlineUser.sumOpen.count
|
state[index].sumOpen["count"] = onlineUser.sumOpen.count;
|
||||||
} else if (!("sumOpen" in state[index])) {
|
} else if (!("sumOpen" in state[index])) {
|
||||||
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
|
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
|
||||||
state[index].sumOpen = onlineUser.sumOpen
|
state[index].sumOpen = onlineUser.sumOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onlineUser.sumClosed) {
|
if (onlineUser.sumClosed) {
|
||||||
|
|
||||||
if ("sumClosed" in state[index]) {
|
if ("sumClosed" in state[index]) {
|
||||||
// console.log(' >>>>>>>>>>>>>>>>>> sumClosed 1 | state[index].sumClosed["count"]: ', state[index].sumClosed['count'], ' | onlineUser.sumClosed.count: ', onlineUser.sumClosed.count)
|
// console.log(' >>>>>>>>>>>>>>>>>> sumClosed 1 | state[index].sumClosed["count"]: ', state[index].sumClosed['count'], ' | onlineUser.sumClosed.count: ', onlineUser.sumClosed.count)
|
||||||
state[index].sumClosed['count'] = onlineUser.sumClosed.count
|
state[index].sumClosed["count"] = onlineUser.sumClosed.count;
|
||||||
} else if (!("sumClosed" in state[index])) {
|
} else if (!("sumClosed" in state[index])) {
|
||||||
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
|
// console.log(' >>>>>>>>>>>>>>>>>> sumOpen 1')
|
||||||
state[index].sumClosed = onlineUser.sumClosed
|
state[index].sumClosed = onlineUser.sumClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return [...state]
|
return [...state];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (action.type === "RESET") {
|
if (action.type === "RESET") {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const reducer = (state, action) => {
|
const reducer = (state, action) => {
|
||||||
|
|
||||||
if (action.type === "LOAD_USERS") {
|
if (action.type === "LOAD_USERS") {
|
||||||
const users = action.payload;
|
const users = action.payload;
|
||||||
const newUsers = [];
|
const newUsers = [];
|
||||||
|
@ -253,24 +216,20 @@ const reducer = (state, action) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function Item(props) {
|
function Item(props) {
|
||||||
const { sx, ...other } = props;
|
const { sx, ...other } = props;
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
bgcolor: (theme) => (theme.palette.mode === 'dark' ? '#101010' : '#fff'),
|
bgcolor: (theme) => (theme.palette.mode === "dark" ? "#101010" : "#fff"),
|
||||||
color: (theme) => (theme.palette.mode === 'dark' ? 'grey.300' : 'grey.800'),
|
color: (theme) => (theme.palette.mode === "dark" ? "grey.300" : "grey.800"),
|
||||||
border: '1px solid',
|
border: "1px solid",
|
||||||
borderColor: (theme) =>
|
borderColor: (theme) => (theme.palette.mode === "dark" ? "grey.800" : "grey.300"),
|
||||||
theme.palette.mode === 'dark' ? 'grey.800' : 'grey.300',
|
|
||||||
p: 1,
|
p: 1,
|
||||||
m: 1,
|
m: 1,
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
fontSize: '0.875rem',
|
fontSize: "0.875rem",
|
||||||
fontWeight: '700',
|
fontWeight: "700",
|
||||||
...sx,
|
...sx,
|
||||||
}}
|
}}
|
||||||
{...other}
|
{...other}
|
||||||
|
@ -280,33 +239,28 @@ function Item(props) {
|
||||||
|
|
||||||
Item.propTypes = {
|
Item.propTypes = {
|
||||||
sx: PropTypes.oneOfType([
|
sx: PropTypes.oneOfType([
|
||||||
PropTypes.arrayOf(
|
PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])),
|
||||||
PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool]),
|
|
||||||
),
|
|
||||||
PropTypes.func,
|
PropTypes.func,
|
||||||
PropTypes.object,
|
PropTypes.object,
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let columnsData = [
|
let columnsData = [
|
||||||
{ title: 'Unidade', field: 'whatsapp.name' },
|
{ title: "Unidade", field: "whatsapp.name" },
|
||||||
{ title: 'Atendente', field: 'user.name' },
|
{ title: "Atendente", field: "user.name" },
|
||||||
{ title: 'Contato', field: 'contact.number' },
|
{ title: "Contato", field: "contact.number" },
|
||||||
{ title: 'Nome', field: 'contact.name' },
|
{ title: "Nome", field: "contact.name" },
|
||||||
{ title: 'Assunto', field: 'queue.name' },
|
{ title: "Assunto", field: "queue.name" },
|
||||||
|
|
||||||
{ title: 'Status', field: 'status' },
|
{ title: "Status", field: "status" },
|
||||||
|
|
||||||
{ title: 'Criado', field: 'createdAt' },
|
{ title: "Criado", field: "createdAt" },
|
||||||
//{title: 'Atualizado', field: 'updatedAt'},
|
//{title: 'Atualizado', field: 'updatedAt'},
|
||||||
{title: 'Status de encerramento', field: 'statusChatEnd'}];
|
{ title: "Status de encerramento", field: "statusChatEnd" },
|
||||||
|
];
|
||||||
|
|
||||||
const Report = () => {
|
const Report = () => {
|
||||||
|
const csvLink = useRef();
|
||||||
const csvLink = useRef()
|
|
||||||
|
|
||||||
const { user: userA } = useContext(AuthContext);
|
const { user: userA } = useContext(AuthContext);
|
||||||
|
|
||||||
|
@ -317,39 +271,32 @@ const Report = () => {
|
||||||
const [pageNumber, setPageNumber] = useState(1);
|
const [pageNumber, setPageNumber] = useState(1);
|
||||||
const [users, dispatch] = useReducer(reducer, []);
|
const [users, dispatch] = useReducer(reducer, []);
|
||||||
//const [columns, setColums] = useState([])
|
//const [columns, setColums] = useState([])
|
||||||
const [startDate, setDatePicker1] = useState(new Date())
|
const [startDate, setDatePicker1] = useState(new Date());
|
||||||
const [endDate, setDatePicker2] = useState(new Date())
|
const [endDate, setDatePicker2] = useState(new Date());
|
||||||
const [userId, setUser] = useState(null)
|
const [userId, setUser] = useState(null);
|
||||||
const [query, dispatchQ] = useReducer(reducerQ, [])
|
const [query, dispatchQ] = useReducer(reducerQ, []);
|
||||||
|
|
||||||
const [dataCSV, setDataCSV] = useState([])
|
const [dataCSV, setDataCSV] = useState([]);
|
||||||
const [isMount, setIsMount] = useState(true);
|
const [isMount, setIsMount] = useState(true);
|
||||||
|
|
||||||
const [reportOption, setReport] = useState('1')
|
const [reportOption, setReport] = useState("1");
|
||||||
const [reporList,] = useState(report)
|
const [reporList] = useState(report);
|
||||||
const [profile, setProfile] = useState('')
|
const [profile, setProfile] = useState("");
|
||||||
const [dataRows, setData] = useState([]);
|
const [dataRows, setData] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch({ type: "RESET" });
|
dispatch({ type: "RESET" });
|
||||||
dispatchQ({ type: "RESET" })
|
dispatchQ({ type: "RESET" });
|
||||||
|
|
||||||
setPageNumber(1);
|
setPageNumber(1);
|
||||||
}, [searchParam, profile]);
|
}, [searchParam, profile]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//setLoading(true);
|
//setLoading(true);
|
||||||
|
|
||||||
const delayDebounceFn = setTimeout(() => {
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
const fetchUsers = async () => {
|
const fetchUsers = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
//console.log('profile: ', profile)
|
//console.log('profile: ', profile)
|
||||||
|
|
||||||
const { data } = await api.get("/users/", {
|
const { data } = await api.get("/users/", {
|
||||||
|
@ -359,34 +306,27 @@ const Report = () => {
|
||||||
dispatch({ type: "LOAD_USERS", payload: data.users });
|
dispatch({ type: "LOAD_USERS", payload: data.users });
|
||||||
//setHasMore(data.hasMore);
|
//setHasMore(data.hasMore);
|
||||||
//setLoading(false);
|
//setLoading(false);
|
||||||
|
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchUsers();
|
fetchUsers();
|
||||||
|
|
||||||
}, 500);
|
}, 500);
|
||||||
return () => clearTimeout(delayDebounceFn);
|
return () => clearTimeout(delayDebounceFn);
|
||||||
}, [searchParam, pageNumber, reportOption, profile]);
|
}, [searchParam, pageNumber, reportOption, profile]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
//setLoading(true);
|
//setLoading(true);
|
||||||
|
|
||||||
const delayDebounceFn = setTimeout(() => {
|
const delayDebounceFn = setTimeout(() => {
|
||||||
|
|
||||||
const fetchQueries = async () => {
|
const fetchQueries = async () => {
|
||||||
try {
|
try {
|
||||||
|
if (reportOption === "1") {
|
||||||
if (reportOption === '1') {
|
const dataQuery = await api.get("/reports/", {
|
||||||
|
params: { userId, startDate, endDate },
|
||||||
const dataQuery = await api.get("/reports/", { params: { userId, startDate, endDate }, });
|
});
|
||||||
dispatchQ({ type: "RESET" })
|
dispatchQ({ type: "RESET" });
|
||||||
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
|
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
|
||||||
|
|
||||||
//setLoading(false);
|
//setLoading(false);
|
||||||
|
@ -394,12 +334,11 @@ const Report = () => {
|
||||||
// console.log('dataQuery: ', dataQuery.data)
|
// console.log('dataQuery: ', dataQuery.data)
|
||||||
|
|
||||||
// console.log()
|
// console.log()
|
||||||
|
} else if (reportOption === "2") {
|
||||||
}
|
const dataQuery = await api.get("/reports/user/services", {
|
||||||
else if (reportOption === '2') {
|
params: { userId, startDate, endDate },
|
||||||
|
});
|
||||||
const dataQuery = await api.get("/reports/user/services", { params: { userId, startDate, endDate }, });
|
dispatchQ({ type: "RESET" });
|
||||||
dispatchQ({ type: "RESET" })
|
|
||||||
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
|
dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data });
|
||||||
|
|
||||||
//setLoading(false);
|
//setLoading(false);
|
||||||
|
@ -407,62 +346,46 @@ const Report = () => {
|
||||||
// console.log('REPORT 2 dataQuery : ', dataQuery.data)
|
// console.log('REPORT 2 dataQuery : ', dataQuery.data)
|
||||||
|
|
||||||
//console.log()
|
//console.log()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchQueries();
|
fetchQueries();
|
||||||
|
|
||||||
}, 500);
|
}, 500);
|
||||||
return () => clearTimeout(delayDebounceFn);
|
return () => clearTimeout(delayDebounceFn);
|
||||||
|
|
||||||
}, [userId, startDate, endDate, reportOption]);
|
}, [userId, startDate, endDate, reportOption]);
|
||||||
|
|
||||||
|
|
||||||
// Get from child 1
|
// Get from child 1
|
||||||
const datePicker1Value = (data) => {
|
const datePicker1Value = (data) => {
|
||||||
|
setDatePicker1(data);
|
||||||
setDatePicker1(data)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Get from child 2
|
// Get from child 2
|
||||||
const datePicker2Value = (data) => {
|
const datePicker2Value = (data) => {
|
||||||
|
setDatePicker2(data);
|
||||||
setDatePicker2(data)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Get from child 3
|
// Get from child 3
|
||||||
const textFieldSelectUser = (data) => {
|
const textFieldSelectUser = (data) => {
|
||||||
|
setUser(data);
|
||||||
setUser(data)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get from report option
|
// Get from report option
|
||||||
const reportValue = (data) => {
|
const reportValue = (data) => {
|
||||||
|
setReport(data);
|
||||||
setReport(data)
|
|
||||||
|
|
||||||
// console.log(' data: ', data)
|
// console.log(' data: ', data)
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (reportOption === "1") {
|
||||||
if (reportOption === '1') {
|
setProfile("");
|
||||||
setProfile('')
|
} else if (reportOption === "2") {
|
||||||
|
setProfile("user");
|
||||||
}
|
}
|
||||||
else if (reportOption === '2') {
|
}, [reportOption]);
|
||||||
setProfile('user')
|
|
||||||
}
|
|
||||||
|
|
||||||
}, [reportOption])
|
|
||||||
|
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|
||||||
|
@ -470,106 +393,85 @@ const Report = () => {
|
||||||
|
|
||||||
// }, [query])
|
// }, [query])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// test del
|
// test del
|
||||||
|
|
||||||
const handleCSVMessages = () => {
|
const handleCSVMessages = () => {
|
||||||
|
|
||||||
// setLoading(true);
|
// setLoading(true);
|
||||||
|
|
||||||
const fetchQueries = async () => {
|
const fetchQueries = async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const dataQuery = await api.get("/reports/messages", {
|
||||||
const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, });
|
params: { userId, startDate, endDate },
|
||||||
|
});
|
||||||
|
|
||||||
// console.log('dataQuery messages: ', dataQuery.data)
|
// console.log('dataQuery messages: ', dataQuery.data)
|
||||||
|
|
||||||
if (dataQuery.data.length > 0) {
|
if (dataQuery.data.length > 0) {
|
||||||
|
|
||||||
let dataCSVFormat = dataQuery.data;
|
let dataCSVFormat = dataQuery.data;
|
||||||
|
|
||||||
for (var i = 0; i < dataCSVFormat.length; i++) {
|
for (var i = 0; i < dataCSVFormat.length; i++) {
|
||||||
if (dataCSVFormat[i].fromMe) {
|
if (dataCSVFormat[i].fromMe) {
|
||||||
dataCSVFormat[i].fromMe = 'Atendente'
|
dataCSVFormat[i].fromMe = "Atendente";
|
||||||
}
|
} else {
|
||||||
else {
|
dataCSVFormat[i].fromMe = "Cliente";
|
||||||
dataCSVFormat[i].fromMe = 'Cliente'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('dataCSVFormat: ', dataCSVFormat)
|
// console.log('dataCSVFormat: ', dataCSVFormat)
|
||||||
|
|
||||||
setDataCSV(dataCSVFormat)
|
setDataCSV(dataCSVFormat);
|
||||||
setIsMount(false);
|
setIsMount(false);
|
||||||
// setDataCSV(dataQuery.data)
|
// setDataCSV(dataQuery.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setLoading(false);
|
// setLoading(false);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchQueries();
|
fetchQueries();
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (isMount) {
|
if (isMount) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
csvLink.current.link.click()
|
csvLink.current.link.click();
|
||||||
|
|
||||||
}, [dataCSV, isMount, csvLink]);
|
}, [dataCSV, isMount, csvLink]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (reportOption === "2") {
|
||||||
if (reportOption === '2') {
|
|
||||||
|
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
||||||
|
|
||||||
socket.on("onlineStatus", (data) => {
|
socket.on("onlineStatus", (data) => {
|
||||||
|
|
||||||
// setLoading(true);
|
// setLoading(true);
|
||||||
|
|
||||||
|
let date = new Date().toLocaleDateString("pt-BR").split("/");
|
||||||
let date = new Date().toLocaleDateString('pt-BR').split('/')
|
let dateToday = `${date[2]}-${date[1]}-${date[0]}`;
|
||||||
let dateToday = `${date[2]}-${date[1]}-${date[0]}`
|
|
||||||
|
|
||||||
// console.log('date: ', new Date(startDate).toLocaleDateString('pt-BR'))
|
// console.log('date: ', new Date(startDate).toLocaleDateString('pt-BR'))
|
||||||
// console.log('date2: ', startDate)
|
// console.log('date2: ', startDate)
|
||||||
|
|
||||||
|
if (
|
||||||
if (data.action === "logout" || (data.action === "update" &&
|
data.action === "logout" ||
|
||||||
((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) {
|
(data.action === "update" &&
|
||||||
|
`${startDate}` === `${endDate}` &&
|
||||||
|
`${endDate}` === `${dateToday}` &&
|
||||||
|
`${startDate}` === `${dateToday}`)
|
||||||
|
) {
|
||||||
//console.log('UPDATE FROM ONLINE/OFFLINE LOGED USERS: ', data.userOnlineTime, ' | data.action : ', data.action)
|
//console.log('UPDATE FROM ONLINE/OFFLINE LOGED USERS: ', data.userOnlineTime, ' | data.action : ', data.action)
|
||||||
|
|
||||||
dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime });
|
dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime });
|
||||||
|
} else if (data.action === "delete") {
|
||||||
}
|
|
||||||
else if (data.action === "delete") {
|
|
||||||
dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
|
dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime });
|
||||||
}
|
}
|
||||||
|
|
||||||
// setLoading(false);
|
// setLoading(false);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("user", (data) => {
|
socket.on("user", (data) => {
|
||||||
|
|
||||||
if (data.action === "delete") {
|
if (data.action === "delete") {
|
||||||
// console.log(' entrou no delete user: ', data)
|
// console.log(' entrou no delete user: ', data)
|
||||||
dispatch({ type: "DELETE_USER", payload: +data.userId });
|
dispatch({ type: "DELETE_USER", payload: +data.userId });
|
||||||
|
@ -579,13 +481,9 @@ const Report = () => {
|
||||||
return () => {
|
return () => {
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}, [reportOption, startDate, endDate]);
|
}, [reportOption, startDate, endDate]);
|
||||||
|
|
||||||
|
|
||||||
// const handleDeleteRows = (id) => {
|
// const handleDeleteRows = (id) => {
|
||||||
|
|
||||||
// let _data = [...dataRows];
|
// let _data = [...dataRows];
|
||||||
|
@ -597,20 +495,20 @@ const Report = () => {
|
||||||
|
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
//if (!loading) {
|
//if (!loading) {
|
||||||
|
|
||||||
|
|
||||||
// setData(query.map(({ scheduleReminder, ...others }) => (
|
// setData(query.map(({ scheduleReminder, ...others }) => (
|
||||||
// { ...others, 'scheduleReminder': `${others.statusChatEndId}` === '3' ? 'Agendamento' : 'Lembrete' }
|
// { ...others, 'scheduleReminder': `${others.statusChatEndId}` === '3' ? 'Agendamento' : 'Lembrete' }
|
||||||
// )))
|
// )))
|
||||||
// }
|
// }
|
||||||
|
|
||||||
setData(query.map((column) => { return { ...column } }))
|
setData(
|
||||||
|
query.map((column) => {
|
||||||
}, [query])
|
return { ...column };
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}, [query]);
|
||||||
|
|
||||||
const handleLogouOnlineUser = async (userId) => {
|
const handleLogouOnlineUser = async (userId) => {
|
||||||
try {
|
try {
|
||||||
|
@ -620,42 +518,51 @@ const Report = () => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// toastError(err);
|
// toastError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Can
|
<Can
|
||||||
role={userA.profile}
|
role={userA.profile}
|
||||||
perform="ticket-report:show"
|
perform="ticket-report:show"
|
||||||
yes={() => (
|
yes={() => (
|
||||||
|
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
|
<Box sx={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)" }}>
|
||||||
|
<Item>
|
||||||
|
<SelectField
|
||||||
|
func={textFieldSelectUser}
|
||||||
|
emptyField={true}
|
||||||
|
header={"Usuário"}
|
||||||
|
currencies={users.map((obj) => {
|
||||||
|
return { value: obj.id, label: obj.name };
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Item>
|
||||||
|
|
||||||
<Item><SelectField func={textFieldSelectUser} emptyField={true} header={'Usuário'} currencies={users.map((obj) => {
|
<Item>
|
||||||
return { 'value': obj.id, 'label': obj.name }
|
<DatePicker1
|
||||||
})} /></Item>
|
func={datePicker1Value}
|
||||||
|
minDate={false}
|
||||||
<Item><DatePicker1 func={datePicker1Value} minDate={false} startEmpty={false} title={'Data inicio'} /></Item>
|
startEmpty={false}
|
||||||
<Item><DatePicker2 func={datePicker2Value} minDate={false} startEmpty={false} title={'Data fim'} /></Item>
|
title={"Data inicio"}
|
||||||
|
/>
|
||||||
<Item sx={{ display: 'grid', gridColumn: '4 / 5', }}>
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<DatePicker2
|
||||||
|
func={datePicker2Value}
|
||||||
|
minDate={false}
|
||||||
|
startEmpty={false}
|
||||||
|
title={"Data fim"}
|
||||||
|
/>
|
||||||
|
</Item>
|
||||||
|
|
||||||
|
<Item sx={{ display: "grid", gridColumn: "4 / 5" }}>
|
||||||
<ReportModal currencies={reporList} func={reportValue} reportOption={reportOption} />
|
<ReportModal currencies={reporList} func={reportValue} reportOption={reportOption} />
|
||||||
|
|
||||||
<div style={{ margin: '2px' }}></div>
|
<div style={{ margin: "2px" }}></div>
|
||||||
|
|
||||||
{reportOption === '1' &&
|
|
||||||
|
|
||||||
|
{reportOption === "1" && (
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button variant="contained" color="primary" onClick={(e) => handleCSVMessages()}>
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
onClick={(e) => handleCSVMessages()}
|
|
||||||
>
|
|
||||||
{"CSV ALL"}
|
{"CSV ALL"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
@ -663,125 +570,95 @@ const Report = () => {
|
||||||
<CSVLink
|
<CSVLink
|
||||||
data={dataCSV}
|
data={dataCSV}
|
||||||
headers={columns}
|
headers={columns}
|
||||||
filename={'Relatorio_detalhado_atendimento_atendentes.csv'}
|
filename={"Relatorio_detalhado_atendimento_atendentes.csv"}
|
||||||
target={'_blank'}
|
target={"_blank"}
|
||||||
ref={csvLink} />
|
ref={csvLink}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{
|
<Box
|
||||||
display: 'grid',
|
sx={{
|
||||||
}}>
|
display: "grid",
|
||||||
|
}}
|
||||||
<Item sx={{ gridColumn: '1', gridRow: 'span 1' }}>
|
>
|
||||||
|
<Item sx={{ gridColumn: "1", gridRow: "span 1" }}>
|
||||||
{reportOption === '1' &&
|
{reportOption === "1" && (
|
||||||
|
<MTable
|
||||||
<MTable data={query}
|
data={query}
|
||||||
columns={columnsData}
|
columns={columnsData}
|
||||||
hasChild={true}
|
hasChild={true}
|
||||||
removeClickRow={false}
|
removeClickRow={false}
|
||||||
table_title={'Atendimento por atendentes'} />
|
table_title={"Atendimento por atendentes"}
|
||||||
}
|
/>
|
||||||
{reportOption === '2' &&
|
)}
|
||||||
|
{reportOption === "2" && (
|
||||||
<MaterialTable
|
<MaterialTable
|
||||||
|
|
||||||
localization={{
|
localization={{
|
||||||
|
|
||||||
header: {
|
header: {
|
||||||
actions: 'Deslogar'
|
actions: "Deslogar",
|
||||||
},
|
},
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
title="Usuários online/offline"
|
title="Usuários online/offline"
|
||||||
columns={
|
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: '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: 'name', cellStyle: {whiteSpace: 'nowrap'}, },
|
{ title: "Nome", field: "name", cellStyle: { whiteSpace: "nowrap" } },
|
||||||
|
|
||||||
{
|
{
|
||||||
title: 'Status', field: 'statusOnline.status',
|
title: "Status",
|
||||||
|
field: "statusOnline.status",
|
||||||
|
|
||||||
cellStyle: (e, rowData) => {
|
cellStyle: (e, rowData) => {
|
||||||
|
if (rowData["statusOnline"] && rowData["statusOnline"].status) {
|
||||||
if (rowData['statusOnline'] && rowData['statusOnline'].status) {
|
if (rowData["statusOnline"].status === "offline") {
|
||||||
|
|
||||||
if (rowData['statusOnline'].status === 'offline') {
|
|
||||||
|
|
||||||
return { color: "red" };
|
return { color: "red" };
|
||||||
}
|
} else if (rowData["statusOnline"].status === "online") {
|
||||||
else if (rowData['statusOnline'].status === 'online') {
|
|
||||||
return { color: "green" };
|
return { color: "green" };
|
||||||
}
|
} else if (rowData["statusOnline"].status === "logout...") {
|
||||||
else if (rowData['statusOnline'].status === 'logout...') {
|
|
||||||
return { color: "orange" };
|
return { color: "orange" };
|
||||||
}
|
} else if (rowData["statusOnline"].status === "waiting...") {
|
||||||
else if (rowData['statusOnline'].status === 'waiting...') {
|
|
||||||
return { color: "orange" };
|
return { color: "orange" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
{ title: "Tempo online", field: "sumOnlineTime.sum" },
|
||||||
|
{ title: "Data inicio", field: "startDate" },
|
||||||
{ title: 'Tempo online', field: 'sumOnlineTime.sum' },
|
{ title: "Data fim", field: "endDate" },
|
||||||
{ title: 'Data inicio', field: 'startDate' },
|
{ title: "Em atendimento", field: "sumOpen.count" },
|
||||||
{ title: 'Data fim', field: 'endDate' },
|
{ title: "Finalizado", field: "sumClosed.count" },
|
||||||
{ title: 'Em atendimento', field: 'sumOpen.count' },
|
]}
|
||||||
{ title: 'Finalizado', field: 'sumClosed.count' },
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
||||||
data={dataRows}
|
data={dataRows}
|
||||||
// icons={tableIcons}
|
// icons={tableIcons}
|
||||||
|
|
||||||
actions={[
|
actions={[
|
||||||
(rowData) => {
|
(rowData) => {
|
||||||
|
if (
|
||||||
if (rowData.statusOnline &&
|
rowData.statusOnline &&
|
||||||
rowData.statusOnline['status'] &&
|
rowData.statusOnline["status"] &&
|
||||||
rowData.statusOnline['status'] === 'online') {
|
rowData.statusOnline["status"] === "online"
|
||||||
|
) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
icon: LogoutIcon,
|
icon: LogoutIcon,
|
||||||
tooltip: 'deslogar',
|
tooltip: "deslogar",
|
||||||
disable: false,
|
disable: false,
|
||||||
onClick: (event, rowData) => {
|
onClick: (event, rowData) => {
|
||||||
|
|
||||||
// console.log(' ROW DATA INFO: ', rowData, ' | rowData: ', rowData.id)
|
// console.log(' ROW DATA INFO: ', rowData, ' | rowData: ', rowData.id)
|
||||||
handleLogouOnlineUser(rowData.id)
|
handleLogouOnlineUser(rowData.id);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
|
options={{
|
||||||
|
|
||||||
options={
|
|
||||||
{
|
|
||||||
search: true,
|
search: true,
|
||||||
selection: false,
|
selection: false,
|
||||||
paging: false,
|
paging: false,
|
||||||
padding: 'dense',
|
padding: "dense",
|
||||||
sorting: true,
|
sorting: true,
|
||||||
//loadingType: 'linear',
|
//loadingType: 'linear',
|
||||||
searchFieldStyle: {
|
searchFieldStyle: {
|
||||||
|
@ -791,14 +668,13 @@ const Report = () => {
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
headerStyle: {
|
headerStyle: {
|
||||||
position: "sticky",
|
position: "sticky",
|
||||||
top: "0"
|
top: "0",
|
||||||
},
|
},
|
||||||
maxBodyHeight: "400px",
|
maxBodyHeight: "400px",
|
||||||
|
|
||||||
rowStyle: {
|
rowStyle: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
}
|
},
|
||||||
|
|
||||||
|
|
||||||
// cellStyle: (rowData) => {
|
// cellStyle: (rowData) => {
|
||||||
// return {
|
// return {
|
||||||
|
@ -807,26 +683,16 @@ const Report = () => {
|
||||||
|
|
||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
}
|
|
||||||
|
|
||||||
</Item>
|
</Item>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Report;
|
export default Report;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const color = {
|
||||||
status: {
|
status: {
|
||||||
no: "#FF0000",
|
no: "#FF0000",
|
||||||
yes: "#00BE1E",
|
yes: "#00BE1E",
|
||||||
warning: "#FFC700",
|
warning: "#ffc800c7",
|
||||||
},
|
},
|
||||||
gradient: {
|
gradient: {
|
||||||
bgOpacity: "#212f3cd7",
|
bgOpacity: "#212f3cd7",
|
||||||
|
|
Loading…
Reference in New Issue