mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 12:49:32 +00:00
feat: add options to handle whatsapp session on frontend
This commit is contained in:
@@ -2,8 +2,6 @@ import { Request, Response } from "express";
|
|||||||
import { getIO } from "../libs/socket";
|
import { getIO } from "../libs/socket";
|
||||||
import { removeWbot } from "../libs/wbot";
|
import { removeWbot } from "../libs/wbot";
|
||||||
import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession";
|
import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession";
|
||||||
import wbotMessageListener from "../services/WbotServices/wbotMessageListener";
|
|
||||||
import wbotMonitor from "../services/WbotServices/wbotMonitor";
|
|
||||||
|
|
||||||
import CreateWhatsAppService from "../services/WhatsappService/CreateWhatsAppService";
|
import CreateWhatsAppService from "../services/WhatsappService/CreateWhatsAppService";
|
||||||
import DeleteWhatsAppService from "../services/WhatsappService/DeleteWhatsAppService";
|
import DeleteWhatsAppService from "../services/WhatsappService/DeleteWhatsAppService";
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
// import Whatsapp from "../models/Whatsapp";
|
|
||||||
// import { getIO } from "../libs/socket";
|
|
||||||
import { getWbot } from "../libs/wbot";
|
import { getWbot } from "../libs/wbot";
|
||||||
import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService";
|
import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService";
|
||||||
import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession";
|
import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession";
|
||||||
// import wbotMonitor from "../services/wbotMonitor";
|
|
||||||
|
|
||||||
const store = async (req: Request, res: Response): Promise<Response> => {
|
const store = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { whatsappId } = req.params;
|
const { whatsappId } = req.params;
|
||||||
@@ -15,6 +12,17 @@ const store = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
return res.status(200).json({ message: "Starting session." });
|
return res.status(200).json({ message: "Starting session." });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const update = async (req: Request, res: Response): Promise<Response> => {
|
||||||
|
const { whatsappId } = req.params;
|
||||||
|
const whatsapp = await ShowWhatsAppService(whatsappId);
|
||||||
|
|
||||||
|
await whatsapp.update({ session: "" });
|
||||||
|
|
||||||
|
StartWhatsAppSession(whatsapp);
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "Starting session." });
|
||||||
|
};
|
||||||
|
|
||||||
const remove = async (req: Request, res: Response): Promise<Response> => {
|
const remove = async (req: Request, res: Response): Promise<Response> => {
|
||||||
const { whatsappId } = req.params;
|
const { whatsappId } = req.params;
|
||||||
const whatsapp = await ShowWhatsAppService(whatsappId);
|
const whatsapp = await ShowWhatsAppService(whatsappId);
|
||||||
@@ -26,4 +34,4 @@ const remove = async (req: Request, res: Response): Promise<Response> => {
|
|||||||
return res.status(200).json({ message: "Session disconnected." });
|
return res.status(200).json({ message: "Session disconnected." });
|
||||||
};
|
};
|
||||||
|
|
||||||
export default { store, remove };
|
export default { store, remove, update };
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Client } from "whatsapp-web.js";
|
|||||||
import { getIO } from "./socket";
|
import { getIO } from "./socket";
|
||||||
import Whatsapp from "../models/Whatsapp";
|
import Whatsapp from "../models/Whatsapp";
|
||||||
import AppError from "../errors/AppError";
|
import AppError from "../errors/AppError";
|
||||||
import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession";
|
|
||||||
|
|
||||||
interface Session extends Client {
|
interface Session extends Client {
|
||||||
id?: number;
|
id?: number;
|
||||||
@@ -22,10 +21,10 @@ export const initWbot = async (whatsapp: Whatsapp): Promise<Session> => {
|
|||||||
sessionCfg = JSON.parse(whatsapp.session);
|
sessionCfg = JSON.parse(whatsapp.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
|
const currentSessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
|
||||||
if (sessionIndex !== -1) {
|
if (currentSessionIndex !== -1) {
|
||||||
sessions[sessionIndex].destroy();
|
sessions[currentSessionIndex].destroy();
|
||||||
sessions.splice(sessionIndex, 1);
|
sessions.splice(currentSessionIndex, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const wbot: Session = new Client({
|
const wbot: Session = new Client({
|
||||||
@@ -37,7 +36,13 @@ export const initWbot = async (whatsapp: Whatsapp): Promise<Session> => {
|
|||||||
wbot.on("qr", async qr => {
|
wbot.on("qr", async qr => {
|
||||||
console.log("Session:", sessionName);
|
console.log("Session:", sessionName);
|
||||||
qrCode.generate(qr, { small: true });
|
qrCode.generate(qr, { small: true });
|
||||||
await whatsapp.update({ qrcode: qr, status: "qrcode" });
|
await whatsapp.update({ qrcode: qr, status: "qrcode", retries: 0 });
|
||||||
|
|
||||||
|
const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
|
||||||
|
if (sessionIndex === -1) {
|
||||||
|
wbot.id = whatsapp.id;
|
||||||
|
sessions.push(wbot);
|
||||||
|
}
|
||||||
|
|
||||||
io.emit("whatsappSession", {
|
io.emit("whatsappSession", {
|
||||||
action: "update",
|
action: "update",
|
||||||
@@ -48,20 +53,14 @@ export const initWbot = async (whatsapp: Whatsapp): Promise<Session> => {
|
|||||||
wbot.on("authenticated", async session => {
|
wbot.on("authenticated", async session => {
|
||||||
console.log("Session:", sessionName, "AUTHENTICATED");
|
console.log("Session:", sessionName, "AUTHENTICATED");
|
||||||
await whatsapp.update({
|
await whatsapp.update({
|
||||||
session: JSON.stringify(session),
|
session: JSON.stringify(session)
|
||||||
status: "authenticated"
|
|
||||||
});
|
|
||||||
|
|
||||||
io.emit("whatsappSession", {
|
|
||||||
action: "update",
|
|
||||||
session: whatsapp
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
wbot.on("auth_failure", async msg => {
|
wbot.on("auth_failure", async msg => {
|
||||||
console.error("Session:", sessionName, "AUTHENTICATION FAILURE", msg);
|
console.error("Session:", sessionName, "AUTHENTICATION FAILURE", msg);
|
||||||
|
|
||||||
if (whatsapp.retries > 2) {
|
if (whatsapp.retries > 1) {
|
||||||
await whatsapp.update({ session: "", retries: 0 });
|
await whatsapp.update({ session: "", retries: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +75,6 @@ export const initWbot = async (whatsapp: Whatsapp): Promise<Session> => {
|
|||||||
session: whatsapp
|
session: whatsapp
|
||||||
});
|
});
|
||||||
|
|
||||||
StartWhatsAppSession(whatsapp);
|
|
||||||
reject(new Error("Error starting whatsapp session."));
|
reject(new Error("Error starting whatsapp session."));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,8 +93,13 @@ export const initWbot = async (whatsapp: Whatsapp): Promise<Session> => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
wbot.sendPresenceAvailable();
|
wbot.sendPresenceAvailable();
|
||||||
wbot.id = whatsapp.id;
|
|
||||||
sessions.push(wbot);
|
const sessionIndex = sessions.findIndex(s => s.id === whatsapp.id);
|
||||||
|
if (sessionIndex === -1) {
|
||||||
|
wbot.id = whatsapp.id;
|
||||||
|
sessions.push(wbot);
|
||||||
|
}
|
||||||
|
|
||||||
resolve(wbot);
|
resolve(wbot);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ whatsappSessionRoutes.post(
|
|||||||
WhatsAppSessionController.store
|
WhatsAppSessionController.store
|
||||||
);
|
);
|
||||||
|
|
||||||
|
whatsappSessionRoutes.put(
|
||||||
|
"/whatsappsession/:whatsappId",
|
||||||
|
isAuth,
|
||||||
|
WhatsAppSessionController.update
|
||||||
|
);
|
||||||
|
|
||||||
whatsappSessionRoutes.delete(
|
whatsappSessionRoutes.delete(
|
||||||
"/whatsappsession/:whatsappId",
|
"/whatsappsession/:whatsappId",
|
||||||
isAuth,
|
isAuth,
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import { initWbot } from "../../libs/wbot";
|
import { initWbot } from "../../libs/wbot";
|
||||||
import Whatsapp from "../../models/Whatsapp";
|
import Whatsapp from "../../models/Whatsapp";
|
||||||
import wbotMessageListener from "./wbotMessageListener";
|
import wbotMessageListener from "./wbotMessageListener";
|
||||||
|
import { getIO } from "../../libs/socket";
|
||||||
import wbotMonitor from "./wbotMonitor";
|
import wbotMonitor from "./wbotMonitor";
|
||||||
|
|
||||||
export const StartWhatsAppSession = async (
|
export const StartWhatsAppSession = async (
|
||||||
whatsapp: Whatsapp
|
whatsapp: Whatsapp
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
|
await whatsapp.update({ status: "OPENING" });
|
||||||
|
|
||||||
|
const io = getIO();
|
||||||
|
io.emit("whatsappSession", {
|
||||||
|
action: "update",
|
||||||
|
session: whatsapp
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const wbot = await initWbot(whatsapp);
|
const wbot = await initWbot(whatsapp);
|
||||||
wbotMessageListener(wbot);
|
wbotMessageListener(wbot);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const wbotMonitor = async (
|
|||||||
wbot.on("disconnected", async reason => {
|
wbot.on("disconnected", async reason => {
|
||||||
console.log("Disconnected session:", sessionName, reason);
|
console.log("Disconnected session:", sessionName, reason);
|
||||||
try {
|
try {
|
||||||
await whatsapp.update({ status: "DISCONNECTED", session: "" });
|
await whatsapp.update({ status: "OPENING", session: "" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ interface Response {
|
|||||||
|
|
||||||
const CreateWhatsAppService = async ({
|
const CreateWhatsAppService = async ({
|
||||||
name,
|
name,
|
||||||
status = "INITIALIZING",
|
status = "OPENING",
|
||||||
isDefault = false
|
isDefault = false
|
||||||
}: Request): Promise<Response> => {
|
}: Request): Promise<Response> => {
|
||||||
const schema = Yup.object().shape({
|
const schema = Yup.object().shape({
|
||||||
|
|||||||
@@ -14,8 +14,19 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
TableHead,
|
TableHead,
|
||||||
Paper,
|
Paper,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Edit, DeleteOutline, CheckCircle } from "@material-ui/icons";
|
import {
|
||||||
|
Edit,
|
||||||
|
CheckCircle,
|
||||||
|
SignalCellularConnectedNoInternet2Bar,
|
||||||
|
SignalCellularConnectedNoInternet0Bar,
|
||||||
|
Schedule,
|
||||||
|
SignalCellular4Bar,
|
||||||
|
CropFree,
|
||||||
|
DeleteOutline,
|
||||||
|
} from "@material-ui/icons";
|
||||||
|
|
||||||
import MainContainer from "../../components/MainContainer";
|
import MainContainer from "../../components/MainContainer";
|
||||||
import MainHeader from "../../components/MainHeader";
|
import MainHeader from "../../components/MainHeader";
|
||||||
@@ -26,6 +37,7 @@ import TableRowSkeleton from "../../components/TableRowSkeleton";
|
|||||||
import api from "../../services/api";
|
import api from "../../services/api";
|
||||||
import WhatsAppModal from "../../components/WhatsAppModal";
|
import WhatsAppModal from "../../components/WhatsAppModal";
|
||||||
import ConfirmationModal from "../../components/ConfirmationModal";
|
import ConfirmationModal from "../../components/ConfirmationModal";
|
||||||
|
import ButtonWithSpinner from "../../components/ButtonWithSpinner";
|
||||||
import QrcodeModal from "../../components/QrcodeModal";
|
import QrcodeModal from "../../components/QrcodeModal";
|
||||||
import { i18n } from "../../translate/i18n";
|
import { i18n } from "../../translate/i18n";
|
||||||
|
|
||||||
@@ -56,6 +68,7 @@ const reducer = (state, action) => {
|
|||||||
state[whatsAppIndex].status = whatsApp.status;
|
state[whatsAppIndex].status = whatsApp.status;
|
||||||
state[whatsAppIndex].updatedAt = whatsApp.updatedAt;
|
state[whatsAppIndex].updatedAt = whatsApp.updatedAt;
|
||||||
state[whatsAppIndex].qrcode = whatsApp.qrcode;
|
state[whatsAppIndex].qrcode = whatsApp.qrcode;
|
||||||
|
state[whatsAppIndex].retries = whatsApp.retries;
|
||||||
return [...state];
|
return [...state];
|
||||||
} else {
|
} else {
|
||||||
return [...state];
|
return [...state];
|
||||||
@@ -84,8 +97,47 @@ const useStyles = makeStyles(theme => ({
|
|||||||
overflowY: "scroll",
|
overflowY: "scroll",
|
||||||
...theme.scrollbarStyles,
|
...theme.scrollbarStyles,
|
||||||
},
|
},
|
||||||
|
customTableCell: {
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: "#f5f5f9",
|
||||||
|
color: "rgba(0, 0, 0, 0.87)",
|
||||||
|
fontSize: theme.typography.pxToRem(14),
|
||||||
|
border: "1px solid #dadde9",
|
||||||
|
maxWidth: 450,
|
||||||
|
},
|
||||||
|
tooltipPopper: {
|
||||||
|
textAlign: "center",
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const CustomToolTip = ({ title, content, children }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
arrow
|
||||||
|
classes={{
|
||||||
|
tooltip: classes.tooltip,
|
||||||
|
popper: classes.tooltipPopper,
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
<React.Fragment>
|
||||||
|
<Typography gutterBottom color="inherit">
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
{content && <Typography>{content}</Typography>}
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Connections = () => {
|
const Connections = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
@@ -94,15 +146,28 @@ const Connections = () => {
|
|||||||
const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false);
|
const [whatsAppModalOpen, setWhatsAppModalOpen] = useState(false);
|
||||||
const [qrModalOpen, setQrModalOpen] = useState(false);
|
const [qrModalOpen, setQrModalOpen] = useState(false);
|
||||||
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null);
|
const [selectedWhatsApp, setSelectedWhatsApp] = useState(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
|
const [confirmModalOpen, setConfirmModalOpen] = useState(false);
|
||||||
const [deletingWhatsApp, setDeletingWhatsApp] = useState(null);
|
const confirmationModalInitialState = {
|
||||||
|
action: "",
|
||||||
|
title: "",
|
||||||
|
message: "",
|
||||||
|
whatsAppId: "",
|
||||||
|
open: false,
|
||||||
|
};
|
||||||
|
const [confirmModalInfo, setConfirmModalInfo] = useState(
|
||||||
|
confirmationModalInitialState
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
const fetchSession = async () => {
|
const fetchSession = async () => {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get("/whatsapp/");
|
const { data } = await api.get("/whatsapp/");
|
||||||
dispatch({ type: "LOAD_WHATSAPPS", payload: data });
|
dispatch({ type: "LOAD_WHATSAPPS", payload: data });
|
||||||
|
setLoading(false);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
setLoading(false);
|
||||||
const errorMsg = err.response?.data?.error;
|
const errorMsg = err.response?.data?.error;
|
||||||
if (errorMsg) {
|
if (errorMsg) {
|
||||||
if (i18n.exists(`backendErrors.${errorMsg}`)) {
|
if (i18n.exists(`backendErrors.${errorMsg}`)) {
|
||||||
@@ -144,19 +209,27 @@ const Connections = () => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const handleDisconnectSession = async whatsAppId => {
|
const handleStartWhatsAppSession = async whatsAppId => {
|
||||||
// try {
|
try {
|
||||||
// await api.put(`/whatsapp/whatsApp/${whatsAppId}`, {
|
await api.post(`/whatsappsession/${whatsAppId}`);
|
||||||
// whatsApp: "",
|
} catch (err) {
|
||||||
// status: "pending",
|
console.log(err);
|
||||||
// });
|
if (err.response && err.response.data && err.response.data.error) {
|
||||||
// } catch (err) {
|
toast.error(err.response.data.error);
|
||||||
// console.log(err);
|
}
|
||||||
// if (err.response && err.response.data && err.response.data.error) {
|
}
|
||||||
// toast.error(err.response.data.error);
|
};
|
||||||
// }
|
|
||||||
// }
|
const handleRequestNewQrCode = async whatsAppId => {
|
||||||
// };
|
try {
|
||||||
|
await api.put(`/whatsappsession/${whatsAppId}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
if (err.response && err.response.data && err.response.data.error) {
|
||||||
|
toast.error(err.response.data.error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleOpenWhatsAppModal = () => {
|
const handleOpenWhatsAppModal = () => {
|
||||||
setSelectedWhatsApp(null);
|
setSelectedWhatsApp(null);
|
||||||
@@ -183,51 +256,187 @@ const Connections = () => {
|
|||||||
setWhatsAppModalOpen(true);
|
setWhatsAppModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteWhatsApp = async whatsAppId => {
|
const renderActionButtons = whatsApp => {
|
||||||
try {
|
return (
|
||||||
await api.delete(`/whatsapp/${whatsAppId}`);
|
<>
|
||||||
toast.success(i18n.t("connections.toasts.deleted"));
|
{whatsApp.status === "qrcode" && (
|
||||||
} catch (err) {
|
<Button
|
||||||
const errorMsg = err.response?.data?.error;
|
size="small"
|
||||||
if (errorMsg) {
|
variant="contained"
|
||||||
if (i18n.exists(`backendErrors.${errorMsg}`)) {
|
color="primary"
|
||||||
toast.error(i18n.t(`backendErrors.${errorMsg}`));
|
onClick={() => handleOpenQrModal(whatsApp)}
|
||||||
|
>
|
||||||
|
{i18n.t("connections.buttons.qrcode")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{whatsApp.status === "DISCONNECTED" && (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => handleStartWhatsAppSession(whatsApp.id)}
|
||||||
|
>
|
||||||
|
{i18n.t("connections.buttons.tryAgain")}
|
||||||
|
</Button>{" "}
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => handleRequestNewQrCode(whatsApp.id)}
|
||||||
|
>
|
||||||
|
{i18n.t("connections.buttons.newQr")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{(whatsApp.status === "CONNECTED" ||
|
||||||
|
whatsApp.status === "PAIRING" ||
|
||||||
|
whatsApp.status === "TIMEOUT") && (
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
handleOpenConfirmationModal("disconnect", whatsApp.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18n.t("connections.buttons.disconnect")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{whatsApp.status === "OPENING" && (
|
||||||
|
<ButtonWithSpinner
|
||||||
|
size="small"
|
||||||
|
variant="outlined"
|
||||||
|
loading={true}
|
||||||
|
color="default"
|
||||||
|
>
|
||||||
|
{i18n.t("connections.buttons.connecting")}
|
||||||
|
</ButtonWithSpinner>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderStatusToolTips = whatsApp => {
|
||||||
|
return (
|
||||||
|
<div className={classes.customTableCell}>
|
||||||
|
{whatsApp.status === "DISCONNECTED" && (
|
||||||
|
<CustomToolTip
|
||||||
|
title={i18n.t("connections.toolTips.disconnected.title")}
|
||||||
|
content={i18n.t("connections.toolTips.disconnected.content")}
|
||||||
|
>
|
||||||
|
<SignalCellularConnectedNoInternet0Bar color="secondary" />
|
||||||
|
</CustomToolTip>
|
||||||
|
)}
|
||||||
|
{whatsApp.status === "OPENING" && (
|
||||||
|
<CustomToolTip title={i18n.t("connections.toolTips.opening.title")}>
|
||||||
|
<Schedule color="disabled" />
|
||||||
|
</CustomToolTip>
|
||||||
|
)}
|
||||||
|
{whatsApp.status === "qrcode" && (
|
||||||
|
<CustomToolTip
|
||||||
|
title={i18n.t("connections.toolTips.qrcode.title")}
|
||||||
|
content={i18n.t("connections.toolTips.qrcode.content")}
|
||||||
|
>
|
||||||
|
<CropFree />
|
||||||
|
</CustomToolTip>
|
||||||
|
)}
|
||||||
|
{whatsApp.status === "CONNECTED" && (
|
||||||
|
<CustomToolTip title={i18n.t("connections.toolTips.connected.title")}>
|
||||||
|
<SignalCellular4Bar style={{ color: green[500] }} />
|
||||||
|
</CustomToolTip>
|
||||||
|
)}
|
||||||
|
{(whatsApp.status === "TIMEOUT" || whatsApp.status === "PAIRING") && (
|
||||||
|
<CustomToolTip
|
||||||
|
title={i18n.t("connections.toolTips.timeout.title")}
|
||||||
|
content={i18n.t("connections.toolTips.timeout.content")}
|
||||||
|
>
|
||||||
|
<SignalCellularConnectedNoInternet2Bar color="secondary" />
|
||||||
|
</CustomToolTip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenConfirmationModal = (action, whatsAppId) => {
|
||||||
|
if (action === "disconnect") {
|
||||||
|
setConfirmModalInfo({
|
||||||
|
action: action,
|
||||||
|
title: i18n.t("connections.confirmationModal.disconnectTitle"),
|
||||||
|
message: i18n.t("connections.confirmationModal.disconnectMessage"),
|
||||||
|
whatsAppId: whatsAppId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action === "delete") {
|
||||||
|
setConfirmModalInfo({
|
||||||
|
action: action,
|
||||||
|
title: i18n.t("connections.confirmationModal.deleteTitle"),
|
||||||
|
message: i18n.t("connections.confirmationModal.deleteMessage"),
|
||||||
|
whatsAppId: whatsAppId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setConfirmModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmitConfirmationModal = async () => {
|
||||||
|
if (confirmModalInfo.action === "disconnect") {
|
||||||
|
try {
|
||||||
|
await api.delete(`/whatsappsession/${confirmModalInfo.whatsAppId}`);
|
||||||
|
} catch (err) {
|
||||||
|
const errorMsg = err.response?.data?.error;
|
||||||
|
if (errorMsg) {
|
||||||
|
if (i18n.exists(`backendErrors.${errorMsg}`)) {
|
||||||
|
toast.error(i18n.t(`backendErrors.${errorMsg}`));
|
||||||
|
} else {
|
||||||
|
toast.error(err.response.data.error);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toast.error(err.response.data.error);
|
toast.error("Unknown error");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
toast.error("Unknown error");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setDeletingWhatsApp(null);
|
|
||||||
|
if (confirmModalInfo.action === "delete") {
|
||||||
|
try {
|
||||||
|
await api.delete(`/whatsapp/${confirmModalInfo.whatsAppId}`);
|
||||||
|
toast.success(i18n.t("connections.toasts.deleted"));
|
||||||
|
} catch (err) {
|
||||||
|
const errorMsg = err.response?.data?.error;
|
||||||
|
if (errorMsg) {
|
||||||
|
if (i18n.exists(`backendErrors.${errorMsg}`)) {
|
||||||
|
toast.error(i18n.t(`backendErrors.${errorMsg}`));
|
||||||
|
} else {
|
||||||
|
toast.error(err.response.data.error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast.error("Unknown error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfirmModalInfo(confirmationModalInitialState);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
title={
|
title={confirmModalInfo.title}
|
||||||
deletingWhatsApp &&
|
|
||||||
`${i18n.t("connections.confirmationModal.deleteTitle")} ${
|
|
||||||
deletingWhatsApp.name
|
|
||||||
}?`
|
|
||||||
}
|
|
||||||
open={confirmModalOpen}
|
open={confirmModalOpen}
|
||||||
setOpen={setConfirmModalOpen}
|
setOpen={setConfirmModalOpen}
|
||||||
onConfirm={() => handleDeleteWhatsApp(deletingWhatsApp.id)}
|
onConfirm={handleSubmitConfirmationModal}
|
||||||
>
|
>
|
||||||
{i18n.t("connections.confirmationModal.deleteMessage")}
|
{confirmModalInfo.message}
|
||||||
</ConfirmationModal>
|
</ConfirmationModal>
|
||||||
<QrcodeModal
|
<QrcodeModal
|
||||||
open={qrModalOpen}
|
open={qrModalOpen}
|
||||||
onClose={handleCloseQrModal}
|
onClose={handleCloseQrModal}
|
||||||
whatsAppId={
|
whatsAppId={!whatsAppModalOpen && selectedWhatsApp?.id}
|
||||||
selectedWhatsApp && !whatsAppModalOpen && selectedWhatsApp.id
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<WhatsAppModal
|
<WhatsAppModal
|
||||||
open={whatsAppModalOpen}
|
open={whatsAppModalOpen}
|
||||||
onClose={handleCloseWhatsAppModal}
|
onClose={handleCloseWhatsAppModal}
|
||||||
whatsAppId={selectedWhatsApp && !qrModalOpen && selectedWhatsApp.id}
|
whatsAppId={!qrModalOpen && selectedWhatsApp?.id}
|
||||||
/>
|
/>
|
||||||
<MainHeader>
|
<MainHeader>
|
||||||
<Title>{i18n.t("connections.title")}</Title>
|
<Title>{i18n.t("connections.title")}</Title>
|
||||||
@@ -251,6 +460,9 @@ const Connections = () => {
|
|||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.status")}
|
{i18n.t("connections.table.status")}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
{i18n.t("connections.table.session")}
|
||||||
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{i18n.t("connections.table.lastUpdate")}
|
{i18n.t("connections.table.lastUpdate")}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -263,35 +475,28 @@ const Connections = () => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{false ? (
|
{loading ? (
|
||||||
<TableRowSkeleton />
|
<TableRowSkeleton />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{whatsApps &&
|
{whatsApps?.length > 0 &&
|
||||||
whatsApps.length > 0 &&
|
whatsApps.map(whatsApp => (
|
||||||
whatsApps.map((whatsApp, index) => (
|
|
||||||
<TableRow key={whatsApp.id}>
|
<TableRow key={whatsApp.id}>
|
||||||
<TableCell align="center">{whatsApp.name}</TableCell>
|
<TableCell align="center">{whatsApp.name}</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{whatsApp.status === "qrcode" ? (
|
{renderStatusToolTips(whatsApp)}
|
||||||
<Button
|
</TableCell>
|
||||||
size="small"
|
<TableCell align="center">
|
||||||
variant="contained"
|
{renderActionButtons(whatsApp)}
|
||||||
color="primary"
|
|
||||||
onClick={() => handleOpenQrModal(whatsApp)}
|
|
||||||
>
|
|
||||||
QR CODE
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
whatsApp.status
|
|
||||||
)}
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")}
|
{format(parseISO(whatsApp.updatedAt), "dd/MM/yy HH:mm")}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{whatsApp.isDefault && (
|
{whatsApp.isDefault && (
|
||||||
<CheckCircle style={{ color: green[500] }} />
|
<div className={classes.customTableCell}>
|
||||||
|
<CheckCircle style={{ color: green[500] }} />
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
@@ -305,8 +510,7 @@ const Connections = () => {
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
setConfirmModalOpen(true);
|
handleOpenConfirmationModal("delete", whatsApp.id);
|
||||||
setDeletingWhatsApp(whatsApp);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DeleteOutline />
|
<DeleteOutline />
|
||||||
|
|||||||
@@ -48,9 +48,40 @@ const messages = {
|
|||||||
confirmationModal: {
|
confirmationModal: {
|
||||||
deleteTitle: "Delete",
|
deleteTitle: "Delete",
|
||||||
deleteMessage: "Are you sure? It cannot be reverted.",
|
deleteMessage: "Are you sure? It cannot be reverted.",
|
||||||
|
disconnectTitle: "Disconnect",
|
||||||
|
disconnectMessage:
|
||||||
|
"You will need to read QR Code again to start receiving messages.",
|
||||||
},
|
},
|
||||||
buttons: {
|
buttons: {
|
||||||
add: "Add WhatsApp",
|
add: "Add WhatsApp",
|
||||||
|
disconnect: "Disconnect",
|
||||||
|
tryAgain: "Try Again",
|
||||||
|
qrcode: "QR CODE",
|
||||||
|
newQr: "New QR CODE",
|
||||||
|
connecting: "Connectiing",
|
||||||
|
},
|
||||||
|
toolTips: {
|
||||||
|
disconnected: {
|
||||||
|
title: "Failed to start WhatsApp session",
|
||||||
|
content:
|
||||||
|
"Make sure your cell phone is connected to the internet and try again, or request a new QR Code",
|
||||||
|
},
|
||||||
|
opening: {
|
||||||
|
title: "Starting session...",
|
||||||
|
},
|
||||||
|
qrcode: {
|
||||||
|
title: "Waiting for QR Code read",
|
||||||
|
content:
|
||||||
|
"Click on 'QR CODE' button and read the QR Code with your cell phone to start session",
|
||||||
|
},
|
||||||
|
connected: {
|
||||||
|
title: "Connection established",
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
title: "Connection with cell phone has been lost",
|
||||||
|
content:
|
||||||
|
"Make sure your cell phone is connected to the internet and WhatsApp is open, or click on 'Disconnect' button to get a new QRcode",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
name: "Name",
|
name: "Name",
|
||||||
@@ -58,6 +89,7 @@ const messages = {
|
|||||||
lastUpdate: "Last Update",
|
lastUpdate: "Last Update",
|
||||||
default: "Default",
|
default: "Default",
|
||||||
actions: "Actions",
|
actions: "Actions",
|
||||||
|
session: "Session",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
whatsappModal: {
|
whatsappModal: {
|
||||||
|
|||||||
@@ -50,9 +50,40 @@ const messages = {
|
|||||||
confirmationModal: {
|
confirmationModal: {
|
||||||
deleteTitle: "Borrar",
|
deleteTitle: "Borrar",
|
||||||
deleteMessage: "¿Estás seguro? Este proceso no puede ser revertido.",
|
deleteMessage: "¿Estás seguro? Este proceso no puede ser revertido.",
|
||||||
|
disconnectTitle: "Desconectar",
|
||||||
|
disconnectMessage:
|
||||||
|
"Você precisará ler o QR code novamente para começar a receber mensagens.",
|
||||||
},
|
},
|
||||||
buttons: {
|
buttons: {
|
||||||
add: "Agrega WhatsApp",
|
add: "Agrega WhatsApp",
|
||||||
|
disconnect: "Desconectar",
|
||||||
|
tryAgain: "Inténtalo de nuevo",
|
||||||
|
qrcode: "QR CODE",
|
||||||
|
newQr: "Nuevo QR CODE",
|
||||||
|
connecting: "Conectando",
|
||||||
|
},
|
||||||
|
toolTips: {
|
||||||
|
disconnected: {
|
||||||
|
title: "No se pudo iniciar la sesión de WhatsApp",
|
||||||
|
content:
|
||||||
|
"Asegúrese de que su teléfono celular esté conectado a Internet y vuelva a intentarlo o solicite un nuevo código QR",
|
||||||
|
},
|
||||||
|
opening: {
|
||||||
|
title: "Iniciando sesión ...",
|
||||||
|
},
|
||||||
|
qrcode: {
|
||||||
|
title: "Esperando la lectura del código QR",
|
||||||
|
content:
|
||||||
|
"Haga clic en el botón 'CÓDIGO QR' y lea el Código QR con su teléfono celular para iniciar la sesión",
|
||||||
|
},
|
||||||
|
connected: {
|
||||||
|
title: "Conexión establecida",
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
title: "Se perdió la conexión con el teléfono celular",
|
||||||
|
content:
|
||||||
|
"Asegúrese de que su teléfono celular esté conectado a Internet y que WhatsApp esté abierto, o haga clic en el botón 'Desconectar' para obtener un nuevo código QR",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
name: "Nombre",
|
name: "Nombre",
|
||||||
@@ -60,6 +91,7 @@ const messages = {
|
|||||||
lastUpdate: "Última Actualización",
|
lastUpdate: "Última Actualización",
|
||||||
default: "Por Defecto",
|
default: "Por Defecto",
|
||||||
actions: "Acciones",
|
actions: "Acciones",
|
||||||
|
session: "Sesión",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
whatsappModal: {
|
whatsappModal: {
|
||||||
|
|||||||
@@ -48,9 +48,40 @@ const messages = {
|
|||||||
confirmationModal: {
|
confirmationModal: {
|
||||||
deleteTitle: "Deletar",
|
deleteTitle: "Deletar",
|
||||||
deleteMessage: "Você tem certeza? Essa ação não pode ser revertida.",
|
deleteMessage: "Você tem certeza? Essa ação não pode ser revertida.",
|
||||||
|
disconnectTitle: "Desconectar",
|
||||||
|
disconnectMessage:
|
||||||
|
"Você precisará ler o código QR novamente para começar a receber mensagens.",
|
||||||
},
|
},
|
||||||
buttons: {
|
buttons: {
|
||||||
add: "Adicionar WhatsApp",
|
add: "Adicionar WhatsApp",
|
||||||
|
disconnect: "desconectar",
|
||||||
|
tryAgain: "Tentar novamente",
|
||||||
|
qrcode: "QR CODE",
|
||||||
|
newQr: "Novo QR CODE",
|
||||||
|
connecting: "Conectando",
|
||||||
|
},
|
||||||
|
toolTips: {
|
||||||
|
disconnected: {
|
||||||
|
title: "Falha ao iniciar sessão do WhatsApp",
|
||||||
|
content:
|
||||||
|
"Certifique-se de que seu celular esteja conectado à internet e tente novamente, ou solicite um novo QR Code",
|
||||||
|
},
|
||||||
|
opening: {
|
||||||
|
title: "Iniciando a sessão...",
|
||||||
|
},
|
||||||
|
qrcode: {
|
||||||
|
title: "Esperando leitura do QR Code",
|
||||||
|
content:
|
||||||
|
"Clique no botão 'QR CODE' e leia o QR Code com o seu celular para iniciar a sessão",
|
||||||
|
},
|
||||||
|
connected: {
|
||||||
|
title: "Conexão estabelecida!",
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
title: "A conexão com o celular foi perdida",
|
||||||
|
content:
|
||||||
|
"Certifique-se de que seu celular esteja conectado à internet e o WhatsApp esteja aberto, ou clique no botão 'Desconectar' para obter um novo QR Code",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
name: "Nome",
|
name: "Nome",
|
||||||
@@ -58,6 +89,7 @@ const messages = {
|
|||||||
lastUpdate: "Última atualização",
|
lastUpdate: "Última atualização",
|
||||||
default: "Padrão",
|
default: "Padrão",
|
||||||
actions: "Ações",
|
actions: "Ações",
|
||||||
|
session: "Sessão",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
whatsappModal: {
|
whatsappModal: {
|
||||||
|
|||||||
Reference in New Issue
Block a user