From f423dd60bc73d61c0d44fe70657244f1e2b61f85 Mon Sep 17 00:00:00 2001 From: canove Date: Sat, 5 Sep 2020 17:43:09 -0300 Subject: [PATCH] feat: continue session handle in frontend --- .../controllers/WhatsAppSessionController.js | 2 +- frontend/src/components/QrcodeModal/index.js | 74 ++++---- frontend/src/components/SessionModal/index.js | 168 ++++++++++++++++++ frontend/src/pages/Connection/index.js | 79 ++++---- frontend/src/pages/Users/index.js | 35 ++-- 5 files changed, 271 insertions(+), 87 deletions(-) create mode 100644 frontend/src/components/SessionModal/index.js diff --git a/backend/src/controllers/WhatsAppSessionController.js b/backend/src/controllers/WhatsAppSessionController.js index 94937ca..2eca860 100644 --- a/backend/src/controllers/WhatsAppSessionController.js +++ b/backend/src/controllers/WhatsAppSessionController.js @@ -30,7 +30,7 @@ exports.store = async (req, res) => { session: dbSession, }); - return res.status(200).json({ message: "Session created sucessfully." }); + return res.status(200).json(dbSession); }; exports.show = async (req, res) => { diff --git a/frontend/src/components/QrcodeModal/index.js b/frontend/src/components/QrcodeModal/index.js index de80025..09a4d39 100644 --- a/frontend/src/components/QrcodeModal/index.js +++ b/frontend/src/components/QrcodeModal/index.js @@ -1,37 +1,37 @@ -import React from "react"; -import QRCode from "qrcode.react"; - -import { - Dialog, - DialogContent, - Paper, - Typography, - DialogTitle, -} from "@material-ui/core"; -import { i18n } from "../../translate/i18n"; - -const QrcodeModal = ({ open, onClose, session }) => { - if (session) { - return ( - - {session.name} - - - - {i18n.t("qrCode.message")} - - {session.qrcode ? ( - - ) : ( - loading - )} - - - - ); - } else { - return null; - } -}; - -export default QrcodeModal; +import React from "react"; +import QRCode from "qrcode.react"; + +import { + Dialog, + DialogContent, + Paper, + Typography, + DialogTitle, +} from "@material-ui/core"; +import { i18n } from "../../translate/i18n"; + +const QrcodeModal = ({ open, onClose, session }) => { + if (session) { + return ( + + {session.name} + + + + {i18n.t("qrCode.message")} + + {session.qrcode ? ( + + ) : ( + Waiting for QR Code + )} + + + + ); + } else { + return null; + } +}; + +export default QrcodeModal; diff --git a/frontend/src/components/SessionModal/index.js b/frontend/src/components/SessionModal/index.js new file mode 100644 index 0000000..fc7c0a8 --- /dev/null +++ b/frontend/src/components/SessionModal/index.js @@ -0,0 +1,168 @@ +import React, { useState, useEffect } from "react"; +import QRCode from "qrcode.react"; +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; + +import { + Dialog, + DialogContent, + Paper, + Typography, + DialogTitle, + Button, + DialogActions, + CircularProgress, + TextField, +} from "@material-ui/core"; + +import { i18n } from "../../translate/i18n"; +import api from "../../services/api"; + +const useStyles = makeStyles(theme => ({ + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, +})); + +const SessionSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), +}); + +const SessionModal = ({ open, onClose, sessionId }) => { + const classes = useStyles(); + const initialState = { + name: "", + status: "", + }; + const [session, setSession] = useState(initialState); + + useEffect(() => { + const fetchSession = async () => { + if (!sessionId) return; + + try { + const { data } = await api.get(`whatsapp/session/${sessionId}`); + setSession(data); + } catch (err) { + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } + } + }; + fetchSession(); + }, [sessionId]); + + const handleSaveSession = async values => { + try { + if (sessionId) { + await api.put(`/whatsapp/session/${sessionId}`, values); + } else { + await api.post("/whatsapp/session", values); + } + toast.success("Session created!"); + } catch (err) { + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } + } + handleClose(); + }; + + const handleClose = () => { + onClose(); + setSession(initialState); + }; + + return ( + + Edit Session + { + setTimeout(() => { + handleSaveSession(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ touched, errors, isSubmitting }) => ( +
+ + + + + + + + +
+ )} +
+
+ ); +}; + +export default SessionModal; diff --git a/frontend/src/pages/Connection/index.js b/frontend/src/pages/Connection/index.js index e3eb62d..c8e573c 100644 --- a/frontend/src/pages/Connection/index.js +++ b/frontend/src/pages/Connection/index.js @@ -23,7 +23,8 @@ import Title from "../../components/Title"; import TableRowSkeleton from "../../components/TableRowSkeleton"; import api from "../../services/api"; -import QrcodeModal from "../../components/QrcodeModal"; +import SessionModal from "../../components/SessionModal"; +import ConfirmationModal from "../../components/ConfirmationModal"; const reducer = (state, action) => { if (action.type === "LOAD_SESSIONS") { @@ -47,8 +48,6 @@ const reducer = (state, action) => { if (action.type === "DELETE_SESSION") { const sessionId = action.payload; - console.log("cai aqui", sessionId); - const sessionIndex = state.findIndex(s => s.id === sessionId); if (sessionIndex !== -1) { state.splice(sessionIndex, 1); @@ -98,8 +97,11 @@ const WhatsAuth = () => { const [sessions, dispatch] = useReducer(reducer, []); - const [qrModalOpen, setQrModalOpen] = useState(false); + const [sessionModalOpen, setSessionModalOpen] = useState(false); + // const [sessionModalOpen, setSessionModalOpen] = useState(false); const [selectedSession, setSelectedSession] = useState(null); + const [confirmModalOpen, setConfirmModalOpen] = useState(false); + // const [deletingSession, setDeletingSession] = useState(null); useEffect(() => { const fetchSession = async () => { @@ -150,46 +152,55 @@ const WhatsAuth = () => { } }; - console.log(sessions); - - const handleOpenQrMoral = session => { - setQrModalOpen(true); - setSelectedSession(session); + const handleOpenSessionModal = session => { + setSelectedSession(null); + setSessionModalOpen(true); }; - const handleCloseQrModal = () => { - setQrModalOpen(false); + const handleCloseSessionModal = () => { + setSessionModalOpen(false); setSelectedSession(null); }; + const handleEditUser = session => { + setSelectedSession(session); + setSessionModalOpen(true); + }; + + const handleDeleteSession = async sessionId => { + try { + await api.delete(`/whatsapp/session/${sessionId}`); + } catch (err) { + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } + } + }; + return ( - - {/* handleDeleteSession(selectedSession.id)} > - Qr Code - - - - - - */} + Are you sure? It cannot be reverted. + + Connections @@ -216,7 +227,7 @@ const WhatsAuth = () => { <> {sessions && sessions.length > 0 && - sessions.map(session => ( + sessions.map((session, index) => ( {session.name} @@ -225,7 +236,7 @@ const WhatsAuth = () => { size="small" variant="contained" color="primary" - onClick={() => handleOpenQrMoral(session)} + onClick={() => handleEditUser(session)} > QR CODE @@ -247,8 +258,8 @@ const WhatsAuth = () => { { - // setConfirmModalOpen(true); - // setDeletingUser(user); + setConfirmModalOpen(true); + setSelectedSession(session); }} > diff --git a/frontend/src/pages/Users/index.js b/frontend/src/pages/Users/index.js index de554f8..0b5a615 100644 --- a/frontend/src/pages/Users/index.js +++ b/frontend/src/pages/Users/index.js @@ -1,5 +1,5 @@ import React, { useState, useEffect, useReducer } from "react"; - +import { toast } from "react-toastify"; import openSocket from "socket.io-client"; import { makeStyles } from "@material-ui/core/styles"; @@ -87,10 +87,9 @@ const Users = () => { const [loading, setLoading] = useState(false); const [pageNumber, setPageNumber] = useState(1); const [hasMore, setHasMore] = useState(false); - const [selectedUserId, setSelectedUserId] = useState(null); + const [selectedUser, setSelectedUser] = useState(null); const [userModalOpen, setUserModalOpen] = useState(false); const [confirmModalOpen, setConfirmModalOpen] = useState(false); - const [deletingUser, setDeletingUser] = useState(null); const [searchParam, setSearchParam] = useState(""); const [users, dispatch] = useReducer(reducer, []); @@ -112,7 +111,9 @@ const Users = () => { setLoading(false); } catch (err) { console.log(err); - alert(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; fetchUsers(); @@ -138,12 +139,12 @@ const Users = () => { }, []); const handleOpenUserModal = () => { - setSelectedUserId(null); + setSelectedUser(null); setUserModalOpen(true); }; const handleCloseUserModal = () => { - setSelectedUserId(null); + setSelectedUser(null); setUserModalOpen(false); }; @@ -151,18 +152,22 @@ const Users = () => { setSearchParam(event.target.value.toLowerCase()); }; - const handleEditUser = userId => { - setSelectedUserId(userId); + const handleEditUser = user => { + setSelectedUser(user); setUserModalOpen(true); }; const handleDeleteUser = async userId => { try { await api.delete(`/users/${userId}`); + toast.success("User deleted!"); } catch (err) { - alert(err); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } - setDeletingUser(null); + setSelectedUser(null); setSearchParam(""); setPageNumber(1); }; @@ -182,10 +187,10 @@ const Users = () => { return ( handleDeleteUser(deletingUser.id)} + onConfirm={e => handleDeleteUser(selectedUser.id)} > Are you sure? It canoot be reverted. @@ -193,7 +198,7 @@ const Users = () => { open={userModalOpen} onClose={handleCloseUserModal} aria-labelledby="form-dialog-title" - userId={selectedUserId} + userId={selectedUser && selectedUser.id} /> Usuários @@ -247,7 +252,7 @@ const Users = () => { handleEditUser(user.id)} + onClick={() => handleEditUser(user)} > @@ -256,7 +261,7 @@ const Users = () => { size="small" onClick={e => { setConfirmModalOpen(true); - setDeletingUser(user); + setSelectedUser(user); }} >