Merge branch 'old/merge' into features
						commit
						ebb9e7bf65
					
				|  | @ -0,0 +1,193 @@ | |||
| import React from "react"; | ||||
| 
 | ||||
| import Paper from "@material-ui/core/Paper"; | ||||
| import Grid from "@material-ui/core/Grid"; | ||||
| import Typography from "@material-ui/core/Typography"; | ||||
| 
 | ||||
| import Avatar from "@mui/material/Avatar"; | ||||
| import Card from "@mui/material/Card"; | ||||
| import CardHeader from "@mui/material/CardHeader"; | ||||
| import CardContent from "@mui/material/CardContent"; | ||||
| import CardActions from "@mui/material/CardActions"; | ||||
| 
 | ||||
| import { Button } from "@material-ui/core"; | ||||
| import Box from "@mui/material/Box"; | ||||
| import InputLabel from "@mui/material/InputLabel"; | ||||
| import MenuItem from "@mui/material/MenuItem"; | ||||
| import FormControl from "@mui/material/FormControl"; | ||||
| import Select from "@mui/material/Select"; | ||||
| import TextField from "@mui/material/TextField"; | ||||
| 
 | ||||
| import CancelIcon from "@material-ui/icons/Cancel"; | ||||
| import CheckCircleIcon from "@material-ui/icons/CheckCircle"; | ||||
| import ErrorIcon from "@material-ui/icons/Error"; | ||||
| import RemoveCircleIcon from "@material-ui/icons/RemoveCircle"; | ||||
| 
 | ||||
