diff --git a/frontend/src/pages/Contacts/index.js b/frontend/src/pages/Contacts/index.js
index 226d5b8..7a09d0b 100644
--- a/frontend/src/pages/Contacts/index.js
+++ b/frontend/src/pages/Contacts/index.js
@@ -1,319 +1,318 @@
-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";
-import TableBody from "@material-ui/core/TableBody";
-import TableCell from "@material-ui/core/TableCell";
-import TableHead from "@material-ui/core/TableHead";
-import TableRow from "@material-ui/core/TableRow";
-import Paper from "@material-ui/core/Paper";
-import Button from "@material-ui/core/Button";
-import Avatar from "@material-ui/core/Avatar";
-
-import SearchIcon from "@material-ui/icons/Search";
-import TextField from "@material-ui/core/TextField";
-import InputAdornment from "@material-ui/core/InputAdornment";
-
-import IconButton from "@material-ui/core/IconButton";
-import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
-import EditIcon from "@material-ui/icons/Edit";
-
-import api from "../../services/api";
-import TableRowSkeleton from "../../components/TableRowSkeleton";
-import ContactModal from "../../components/ContactModal";
-import ConfirmationModal from "../../components/ConfirmationModal/";
-
-import { i18n } from "../../translate/i18n";
-import MainHeader from "../../components/MainHeader";
-import Title from "../../components/Title";
-import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper";
-import MainContainer from "../../components/MainContainer";
-
-const reducer = (state, action) => {
- if (action.type === "LOAD_CONTACTS") {
- const contacts = action.payload;
- const newContacts = [];
-
- contacts.forEach(contact => {
- const contactIndex = state.findIndex(c => c.id === contact.id);
- if (contactIndex !== -1) {
- state[contactIndex] = contact;
- } else {
- newContacts.push(contact);
- }
- });
-
- return [...state, ...newContacts];
- }
-
- if (action.type === "UPDATE_CONTACTS") {
- const contact = action.payload;
- const contactIndex = state.findIndex(c => c.id === contact.id);
-
- if (contactIndex !== -1) {
- state[contactIndex] = contact;
- return [...state];
- } else {
- return [contact, ...state];
- }
- }
-
- if (action.type === "DELETE_CONTACT") {
- const contactId = action.payload;
-
- const contactIndex = state.findIndex(c => c.id === contactId);
- if (contactIndex !== -1) {
- state.splice(contactIndex, 1);
- }
- return [...state];
- }
-
- if (action.type === "RESET") {
- return [];
- }
-};
-
-const useStyles = makeStyles(theme => ({
- mainPaper: {
- flex: 1,
- padding: theme.spacing(1),
- overflowY: "scroll",
- ...theme.scrollbarStyles,
- },
-}));
-
-const Contacts = () => {
- const classes = useStyles();
-
- const [loading, setLoading] = useState(false);
- const [pageNumber, setPageNumber] = useState(1);
- const [searchParam, setSearchParam] = useState("");
- const [contacts, dispatch] = useReducer(reducer, []);
- const [selectedContactId, setSelectedContactId] = useState(null);
- const [contactModalOpen, setContactModalOpen] = useState(false);
- const [deletingContact, setDeletingContact] = useState(null);
- const [confirmOpen, setConfirmOpen] = useState(false);
- const [hasMore, setHasMore] = useState(false);
-
- useEffect(() => {
- dispatch({ type: "RESET" });
- setPageNumber(1);
- }, [searchParam]);
-
- useEffect(() => {
- setLoading(true);
- const delayDebounceFn = setTimeout(() => {
- const fetchContacts = async () => {
- try {
- const { data } = await api.get("/contacts/", {
- params: { searchParam, pageNumber },
- });
- dispatch({ type: "LOAD_CONTACTS", payload: data.contacts });
- setHasMore(data.hasMore);
- setLoading(false);
- } catch (err) {
- console.log(err);
- if (err.response && err.response.data && err.response.data.error) {
- toast.error(err.response.data.error);
- }
- }
- };
- fetchContacts();
- }, 500);
- return () => clearTimeout(delayDebounceFn);
- }, [searchParam, pageNumber]);
-
- useEffect(() => {
- const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
- socket.on("contact", data => {
- if (data.action === "update" || data.action === "create") {
- dispatch({ type: "UPDATE_CONTACTS", payload: data.contact });
- }
-
- if (data.action === "delete") {
- dispatch({ type: "DELETE_CONTACT", payload: +data.contactId });
- }
- });
-
- return () => {
- socket.disconnect();
- };
- }, []);
-
- const handleSearch = event => {
- setSearchParam(event.target.value.toLowerCase());
- };
-
- const handleOpenContactModal = () => {
- setSelectedContactId(null);
- setContactModalOpen(true);
- };
-
- const handleCloseContactModal = () => {
- setSelectedContactId(null);
- setContactModalOpen(false);
- };
-
- const hadleEditContact = contactId => {
- setSelectedContactId(contactId);
- setContactModalOpen(true);
- };
-
- const handleDeleteContact = async contactId => {
- try {
- await api.delete(`/contacts/${contactId}`);
- toast.success("Contact deleted sucessfully!");
- } catch (err) {
- console.log(err);
- if (err.response && err.response.data && err.response.data.error) {
- toast.error(err.response.data.error);
- }
- }
- setDeletingContact(null);
- setSearchParam("");
- setPageNumber(1);
- };
-
- const handleimportContact = async () => {
- try {
- await api.post("/contacts/import");
- window.location.reload(false);
- } catch (err) {
- console.log(err);
- if (err.response && err.response.data && err.response.data.error) {
- toast.error(err.response.data.error);
- }
- }
- };
-
- const loadMore = () => {
- setPageNumber(prevState => prevState + 1);
- };
-
- const handleScroll = e => {
- if (!hasMore || loading) return;
- const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
- if (scrollHeight - (scrollTop + 100) < clientHeight) {
- loadMore();
- }
- };
-
- return (
-
-
-
- deletingContact
- ? handleDeleteContact(deletingContact.id)
- : handleimportContact()
- }
- >
- {deletingContact
- ? `${i18n.t("contacts.confirmationModal.deleteMessage")}`
- : `${i18n.t("contacts.confirmationModal.importMessage")}`}
-
-
- {i18n.t("contacts.title")}
-
-
-
-
- ),
- }}
- />
-
-
-
-
-
-
-
-
-
- {i18n.t("contacts.table.name")}
- {i18n.t("contacts.table.whatsapp")}
- {i18n.t("contacts.table.email")}
-
- {i18n.t("contacts.table.actions")}
-
-
-
-
- <>
- {contacts.map(contact => (
-
-
- {}
-
- {contact.name}
- {contact.number}
- {contact.email}
-
- hadleEditContact(contact.id)}
- >
-
-
-
- {
- setConfirmOpen(true);
- setDeletingContact(contact);
- }}
- >
-
-
-
-
- ))}
- {loading && }
- >
-
-
-
-
- );
-};
-
-export default Contacts;
+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";
+import TableBody from "@material-ui/core/TableBody";
+import TableCell from "@material-ui/core/TableCell";
+import TableHead from "@material-ui/core/TableHead";
+import TableRow from "@material-ui/core/TableRow";
+import Paper from "@material-ui/core/Paper";
+import Button from "@material-ui/core/Button";
+import Avatar from "@material-ui/core/Avatar";
+
+import SearchIcon from "@material-ui/icons/Search";
+import TextField from "@material-ui/core/TextField";
+import InputAdornment from "@material-ui/core/InputAdornment";
+
+import IconButton from "@material-ui/core/IconButton";
+import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
+import EditIcon from "@material-ui/icons/Edit";
+
+import api from "../../services/api";
+import TableRowSkeleton from "../../components/TableRowSkeleton";
+import ContactModal from "../../components/ContactModal";
+import ConfirmationModal from "../../components/ConfirmationModal/";
+
+import { i18n } from "../../translate/i18n";
+import MainHeader from "../../components/MainHeader";
+import Title from "../../components/Title";
+import MainHeaderButtonsWrapper from "../../components/MainHeaderButtonsWrapper";
+import MainContainer from "../../components/MainContainer";
+
+const reducer = (state, action) => {
+ if (action.type === "LOAD_CONTACTS") {
+ const contacts = action.payload;
+ const newContacts = [];
+
+ contacts.forEach(contact => {
+ const contactIndex = state.findIndex(c => c.id === contact.id);
+ if (contactIndex !== -1) {
+ state[contactIndex] = contact;
+ } else {
+ newContacts.push(contact);
+ }
+ });
+
+ return [...state, ...newContacts];
+ }
+
+ if (action.type === "UPDATE_CONTACTS") {
+ const contact = action.payload;
+ const contactIndex = state.findIndex(c => c.id === contact.id);
+
+ if (contactIndex !== -1) {
+ state[contactIndex] = contact;
+ return [...state];
+ } else {
+ return [contact, ...state];
+ }
+ }
+
+ if (action.type === "DELETE_CONTACT") {
+ const contactId = action.payload;
+
+ const contactIndex = state.findIndex(c => c.id === contactId);
+ if (contactIndex !== -1) {
+ state.splice(contactIndex, 1);
+ }
+ return [...state];
+ }
+
+ if (action.type === "RESET") {
+ return [];
+ }
+};
+
+const useStyles = makeStyles(theme => ({
+ mainPaper: {
+ flex: 1,
+ padding: theme.spacing(1),
+ overflowY: "scroll",
+ ...theme.scrollbarStyles,
+ },
+}));
+
+const Contacts = () => {
+ const classes = useStyles();
+
+ const [loading, setLoading] = useState(false);
+ const [pageNumber, setPageNumber] = useState(1);
+ const [searchParam, setSearchParam] = useState("");
+ const [contacts, dispatch] = useReducer(reducer, []);
+ const [selectedContactId, setSelectedContactId] = useState(null);
+ const [contactModalOpen, setContactModalOpen] = useState(false);
+ const [deletingContact, setDeletingContact] = useState(null);
+ const [confirmOpen, setConfirmOpen] = useState(false);
+ const [hasMore, setHasMore] = useState(false);
+
+ useEffect(() => {
+ dispatch({ type: "RESET" });
+ setPageNumber(1);
+ }, [searchParam]);
+
+ useEffect(() => {
+ setLoading(true);
+ const delayDebounceFn = setTimeout(() => {
+ const fetchContacts = async () => {
+ try {
+ const { data } = await api.get("/contacts/", {
+ params: { searchParam, pageNumber },
+ });
+ dispatch({ type: "LOAD_CONTACTS", payload: data.contacts });
+ setHasMore(data.hasMore);
+ setLoading(false);
+ } catch (err) {
+ console.log(err);
+ if (err.response && err.response.data && err.response.data.error) {
+ toast.error(err.response.data.error);
+ }
+ }
+ };
+ fetchContacts();
+ }, 500);
+ return () => clearTimeout(delayDebounceFn);
+ }, [searchParam, pageNumber]);
+
+ useEffect(() => {
+ const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
+ socket.on("contact", data => {
+ if (data.action === "update" || data.action === "create") {
+ dispatch({ type: "UPDATE_CONTACTS", payload: data.contact });
+ }
+
+ if (data.action === "delete") {
+ dispatch({ type: "DELETE_CONTACT", payload: +data.contactId });
+ }
+ });
+
+ return () => {
+ socket.disconnect();
+ };
+ }, []);
+
+ const handleSearch = event => {
+ setSearchParam(event.target.value.toLowerCase());
+ };
+
+ const handleOpenContactModal = () => {
+ setSelectedContactId(null);
+ setContactModalOpen(true);
+ };
+
+ const handleCloseContactModal = () => {
+ setSelectedContactId(null);
+ setContactModalOpen(false);
+ };
+
+ const hadleEditContact = contactId => {
+ setSelectedContactId(contactId);
+ setContactModalOpen(true);
+ };
+
+ const handleDeleteContact = async contactId => {
+ try {
+ await api.delete(`/contacts/${contactId}`);
+ toast.success("Contact deleted sucessfully!");
+ } catch (err) {
+ console.log(err);
+ if (err.response && err.response.data && err.response.data.error) {
+ toast.error(err.response.data.error);
+ }
+ }
+ setDeletingContact(null);
+ setSearchParam("");
+ setPageNumber(1);
+ };
+
+ const handleimportContact = async () => {
+ try {
+ await api.post("/contacts/import");
+ } catch (err) {
+ console.log(err);
+ if (err.response && err.response.data && err.response.data.error) {
+ toast.error(err.response.data.error);
+ }
+ }
+ };
+
+ const loadMore = () => {
+ setPageNumber(prevState => prevState + 1);
+ };
+
+ const handleScroll = e => {
+ if (!hasMore || loading) return;
+ const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
+ if (scrollHeight - (scrollTop + 100) < clientHeight) {
+ loadMore();
+ }
+ };
+
+ return (
+
+
+
+ deletingContact
+ ? handleDeleteContact(deletingContact.id)
+ : handleimportContact()
+ }
+ >
+ {deletingContact
+ ? `${i18n.t("contacts.confirmationModal.deleteMessage")}`
+ : `${i18n.t("contacts.confirmationModal.importMessage")}`}
+
+
+ {i18n.t("contacts.title")}
+
+
+
+
+ ),
+ }}
+ />
+
+
+
+
+
+
+
+
+
+ {i18n.t("contacts.table.name")}
+ {i18n.t("contacts.table.whatsapp")}
+ {i18n.t("contacts.table.email")}
+
+ {i18n.t("contacts.table.actions")}
+
+
+
+
+ <>
+ {contacts.map(contact => (
+
+
+ {}
+
+ {contact.name}
+ {contact.number}
+ {contact.email}
+
+ hadleEditContact(contact.id)}
+ >
+
+
+
+ {
+ setConfirmOpen(true);
+ setDeletingContact(contact);
+ }}
+ >
+
+
+
+
+ ))}
+ {loading && }
+ >
+
+
+
+
+ );
+};
+
+export default Contacts;