| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- import React, { useContext, useEffect, useReducer, useState } from "react";
- import { Link as RouterLink, useHistory } from "react-router-dom";
- import ListItem from "@material-ui/core/ListItem";
- import ListItemIcon from "@material-ui/core/ListItemIcon";
- import ListItemText from "@material-ui/core/ListItemText";
- import ListSubheader from "@material-ui/core/ListSubheader";
- import Divider from "@material-ui/core/Divider";
- import { Badge, Collapse, List } from "@material-ui/core";
- import DashboardOutlinedIcon from "@material-ui/icons/DashboardOutlined";
- import WhatsAppIcon from "@material-ui/icons/WhatsApp";
- import SyncAltIcon from "@material-ui/icons/SyncAlt";
- import SettingsOutlinedIcon from "@material-ui/icons/SettingsOutlined";
- import PeopleAltOutlinedIcon from "@material-ui/icons/PeopleAltOutlined";
- import ContactPhoneOutlinedIcon from "@material-ui/icons/ContactPhoneOutlined";
- import AccountTreeOutlinedIcon from "@material-ui/icons/AccountTreeOutlined";
- import FlashOnIcon from "@material-ui/icons/FlashOn";
- import HelpOutlineIcon from "@material-ui/icons/HelpOutline";
- import CodeRoundedIcon from "@material-ui/icons/CodeRounded";
- import EventIcon from "@material-ui/icons/Event";
- import LocalOfferIcon from "@material-ui/icons/LocalOffer";
- import EventAvailableIcon from "@material-ui/icons/EventAvailable";
- import ExpandLessIcon from "@material-ui/icons/ExpandLess";
- import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
- import PeopleIcon from "@material-ui/icons/People";
- import ListIcon from "@material-ui/icons/ListAlt";
- import AnnouncementIcon from "@material-ui/icons/Announcement";
- import ForumIcon from "@material-ui/icons/Forum";
- import LocalAtmIcon from '@material-ui/icons/LocalAtm';
- import RotateRight from "@material-ui/icons/RotateRight";
- import { i18n } from "../translate/i18n";
- import { WhatsAppsContext } from "../context/WhatsApp/WhatsAppsContext";
- import { AuthContext } from "../context/Auth/AuthContext";
- import LoyaltyRoundedIcon from '@material-ui/icons/LoyaltyRounded';
- import { Can } from "../components/Can";
- import { SocketContext } from "../context/Socket/SocketContext";
- import { isArray } from "lodash";
- import TableChartIcon from '@material-ui/icons/TableChart';
- import api from "../services/api";
- import BorderColorIcon from '@material-ui/icons/BorderColor';
- import ToDoList from "../pages/ToDoList/";
- import toastError from "../errors/toastError";
- import { makeStyles } from "@material-ui/core/styles";
- import { AllInclusive, AttachFile, BlurCircular, DeviceHubOutlined, Schedule } from '@material-ui/icons';
- import usePlans from "../hooks/usePlans";
- import Typography from "@material-ui/core/Typography";
- import useVersion from "../hooks/useVersion";
- const useStyles = makeStyles((theme) => ({
- ListSubheader: {
- height: 26,
- marginTop: "-15px",
- marginBottom: "-10px",
- },
- }));
- function ListItemLink(props) {
- const { icon, primary, to, className } = props;
- const renderLink = React.useMemo(
- () =>
- React.forwardRef((itemProps, ref) => (
- <RouterLink to={to} ref={ref} {...itemProps} />
- )),
- [to]
- );
- return (
- <li>
- <ListItem button dense component={renderLink} className={className}>
- {icon ? <ListItemIcon>{icon}</ListItemIcon> : null}
- <ListItemText primary={primary} />
- </ListItem>
- </li>
- );
- }
- const reducer = (state, action) => {
- if (action.type === "LOAD_CHATS") {
- const chats = action.payload;
- const newChats = [];
- if (isArray(chats)) {
- chats.forEach((chat) => {
- const chatIndex = state.findIndex((u) => u.id === chat.id);
- if (chatIndex !== -1) {
- state[chatIndex] = chat;
- } else {
- newChats.push(chat);
- }
- });
- }
- return [...state, ...newChats];
- }
- if (action.type === "UPDATE_CHATS") {
- const chat = action.payload;
- const chatIndex = state.findIndex((u) => u.id === chat.id);
- if (chatIndex !== -1) {
- state[chatIndex] = chat;
- return [...state];
- } else {
- return [chat, ...state];
- }
- }
- if (action.type === "DELETE_CHAT") {
- const chatId = action.payload;
- const chatIndex = state.findIndex((u) => u.id === chatId);
- if (chatIndex !== -1) {
- state.splice(chatIndex, 1);
- }
- return [...state];
- }
- if (action.type === "RESET") {
- return [];
- }
- if (action.type === "CHANGE_CHAT") {
- const changedChats = state.map((chat) => {
- if (chat.id === action.payload.chat.id) {
- return action.payload.chat;
- }
- return chat;
- });
- return changedChats;
- }
- };
- const MainListItems = (props) => {
- const classes = useStyles();
- const { drawerClose, collapsed } = props;
- const { whatsApps } = useContext(WhatsAppsContext);
- const { user, handleLogout } = useContext(AuthContext);
- const [connectionWarning, setConnectionWarning] = useState(false);
- const [openCampaignSubmenu, setOpenCampaignSubmenu] = useState(false);
- const [showCampaigns, setShowCampaigns] = useState(false);
- const [showKanban, setShowKanban] = useState(false);
- const [showOpenAi, setShowOpenAi] = useState(false);
- const [showIntegrations, setShowIntegrations] = useState(false); const history = useHistory();
- const [showSchedules, setShowSchedules] = useState(false);
- const [showInternalChat, setShowInternalChat] = useState(false);
- const [showExternalApi, setShowExternalApi] = useState(false);
- const [invisible, setInvisible] = useState(true);
- const [pageNumber, setPageNumber] = useState(1);
- const [searchParam] = useState("");
- const [chats, dispatch] = useReducer(reducer, []);
- const { getPlanCompany } = usePlans();
-
- const [version, setVersion] = useState(false);
-
-
- const { getVersion } = useVersion();
- const socketManager = useContext(SocketContext);
- useEffect(() => {
- async function fetchVersion() {
- const _version = await getVersion();
- setVersion(_version.version);
- }
- fetchVersion();
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- useEffect(() => {
- dispatch({ type: "RESET" });
- setPageNumber(1);
- }, [searchParam]);
- useEffect(() => {
- async function fetchData() {
- const companyId = user.companyId;
- const planConfigs = await getPlanCompany(undefined, companyId);
- setShowCampaigns(planConfigs.plan.useCampaigns);
- setShowKanban(planConfigs.plan.useKanban);
- setShowOpenAi(planConfigs.plan.useOpenAi);
- setShowIntegrations(planConfigs.plan.useIntegrations);
- setShowSchedules(planConfigs.plan.useSchedules);
- setShowInternalChat(planConfigs.plan.useInternalChat);
- setShowExternalApi(planConfigs.plan.useExternalApi);
- }
- fetchData();
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
- useEffect(() => {
- const delayDebounceFn = setTimeout(() => {
- fetchChats();
- }, 500);
- return () => clearTimeout(delayDebounceFn);
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [searchParam, pageNumber]);
- useEffect(() => {
- const companyId = localStorage.getItem("companyId");
- const socket = socketManager.getSocket(companyId);
- socket.on(`company-${companyId}-chat`, (data) => {
- if (data.action === "new-message") {
- dispatch({ type: "CHANGE_CHAT", payload: data });
- }
- if (data.action === "update") {
- dispatch({ type: "CHANGE_CHAT", payload: data });
- }
- });
- return () => {
- socket.disconnect();
- };
- }, [socketManager]);
- useEffect(() => {
- let unreadsCount = 0;
- if (chats.length > 0) {
- for (let chat of chats) {
- for (let chatUser of chat.users) {
- if (chatUser.userId === user.id) {
- unreadsCount += chatUser.unreads;
- }
- }
- }
- }
- if (unreadsCount > 0) {
- setInvisible(false);
- } else {
- setInvisible(true);
- }
- }, [chats, user.id]);
- useEffect(() => {
- if (localStorage.getItem("cshow")) {
- setShowCampaigns(true);
- }
- }, []);
- useEffect(() => {
- const delayDebounceFn = setTimeout(() => {
- if (whatsApps.length > 0) {
- const offlineWhats = whatsApps.filter((whats) => {
- return (
- whats.status === "qrcode" ||
- whats.status === "PAIRING" ||
- whats.status === "DISCONNECTED" ||
- whats.status === "TIMEOUT" ||
- whats.status === "OPENING"
- );
- });
- if (offlineWhats.length > 0) {
- setConnectionWarning(true);
- } else {
- setConnectionWarning(false);
- }
- }
- }, 2000);
- return () => clearTimeout(delayDebounceFn);
- }, [whatsApps]);
- const fetchChats = async () => {
- try {
- const { data } = await api.get("/chats/", {
- params: { searchParam, pageNumber },
- });
- dispatch({ type: "LOAD_CHATS", payload: data.records });
- } catch (err) {
- toastError(err);
- }
- };
- const handleClickLogout = () => {
- //handleCloseMenu();
- handleLogout();
- };
- return (
- <div onClick={drawerClose}>
- <Can
- role={user.profile}
- perform="dashboard:view"
- yes={() => (
- <ListItemLink
- to="/"
- primary="Dashboard"
- icon={<DashboardOutlinedIcon />}
- />
- )}
- />
- <ListItemLink
- to="/tickets"
- primary={i18n.t("mainDrawer.listItems.tickets")}
- icon={<WhatsAppIcon />}
- />
-
- {showKanban && (
- <ListItemLink
- to="/kanban"
- primary={`Kanban`}
- icon={<TableChartIcon />}
- />
- )}
- <ListItemLink
- to="/quick-messages"
- primary={i18n.t("mainDrawer.listItems.quickMessages")}
- icon={<FlashOnIcon />}
- />
-
- <ListItemLink
- to="/todolist"
- primary={i18n.t("mainDrawer.listItems.tasks")}
- icon={<BorderColorIcon />}
- />
- <ListItemLink
- to="/contacts"
- primary={i18n.t("mainDrawer.listItems.contacts")}
- icon={<ContactPhoneOutlinedIcon />}
- />
- <ListItemLink
- to="/schedules"
- primary={i18n.t("mainDrawer.listItems.schedules")}
- icon={<EventIcon />}
- />
- <ListItemLink
- to="/tags"
- primary={i18n.t("mainDrawer.listItems.tags")}
- icon={<LocalOfferIcon />}
- />
- <ListItemLink
- to="/chats"
- primary={i18n.t("mainDrawer.listItems.chats")}
- icon={
- <Badge color="secondary" variant="dot" invisible={invisible}>
- <ForumIcon />
- </Badge>
- }
- />
- <ListItemLink
- to="/helps"
- primary={i18n.t("mainDrawer.listItems.helps")}
- icon={<HelpOutlineIcon />}
- />
- <Can
- role={user.profile}
- perform="drawer-admin-items:view"
- yes={() => (
- <>
- <Divider />
- <ListSubheader
- hidden={collapsed}
- style={{
- position: "relative",
- fontSize: "17px",
- textAlign: "left",
- paddingLeft: 20
- }}
- inset
- color="inherit">
- {i18n.t("mainDrawer.listItems.administration")}
- </ListSubheader>
-
- {showCampaigns && (
- <>
- <ListItem
- button
- onClick={() => setOpenCampaignSubmenu((prev) => !prev)}
- >
- <ListItemIcon>
- <EventAvailableIcon />
- </ListItemIcon>
- <ListItemText
- primary={i18n.t("mainDrawer.listItems.campaigns")}
- />
- {openCampaignSubmenu ? (
- <ExpandLessIcon />
- ) : (
- <ExpandMoreIcon />
- )}
- </ListItem>
- <Collapse
- style={{ paddingLeft: 15 }}
- in={openCampaignSubmenu}
- timeout="auto"
- unmountOnExit
- >
- <List component="div" disablePadding>
- <ListItem onClick={() => history.push("/campaigns")} button>
- <ListItemIcon>
- <ListIcon />
- </ListItemIcon>
- <ListItemText primary="Listagem" />
- </ListItem>
- <ListItem
- onClick={() => history.push("/contact-lists")}
- button
- >
- <ListItemIcon>
- <PeopleIcon />
- </ListItemIcon>
- <ListItemText primary="Listas de Contatos" />
- </ListItem>
- <ListItem
- onClick={() => history.push("/campaigns-config")}
- button
- >
- <ListItemIcon>
- <SettingsOutlinedIcon />
- </ListItemIcon>
- <ListItemText primary="Configurações" />
- </ListItem>
- </List>
- </Collapse>
- </>
- )}
- {user.super && (
- <ListItemLink
- to="/announcements"
- primary={i18n.t("mainDrawer.listItems.annoucements")}
- icon={<AnnouncementIcon />}
- />
- )}
- {showOpenAi && (
- <ListItemLink
- to="/prompts"
- primary={i18n.t("mainDrawer.listItems.prompts")}
- icon={<AllInclusive />}
- />
- )}
- {showIntegrations && (
- <ListItemLink
- to="/queue-integration"
- primary={i18n.t("mainDrawer.listItems.queueIntegration")}
- icon={<DeviceHubOutlined />}
- />
- )}
- <ListItemLink
- to="/connections"
- primary={i18n.t("mainDrawer.listItems.connections")}
- icon={
- <Badge badgeContent={connectionWarning ? "!" : 0} color="error">
- <SyncAltIcon />
- </Badge>
- }
- />
- <ListItemLink
- to="/files"
- primary={i18n.t("mainDrawer.listItems.files")}
- icon={<AttachFile />}
- />
- <ListItemLink
- to="/queues"
- primary={i18n.t("mainDrawer.listItems.queues")}
- icon={<AccountTreeOutlinedIcon />}
- />
- <ListItemLink
- to="/users"
- primary={i18n.t("mainDrawer.listItems.users")}
- icon={<PeopleAltOutlinedIcon />}
- />
- {showExternalApi && (
- <>
- <ListItemLink
- to="/messages-api"
- primary={i18n.t("mainDrawer.listItems.messagesAPI")}
- icon={<CodeRoundedIcon />}
- />
- </>
- )}
- <ListItemLink
- to="/financeiro"
- primary={i18n.t("mainDrawer.listItems.financeiro")}
- icon={<LocalAtmIcon />}
- />
- <ListItemLink
- to="/settings"
- primary={i18n.t("mainDrawer.listItems.settings")}
- icon={<SettingsOutlinedIcon />}
- />
-
-
- {!collapsed && <React.Fragment>
- <Divider />
- {/*
- // IMAGEM NO MENU
- <Hidden only={['sm', 'xs']}>
- <img style={{ width: "100%", padding: "10px" }} src={logo} alt="image" />
- </Hidden>
- */}
- <Typography style={{ fontSize: "12px", padding: "10px", textAlign: "right", fontWeight: "bold" }}>
- {version}
- </Typography>
- </React.Fragment>
- }
-
- </>
- )}
- />
- </div>
- );
- };
- export default MainListItems;
|