import React, { useState, useEffect, useReducer, useContext } from "react"; import MainContainer from "../../components/MainContainer"; import api from "../../services/api"; import SelectField from "../../components/Report/SelectField"; import DatePicker1 from '../../components/Report/DatePicker' import DatePicker2 from '../../components/Report/DatePicker' import MTable from "../../components/Report/MTable"; import PropTypes from 'prop-types'; import Box from '@mui/material/Box'; import { AuthContext } from "../../context/Auth/AuthContext"; import { Can } from "../../components/Can"; import { Button } from "@material-ui/core"; import ReportModal from "../../components/ReportModal"; import MaterialTable from 'material-table'; import LogoutIcon from '@material-ui/icons/CancelOutlined'; import apiBroker from "../../services/apiBroker"; import fileDownload from 'js-file-download' import openSocket from "socket.io-client"; import { TramOutlined } from "@material-ui/icons"; const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }] const reducerQ = (state, action) => { if (action.type === "DELETE_USER_STATUS") { const userId = action.payload; const userIndex = state.findIndex((u) => `${u.id}` === `${userId}`); if (userIndex !== -1) { state.splice(userIndex, 1); } return [...state]; } 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_STATUS_ONLINE") { let onlineUser = action.payload let index = -1 if (onlineUser.sumOpen || onlineUser.sumClosed) { index = state.findIndex((e) => ((onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId))) } else { index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`) } if (index !== -1) { if (!("statusOnline" in state[index])) { state[index].statusOnline = onlineUser } else if ("statusOnline" in state[index]) { state[index].statusOnline['status'] = onlineUser.status } if ("onlineTime" in onlineUser) { if ("sumOnlineTime" in state[index]) { state[index].sumOnlineTime['sum'] = (onlineUser.onlineTime).split(" ")[1] } else if (!("sumOnlineTime" in state[index])) { state[index].sumOnlineTime = { userId: onlineUser.userId, sum: (onlineUser.onlineTime).split(" ")[1] } } } if (onlineUser.sumOpen) { if ("sumOpen" in state[index]) { state[index].sumOpen['count'] = onlineUser.sumOpen.count } else if (!("sumOpen" in state[index])) { state[index].sumOpen = onlineUser.sumOpen } } if (onlineUser.sumClosed) { if ("sumClosed" in state[index]) { state[index].sumClosed['count'] = onlineUser.sumClosed.count } else if (!("sumClosed" in state[index])) { state[index].sumClosed = onlineUser.sumClosed } } } return [...state] } if (action.type === "RESET") { return []; } } const reducer = (state, action) => { if (action.type === "LOAD_USERS") { 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 === "DELETE_USER") { const userId = action.payload; const userIndex = state.findIndex((u) => u.id === userId); if (userIndex !== -1) { state.splice(userIndex, 1); } return [...state]; } if (action.type === "RESET") { return []; } }; function Item(props) { const { sx, ...other } = props; return ( (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: 'Unidade', field: 'whatsapp.name' }, { title: 'Atendente', field: 'user.name' }, { title: 'Contato', field: 'contact.number' }, { title: 'Nome', field: 'contact.name' }, { title: 'Assunto', field: 'queue.name' }, { title: 'Status', field: 'status' }, { title: 'Criado', field: 'createdAt' }, //{title: 'Atualizado', field: 'updatedAt'}, { title: 'Status de encerramento', field: 'statusChatEnd' }]; const Report = () => { const { user: userA } = useContext(AuthContext); //-------- const [searchParam] = useState(""); const [loading, setLoading] = useState(false); const [hasMore, setHasMore] = useState(false); const [pageNumberTickets, setTicketsPageNumber] = useState(1); const [totalCountTickets, setTotalCountTickets] = useState(0); const [pageNumber, setPageNumber] = useState(1); const [users, dispatch] = useReducer(reducer, []); const [startDate, setDatePicker1] = useState(new Date()) const [endDate, setDatePicker2] = useState(new Date()) const [userId, setUser] = useState(null) const [query, dispatchQ] = useReducer(reducerQ, []) const [reportOption, setReport] = useState('1') const [reporList,] = useState(report) const [profile, setProfile] = useState('') const [dataRows, setData] = useState([]); const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined) const [csvFile, setCsvFile] = useState() useEffect(() => { dispatch({ type: "RESET" }); dispatchQ({ type: "RESET" }) setTicketsPageNumber(1) setPageNumber(1); }, [searchParam, profile]); useEffect(() => { //setLoading(true); const delayDebounceFn = setTimeout(() => { const fetchUsers = async () => { try { const { data } = await api.get("/users/", { params: { searchParam, pageNumber, profile }, }); dispatch({ type: "LOAD_USERS", payload: data.users }); //setLoading(false); } catch (err) { console.log(err); } }; fetchUsers(); }, 500); return () => clearTimeout(delayDebounceFn); }, [searchParam, pageNumber, reportOption, profile]); useEffect(() => { //setLoading(true); const delayDebounceFn = setTimeout(() => { setLoading(true); const fetchQueries = async () => { try { if (reportOption === '1') { const { data } = await api.get("/reports/", { params: { userId, startDate, endDate, pageNumber: pageNumberTickets }, }); dispatchQ({ type: "LOAD_QUERY", payload: data.tickets }); setHasMore(data.hasMore); setTotalCountTickets(data.count) setLoading(false); } else if (reportOption === '2') { const dataQuery = await api.get("/reports/user/services", { params: { userId, startDate, endDate }, }); dispatchQ({ type: "RESET" }) dispatchQ({ type: "LOAD_QUERY", payload: dataQuery.data }); //setLoading(false); console.log('REPORT 2 dataQuery : ', dataQuery.data) //console.log() } } catch (err) { console.log(err); } }; fetchQueries(); }, 500); return () => clearTimeout(delayDebounceFn); }, [userId, startDate, endDate, reportOption, pageNumberTickets, totalCountTickets]); // Get from child 1 const datePicker1Value = (data) => { setDatePicker1(data) } // Get from child 2 const datePicker2Value = (data) => { setDatePicker2(data) } // Get from child 3 const textFieldSelectUser = (data) => { setUser(data) } // Get from report option const reportValue = (data) => { setReport(data) } useEffect(() => { if (reportOption === '1') { setProfile('') } else if (reportOption === '2') { setProfile('user') } }, [reportOption]) useEffect(() => { const delayDebounceFn = setTimeout(() => { const fetchReportOnQueue = async () => { try { const queryOnQueue = await apiBroker.get("/reports/status/query/onqueue", { params: { adminId: userA.id, baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE, identifier: 'csv' } }); if (queryOnQueue.data) { setCsvFile(queryOnQueue.data.app.file) setOnQueueProcessStatus(queryOnQueue.data.app.status) } else { setOnQueueProcessStatus('empty') } } catch (err) { console.log(err); } }; fetchReportOnQueue(); }, 500); return () => clearTimeout(delayDebounceFn); }, [ userA ]) const handleCSVDownload = async () => { setOnQueueProcessStatus('downloading') try { let res = await apiBroker.get(`/reports/download/${csvFile}`, { responseType: 'blob' }); if (res) { fileDownload(res.data, `${csvFile}`); setOnQueueProcessStatus('empty') } } catch (err) { console.log(err); } } const handleCSVMessages = () => { const fetchQueries = async () => { try { // const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, }); const querySavedOnQueue = await apiBroker.post("/reports/messages", { app: { adminId: userA.id, baseURL: process.env.REACT_APP_BACKEND_URL_PRIVATE, frontURL: process.env.REACT_APP_FRONTEND_URL, identifier: 'csv' }, query_params: { userId: userId, startDate: startDate, endDate: endDate } }); const onQueueStatus = querySavedOnQueue.data.queueStatus setOnQueueProcessStatus(onQueueStatus) } catch (err) { console.log(err); } }; fetchQueries(); } useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL); socket.on("queryOnQueueStatus", (data) => { if (data.action === 'update') { if (String(data.queryOnQueue.adminId) === String(userA.id)) { setCsvFile(data.queryOnQueue.file) setOnQueueProcessStatus(data.queryOnQueue.queueStatus) } } }) if (reportOption === '2') { socket.on("onlineStatus", (data) => { let date = new Date().toLocaleDateString('pt-BR').split('/') let dateToday = `${date[2]}-${date[1]}-${date[0]}` if (data.action === "logout" || (data.action === "update" && ((`${startDate}` === `${endDate}`) && (`${endDate}` === `${dateToday}`) && (`${startDate}` === `${dateToday}`)))) { dispatchQ({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }); } else if (data.action === "delete") { dispatchQ({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); } }); socket.on("user", (data) => { if (data.action === "delete") { dispatch({ type: "DELETE_USER", payload: +data.userId }); } }); } else if (reportOption === "1") { dispatchQ({ type: "RESET" }) setTicketsPageNumber(1) } return () => { socket.disconnect(); }; }, [reportOption, startDate, endDate, userId, userA]); useEffect(() => { setData(query.map((column) => { return { ...column } })) }, [query]) const handleLogouOnlineUser = async (userId) => { try { await api.get(`/users/logout/${userId}`); //toast.success(("Desloged!")); //handleDeleteRows(scheduleId) } catch (err) { // toastError(err); } }; const loadMore = () => { setTicketsPageNumber((prevState) => prevState + 1); }; const handleScroll = (e) => { if (!hasMore || loading) return; const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; if (scrollHeight - (scrollTop + 1) < clientHeight) { loadMore(); } }; const renderSwitch = (param) => { switch (param) { case 'empty': return ( <> ); case 'pending' || 'processing': return ( <> PROCESSING... ); case 'success': return ( <> ); case 'downloading': return ( <> DOWNLOADING... ); default: return (<>WAITING...); } } return ( ( { return { 'value': obj.id, 'label': obj.name } })} />
{reportOption === '1' &&
{renderSwitch(onQueueStatus)}
}
{reportOption === '1' && <> } {reportOption === '2' && imagem de perfil do whatsapp }, { title: 'Nome', field: 'name', cellStyle: { whiteSpace: 'nowrap' }, }, { title: 'Status', field: 'statusOnline.status', cellStyle: (e, rowData) => { if (rowData['statusOnline'] && rowData['statusOnline'].status) { if (rowData['statusOnline'].status === 'offline') { return { color: "red" }; } else if (rowData['statusOnline'].status === 'online') { return { color: "green" }; } else if (rowData['statusOnline'].status === 'logout...') { return { color: "orange" }; } else if (rowData['statusOnline'].status === 'waiting...') { return { color: "orange" }; } } }, }, { title: 'Tempo online', field: 'sumOnlineTime.sum' }, { title: 'Data inicio', field: 'startDate' }, { title: 'Data fim', field: 'endDate' }, { title: 'Em atendimento', field: 'sumOpen.count' }, { title: 'Finalizado', field: 'sumClosed.count' }, ] } data={dataRows} actions={[ (rowData) => { if (rowData.statusOnline && rowData.statusOnline['status'] && rowData.statusOnline['status'] === 'online') { return { icon: LogoutIcon, tooltip: 'deslogar', disable: false, onClick: (event, rowData) => { handleLogouOnlineUser(rowData.id) } } } } ]} options={ { search: true, selection: false, paging: false, padding: 'dense', sorting: true, searchFieldStyle: { width: 300, }, pageSize: 20, headerStyle: { position: "sticky", top: "0" }, maxBodyHeight: "400px", rowStyle: { fontSize: 14, } }} /> }
)} /> ) }; export default Report;