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; |   let searchTimeout; | ||||||
| 
 | 
 | ||||||
|   const handleSearch = (e) => { |   const handleSearch = (e) => { | ||||||
|     const searchedTerm = e.target.value.toLowerCase();   |     const searchedTerm = e.target.value.toLowerCase().trim(); | ||||||
| 
 | 
 | ||||||
|     clearTimeout(searchTimeout); |     clearTimeout(searchTimeout); | ||||||
| 
 | 
 | ||||||
|  | @ -274,7 +274,7 @@ const TicketsManager = () => { | ||||||
|         </Tabs> |         </Tabs> | ||||||
|         <Paper className={classes.ticketsWrapper}> |         <Paper className={classes.ticketsWrapper}> | ||||||
|           <TicketsList |           <TicketsList | ||||||
|             status="open" |             status={"open"} | ||||||
|             showAll={showAllTickets} |             showAll={showAllTickets} | ||||||
|             selectedQueueIds={selectedQueueIds} |             selectedQueueIds={selectedQueueIds} | ||||||
|             updateCount={(val) => setOpenCount(val)} |             updateCount={(val) => setOpenCount(val)} | ||||||
|  | @ -285,7 +285,7 @@ const TicketsManager = () => { | ||||||
|             selectedQueueIds={selectedQueueIds} |             selectedQueueIds={selectedQueueIds} | ||||||
|             updateCount={(val) => setPendingCount(val)} |             updateCount={(val) => setPendingCount(val)} | ||||||
|             style={applyPanelStyle("pending")} |             style={applyPanelStyle("pending")} | ||||||
|           /> |           />   | ||||||
|         </Paper> |         </Paper> | ||||||
|       </TabPanel> |       </TabPanel> | ||||||
|       <TabPanel value={tab} name="closed" className={classes.ticketsWrapper}> |       <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 { Badge } from "@material-ui/core"; | ||||||
| import DashboardOutlinedIcon from "@material-ui/icons/DashboardOutlined"; | import DashboardOutlinedIcon from "@material-ui/icons/DashboardOutlined"; | ||||||
| 
 | 
 | ||||||
| import ReportOutlinedIcon from       "@material-ui/icons/ReportOutlined"; | import ReportOutlinedIcon from "@material-ui/icons/ReportOutlined"; | ||||||
| import SendOutlined from '@material-ui/icons/SendOutlined'; | import SendOutlined from "@material-ui/icons/SendOutlined"; | ||||||
| 
 | 
 | ||||||
| //import ReportOutlined from "@bit/mui-org.material-ui-icons.report-outlined";
 | //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 { icon, primary, to, className } = props; | ||||||
| 
 | 
 | ||||||
|   const renderLink = React.useMemo( |   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] |     [to] | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|  | @ -50,7 +47,7 @@ function ListItemLink(props) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const MainListItems = (props) => { | const MainListItems = (props) => { | ||||||
|   const { drawerClose } = props; |   const { drawerClose, setDrawerOpen, drawerOpen } = props; | ||||||
|   const { whatsApps } = useContext(WhatsAppsContext); |   const { whatsApps } = useContext(WhatsAppsContext); | ||||||
|   const { user } = useContext(AuthContext); |   const { user } = useContext(AuthContext); | ||||||
|   const [connectionWarning, setConnectionWarning] = useState(false); |   const [connectionWarning, setConnectionWarning] = useState(false); | ||||||
|  | @ -78,9 +75,8 @@ const MainListItems = (props) => { | ||||||
|   }, [whatsApps]); |   }, [whatsApps]); | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div onClick={drawerClose}> |     //Solicitado pelo Adriano: Click no LinkItem e fechar o menu!
 | ||||||
|       |     <div onClick={() => setDrawerOpen(false)}> | ||||||
|        |  | ||||||
|       <ListItemLink |       <ListItemLink | ||||||
|         to="/tickets" |         to="/tickets" | ||||||
|         primary={i18n.t("mainDrawer.listItems.tickets")} |         primary={i18n.t("mainDrawer.listItems.tickets")} | ||||||
|  | @ -92,11 +88,7 @@ const MainListItems = (props) => { | ||||||
|         primary={i18n.t("mainDrawer.listItems.contacts")} |         primary={i18n.t("mainDrawer.listItems.contacts")} | ||||||
|         icon={<ContactPhoneOutlinedIcon />} |         icon={<ContactPhoneOutlinedIcon />} | ||||||
|       /> |       /> | ||||||
|        <ListItemLink |       <ListItemLink to="/schedulesReminder" primary="Lembretes" icon={<SendOutlined />} /> | ||||||
|         to="/schedulesReminder" |  | ||||||
|         primary="Lembretes" |  | ||||||
|         icon={<SendOutlined />} |  | ||||||
|       /> |  | ||||||
|       <ListItemLink |       <ListItemLink | ||||||
|         to="/quickAnswers" |         to="/quickAnswers" | ||||||
|         primary={i18n.t("mainDrawer.listItems.quickAnswers")} |         primary={i18n.t("mainDrawer.listItems.quickAnswers")} | ||||||
|  | @ -108,9 +100,7 @@ const MainListItems = (props) => { | ||||||
|         yes={() => ( |         yes={() => ( | ||||||
|           <> |           <> | ||||||
|             <Divider /> |             <Divider /> | ||||||
|             <ListSubheader inset> |             <ListSubheader inset>{i18n.t("mainDrawer.listItems.administration")}</ListSubheader> | ||||||
|               {i18n.t("mainDrawer.listItems.administration")} |  | ||||||
|             </ListSubheader> |  | ||||||
|             <ListItemLink |             <ListItemLink | ||||||
|               to="/users" |               to="/users" | ||||||
|               primary={i18n.t("mainDrawer.listItems.users")} |               primary={i18n.t("mainDrawer.listItems.users")} | ||||||
|  | @ -132,32 +122,21 @@ const MainListItems = (props) => { | ||||||
|               } |               } | ||||||
|             /> |             /> | ||||||
| 
 | 
 | ||||||
|             <ListItemLink |             <ListItemLink to="/" primary="Dashboard" icon={<DashboardOutlinedIcon />} /> | ||||||
|                     to="/" |  | ||||||
|                     primary="Dashboard" |  | ||||||
|                     icon={<DashboardOutlinedIcon />} |  | ||||||
|             /> |  | ||||||
| 
 |  | ||||||
|             <ListItemLink |  | ||||||
|                     to="/report" |  | ||||||
|                     primary="Relatório" |  | ||||||
|                     icon={<ReportOutlinedIcon />} |  | ||||||
|             /> |  | ||||||
| 
 | 
 | ||||||
|  |             <ListItemLink to="/report" primary="Relatório" icon={<ReportOutlinedIcon />} /> | ||||||
| 
 | 
 | ||||||
|             <Can |             <Can | ||||||
|                     role={user.profile} |               role={user.profile} | ||||||
|                     perform="settings-view:show" |               perform="settings-view:show" | ||||||
|                     yes={() => ( |               yes={() => ( | ||||||
|                       <ListItemLink |                 <ListItemLink | ||||||
|                         to="/settings" |                   to="/settings" | ||||||
|                         primary={i18n.t("mainDrawer.listItems.settings")} |                   primary={i18n.t("mainDrawer.listItems.settings")} | ||||||
|                         icon={<SettingsOutlinedIcon />} |                   icon={<SettingsOutlinedIcon />} | ||||||
|                       /> |                 /> | ||||||
|                     )} |               )} | ||||||
|             /> |             /> | ||||||
| 
 |  | ||||||
|              |  | ||||||
|           </> |           </> | ||||||
|         )} |         )} | ||||||
|       /> |       /> | ||||||
|  |  | ||||||
|  | @ -185,7 +185,7 @@ const LoggedInLayout = ({ children }) => { | ||||||
|         </div> |         </div> | ||||||
|         <Divider /> |         <Divider /> | ||||||
|         <List> |         <List> | ||||||
|           <MainListItems drawerClose={drawerClose} /> |           <MainListItems drawerClose={drawerClose} setDrawerOpen={setDrawerOpen} drawerOpen={drawerOpen} /> | ||||||
|         </List> |         </List> | ||||||
|         <Divider /> |         <Divider /> | ||||||
|       </Drawer> |       </Drawer> | ||||||
|  |  | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import Typography from "@material-ui/core/Typography"; | import Typography from "@material-ui/core/Typography"; | ||||||
| 
 | 
 | ||||||
| const Title = props => { | const Title = ({children}) => { | ||||||
| 	return ( | 	return ( | ||||||
| 		<Typography component="h2" variant="h6" color="primary" gutterBottom> | 		<Typography component="h2" variant="h6" color="primary" gutterBottom> | ||||||
| 			{props.children} | 			{children} | ||||||
| 		</Typography> | 		</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 Paper from "@material-ui/core/Paper"; | ||||||
| import Container from "@material-ui/core/Container" | import Container from "@material-ui/core/Container"; | ||||||
| import Grid from "@material-ui/core/Grid" | import Grid from "@material-ui/core/Grid"; | ||||||
| import { makeStyles } from "@material-ui/core/styles" | import { makeStyles } from "@material-ui/core/styles"; | ||||||
| import Typography from "@material-ui/core/Typography"; | 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 { AuthContext } from "../../context/Auth/AuthContext"; | ||||||
| 
 | 
 | ||||||
| import { i18n } from "../../translate/i18n"; | 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 openSocket from "socket.io-client"; | ||||||
| 
 | 
 | ||||||
| import api from "../../services/api"; | import api from "../../services/api"; | ||||||
| 
 | 
 | ||||||
| import { Can } from "../../components/Can"; | 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 => ({ | const reducer = (state, action) => { | ||||||
| 	container: { |   if (action.type === "DELETE_USER_STATUS") { | ||||||
| 		paddingTop: theme.spacing(4), |     const userId = action.payload; | ||||||
| 		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 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) => { | const reducer = (state, action) => { | ||||||
|  | @ -199,382 +348,274 @@ const reducer = (state, action) => { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| const Dashboard = () => { | const Dashboard = () => { | ||||||
| 	const classes = useStyles() |   const classes = useStyles(); | ||||||
| 	const [usersOnlineInfo, dispatch] = useReducer(reducer, []) |   const [usersOnlineInfo, dispatch] = useReducer(reducer, []); | ||||||
| 
 |   const { user } = useContext(AuthContext); | ||||||
| 	const [open, setOpen] = useState(0) |   var userQueueIds = []; | ||||||
| 	const [closed, setClosed] = useState(0) | 
 | ||||||
| 	const [pending, setPending] = useState(0) |   if (user.queues && user.queues.length > 0) { | ||||||
| 
 |     userQueueIds = user.queues.map((q) => q.id); | ||||||
| 	const { user } = useContext(AuthContext); |   } | ||||||
| 	// var userQueueIds = [];
 | 
 | ||||||
| 
 |   const GetTickets = (status, showAll, withUnreadMessages, unlimited) => { | ||||||
| 	// if (user.queues && user.queues.length > 0) {
 |     const { tickets } = useTickets({ | ||||||
| 	// 	userQueueIds = user.queues.map(q => q.id);
 |       status: status, | ||||||
| 	// }
 |       showAll: showAll, | ||||||
| 
 |       withUnreadMessages: withUnreadMessages, | ||||||
| 	// const GetTickets = (status, showAll, withUnreadMessages, unlimited) => {
 |       queueIds: JSON.stringify(userQueueIds), | ||||||
| 
 |       unlimited: unlimited, | ||||||
| 	// 	const { tickets } = useTickets({
 |     }); | ||||||
| 	// 		status: status,
 |     return tickets.length; | ||||||
| 	// 		showAll: showAll,
 |   }; | ||||||
| 	// 		withUnreadMessages: withUnreadMessages,
 | 
 | ||||||
| 	// 		queueIds: JSON.stringify(userQueueIds),
 |   useEffect(() => { | ||||||
| 	// 		unlimited: unlimited
 |     dispatch({ type: "RESET" }); | ||||||
| 	// 	});
 |   }, []); | ||||||
| 	// 	return tickets.length;
 | 
 | ||||||
| 	// }
 |   const handleLogouOnlineUser = async (userId) => { | ||||||
| 
 |     try { | ||||||
| 	useEffect(() => { |       await api.get(`/users/logout/${userId}`); | ||||||
| 
 |       //toast.success(("Desloged!"));
 | ||||||
| 		dispatch({ type: "RESET" }); |       //handleDeleteRows(scheduleId)
 | ||||||
| 
 |     } catch (err) { | ||||||
| 	}, []); |       // toastError(err);
 | ||||||
| 
 |     } | ||||||
| 
 |   }; | ||||||
| 
 | 
 | ||||||
| 
 |   useEffect(() => { | ||||||
| 	const handleLogouOnlineUser = async (userId) => { |     //setLoading(true);
 | ||||||
| 		try { | 
 | ||||||
| 			await api.get(`/users/logout/${userId}`); |     const delayDebounceFn = setTimeout(() => { | ||||||
| 			//toast.success(("Desloged!"));
 |       // setLoading(true);
 | ||||||
| 			//handleDeleteRows(scheduleId) 
 |       const fetchQueries = async () => { | ||||||
| 		} catch (err) { |         try { | ||||||
| 			// toastError(err);
 |           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" }); | ||||||
| 	useEffect(() => { |           dispatch({ type: "LOAD_QUERY", payload: dataQuery.data }); | ||||||
| 
 | 
 | ||||||
| 		//setLoading(true);
 |           //console.log()
 | ||||||
| 
 |         } catch (err) { | ||||||
| 		const delayDebounceFn = setTimeout(() => { |           console.log(err); | ||||||
| 
 |         } | ||||||
| 			// setLoading(true);
 |       }; | ||||||
| 			const fetchQueries = async () => { | 
 | ||||||
| 				try { |       fetchQueries(); | ||||||
| 
 |     }, 500); | ||||||
| 					let date = new Date().toLocaleDateString('pt-BR').split('/') |     return () => clearTimeout(delayDebounceFn); | ||||||
| 					let dateToday = `${date[2]}-${date[1]}-${date[0]}` |   }, []); | ||||||
| 
 | 
 | ||||||
| 					const dataQuery = await api.get("/reports/user/services", { params: { userId: null, startDate: dateToday, endDate: dateToday }, }); |   useEffect(() => { | ||||||
| 					dispatch({ type: "RESET" }) |     const socket = openSocket(process.env.REACT_APP_BACKEND_URL); | ||||||
| 					dispatch({ type: "LOAD_QUERY", payload: dataQuery.data }); | 
 | ||||||
| 
 |     socket.on("onlineStatus", (data) => { | ||||||
| 					console.log('xxx REPORT 2 dataQuery : ', dataQuery.data) |       if (data.action === "logout" || data.action === "update") { | ||||||
| 
 |         dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }); | ||||||
| 					//console.log() 
 |       } else if (data.action === "delete") { | ||||||
| 
 |         dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); | ||||||
| 				} catch (err) { |       } | ||||||
| 					console.log(err); |     }); | ||||||
| 				} | 
 | ||||||
| 			}; |     socket.on("user", (data) => { | ||||||
| 
 |       if (data.action === "delete") { | ||||||
| 			fetchQueries(); |         // console.log(' entrou no delete user: ', data)
 | ||||||
| 
 |         dispatch({ type: "DELETE_USER", payload: +data.userId }); | ||||||
| 		}, 500); |       } | ||||||
| 		return () => clearTimeout(delayDebounceFn); |     }); | ||||||
| 
 | 
 | ||||||
| 	}, []); |     return () => { | ||||||
| 
 |       socket.disconnect(); | ||||||
| 
 |     }; | ||||||
| 
 |   }, []); | ||||||
| 	useEffect(() => { | 
 | ||||||
| 
 |   return ( | ||||||
| 		const socket = openSocket(process.env.REACT_APP_BACKEND_URL); |     <Can | ||||||
| 
 |       role={user.profile} | ||||||
| 		// socket.on("ticket", (data) => {
 |       perform="dashboard-view:show" | ||||||
| 		// 	console.log('OK')
 |       yes={() => ( | ||||||
| 		// });
 |         <Container maxWidth="lg" className={classes.container}> | ||||||
| 
 |           <Grid container spacing={3}> | ||||||
| 		socket.on("onlineStatus", (data) => { |             <Paper className={classes.containerPaperFix} sx={12}> | ||||||
| 
 |               <Grid item sx={4}> | ||||||
| 			if (data.action === "logout" || (data.action === "update")) {  |                 <Typography | ||||||
| 
 |                   component="h1" | ||||||
| 				// console.log('>>>>>>> data.userOnlineTime: ', data.userOnlineTime)
 |                   variant="h4" | ||||||
| 				 |                   color="primary" | ||||||
| 
 |                   style={{ marginBottom: "16px" }} | ||||||
| 				dispatch({ type: "UPDATE_STATUS_ONLINE", payload: data.userOnlineTime }); |                 > | ||||||
| 
 |                   tickets | ||||||
| 			} |                   <Tooltip | ||||||
| 			else if (data.action === "delete") { |                     title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString()}`} | ||||||
| 				dispatch({ type: "DELETE_USER_STATUS", payload: data.userOnlineTime }); |                     color="primary" | ||||||
| 			} |                     TransitionComponent={Zoom} | ||||||
| 
 |                   > | ||||||
| 		}); |                     <IconButton> | ||||||
| 
 |                       <Info /> | ||||||
| 		socket.on("user", (data) => { |                     </IconButton> | ||||||
| 
 |                   </Tooltip> | ||||||
| 			if (data.action === "delete") { |                 </Typography> | ||||||
| 				// console.log(' entrou no delete user: ', data)
 |               </Grid> | ||||||
| 				dispatch({ type: "DELETE_USER", payload: +data.userId }); |               <Grid container spacing={3}> | ||||||
| 			} |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 		});   |                   <Paper | ||||||
| 
 |                     className={classes.customFixedHeightPaper} | ||||||
| 		return () => { |                     style={{ overflow: "hidden" }} | ||||||
| 			socket.disconnect(); |                     variant="outlined" | ||||||
| 		}; |                   > | ||||||
| 
 |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 
 |                       {i18n.t("dashboard.messages.inAttendance.title")} | ||||||
| 	}, []); |                     </Typography> | ||||||
| 
 |                     <Grid item> | ||||||
| 
 |                       <Typography component="h1" variant="h4"> | ||||||
| 	useEffect(() => { |                         {GetTickets("open", "true", "false", "true")} | ||||||
| 
 |                       </Typography> | ||||||
| 		const delayDebounceFn = setTimeout(() => { |                     </Grid> | ||||||
| 
 |                   </Paper> | ||||||
| 			const fetchQueries = async () => { |                 </Grid> | ||||||
| 
 |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 				try { |                   <Paper | ||||||
| 
 |                     className={classes.customFixedHeightPaper} | ||||||
| 					let date = new Date().toLocaleDateString('pt-BR').split('/') |                     style={{ overflow: "hidden" }} | ||||||
| 					let dateToday = `${date[2]}-${date[1]}-${date[0]}` |                     variant="outlined" | ||||||
| 
 |                   > | ||||||
| 					const _open = await api.get("/tickets/count", { params: { status: 'open', date: dateToday } }); |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 					const _closed = await api.get("/tickets/count", { params: { status: 'closed', date: dateToday } }); |                       {i18n.t("dashboard.messages.waiting.title")} | ||||||
| 					const _pending = await api.get("/tickets/count", { params: { status: 'pending', date: dateToday } }); |                     </Typography> | ||||||
| 
 |                     <Grid item> | ||||||
| 					setOpen(_open.data.count) |                       <Typography component="h1" variant="h4"> | ||||||
| 					setClosed(_closed.data.count) |                         {GetTickets("pending", "true", "false", "true")} | ||||||
| 					setPending(_pending.data.count)   |                       </Typography> | ||||||
| 
 |                     </Grid> | ||||||
| 
 |                   </Paper> | ||||||
| 				} catch (err) { |                 </Grid> | ||||||
| 					console.log(err); |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 				} |                   <Paper | ||||||
| 			}; |                     className={classes.customFixedHeightPaper} | ||||||
| 
 |                     style={{ overflow: "hidden" }} | ||||||
| 			fetchQueries(); |                     variant="outlined" | ||||||
| 
 |                   > | ||||||
| 		}, 500); |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 		return () => clearTimeout(delayDebounceFn); |                       {i18n.t("dashboard.messages.closed.title")} | ||||||
| 
 |                     </Typography> | ||||||
| 	}, [usersOnlineInfo]); |                     <Grid item> | ||||||
| 
 |                       <Typography component="h1" variant="h4"> | ||||||
| 
 |                         {GetTickets("closed", "true", "false", "true")} | ||||||
| 
 |                       </Typography> | ||||||
| 
 |                     </Grid> | ||||||
| 	return ( |                   </Paper> | ||||||
| 
 |                 </Grid> | ||||||
| 		<Can |                 <Grid item xs={12}> | ||||||
| 			role={user.profile} |                   <Paper className={classes.fixedHeightPaper} variant="outlined"> | ||||||
| 			perform="dashboard-view:show" |                     <Chart /> | ||||||
| 			yes={() => ( |                   </Paper> | ||||||
| 				<div> |                 </Grid> | ||||||
| 					<Container maxWidth="lg" className={classes.container}> |               </Grid> | ||||||
| 						<Grid container spacing={3}> |             </Paper> | ||||||
| 
 |             <Paper className={classes.containerPaperFix} style={{ marginTop: "21px" }} sx={12}> | ||||||
| 							<Grid item xs={4}> |               <Grid item sx={4}> | ||||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> |                 <Typography | ||||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> |                   component="h1" | ||||||
| 										{i18n.t("dashboard.messages.inAttendance.title")} |                   variant="h4" | ||||||
| 									</Typography> |                   color="primary" | ||||||
| 									<Grid item> |                   style={{ marginBottom: "16px" }} | ||||||
| 										<Typography component="h1" variant="h4"> |                 > | ||||||
| 											{/* {GetTickets("open", "true", "false", "true")} */} |                   Usuários | ||||||
| 											{open} |                   <Tooltip | ||||||
| 										</Typography> |                     title={`Os dados informados abaixo é baseado na data: ${new Date().toLocaleDateString()}`} | ||||||
| 									</Grid> |                     color="primary" | ||||||
| 								</Paper> |                     TransitionComponent={Zoom} | ||||||
| 							</Grid> |                   > | ||||||
| 							<Grid item xs={4}> |                     <IconButton> | ||||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> |                       <Info /> | ||||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> |                     </IconButton> | ||||||
| 										{i18n.t("dashboard.messages.waiting.title")} |                   </Tooltip> | ||||||
| 									</Typography> |                 </Typography> | ||||||
| 									<Grid item> |               </Grid> | ||||||
| 										<Typography component="h1" variant="h4"> |               <Grid container spacing={3}> | ||||||
| 											{/* {GetTickets("pending", "true", "false", "true")} */} |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 											{pending} |                   <Paper | ||||||
| 										</Typography> |                     className={classes.customFixedHeightPaper} | ||||||
| 									</Grid> |                     style={{ overflow: "hidden" }} | ||||||
| 								</Paper> |                     variant="outlined" | ||||||
| 							</Grid> |                   > | ||||||
| 							<Grid item xs={4}> |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 								<Paper className={classes.customFixedHeightPaper} style={{ overflow: "hidden" }}> |                       Total de Agentes | ||||||
| 									<Typography component="h3" variant="h6" color="primary" paragraph> |                     </Typography> | ||||||
| 										{i18n.t("dashboard.messages.closed.title")} |                     <Grid item> | ||||||
| 									</Typography> |                       <Typography component="h1" variant="h4"> | ||||||
| 									<Grid item> |                         {usersOnlineInfo.length} | ||||||
| 										<Typography component="h1" variant="h4"> |                       </Typography> | ||||||
| 											{/* {GetTickets("closed", "true", "false", "true")} */} |                     </Grid> | ||||||
| 											{closed} |                   </Paper> | ||||||
| 										</Typography> |                 </Grid> | ||||||
| 									</Grid> |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 								</Paper> |                   <Paper | ||||||
| 							</Grid> |                     className={classes.customFixedHeightPaper} | ||||||
| 
 |                     style={{ overflow: "hidden" }} | ||||||
| 
 |                     variant="outlined" | ||||||
| 
 |                   > | ||||||
| 
 |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 							<Grid item sm={6}> |                       Online | ||||||
| 								<Paper style={{ padding: "15px", }}> |                     </Typography> | ||||||
| 									<Typography component="h3" color="primary" paragraph> |                     <Grid item> | ||||||
| 										{'Total online'} |                       <Typography component="h1" variant="h4"> | ||||||
| 									</Typography> |                         { | ||||||
| 									<Grid item> |                           usersOnlineInfo.filter( | ||||||
| 										<Typography component="h1" paragraph> |                             (status) => | ||||||
| 											{usersOnlineInfo && |                               status.statusOnline && status.statusOnline.status === "online" | ||||||
| 												usersOnlineInfo.filter((user) => user.statusOnline && user.statusOnline.status === 'online').length |                           ).length | ||||||
| 											} |                         } | ||||||
| 										</Typography> |                       </Typography> | ||||||
| 									</Grid> |                     </Grid> | ||||||
| 								</Paper> |                   </Paper> | ||||||
| 							</Grid> |                 </Grid> | ||||||
| 							<Grid item sm={6}> |                 <Grid item xs={12} sm={6} md={6} lg={4}> | ||||||
| 								<Paper style={{ padding: "15px", }}> |                   <Paper | ||||||
| 									<Typography component="h3" color="primary" paragraph> |                     className={classes.customFixedHeightPaper} | ||||||
| 										{'Total offline'} |                     style={{ overflow: "hidden" }} | ||||||
| 									</Typography> |                     variant="outlined" | ||||||
| 									<Grid item> |                   > | ||||||
| 										<Typography component="h1" paragraph> |                     <Typography component="h3" variant="h6" color="primary" paragraph> | ||||||
| 											{usersOnlineInfo && |                       Offline | ||||||
| 												usersOnlineInfo.filter((user) => !user.statusOnline || user.statusOnline.status === 'offline').length |                     </Typography> | ||||||
| 											} |                     <Grid item> | ||||||
| 										</Typography> |                       <Typography component="h1" variant="h4"> | ||||||
| 									</Grid> |                         { | ||||||
| 								</Paper> |                           usersOnlineInfo.filter( | ||||||
| 							</Grid> |                             (status) => | ||||||
| 
 |                               !status.statusOnline || status.statusOnline.status === "offline" | ||||||
| 
 |                           ).length | ||||||
| 
 |                         } | ||||||
| 
 |                       </Typography> | ||||||
| 
 |                     </Grid> | ||||||
| 
 |                   </Paper> | ||||||
| 
 |                 </Grid> | ||||||
| 
 |                 {window.innerWidth <= 992 ? ( | ||||||
| 							<Grid item xs={12}> |                   <CardUser | ||||||
| 								<Paper className={classes.fixedHeightPaper}> |                     classes={classes} | ||||||
| 									<Chart /> |                     usersOnlineInfo={usersOnlineInfo} | ||||||
| 								</Paper> |                     logout={handleLogouOnlineUser} | ||||||
| 							</Grid> |                   /> | ||||||
| 
 |                 ) : ( | ||||||
| 
 |                   <TableUser | ||||||
| 
 |                     classes={classes} | ||||||
| 							{usersOnlineInfo && |                     usersOnlineInfo={usersOnlineInfo} | ||||||
| 
 |                     logout={handleLogouOnlineUser} | ||||||
| 								usersOnlineInfo.map((userInfo, index) => ( |                   /> | ||||||
| 
 |                 )} | ||||||
| 									// <MenuItem key={index} value={option.value}>   {option.label}  </MenuItem>
 |               </Grid> | ||||||
| 
 |             </Paper> | ||||||
| 
 |           </Grid> | ||||||
| 									<> |         </Container> | ||||||
| 										{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} | export default Dashboard; | ||||||
| 													</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 |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue