From f7fe3286b84919dd0493b9fc4b1733180fdbd538 Mon Sep 17 00:00:00 2001 From: canove Date: Fri, 4 Sep 2020 17:09:39 -0300 Subject: [PATCH] improvement: better error handling --- backend/src/controllers/ContactController.js | 51 ++-- .../ImportPhoneContactsController.js | 11 +- backend/src/controllers/MessageController.js | 7 +- backend/src/controllers/SessionController.js | 2 +- backend/src/controllers/SettingController.js | 2 +- backend/src/controllers/TicketController.js | 4 +- backend/src/controllers/UserController.js | 23 +- .../controllers/WhatsAppSessionController.js | 2 +- .../seeds/20200824172424-create-contacts.js | 48 ---- .../seeds/20200824173654-create-tickets.js | 261 ------------------ .../seeds/20200824174824-create-messages.js | 148 ---------- frontend/src/components/ContactModal/index.js | 18 +- frontend/src/components/MessageInput/index.js | 13 +- frontend/src/components/MessagesList/index.js | 11 +- .../src/components/NewTicketModal/index.js | 24 +- frontend/src/components/SessionInfo/index.js | 4 + frontend/src/components/UserModal/index.js | 22 +- frontend/src/context/Auth/useAuth.js | 10 +- frontend/src/hooks/useTickets/index.js | 4 + frontend/src/pages/Connection/index.js | 4 + frontend/src/pages/Contacts/index.js | 13 +- frontend/src/pages/Settings/index.js | 11 +- frontend/src/pages/Signup/index.js | 5 +- 23 files changed, 166 insertions(+), 532 deletions(-) delete mode 100644 backend/src/database/seeds/20200824172424-create-contacts.js delete mode 100644 backend/src/database/seeds/20200824173654-create-tickets.js delete mode 100644 backend/src/database/seeds/20200824174824-create-messages.js diff --git a/backend/src/controllers/ContactController.js b/backend/src/controllers/ContactController.js index 3ee343b..2b0072f 100644 --- a/backend/src/controllers/ContactController.js +++ b/backend/src/controllers/ContactController.js @@ -43,23 +43,22 @@ exports.store = async (req, res) => { const io = getIO(); const newContact = req.body; - let isValidNumber; - try { - isValidNumber = await wbot.isRegisteredUser(`${newContact.number}@c.us`); + const isValidNumber = await wbot.isRegisteredUser( + `${newContact.number}@c.us` + ); + if (!isValidNumber) { + return res + .status(400) + .json({ error: "The suplied number is not a valid Whatsapp number" }); + } } catch (err) { - console.log("Could not check whatsapp contact. Is session details valid?"); + console.log(err); return res.status(500).json({ error: "Could not check whatsapp contact. Check connection page.", }); } - if (!isValidNumber) { - return res - .status(400) - .json({ error: "The suplied number is not a valid Whatsapp number" }); - } - const profilePicUrl = await wbot.getProfilePicUrl( `${newContact.number}@c.us` ); @@ -76,26 +75,22 @@ exports.store = async (req, res) => { contact: contact, }); - res.status(200).json(contact); + return res.status(200).json(contact); }; exports.show = async (req, res) => { const { contactId } = req.params; - const { id, name, number, email, extraInfo } = await Contact.findByPk( - contactId, - { - include: "extraInfo", - } - ); - - res.status(200).json({ - id, - name, - number, - email, - extraInfo, + const contact = await Contact.findByPk(contactId, { + include: "extraInfo", + attributes: ["id", "name", "number", "email"], }); + + if (!contact) { + return res.status(404).json({ error: "No contact found with this id." }); + } + + return res.status(200).json(contact); }; exports.update = async (req, res) => { @@ -110,7 +105,7 @@ exports.update = async (req, res) => { }); if (!contact) { - return res.status(400).json({ error: "No contact found with this ID" }); + return res.status(404).json({ error: "No contact found with this ID" }); } if (updatedContact.extraInfo) { @@ -140,7 +135,7 @@ exports.update = async (req, res) => { contact: contact, }); - res.status(200).json(contact); + return res.status(200).json(contact); }; exports.delete = async (req, res) => { @@ -150,7 +145,7 @@ exports.delete = async (req, res) => { const contact = await Contact.findByPk(contactId); if (!contact) { - return res.status(400).json({ error: "No contact found with this ID" }); + return res.status(404).json({ error: "No contact found with this ID" }); } await contact.destroy(); @@ -160,5 +155,5 @@ exports.delete = async (req, res) => { contactId: contactId, }); - res.status(200).json({ message: "Contact deleted" }); + return res.status(200).json({ message: "Contact deleted" }); }; diff --git a/backend/src/controllers/ImportPhoneContactsController.js b/backend/src/controllers/ImportPhoneContactsController.js index b410c08..19b5537 100644 --- a/backend/src/controllers/ImportPhoneContactsController.js +++ b/backend/src/controllers/ImportPhoneContactsController.js @@ -6,7 +6,16 @@ exports.store = async (req, res, next) => { const io = getIO(); const wbot = getWbot(); - const phoneContacts = await wbot.getContacts(); + let phoneContacts; + + try { + phoneContacts = await wbot.getContacts(); + } catch (err) { + console.log(err); + return res.status(500).json({ + error: "Could not check whatsapp contact. Check connection page.", + }); + } await Promise.all( phoneContacts.map(async ({ number, name }) => { diff --git a/backend/src/controllers/MessageController.js b/backend/src/controllers/MessageController.js index 62d9afc..2639b55 100644 --- a/backend/src/controllers/MessageController.js +++ b/backend/src/controllers/MessageController.js @@ -38,9 +38,6 @@ const setMessagesAsRead = async ticket => { }; exports.index = async (req, res, next) => { - // const wbot = getWbot(); - // const io = getIO(); - const { ticketId } = req.params; const { searchParam = "", pageNumber = 1 } = req.query; @@ -125,6 +122,10 @@ exports.store = async (req, res, next) => { ], }); + if (!ticket) { + return res.status(404).json({ error: "No ticket found with this ID" }); + } + try { if (media) { const newMedia = MessageMedia.fromFilePath(req.file.path); diff --git a/backend/src/controllers/SessionController.js b/backend/src/controllers/SessionController.js index f8d22ff..2f19dca 100644 --- a/backend/src/controllers/SessionController.js +++ b/backend/src/controllers/SessionController.js @@ -8,7 +8,7 @@ exports.store = async (req, res, next) => { const user = await User.findOne({ where: { email: email } }); if (!user) { - return res.status(401).json({ error: "No user found with this email" }); + return res.status(404).json({ error: "No user found with this email" }); } if (!(await user.checkPassword(password))) { diff --git a/backend/src/controllers/SettingController.js b/backend/src/controllers/SettingController.js index 322e8c9..15e4203 100644 --- a/backend/src/controllers/SettingController.js +++ b/backend/src/controllers/SettingController.js @@ -13,7 +13,7 @@ exports.update = async (req, res) => { const setting = await Setting.findByPk(settingKey); if (!setting) { - return res.status(400).json({ error: "No setting found with this ID" }); + return res.status(404).json({ error: "No setting found with this ID" }); } await setting.update(req.body); diff --git a/backend/src/controllers/TicketController.js b/backend/src/controllers/TicketController.js index 3e42513..825203e 100644 --- a/backend/src/controllers/TicketController.js +++ b/backend/src/controllers/TicketController.js @@ -105,7 +105,7 @@ exports.index = async (req, res) => { const hasMore = count > offset + tickets.length; - return res.json({ count, tickets, hasMore }); + return res.status(200).json({ count, tickets, hasMore }); }; exports.store = async (req, res) => { @@ -139,7 +139,7 @@ exports.update = async (req, res) => { }); if (!ticket) { - return res.status(400).json({ error: "No ticket found with this ID" }); + return res.status(404).json({ error: "No ticket found with this ID" }); } await ticket.update(req.body); diff --git a/backend/src/controllers/UserController.js b/backend/src/controllers/UserController.js index 710d433..a77da49 100644 --- a/backend/src/controllers/UserController.js +++ b/backend/src/controllers/UserController.js @@ -71,7 +71,11 @@ exports.store = async (req, res, next) => { .json({ error: "Only administrators can create users." }); } - await schema.validate(req.body); + try { + await schema.validate(req.body); + } catch (err) { + return res.status(400).json({ error: err.message }); + } const io = getIO(); @@ -88,14 +92,15 @@ exports.store = async (req, res, next) => { exports.show = async (req, res) => { const { userId } = req.params; - const { id, name, email, profile } = await User.findByPk(userId); - - return res.status(200).json({ - id, - name, - email, - profile, + const user = await User.findByPk(userId, { + attributes: ["id", "name", "email", "profile"], }); + + if (!user) { + res.status(400).json({ error: "No user found with this id." }); + } + + return res.status(200).json(user); }; exports.update = async (req, res) => { @@ -121,7 +126,7 @@ exports.update = async (req, res) => { }); if (!user) { - res.status(400).json({ error: "No user found with this id." }); + res.status(404).json({ error: "No user found with this id." }); } if (user.profile === "admin" && req.body.profile === "user") { diff --git a/backend/src/controllers/WhatsAppSessionController.js b/backend/src/controllers/WhatsAppSessionController.js index 643d330..882f2b1 100644 --- a/backend/src/controllers/WhatsAppSessionController.js +++ b/backend/src/controllers/WhatsAppSessionController.js @@ -21,7 +21,7 @@ exports.delete = async (req, res) => { const dbSession = await Whatsapp.findByPk(sessionId); if (!dbSession) { - return res.status(200).json({ message: "Session not found" }); + return res.status(404).json({ message: "Session not found" }); } await dbSession.update({ session: "", status: "pending" }); diff --git a/backend/src/database/seeds/20200824172424-create-contacts.js b/backend/src/database/seeds/20200824172424-create-contacts.js deleted file mode 100644 index 54a55cd..0000000 --- a/backend/src/database/seeds/20200824172424-create-contacts.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert( - "Contacts", - [ - { - name: "Joana Doe", - profilePicUrl: - "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1834&q=80", - number: 5512345678, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - name: "John Rulles", - profilePicUrl: - "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80", - number: 5512345679, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - name: "Jonas Jhones", - profilePicUrl: - "https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80", - number: 5512345680, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - name: "Julie June", - profilePicUrl: - "https://images.unsplash.com/photo-1493666438817-866a91353ca9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1049&q=80", - number: 5512345681, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], - {} - ); - }, - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete("Contacts", null, {}); - }, -}; diff --git a/backend/src/database/seeds/20200824173654-create-tickets.js b/backend/src/database/seeds/20200824173654-create-tickets.js deleted file mode 100644 index 83fd634..0000000 --- a/backend/src/database/seeds/20200824173654-create-tickets.js +++ /dev/null @@ -1,261 +0,0 @@ -"use strict"; - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert( - "Tickets", - [ - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 3, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 4, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 2, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - status: "pending", - lastMessage: "hello!", - contactId: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], - {} - ); - }, - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete("Tickets", null, {}); - }, -}; diff --git a/backend/src/database/seeds/20200824174824-create-messages.js b/backend/src/database/seeds/20200824174824-create-messages.js deleted file mode 100644 index 0037136..0000000 --- a/backend/src/database/seeds/20200824174824-create-messages.js +++ /dev/null @@ -1,148 +0,0 @@ -"use strict"; - -module.exports = { - up: (queryInterface, Sequelize) => { - return queryInterface.bulkInsert( - "Messages", - [ - { - id: "12312321342", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 1, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321313", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 1, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321314", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 1, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321315", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 1, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321316", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 5, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321355", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 5, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321318", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 5, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321319", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 5, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321399", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 11, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321391", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 11, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321392", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 3, - ticketId: 11, - fromMe: true, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - { - id: "12312321393", - body: - "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", - ack: 0, - ticketId: 11, - fromMe: false, - read: 1, - createdAt: new Date(), - updatedAt: new Date(), - }, - ], - {} - ); - }, - - down: (queryInterface, Sequelize) => { - return queryInterface.bulkDelete("Messages", null, {}); - }, -}; diff --git a/frontend/src/components/ContactModal/index.js b/frontend/src/components/ContactModal/index.js index 1d5a0d3..326837d 100644 --- a/frontend/src/components/ContactModal/index.js +++ b/frontend/src/components/ContactModal/index.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react"; import * as Yup from "yup"; import { Formik, FieldArray, Form, Field } from "formik"; +import { toast } from "react-toastify"; import { makeStyles } from "@material-ui/core/styles"; import { green } from "@material-ui/core/colors"; @@ -76,8 +77,15 @@ const ContactModal = ({ open, onClose, contactId }) => { useEffect(() => { const fetchContact = async () => { if (!contactId) return; - const res = await api.get(`/contacts/${contactId}`); - setContact(res.data); + try { + const { data } = await api.get(`/contacts/${contactId}`); + setContact(data); + } catch (err) { + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } + } }; fetchContact(); @@ -95,9 +103,12 @@ const ContactModal = ({ open, onClose, contactId }) => { } else { await api.post("/contacts", values); } + toast.success("Contact saved sucessfully!"); } catch (err) { - alert(JSON.stringify(err.response.data, null, 2)); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } handleClose(); }; @@ -131,6 +142,7 @@ const ContactModal = ({ open, onClose, contactId }) => { as={TextField} label={i18n.t("contactModal.form.name")} name="name" + autoFocus error={touched.name && Boolean(errors.name)} helperText={touched.name && errors.name} variant="outlined" diff --git a/frontend/src/components/MessageInput/index.js b/frontend/src/components/MessageInput/index.js index 14d3373..20dc358 100644 --- a/frontend/src/components/MessageInput/index.js +++ b/frontend/src/components/MessageInput/index.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react"; import "emoji-mart/css/emoji-mart.css"; import { useParams } from "react-router-dom"; import { Picker } from "emoji-mart"; +import { toast } from "react-toastify"; import MicRecorder from "mic-recorder-to-mp3"; import { makeStyles } from "@material-ui/core/styles"; @@ -163,8 +164,10 @@ const MessageInput = () => { try { await api.post(`/messages/${ticketId}`, formData); } catch (err) { - alert(err.response.data.error); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } setLoading(false); setMedia(mediaInitialState); @@ -182,8 +185,10 @@ const MessageInput = () => { try { await api.post(`/messages/${ticketId}`, message); } catch (err) { - alert(err.response.data.error); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } setInputMessage(""); setShowEmoji(false); @@ -224,8 +229,10 @@ const MessageInput = () => { try { await api.post(`/messages/${ticketId}`, formData); } catch (err) { - alert(err.response.data.error); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } setRecording(false); setLoading(false); diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js index 16f16a0..00b4e55 100644 --- a/frontend/src/components/MessagesList/index.js +++ b/frontend/src/components/MessagesList/index.js @@ -303,8 +303,12 @@ const MessagesList = () => { } } catch (err) { console.log(err); - toast.error("Ticket não encontrado"); - history.push("/tickets"); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + if (err.response.status === 404) { + history.push("/tickets"); + } + } } }; fetchMessages(); @@ -417,6 +421,9 @@ const MessagesList = () => { }); } catch (err) { console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } history.push("/tickets"); }; diff --git a/frontend/src/components/NewTicketModal/index.js b/frontend/src/components/NewTicketModal/index.js index 83769e2..1a6a4a8 100644 --- a/frontend/src/components/NewTicketModal/index.js +++ b/frontend/src/components/NewTicketModal/index.js @@ -1,5 +1,6 @@ import React, { useState, useEffect } from "react"; import { useHistory } from "react-router-dom"; +import { toast } from "react-toastify"; import Button from "@material-ui/core/Button"; import TextField from "@material-ui/core/TextField"; @@ -38,7 +39,7 @@ const useStyles = makeStyles(theme => ({ }, })); -const NewTicketModal = ({ modalOpen, onClose, contactId }) => { +const NewTicketModal = ({ modalOpen, onClose }) => { const history = useHistory(); const classes = useStyles(); const userId = +localStorage.getItem("userId"); @@ -54,18 +55,21 @@ const NewTicketModal = ({ modalOpen, onClose, contactId }) => { const delayDebounceFn = setTimeout(() => { const fetchContacts = async () => { try { - const res = await api.get("contacts", { - params: { searchParam, rowsPerPage: 20 }, + const { data } = await api.get("contacts", { + params: { searchParam }, }); - setOptions(res.data.contacts); + setOptions(data.contacts); setLoading(false); } catch (err) { - alert(err); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; fetchContacts(); - }, 1000); + }, 500); return () => clearTimeout(delayDebounceFn); }, [searchParam, modalOpen]); @@ -87,7 +91,10 @@ const NewTicketModal = ({ modalOpen, onClose, contactId }) => { }); history.push(`/tickets/${ticket.id}`); } catch (err) { - alert(err); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } setLoading(false); handleClose(); @@ -107,13 +114,14 @@ const NewTicketModal = ({ modalOpen, onClose, contactId }) => { `${option.name} - ${option.number}`} onChange={(e, newValue) => { setSelectedContact(newValue); }} options={options} + noOptionsText="No contacts found. Try another term." loading={loading} renderInput={params => ( { await api.delete("/whatsapp/session/1"); } catch (err) { console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; diff --git a/frontend/src/components/UserModal/index.js b/frontend/src/components/UserModal/index.js index f5402bb..52a33e7 100644 --- a/frontend/src/components/UserModal/index.js +++ b/frontend/src/components/UserModal/index.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "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"; @@ -76,10 +77,17 @@ const UserModal = ({ open, onClose, userId }) => { useEffect(() => { const fetchUser = async () => { if (!userId) return; - const { data } = await api.get(`/users/${userId}`); - setUser(prevState => { - return { ...prevState, ...data }; - }); + try { + const { data } = await api.get(`/users/${userId}`); + setUser(prevState => { + return { ...prevState, ...data }; + }); + } catch (err) { + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } + } }; fetchUser(); @@ -97,9 +105,12 @@ const UserModal = ({ open, onClose, userId }) => { } else { await api.post("/users", values); } + toast.success("Success!"); } catch (err) { - alert(JSON.stringify(err.response.data, null, 2)); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } handleClose(); }; @@ -127,6 +138,7 @@ const UserModal = ({ open, onClose, userId }) => { { } catch (err) { setLoading(false); setIsAuth(false); - toast.error(i18n.t("auth.toasts.fail")); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; checkAuth(); @@ -53,7 +56,10 @@ const useAuth = () => { toast.success(i18n.t("auth.toasts.success")); history.push("/tickets"); } catch (err) { - toast.error(i18n.t("auth.toasts.fail")); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; diff --git a/frontend/src/hooks/useTickets/index.js b/frontend/src/hooks/useTickets/index.js index 2bd2b36..535f4ca 100644 --- a/frontend/src/hooks/useTickets/index.js +++ b/frontend/src/hooks/useTickets/index.js @@ -1,5 +1,6 @@ import { useState, useEffect, useReducer } from "react"; import openSocket from "socket.io-client"; +import { toast } from "react-toastify"; import api from "../../services/api"; @@ -97,6 +98,9 @@ const useTickets = ({ searchParam, pageNumber, status, date, showAll }) => { setLoading(false); } catch (err) { console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; fetchTickets(); diff --git a/frontend/src/pages/Connection/index.js b/frontend/src/pages/Connection/index.js index 9fa4a15..84ca425 100644 --- a/frontend/src/pages/Connection/index.js +++ b/frontend/src/pages/Connection/index.js @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react"; import { useHistory } from "react-router-dom"; import api from "../../services/api"; import openSocket from "socket.io-client"; +import { toast } from "react-toastify"; import { makeStyles } from "@material-ui/core/styles"; @@ -46,6 +47,9 @@ const WhatsAuth = () => { setSession(data); } catch (err) { console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; fetchSession(); diff --git a/frontend/src/pages/Contacts/index.js b/frontend/src/pages/Contacts/index.js index e46365f..5f916a2 100644 --- a/frontend/src/pages/Contacts/index.js +++ b/frontend/src/pages/Contacts/index.js @@ -1,5 +1,6 @@ import React, { useState, useEffect, useReducer } from "react"; import openSocket from "socket.io-client"; +import { toast } from "react-toastify"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -114,7 +115,9 @@ const Contacts = () => { 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); + } } }; fetchContacts(); @@ -161,8 +164,12 @@ const Contacts = () => { const handleDeleteContact = async contactId => { try { await api.delete(`/contacts/${contactId}`); + toast.success("Contact deleted sucessfully!"); } catch (err) { - alert(err); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } setDeletingContact(null); setSearchParam(""); @@ -172,8 +179,10 @@ const Contacts = () => { const handleimportContact = async () => { try { await api.post("/contacts/import"); + window.location.reload(false); } catch (err) { console.log(err); + window.location.reload(false); } }; diff --git a/frontend/src/pages/Settings/index.js b/frontend/src/pages/Settings/index.js index 418eebf..a1dc40d 100644 --- a/frontend/src/pages/Settings/index.js +++ b/frontend/src/pages/Settings/index.js @@ -43,6 +43,9 @@ const Settings = () => { setSettings(data); } catch (err) { console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; fetchSession(); @@ -77,14 +80,16 @@ const Settings = () => { }); toast.success("Setting updated"); } catch (err) { - alert(err); console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } }; const getSettingValue = key => { - const setting = settings.find(s => s.key === key); - return setting.value; + const { value } = settings.find(s => s.key === key); + return value; }; return ( diff --git a/frontend/src/pages/Signup/index.js b/frontend/src/pages/Signup/index.js index 9823670..65680c4 100644 --- a/frontend/src/pages/Signup/index.js +++ b/frontend/src/pages/Signup/index.js @@ -78,7 +78,10 @@ const SignUp = () => { toast.success(i18n.t("signup.toasts.success")); history.push("/login"); } catch (err) { - toast.error(i18n.t("signup.toasts.fail")); + console.log(err); + if (err.response && err.response.data && err.response.data.error) { + toast.error(err.response.data.error); + } } };