| const CardUser = ({ classes, usersOnlineInfo, logout }) => { | ||||
|   const [search, setSearch] = React.useState(""); | ||||
| 
 | ||||
|   const [filterStatus, setFilterStatus] = React.useState(null); | ||||
| 
 | ||||
|   const handleFilterChange = (event) => { | ||||
|     setFilterStatus(event.target.value); | ||||
|   }; | ||||
|   const handlesearch = (event) => { | ||||
|     setSearch(event.target.value.toLowerCase()); | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <Grid item xs={12}> | ||||
|       <Paper className={classes.cardPaperFix} sx={12} variant="outlined"> | ||||
|         <Grid container sx={12} justifyContent="space-between" alignItems="baseline"> | ||||
|           <Grid item sx={4}> | ||||
|             <Typography | ||||
|               component="h4" | ||||
|               variant="h6" | ||||
|               color="primary" | ||||
|               style={{ marginBottom: "16px" }} | ||||
|             > | ||||
|               Lista de Usuários | ||||
|             </Typography> | ||||
|           </Grid> | ||||
|           <Grid item sx={8} width="100%"> | ||||
|             <Box sx={{ marginBottom: 2, display: "flex", gap: "12px" }}> | ||||
|               <TextField | ||||
|                 id="outlined-basic" | ||||
|                 label="Usuário" | ||||
|                 variant="standard" | ||||
|                 value={search} | ||||
|                 onChange={handlesearch} | ||||
|               /> | ||||
|               <FormControl fullWidth variant="standard"> | ||||
|                 <InputLabel id="status">Status</InputLabel> | ||||
|                 <Select | ||||
|                   labelId="status" | ||||
|                   id="status" | ||||
|                   value={filterStatus} | ||||
|                   label="Status" | ||||
|                   onChange={handleFilterChange} | ||||
|                 > | ||||
|                   <MenuItem value={null}>Todos</MenuItem> | ||||
|                   <MenuItem value={"online"}>Online</MenuItem> | ||||
|                   <MenuItem value={"offline"}>Offline</MenuItem> | ||||
|                   <MenuItem value={"not"}>Não entrou</MenuItem> | ||||
|                 </Select> | ||||
|               </FormControl> | ||||
|             </Box> | ||||
|           </Grid> | ||||
|         </Grid> | ||||
| 
 | ||||
|         <Grid container spacing={3}> | ||||
|           {usersOnlineInfo && | ||||
|             usersOnlineInfo | ||||
|               .filter((e) => { | ||||
|                 if (filterStatus === null) return e; | ||||
|                 if (filterStatus === "not") return !e.statusOnline; | ||||
|                 return e.statusOnline && e.statusOnline.status === filterStatus; | ||||
|               }) | ||||
|               .filter((e) => { | ||||
|                 return e.name.toLowerCase().includes(search); | ||||
|               }) | ||||
|               .sort((a) => { | ||||
|                 if (a.statusOnline) { | ||||
|                   if (a.statusOnline.status === "online") { | ||||
|                     return -1; | ||||
|                   } | ||||
|                   return 0; | ||||
|                 } | ||||
|                 return 0; | ||||
|               }) | ||||
|               .map((user, index) => ( | ||||
|                 <Grid | ||||
|                   item | ||||
|                   xs={12} | ||||
|                   sm={6} | ||||
|                   md={6} | ||||
|                   lg={3} | ||||
|                   key={index} | ||||
|                   style={{ position: "relative" }} | ||||
|                 > | ||||
|                   <Card variant="outlined"> | ||||
|                     <CardHeader | ||||
|                       avatar={ | ||||
|                         <Avatar | ||||
|                           style={{ | ||||
|                             backgroundColor: user.statusOnline | ||||
|                               ? user.statusOnline.status === "online" | ||||
|                                 ? "green" | ||||
|                                 : user.statusOnline.status === "offline" | ||||
|                                 ? "red" | ||||
|                                 : "black" | ||||
|                               : "grey", | ||||
|                           }} | ||||
|                         > | ||||
|                           {user.statusOnline ? ( | ||||
|                             user.statusOnline.status === "online" ? ( | ||||
|                               <CheckCircleIcon style={{ color: "white" }} /> | ||||
|                             ) : user.statusOnline.status === "offline" ? ( | ||||
|                               <CancelIcon style={{ color: "white" }} /> | ||||
|                             ) : ( | ||||
|                               <ErrorIcon style={{ color: "yellow" }} /> | ||||
|                             ) | ||||
|                           ) : ( | ||||
|                             <RemoveCircleIcon style={{ color: "black" }} /> | ||||
|                           )} | ||||
|                         </Avatar> | ||||
|                       } | ||||
|                       title={ | ||||
|                         <Typography variant="h5" component="div"> | ||||
|                           {user.name} | ||||
|                         </Typography> | ||||
|                       } | ||||
|                     /> | ||||
| 
 | ||||
|                     <CardContent> | ||||
|                       <Typography variant="h6" component="h1" color="textPrimary"> | ||||
|                         Em atendimento: | ||||
|                         <Typography component="p" color="textPrimary" paragraph> | ||||
|                           {user.sumOpen && user.sumOpen.count ? user.sumOpen.count : 0} | ||||
|                         </Typography> | ||||
|                       </Typography> | ||||
| 
 | ||||
|                       <Typography variant="h6" component="h1" color="textPrimary"> | ||||
|                         Finalizado: | ||||
|                         <Typography component="p" color="textPrimary" paragraph> | ||||
|                           {user.sumClosed && user.sumClosed.count ? user.sumClosed.count : 0} | ||||
|                         </Typography> | ||||
|                       </Typography> | ||||
| 
 | ||||
|                       <Typography variant="h6" component="h1" color="textPrimary"> | ||||
|                         Tempo online: | ||||
|                         <Typography component="p" color="textPrimary" paragraph> | ||||
|                           {user.sumOnlineTime && user.sumOnlineTime.sum | ||||
|                             ? user.sumOnlineTime.sum | ||||
|                             : "Não entrou Hoje"} | ||||
|                         </Typography> | ||||
|                       </Typography> | ||||
|                     </CardContent> | ||||
|                     <CardActions> | ||||
|                       {user.statusOnline && | ||||
|                         user.statusOnline.status === "online" && | ||||
|                         user.statusOnline && ( | ||||
|                           <Button | ||||
|                             className={classes.logginBtn} | ||||
|                             variant="contained" | ||||
|                             color="primary" | ||||
|                             onClick={(e) => { | ||||
|                                 logout(user.id); | ||||
|                             }} | ||||
|                           > | ||||
|                             {"Deslogar"} | ||||
|                           </Button> | ||||
|                         )} | ||||
|                     </CardActions> | ||||
|                   </Card> | ||||
|                 </Grid> | ||||
|               ))} | ||||
|         </Grid> | ||||
|       </Paper> | ||||
|     </Grid> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default CardUser; | ||||
|  | @ -0,0 +1,167 @@ | |||
| import React from "react"; | ||||
| 
 | ||||
| import Select from "@mui/material/Select"; | ||||
| import TextField from "@mui/material/TextField"; | ||||
| import Typography from "@material-ui/core/Typography"; | ||||
| import Grid from "@material-ui/core/Grid"; | ||||
| 
 | ||||
| import Table from "@material-ui/core/Table"; | ||||
| import TableBody from "@material-ui/core/TableBody"; | ||||
| import TableCell from "@material-ui/core/TableCell"; | ||||
| import TableContainer from "@material-ui/core/TableContainer"; | ||||
| import TableHead from "@material-ui/core/TableHead"; | ||||
| import TableRow from "@material-ui/core/TableRow"; | ||||
| import Paper from "@material-ui/core/Paper"; | ||||
| import Box from "@mui/material/Box"; | ||||
| import InputLabel from "@mui/material/InputLabel"; | ||||
| import MenuItem from "@mui/material/MenuItem"; | ||||
| import FormControl from "@mui/material/FormControl"; | ||||
| 
 | ||||
| import CancelIcon from "@material-ui/icons/Cancel"; | ||||
| import CheckCircleIcon from "@material-ui/icons/CheckCircle"; | ||||
| import ErrorIcon from "@material-ui/icons/Error"; | ||||
| import RemoveCircleIcon from "@material-ui/icons/RemoveCircle"; | ||||
| import PowerSettingsNewIcon from "@material-ui/icons/PowerSettingsNew"; | ||||
| 
 | ||||
| const TableUser = ({ classes, usersOnlineInfo, logout }) => { | ||||
|   const [search, setSearch] = React.useState(""); | ||||
|   const [filterStatus, setFilterStatus] = React.useState(null); | ||||
| 
 | ||||
|   const handleFilterChange = (event) => { | ||||
|     setFilterStatus(event.target.value); | ||||
|   }; | ||||
|   const handlesearch = (event) => { | ||||
|     setSearch(event.target.value.toLowerCase()); | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <Grid item xs={12}> | ||||
|       <Paper className={classes.cardPaperFix} sx={12} variant="outlined"> | ||||
|         <Grid container sx={12} justifyContent="space-between" alignItems="baseline"> | ||||
|           <Grid item sx={4}> | ||||
|             <Typography | ||||
|               component="h4" | ||||
|               variant="h6" | ||||
|               color="primary" | ||||
|               style={{ marginBottom: "16px" }} | ||||
|             > | ||||
|               Lista de Usuários | ||||
|             </Typography> | ||||
|           </Grid> | ||||
|           <Grid item sx={8} width="100%"> | ||||
|             <Box sx={{ marginBottom: 2, display: "flex", gap: "12px" }}> | ||||
|               <TextField | ||||
|                 id="outlined-basic" | ||||
|                 label="Usuário" | ||||
|                 variant="standard" | ||||
|                 value={search} | ||||
|                 onChange={handlesearch} | ||||
|               /> | ||||
|               <FormControl fullWidth variant="standard"> | ||||
|                 <InputLabel id="status">Status</InputLabel> | ||||
|                 <Select | ||||
|                   labelId="status" | ||||
|                   id="status" | ||||
|                   value={filterStatus} | ||||
|                   label="Status" | ||||
|                   onChange={handleFilterChange} | ||||
|                 > | ||||
|                   <MenuItem value={null}>Todos</MenuItem> | ||||
|                   <MenuItem value={"online"}>Online</MenuItem> | ||||
|                   <MenuItem value={"offline"}>Offline</MenuItem> | ||||
|                   <MenuItem value={"not"}>Não entrou</MenuItem> | ||||
|                 </Select> | ||||
|               </FormControl> | ||||
|             </Box> | ||||
|           </Grid> | ||||
|         </Grid> | ||||
| 
 | ||||
|         <Grid container spacing={3} style={{ marginTop: "16px", marginBottom: "16px" }}> | ||||
|           <TableContainer component={Paper}> | ||||
|             <Table> | ||||
|               <TableHead> | ||||
|                 <TableRow className={classes.tableRowHead}> | ||||
|                   <TableCell>Status</TableCell> | ||||
|                   <TableCell>Nome</TableCell> | ||||
|                   <TableCell>Em Atendimento</TableCell> | ||||
|                   <TableCell>Finalizado(s)</TableCell> | ||||
|                   <TableCell>Tempo Online</TableCell> | ||||
|                   <TableCell>Ações</TableCell> | ||||
|                 </TableRow> | ||||
|               </TableHead> | ||||
| 
 | ||||
|               <TableBody> | ||||
|                 {usersOnlineInfo && | ||||
|                   usersOnlineInfo | ||||
|                     .filter((e) => { | ||||
|                       if (filterStatus === null) return e; | ||||
|                       if (filterStatus === "not") return !e.statusOnline; | ||||
|                       return e.statusOnline && e.statusOnline.status === filterStatus; | ||||
|                     }) | ||||
|                     .filter((e) => { | ||||
|                       return e.name.toLowerCase().includes(search); | ||||
|                     }) | ||||
|                     .sort((a) => { | ||||
|                       if (a.statusOnline) { | ||||
|                         if (a.statusOnline.status === "online") { | ||||
|                           return -1; | ||||
|                         } | ||||
|                         return 0; | ||||
|                       } | ||||
|                       return 0; | ||||
|                     }) | ||||
|                     .map((user, index) => ( | ||||
|                       <TableRow key={index} className={classes.tableRowBody}> | ||||
|                         <TableCell title={user.statusOnline && user.statusOnline.status}> | ||||
|                           {user.statusOnline ? ( | ||||
|                             user.statusOnline.status === "online" ? ( | ||||
|                               <CheckCircleIcon style={{ color: "green" }} /> | ||||
|                             ) : user.statusOnline.status === "offline" ? ( | ||||
|                               <CancelIcon style={{ color: "red" }} /> | ||||
|                             ) : ( | ||||
|                               <ErrorIcon style={{ color: "gold" }} /> | ||||
|                             ) | ||||
|                           ) : ( | ||||
|                             <RemoveCircleIcon style={{ color: "black" }} /> | ||||
|                           )} | ||||
|                         </TableCell> | ||||
|                         <TableCell>{user.name}</TableCell> | ||||
|                         <TableCell> | ||||
|                           <Typography className={classes.tableCounterOpen}> | ||||
|                             {user.sumOpen ? user.sumOpen.count : "0"} | ||||
|                           </Typography> | ||||
|                         </TableCell> | ||||
|                         <TableCell> | ||||
|                           <Typography className={classes.tableCounterClosed}> | ||||
|                             {user.sumClosed ? user.sumClosed.count : "0"} | ||||
|                           </Typography> | ||||
|                         </TableCell> | ||||
|                         <TableCell> | ||||
|                           {user.sumOnlineTime ? user.sumOnlineTime.sum : "Não entrou"} | ||||
|                         </TableCell> | ||||
|                         <TableCell> | ||||
|                           {user.statusOnline && user.statusOnline.status === "online" ? ( | ||||
|                             <PowerSettingsNewIcon | ||||
|                               style={{ color: "red", cursor: "pointer" }} | ||||
|                               onClick={(e) => { | ||||
|                                 logout(user.id); | ||||
|                               }} | ||||
|                             /> | ||||
|                           ) : ( | ||||
|                             <PowerSettingsNewIcon | ||||
|                               style={{ color: "grey", cursor: "not-allowed" }} | ||||
|                             /> | ||||
|                           )} | ||||
|                         </TableCell> | ||||
|                       </TableRow> | ||||
|                     ))} | ||||
|               </TableBody> | ||||
|             </Table> | ||||
|           </TableContainer> | ||||
|         </Grid> | ||||
|       </Paper> | ||||
|     </Grid> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default TableUser; | ||||
|  | @ -124,7 +124,7 @@ const TicketsManager = () => { | |||
|   let searchTimeout; | ||||
| 
 | ||||
|   const handleSearch = (e) => { | ||||
|     const searchedTerm = e.target.value.toLowerCase();   | ||||
|     const searchedTerm = e.target.value.toLowerCase().trim(); | ||||
| 
 | ||||
|     clearTimeout(searchTimeout); | ||||
| 
 | ||||
|  | @ -274,7 +274,7 @@ const TicketsManager = () => { | |||
|         </Tabs> | ||||
|         <Paper className={classes.ticketsWrapper}> | ||||
|           <TicketsList | ||||
|             status="open" | ||||
|             status={"open"} | ||||
|             showAll={showAllTickets} | ||||
|             selectedQueueIds={selectedQueueIds} | ||||
|             updateCount={(val) => setOpenCount(val)} | ||||
|  | @ -285,7 +285,7 @@ const TicketsManager = () => { | |||
|             selectedQueueIds={selectedQueueIds} | ||||
|             updateCount={(val) => setPendingCount(val)} | ||||
|             style={applyPanelStyle("pending")} | ||||
|           /> | ||||
|           />   | ||||
|         </Paper> | ||||
|       </TabPanel> | ||||
|       <TabPanel value={tab} name="closed" className={classes.ticketsWrapper}> | ||||
|  |  | |||
|  | @ -9,8 +9,8 @@ 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 SendOutlined from '@material-ui/icons/SendOutlined'; | ||||
| 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";
 | ||||
| 
 | ||||
|  | @ -32,10 +32,7 @@ function ListItemLink(props) { | |||
|   const { icon, primary, to, className } = props; | ||||
| 
 | ||||
|   const renderLink = React.useMemo( | ||||
|     () => | ||||
|       React.forwardRef((itemProps, ref) => ( | ||||
|         <RouterLink to={to} ref={ref} {...itemProps} /> | ||||
|       )), | ||||
|     () => React.forwardRef((itemProps, ref) => <RouterLink to={to} ref={ref} {...itemProps} />), | ||||
|     [to] | ||||
|   ); | ||||
| 
 | ||||
|  | @ -50,7 +47,7 @@ function ListItemLink(props) { | |||
| } | ||||
| 
 | ||||
| const MainListItems = (props) => { | ||||
|   const { drawerClose } = props; | ||||
|   const { drawerClose, setDrawerOpen, drawerOpen } = props; | ||||
|   const { whatsApps } = useContext(WhatsAppsContext); | ||||
|   const { user } = useContext(AuthContext); | ||||
|   const [connectionWarning, setConnectionWarning] = useState(false); | ||||
|  | @ -78,9 +75,8 @@ const MainListItems = (props) => { | |||
|   }, [whatsApps]); | ||||
| 
 | ||||
|   return ( | ||||
|     <div onClick={drawerClose}> | ||||
|       | ||||
|        | ||||
|     //Solicitado pelo Adriano: Click no LinkItem e fechar o menu!
 | ||||
|     <div onClick={() => setDrawerOpen(false)}> | ||||
|       <ListItemLink | ||||
|         to="/tickets" | ||||
|         primary={i18n.t("mainDrawer.listItems.tickets")} | ||||
|  | @ -92,11 +88,7 @@ const MainListItems = (props) => { | |||
|         primary={i18n.t("mainDrawer.listItems.contacts")} | ||||
|         icon={<ContactPhoneOutlinedIcon />} | ||||
|       /> | ||||
|        <ListItemLink | ||||
|         to="/schedulesReminder" | ||||
|         primary="Lembretes" | ||||
|         icon={<SendOutlined />} | ||||
|       /> | ||||
|       <ListItemLink to="/schedulesReminder" primary="Lembretes" icon={<SendOutlined />} /> | ||||
|       <ListItemLink | ||||
|         to="/quickAnswers" | ||||
|         primary={i18n.t("mainDrawer.listItems.quickAnswers")} | ||||
|  | @ -108,9 +100,7 @@ const MainListItems = (props) => { | |||
|         yes={() => ( | ||||
|           <> | ||||
|             <Divider /> | ||||
|             <ListSubheader inset> | ||||
|               {i18n.t("mainDrawer.listItems.administration")} | ||||
|             </ListSubheader> | ||||
|             <ListSubheader inset>{i18n.t("mainDrawer.listItems.administration")}</ListSubheader> | ||||
|             <ListItemLink | ||||
|               to="/users" | ||||
|               primary={i18n.t("mainDrawer.listItems.users")} | ||||
|  | @ -132,32 +122,21 @@ const MainListItems = (props) => { | |||
|               } | ||||
|             /> | ||||
| 
 | ||||
|             <ListItemLink | ||||
|                     to="/" | ||||
|                     primary="Dashboard" | ||||
|                     icon={<DashboardOutlinedIcon />} | ||||
|             /> | ||||
| 
 | ||||
|             <ListItemLink | ||||
|                     to="/report" | ||||
|                     primary="Relatório" | ||||
|                     icon={<ReportOutlinedIcon />} | ||||
|             /> | ||||
|             <ListItemLink to="/" primary="Dashboard" icon={<DashboardOutlinedIcon />} /> | ||||
| 
 | ||||
|             <ListItemLink to="/report" primary="Relatório" icon={<ReportOutlinedIcon />} /> | ||||
| 
 | ||||
|             <Can | ||||
|                     role={user.profile} | ||||
|                     perform="settings-view:show" | ||||
|                     yes={() => ( | ||||
|                       <ListItemLink | ||||
|                         to="/settings" | ||||
|                         primary={i18n.t("mainDrawer.listItems.settings")} | ||||
|                         icon={<SettingsOutlinedIcon />} | ||||
|                       /> | ||||
|                     )} | ||||
|               role={user.profile} | ||||
|               perform="settings-view:show" | ||||
|               yes={() => ( | ||||
|                 <ListItemLink | ||||
|                   to="/settings" | ||||
|                   primary={i18n.t("mainDrawer.listItems.settings")} | ||||
|                   icon={<SettingsOutlinedIcon />} | ||||
|                 /> | ||||
|               )} | ||||
|             /> | ||||
| 
 | ||||
|              | ||||
|           </> | ||||
|         )} | ||||
|       /> | ||||
|  |  | |||
|  | @ -185,7 +185,7 @@ const LoggedInLayout = ({ children }) => { | |||
|         </div> | ||||
|         <Divider /> | ||||
|         <List> | ||||
|           <MainListItems drawerClose={drawerClose} /> | ||||
|           <MainListItems drawerClose={drawerClose} setDrawerOpen={setDrawerOpen} drawerOpen={drawerOpen} /> | ||||
|         </List> | ||||
|         <Divider /> | ||||
|       </Drawer> | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| import React from "react"; | ||||
| import Typography from "@material-ui/core/Typography"; | ||||
| 
 | ||||
| const Title = props => { | ||||
| const Title = ({children}) => { | ||||
| 	return ( | ||||
| 		<Typography component="h2" variant="h6" color="primary" gutterBottom> | ||||
| 			{props.children} | ||||
| 			{children} | ||||
| 		</Typography> | ||||
| 	); | ||||
| }; | ||||
|  |  | |||
|  | @ -1,56 +1,205 @@ | |||
| import React, { useContext, useReducer, useEffect, useState } from "react" | ||||
| import React, { useContext, useReducer, useEffect, useState } from "react"; | ||||
| 
 | ||||
| import Paper from "@material-ui/core/Paper" | ||||
| import Container from "@material-ui/core/Container" | ||||
| import Grid from "@material-ui/core/Grid" | ||||
| import { makeStyles } from "@material-ui/core/styles" | ||||
| import Paper from "@material-ui/core/Paper"; | ||||
| import Container from "@material-ui/core/Container"; | ||||
| import Grid from "@material-ui/core/Grid"; | ||||
| import { makeStyles } from "@material-ui/core/styles"; | ||||
| import Typography from "@material-ui/core/Typography"; | ||||
| import Tooltip from "@mui/material/Tooltip"; | ||||
| import Zoom from "@mui/material/Zoom"; | ||||
| import IconButton from "@mui/material/IconButton"; | ||||
| import Info from "@material-ui/icons/Info"; | ||||
| 
 | ||||
| // import useTickets from "../../hooks/useTickets"
 | ||||
| import useTickets from "../../hooks/useTickets"; | ||||
| 
 | ||||
| import { AuthContext } from "../../context/Auth/AuthContext"; | ||||
| 
 | ||||
| import { i18n } from "../../translate/i18n"; | ||||
| 
 | ||||
| import Chart from "./Chart" | ||||
| import Chart from "./Chart"; | ||||
| 
 | ||||
| import openSocket from "socket.io-client"; | ||||
| 
 | ||||
| import api from "../../services/api"; | ||||
| 
 | ||||
| import openSocket from "socket.io-client"; | ||||
| 
 | ||||
| import api from "../../services/api"; | ||||
| 
 | ||||
| import { Can } from "../../components/Can"; | ||||
| import CardUser from "../../components/DashboardUser/CardUser"; | ||||
| import TableUser from "../../components/DashboardUser/TableUser"; | ||||
| 
 | ||||
| import { Button } from "@material-ui/core"; | ||||
| const useStyles = makeStyles((theme) => ({ | ||||
|   container: { | ||||
|     paddingTop: theme.spacing(4), | ||||
|     paddingBottom: theme.spacing(4), | ||||
|   }, | ||||
|   fixedHeightPaper: { | ||||
|     padding: theme.spacing(2), | ||||
|     display: "flex", | ||||
|     overflow: "auto", | ||||
|     flexDirection: "column", | ||||
|     height: 240, | ||||
|   }, | ||||
|   customFixedHeightPaper: { | ||||
|     padding: theme.spacing(2), | ||||
|     display: "flex", | ||||
|     overflow: "auto", | ||||
|     flexDirection: "column", | ||||
|     height: 120, | ||||
|   }, | ||||
|   customFixedHeightPaperLg: { | ||||
|     padding: theme.spacing(2), | ||||
|     display: "flex", | ||||
|     overflow: "auto", | ||||
|     flexDirection: "column", | ||||
|     height: "100%", | ||||
|   }, | ||||
|   containerPaperFix: { | ||||
|     width: "100%", | ||||
|     textTransform: "capitalize", | ||||
|     padding: theme.spacing(2), | ||||
|     paddingBottom: theme.spacing(4), | ||||
|     height: "auto", | ||||
|     overflowY: "hidden", | ||||
|   }, | ||||
|   cardPaperFix: { | ||||
|     textTransform: "capitalize", | ||||
|     paddingLeft: theme.spacing(4), | ||||
|     paddingRight: theme.spacing(4), | ||||
|     height: window.innerWidth <= 992 ? "500px" : "auto", | ||||
|     overflowY: "hidden", | ||||
|   }, | ||||
|   cardStyleFix: { | ||||
|     display: "flex", | ||||
|     flexDirection: "row", | ||||
|     justifyContent: "left", | ||||
|     alignItems: "center", | ||||
|     gap: "32px", | ||||
|   }, | ||||
|   logginBtn: { | ||||
|     position: "absolute", | ||||
|     bottom: "21px", | ||||
|     right: "21px", | ||||
|     fontSize: "12px", | ||||
|   }, | ||||
|   tableRowHead: { | ||||
|     backgroundColor: "lightgrey", | ||||
|   }, | ||||
|   tableRowBody: { | ||||
|     textAlign: "center", | ||||
|     " &:nth-child(even)": { | ||||
|       backgroundColor: "#f7f7f7", | ||||
|     }, | ||||
|   }, | ||||
|   tableCounterOpen: { | ||||
|     color: "white", | ||||
|     backgroundColor: "green", | ||||
|     width: "25px", | ||||
|     textAlign: "center", | ||||
|     borderRadius: "5px", | ||||
|   }, | ||||
|   tableCounterClosed: { | ||||
|     color: "white", | ||||
|     backgroundColor: "red", | ||||
|     width: "25px", | ||||
|     textAlign: "center", | ||||
|     borderRadius: "5px", | ||||
|   }, | ||||
| })); | ||||
| 
 | ||||
| const useStyles = makeStyles(theme => ({ | ||||
| 	container: { | ||||
| 		paddingTop: theme.spacing(4), | ||||
| 		paddingBottom: theme.spacing(4), | ||||
| 	}, | ||||
| 	fixedHeightPaper: { | ||||
| 		padding: theme.spacing(2), | ||||
| 		display: "flex", | ||||
| 		overflow: "auto", | ||||
| 		flexDirection: "column", | ||||
| 		height: 240, | ||||
| 	}, | ||||
| 	customFixedHeightPaper: { | ||||
| 		padding: theme.spacing(2), | ||||
| 		display: "flex", | ||||
| 		overflow: "auto", | ||||
| 		flexDirection: "column", | ||||
| 		height: 120, | ||||
| 	}, | ||||
| 	customFixedHeightPaperLg: { | ||||
| 		padding: theme.spacing(2), | ||||
| 		display: "flex", | ||||
| 		overflow: "auto", | ||||
| 		flexDirection: "column", | ||||
| 		height: "100%", | ||||
| 	}, | ||||
| })) | ||||
| const reducer = (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; | ||||
| 
 | ||||
|     let onlySumOpenClosed = false; | ||||
| 
 | ||||
|     if (onlineUser.sumOpen || onlineUser.sumClosed) { | ||||
|       index = state.findIndex( | ||||
|         (e) => | ||||
|           (onlineUser.sumOpen && e.id === onlineUser.sumOpen.userId) || | ||||
|           (onlineUser.sumClosed && e.id === onlineUser.sumClosed.userId) | ||||
|       ); | ||||
| 
 | ||||
|       onlySumOpenClosed = true; | ||||
|     } else { | ||||
|       index = state.findIndex((e) => `${e.id}` === `${onlineUser.userId}`); | ||||
|     } | ||||
| 
 | ||||
|     if (index !== -1) { | ||||
|       if (!onlySumOpenClosed) { | ||||
|         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) => { | ||||
|  | @ -199,382 +348,274 @@ const reducer = (state, action) => { | |||
| 
 | ||||
| 
 | ||||
| const Dashboard = () => { | ||||
| 	const classes = useStyles() | ||||
| 	const [usersOnlineInfo, dispatch] = useReducer(reducer, []) | ||||
| 
 | ||||
| 	const [open, setOpen] = useState(0) | ||||
| 	const [closed, setClosed] = useState(0) | ||||
| 	const [pending, setPending] = useState(0) | ||||
| 
 | ||||
| 	const { user } = useContext(AuthContext); | ||||
| 	// var userQueueIds = [];
 | ||||
| 
 | ||||
| 	// if (user.queues && user.queues.length > 0) {
 | ||||
| 	// 	userQueueIds = user.queues.map(q => q.id);
 | ||||
| 	// }
 | ||||
| 
 | ||||
| 	// const GetTickets = (status, showAll, withUnreadMessages, unlimited) => {
 | ||||
| 
 | ||||
| 	// 	const { tickets } = useTickets({
 | ||||
| 	// 		status: status,
 | ||||
| 	// 		showAll: showAll,
 | ||||
| 	// 		withUnreadMessages: withUnreadMessages,
 | ||||
| 	// 		queueIds: JSON.stringify(userQueueIds),
 | ||||
| 	// 		unlimited: unlimited
 | ||||
| 	// 	});
 | ||||
| 	// 	return tickets.length;
 | ||||
| 	// }
 | ||||
| 
 | ||||
| 	useEffect(() => { | ||||
| 
 | ||||
| 		dispatch({ type: "RESET" }); | ||||
| 
 | ||||
| 	}, []); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	const handleLogouOnlineUser = async (userId) => { | ||||
| 		try { | ||||
| 			await api.get(`/users/logout/${userId}`); | ||||
| 			//toast.success(("Desloged!"));
 | ||||
| 			//handleDeleteRows(scheduleId) 
 | ||||
| 		} catch (err) { | ||||
| 			// toastError(err);
 | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
| 	useEffect(() => { | ||||
| 
 | ||||
| 		//setLoading(true);
 | ||||
| 
 | ||||
| 		const delayDebounceFn = setTimeout(() => { | ||||
| 
 | ||||
| 			// setLoading(true);
 | ||||
| 			const fetchQueries = async () => { | ||||
| 				try { | ||||
| 
 | ||||
| 					let date = new Date().toLocaleDateString('pt-BR').split('/') | ||||
| 					let dateToday = `${date[2]}-${date[1]}-${date[0]}` | ||||
| 
 | ||||
| 					const dataQuery = await api.get("/reports/user/services", { params: { userId: null, startDate: dateToday, endDate: dateToday }, }); | ||||
| 					dispatch({ type: "RESET" }) | ||||
| 					dispatch({ type: "LOAD_QUERY", payload: dataQuery.data }); | ||||
| 
 | ||||
| 					console.log('xxx REPORT 2 dataQuery : ', dataQuery.data) | ||||
| 
 | ||||
| 					//console.log() 
 | ||||
| 
 | ||||
| 				} catch (err) { | ||||
| 					console.log(err); | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			fetchQueries(); | ||||
| 
 | ||||
| 		}, 500); | ||||
| 		return () => clearTimeout(delayDebounceFn); | ||||
| 
 | ||||
| 	}, []); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	useEffect(() => { | ||||
| 
 | ||||
| 		const socket = openSocket(process.env.REACT_APP_BACKEND_URL); | ||||
| 
 | ||||
| 		// socket.on("ticket", (data) => {
 | ||||
| 		// 	console.log('OK')
 | ||||
| 		// });
 | ||||
| 
 | ||||
| 		socket.on("onlineStatus", (data) => { | ||||
| 
 | ||||
| 			if (data.action === "logout" || (data.action === "update")) {  | ||||
| 
 | ||||
| 				// console.log('>>>>>>> data.userOnlineTime: ', data.userOnlineTime)
 | ||||
| 				 | ||||
| 
 | ||||
| 				dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }); | ||||
| 
 | ||||
| 			} | ||||
| 			else if (data.action === "delete") { | ||||
| 				dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); | ||||
| 			} | ||||
| 
 | ||||
| 		}); | ||||
| 
 | ||||
| 		socket.on("user", (data) => { | ||||
| 
 | ||||
| 			if (data.action === "delete") { | ||||
| 				// console.log(' entrou no delete user: ', data)
 | ||||
| 				dispatch({ type: "DELETE_USER", payload: +data.userId }); | ||||
| 			} | ||||
| 		});   | ||||
| 
 | ||||
| 		return () => { | ||||
| 			socket.disconnect(); | ||||
| 		}; | ||||
| 
 | ||||
| 
 | ||||
| 	}, []); | ||||
| 
 | ||||
| 
 | ||||
| 	useEffect(() => { | ||||
| 
 | ||||
| 		const delayDebounceFn = setTimeout(() => { | ||||
| 
 | ||||
| 			const fetchQueries = async () => { | ||||
| 
 | ||||
| 				try { | ||||
| 
 | ||||
| 					let date = new Date().toLocaleDateString('pt-BR').split('/') | ||||
| 					let dateToday = `${date[2]}-${date[1]}-${date[0]}` | ||||
| 
 | ||||
| 					const _open = await api.get("/tickets/count", { params: { status: 'open', date: dateToday } }); | ||||
| 					const _closed = await api.get("/tickets/count", { params: { status: 'closed', date: dateToday } }); | ||||
| 					const _pending = await api.get("/tickets/count", { params: { status: 'pending', date: dateToday } }); | ||||
| 
 | ||||
| 					setOpen(_open.data.count) | ||||
| 					setClosed(_closed.data.count) | ||||
| 					setPending(_pending.data.count)   | ||||
| 
 | ||||
| 
 | ||||
| 				} catch (err) { | ||||
| 					console.log(err); | ||||
| 				} | ||||
| 			}; | ||||
| 
 | ||||
| 			fetchQueries(); | ||||
| 
 | ||||
| 		}, 500); | ||||
| 		return () => clearTimeout(delayDebounceFn); | ||||
| 
 | ||||
| 	}, [usersOnlineInfo]); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	return ( | ||||
| 
 | ||||
| 		<Can | ||||
| 			role={user.profile} | ||||
| 			perform="dashboard-view:show" | ||||
| 			yes={() => ( | ||||
| 				<div> | ||||
| 					<Container maxWidth="lg" className={classes.container}> | ||||
| 						<Grid container spacing={3}> | ||||
| 
 | ||||
| 							<Grid item xs={4}> | ||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> | ||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> | ||||
| 										{i18n.t("dashboard.messages.inAttendance.title")} | ||||
| 									</Typography> | ||||
| 									<Grid item> | ||||
| 										<Typography component="h1" variant="h4"> | ||||
| 											{/* {GetTickets("open", "true", "false", "true")} */} | ||||
| 											{open} | ||||
| 										</Typography> | ||||
| 									</Grid> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 							<Grid item xs={4}> | ||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> | ||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> | ||||
| 										{i18n.t("dashboard.messages.waiting.title")} | ||||
| 									</Typography> | ||||
| 									<Grid item> | ||||
| 										<Typography component="h1" variant="h4"> | ||||
| 											{/* {GetTickets("pending", "true", "false", "true")} */} | ||||
| 											{pending} | ||||
| 										</Typography> | ||||
| 									</Grid> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 							<Grid item xs={4}> | ||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> | ||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> | ||||
| 										{i18n.t("dashboard.messages.closed.title")} | ||||
| 									</Typography> | ||||
| 									<Grid item> | ||||
| 										<Typography component="h1" variant="h4"> | ||||
| 											{/* {GetTickets("closed", "true", "false", "true")} */} | ||||
| 											{closed} | ||||
| 										</Typography> | ||||
| 									</Grid> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 							<Grid item sm={6}> | ||||
| 								<Paper style={{ padding: "15px", }}> | ||||
| 									<Typography component="h3" color="primary" paragraph> | ||||
| 										{'Total online'} | ||||
| 									</Typography> | ||||
| 									<Grid item> | ||||
| 										<Typography component="h1" paragraph> | ||||
| 											{usersOnlineInfo && | ||||
| 												usersOnlineInfo.filter((user) => user.statusOnline && user.statusOnline.status === 'online').length | ||||
| 											} | ||||
| 										</Typography> | ||||
| 									</Grid> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 							<Grid item sm={6}> | ||||
| 								<Paper style={{ padding: "15px", }}> | ||||
| 									<Typography component="h3" color="primary" paragraph> | ||||
| 										{'Total offline'} | ||||
| 									</Typography> | ||||
| 									<Grid item> | ||||
| 										<Typography component="h1" paragraph> | ||||
| 											{usersOnlineInfo && | ||||
| 												usersOnlineInfo.filter((user) => !user.statusOnline || user.statusOnline.status === 'offline').length | ||||
| 											} | ||||
| 										</Typography> | ||||
| 									</Grid> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 							<Grid item xs={12}> | ||||
| 								<Paper className={classes.fixedHeightPaper}> | ||||
| 									<Chart /> | ||||
| 								</Paper> | ||||
| 							</Grid> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 							{usersOnlineInfo && | ||||
| 
 | ||||
| 								usersOnlineInfo.map((userInfo, index) => ( | ||||
| 
 | ||||
| 									// <MenuItem key={index} value={option.value}>   {option.label}  </MenuItem>
 | ||||
| 
 | ||||
| 
 | ||||
| 									<> | ||||
| 										{userInfo.statusOnline && | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 											<Grid item sm={3} key={index} style={{ margin: "25px" }}> | ||||
| 												<Paper style={{ height: "480px", width: "300px", padding: "5px", overflow: "hidden" }}> | ||||
| 													<Typography component="h3" color="primary"> | ||||
| 														{userInfo.name} | ||||
| 													</Typography> | ||||
| 													<Grid item> | ||||
| 
 | ||||
| 														<Typography component="h1"> | ||||
| 															{userInfo.statusOnline && | ||||
| 																userInfo.statusOnline.status | ||||
| 															} | ||||
| 														</Typography> | ||||
| 
 | ||||
| 														<Typography component="h1"> | ||||
| 															Em atendimento: {userInfo.sumOpen && userInfo.sumOpen.count} | ||||
| 														</Typography> | ||||
| 
 | ||||
| 														<Typography component="h1"> | ||||
| 															Finalizado: {userInfo.sumClosed && userInfo.sumClosed.count} | ||||
| 														</Typography> | ||||
| 
 | ||||
| 														<Typography component="h1"> | ||||
| 															Tempo online: {userInfo.sumOnlineTime && userInfo.sumOnlineTime.sum} | ||||
| 														</Typography> | ||||
| 
 | ||||
| 
 | ||||
| 														<div style={{ border: 'dotted', margin: '3px', padding: '2px' }}> | ||||
| 
 | ||||
| 															<div>Em atendimento(open/closed) por fila, conversas iniciadas pelos clientes:</div> | ||||
| 
 | ||||
| 
 | ||||
| 															{userInfo.openClosedInQueue && | ||||
| 
 | ||||
| 																userInfo.openClosedInQueue.map((info, index) => ( | ||||
| 																	<> | ||||
| 																		<Typography component="h1" key={index}> | ||||
| 																		 {info.name}: OPEN {info.countOpen} | CLOSED  {info.countClosed} | ||||
| 																		</Typography> | ||||
| 																	</> | ||||
| 																)) | ||||
| 
 | ||||
| 															} | ||||
| 
 | ||||
| 														</div> | ||||
| 
 | ||||
| 														<div style={{ border: 'dotted', margin: '3px', padding: '2px' }}> | ||||
| 
 | ||||
| 															<div>Em atendimento(open/closed) sem fila, conversas iniciadas por atendentes:</div> | ||||
| 
 | ||||
| 															{userInfo.openClosedOutQueue && | ||||
|   | ||||
| 																<Typography component="h1" key={index}>  | ||||
| 																	SEM FILA: OPEN {userInfo.openClosedOutQueue.countOpen} | CLOSED  {userInfo.openClosedOutQueue.countClosed}  | ||||
| 																</Typography>  | ||||
| 
 | ||||
| 															} | ||||
| 
 | ||||
| 														</div>  | ||||
| 
 | ||||
| 
 | ||||
| 														{userInfo.statusOnline && userInfo.statusOnline.status === "online" && | ||||
| 
 | ||||
| 															userInfo.statusOnline && | ||||
| 
 | ||||
| 															<Typography component="h1"> | ||||
| 
 | ||||
| 																<Button style={{ display: "block" }} | ||||
| 																	variant="contained" | ||||
| 																	color="primary" | ||||
| 																	onClick={(e) => { | ||||
| 																		// handleCSVMessages()
 | ||||
| 																		handleLogouOnlineUser(userInfo.id) | ||||
| 																	}} | ||||
| 																> | ||||
| 																	{"Deslogar"} | ||||
| 																</Button> | ||||
| 
 | ||||
| 															</Typography> | ||||
| 
 | ||||
| 														} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 													</Grid> | ||||
| 												</Paper> | ||||
| 											</Grid> | ||||
| 										} | ||||
| 									</> | ||||
| 
 | ||||
| 
 | ||||
| 								)) | ||||
| 							} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 						</Grid> | ||||
| 					</Container > | ||||
| 				</div > | ||||
| 			)} | ||||
| 		/> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		/**/ | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| export default Dashboard | ||||
|   const classes = useStyles(); | ||||
|   const [usersOnlineInfo, dispatch] = useReducer(reducer, []); | ||||
|   const { user } = useContext(AuthContext); | ||||
|   var userQueueIds = []; | ||||
| 
 | ||||
|   if (user.queues && user.queues.length > 0) { | ||||
|     userQueueIds = user.queues.map((q) => q.id); | ||||
|   } | ||||
| 
 | ||||
|   const GetTickets = (status, showAll, withUnreadMessages, unlimited) => { | ||||
|     const { tickets } = useTickets({ | ||||
|       status: status, | ||||
|       showAll: showAll, | ||||
|       withUnreadMessages: withUnreadMessages, | ||||
|       queueIds: JSON.stringify(userQueueIds), | ||||
|       unlimited: unlimited, | ||||
|     }); | ||||
|     return tickets.length; | ||||
|   }; | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     dispatch({ type: "RESET" }); | ||||
|   }, []); | ||||
| 
 | ||||
|   const handleLogouOnlineUser = async (userId) => { | ||||
|     try { | ||||
|       await api.get(`/users/logout/${userId}`); | ||||
|       //toast.success(("Desloged!"));
 | ||||
|       //handleDeleteRows(scheduleId)
 | ||||
|     } catch (err) { | ||||
|       // toastError(err);
 | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     //setLoading(true);
 | ||||
| 
 | ||||
|     const delayDebounceFn = setTimeout(() => { | ||||
|       // setLoading(true);
 | ||||
|       const fetchQueries = async () => { | ||||
|         try { | ||||
|           let date = new Date().toLocaleDateString("pt-BR").split("/"); | ||||
|           let dateToday = `${date[2]}-${date[1]}-${date[0]}`; | ||||
| 
 | ||||
|           const dataQuery = await api.get("/reports/user/services", { | ||||
|             params: { userId: null, startDate: dateToday, endDate: dateToday }, | ||||
|           }); | ||||
|           dispatch({ type: "RESET" }); | ||||
|           dispatch({ type: "LOAD_QUERY", payload: dataQuery.data }); | ||||
| 
 | ||||
|           //console.log()
 | ||||
|         } catch (err) { | ||||
|           console.log(err); | ||||
|         } | ||||
|       }; | ||||
| 
 | ||||
|       fetchQueries(); | ||||
|     }, 500); | ||||
|     return () => clearTimeout(delayDebounceFn); | ||||
|   }, []); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     const socket = openSocket(process.env.REACT_APP_BACKEND_URL); | ||||
| 
 | ||||
|     socket.on("onlineStatus", (data) => { | ||||
|       if (data.action === "logout" || data.action === "update") { | ||||
|         dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }); | ||||
|       } else if (data.action === "delete") { | ||||
|         dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     socket.on("user", (data) => { | ||||
|       if (data.action === "delete") { | ||||
|         // console.log(' entrou no delete user: ', data)
 | ||||
|         dispatch({ type: "DELETE_USER", payload: +data.userId }); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     return () => { | ||||
|       socket.disconnect(); | ||||
|     }; | ||||
|   }, []); | ||||
| 
 | ||||
|   return ( | ||||
|     <Can | ||||
|       role={user.profile} | ||||
|       perform="dashboard-view:show" | ||||
|       yes={() => ( | ||||
|         <Container maxWidth="lg" className={classes.container}> | ||||
|           <Grid container spacing={3}> | ||||
|             <Paper className={classes.containerPaperFix} sx={12}> | ||||
|               <Grid item sx={4}> | ||||
|                 <Typography | ||||
|                   component="h1" | ||||
|                   variant="h4" | ||||
|                   color="primary" | ||||
|                   style={{ marginBottom: "16px" }} | ||||
|                 > | ||||
|                   tickets | ||||
|                   <Tooltip | ||||
|                     title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString()}`} | ||||
|                     color="primary" | ||||
|                     TransitionComponent={Zoom} | ||||
|                   > | ||||
|                     <IconButton> | ||||
|                       <Info /> | ||||
|                     </IconButton> | ||||
|                   </Tooltip> | ||||
|                 </Typography> | ||||
|               </Grid> | ||||
|               <Grid container spacing={3}> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       {i18n.t("dashboard.messages.inAttendance.title")} | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         {GetTickets("open", "true", "false", "true")} | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       {i18n.t("dashboard.messages.waiting.title")} | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         {GetTickets("pending", "true", "false", "true")} | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       {i18n.t("dashboard.messages.closed.title")} | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         {GetTickets("closed", "true", "false", "true")} | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12}> | ||||
|                   <Paper className={classes.fixedHeightPaper} variant="outlined"> | ||||
|                     <Chart /> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|               </Grid> | ||||
|             </Paper> | ||||
|             <Paper className={classes.containerPaperFix} style={{ marginTop: "21px" }} sx={12}> | ||||
|               <Grid item sx={4}> | ||||
|                 <Typography | ||||
|                   component="h1" | ||||
|                   variant="h4" | ||||
|                   color="primary" | ||||
|                   style={{ marginBottom: "16px" }} | ||||
|                 > | ||||
|                   Usuários | ||||
|                   <Tooltip | ||||
|                     title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString()}`} | ||||
|                     color="primary" | ||||
|                     TransitionComponent={Zoom} | ||||
|                   > | ||||
|                     <IconButton> | ||||
|                       <Info /> | ||||
|                     </IconButton> | ||||
|                   </Tooltip> | ||||
|                 </Typography> | ||||
|               </Grid> | ||||
|               <Grid container spacing={3}> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       Total de Agentes | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         {usersOnlineInfo.length} | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       Online | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         { | ||||
|                           usersOnlineInfo.filter( | ||||
|                             (status) => | ||||
|                               status.statusOnline && status.statusOnline.status === "online" | ||||
|                           ).length | ||||
|                         } | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||
|                   <Paper | ||||
|                     className={classes.customFixedHeightPaper} | ||||
|                     style={{ overflow: "hidden" }} | ||||
|                     variant="outlined" | ||||
|                   > | ||||
|                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||
|                       Offline | ||||
|                     </Typography> | ||||
|                     <Grid item> | ||||
|                       <Typography component="h1" variant="h4"> | ||||
|                         { | ||||
|                           usersOnlineInfo.filter( | ||||
|                             (status) => | ||||
|                               !status.statusOnline || status.statusOnline.status === "offline" | ||||
|                           ).length | ||||
|                         } | ||||
|                       </Typography> | ||||
|                     </Grid> | ||||
|                   </Paper> | ||||
|                 </Grid> | ||||
|                 {window.innerWidth <= 992 ? ( | ||||
|                   <CardUser | ||||
|                     classes={classes} | ||||
|                     usersOnlineInfo={usersOnlineInfo} | ||||
|                     logout={handleLogouOnlineUser} | ||||
|                   /> | ||||
|                 ) : ( | ||||
|                   <TableUser | ||||
|                     classes={classes} | ||||
|                     usersOnlineInfo={usersOnlineInfo} | ||||
|                     logout={handleLogouOnlineUser} | ||||
|                   /> | ||||
|                 )} | ||||
|               </Grid> | ||||
|             </Paper> | ||||
|           </Grid> | ||||
|         </Container> | ||||
|       )} | ||||
|     /> | ||||
| 
 | ||||
|     /**/ | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default Dashboard; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue