Fix lint errors

Manually fix all lint errors.
Some errors could not be fixed, a TODO comment was added.

To fix errors caused by `react-hooks/exhaustive-deps`, missing
dependencies were added to the dependencies array of some `useEffect`
calls.
We need to make sure that all `useEffect` call work as intended before
merging

Gitlab: #29
Change-Id: I939a99b0be53795ecc28d25b5067f037403f5e08
diff --git a/client/src/App.js b/client/src/App.js
index d4ef605..7cec1ee 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -29,7 +29,7 @@
   return <Navigate to="/account" />;
 };
 
-const App = (props) => {
+const App = () => {
   // const count = useSelector(state => state.counter.value)
   // const dispatch = useDispatch();
   // const count = useAppSelector((state) => state.counter.value);
diff --git a/client/src/AuthManager.js b/client/src/AuthManager.js
index 60c903b..ea55c3a 100644
--- a/client/src/AuthManager.js
+++ b/client/src/AuthManager.js
@@ -1,3 +1,6 @@
+/* eslint-disable no-undef */
+// TODO: This hides eslint errors for this file. This should be removed once this file is cleaned up.
+
 /*
  *  Copyright (c) 2017-2021 Savoir-faire Linux Inc.
  *
@@ -118,8 +121,8 @@
     if (response.ok) {
       console.log('Success, going home');
       //navigate('/')
-    } else {
     }
+
     this.authenticating = false;
     this.state.setupComplete = true;
     if (this.onAuthChanged) this.onAuthChanged(this.state);
diff --git a/client/src/components/AccountPreferences.js b/client/src/components/AccountPreferences.js
index 7ad89da..23b23f6 100644
--- a/client/src/components/AccountPreferences.js
+++ b/client/src/components/AccountPreferences.js
@@ -131,8 +131,8 @@
                   Appareils associés
                 </Typography>
                 <Typography gutterBottom variant="h5" component="h2">
-                  {devices.map((device) => (
-                    <ListItem>
+                  {devices.map((device, i) => (
+                    <ListItem key={i}>
                       <GroupRounded />
                       <ListItemText id="switch-list-label-rendezvous" primary={device[1]} secondary={device[0]} />
                     </ListItem>
diff --git a/client/src/components/ContactList.js b/client/src/components/ContactList.js
index d8e6add..09885ca 100644
--- a/client/src/components/ContactList.js
+++ b/client/src/components/ContactList.js
@@ -63,7 +63,6 @@
         method: 'DELETE',
       })
       .then((res) => res.json())
-      .then((result) => {})
       .catch((e) => console.log(`ERROR ${typeOfRemove}ing CONTACT : `, e));
     closeModalDelete();
   };
@@ -80,7 +79,7 @@
         setContacts(result);
       });
     return () => controller.abort();
-  }, [blockOrRemove]);
+  }, [accountId, blockOrRemove]);
 
   return (
     <div className="rooms-list">
diff --git a/client/src/components/ConversationListItem.js b/client/src/components/ConversationListItem.js
index 4bea190..40057b3 100644
--- a/client/src/components/ConversationListItem.js
+++ b/client/src/components/ConversationListItem.js
@@ -274,7 +274,7 @@
                   Informations
                 </div>
 
-                <Typography variant="caption">Nom d'utilisateur</Typography>
+                <Typography variant="caption">Nom d&apos;utilisateur</Typography>
                 <div style={{ height: '20px' }} />
                 <Typography variant="caption">Identifiant </Typography>
                 <div style={{ height: '20px' }} />
diff --git a/client/src/components/ConversationView.js b/client/src/components/ConversationView.js
index 51e9254..69727d5 100644
--- a/client/src/components/ConversationView.js
+++ b/client/src/components/ConversationView.js
@@ -9,30 +9,30 @@
 import MessageList from './MessageList';
 import SendMessageForm from './SendMessageForm';
 
-const ConversationView = (props) => {
+const ConversationView = ({ accountId, conversationId, ...props }) => {
   const socket = useContext(SocketContext);
   const [conversation, setConversation] = useState();
   const [messages, setMessages] = useState([]);
   const [isLoading, setIsLoading] = useState(true);
   const [error, setError] = useState(false);
 
-  const conversationQuery = useConversationQuery(props.accountId, props.conversationId);
-  const messagesQuery = useMessagesQuery(props.accountId, props.conversationId);
-  const sendMessageMutation = useSendMessageMutation(props.accountId, props.conversationId);
+  const conversationQuery = useConversationQuery(accountId, conversationId);
+  const messagesQuery = useMessagesQuery(accountId, conversationId);
+  const sendMessageMutation = useSendMessageMutation(accountId, conversationId);
 
   useEffect(() => {
     if (conversationQuery.isSuccess) {
-      const conversation = Conversation.from(props.accountId, conversationQuery.data);
+      const conversation = Conversation.from(accountId, conversationQuery.data);
       setConversation(conversation);
     }
-  }, [conversationQuery.data]);
+  }, [accountId, conversationQuery.isSuccess, conversationQuery.data]);
 
   useEffect(() => {
     if (messagesQuery.isSuccess) {
       const sortedMessages = sortMessages(messagesQuery.data);
       setMessages(sortedMessages);
     }
-  }, [messagesQuery.data]);
+  }, [messagesQuery.isSuccess, messagesQuery.data]);
 
   useEffect(() => {
     setIsLoading(conversationQuery.isLoading || messagesQuery.isLoading);
@@ -46,19 +46,19 @@
 
   useEffect(() => {
     if (!conversation) return;
-    console.log(`io set conversation ${props.conversationId} ` + socket);
-    if (socket) socket.emit('conversation', { accountId: props.accountId, conversationId: props.conversationId });
+    console.log(`io set conversation ${conversationId} ` + socket);
+    if (socket) socket.emit('conversation', { accountId, conversationId });
     socket.off('newMessage');
     socket.on('newMessage', (data) => {
       console.log('newMessage');
       setMessages((messages) => addMessage(messages, data));
     });
-  }, [socket, setMessages]);
+  }, [accountId, conversation, conversationId, socket]);
 
   if (isLoading) {
     return <LoadingPage />;
   } else if (error) {
-    return <div>Error loading {props.conversationId}</div>;
+    return <div>Error loading {conversationId}</div>;
   }
 
   return (
@@ -72,7 +72,7 @@
             {conversation?.getDisplayName()}
           </Typography>
           <Typography className="subtitle" variant="subtitle1">
-            {props.conversationId}
+            {conversationId}
           </Typography>
         </Box>
       </Stack>
diff --git a/client/src/components/ConversationsOverviewCard.js b/client/src/components/ConversationsOverviewCard.js
index 8acaf52..095e3d7 100644
--- a/client/src/components/ConversationsOverviewCard.js
+++ b/client/src/components/ConversationsOverviewCard.js
@@ -7,7 +7,10 @@
 
 export default function ConversationsOverviewCard(props) {
   const navigate = useNavigate();
-  const accountId = props.accountId || useParams().accountId;
+  let accountId = useParams().accountId;
+  if (props.accountId) {
+    accountId = props.accountId;
+  }
   const [loaded, setLoaded] = useState(false);
   const [conversations, setConversations] = useState([]);
 
diff --git a/client/src/components/ListItemLink.js b/client/src/components/ListItemLink.js
index d020503..fb7bbc4 100644
--- a/client/src/components/ListItemLink.js
+++ b/client/src/components/ListItemLink.js
@@ -14,7 +14,7 @@
         console.log('LIST ITEM LINK: ', account, itemProps);
         return <RouterLink to={to} ref={ref} {...itemProps} state={account} />;
       }),
-    [to]
+    [account, to]
   );
 
   return (
diff --git a/client/src/components/Message.js b/client/src/components/Message.js
index 0278d0b..e36b0da 100644
--- a/client/src/components/Message.js
+++ b/client/src/components/Message.js
@@ -14,7 +14,7 @@
 dayjs.extend(isYesterday);
 
 export const MessageCall = (props) => {
-  return <Stack alignItems="center">"Appel"</Stack>;
+  return <Stack alignItems="center">&quot;Appel&quot;</Stack>;
 };
 
 export const MessageInitial = (props) => {
@@ -30,7 +30,7 @@
       isFirstOfGroup={props.isFirstOfGroup}
       isLastOfGroup={props.isLastOfGroup}
     >
-      "data-transfer"
+      &quot;data-transfer&quot;
     </MessageBubble>
   );
 };
@@ -50,7 +50,7 @@
 };
 
 export const MessageMerge = (props) => {
-  return <Stack alignItems="center">"merge"</Stack>;
+  return <Stack alignItems="center">&quot;merge&quot;</Stack>;
 };
 
 export const MessageText = (props) => {
diff --git a/client/src/components/UsernameChooser.js b/client/src/components/UsernameChooser.js
index 57fa242..c1678b5 100644
--- a/client/src/components/UsernameChooser.js
+++ b/client/src/components/UsernameChooser.js
@@ -7,7 +7,7 @@
 
 const isInputValid = (input) => input && input.length > 2;
 
-export default function UsernameChooser(props) {
+export default function UsernameChooser({ setName, ...props }) {
   const [query, setQuery] = useState('');
 
   const { isLoading, data, error } = usePromise(
@@ -23,10 +23,10 @@
 
   useEffect(() => {
     if (!isLoading) {
-      if (error === 404) props.setName(query);
-      else props.setName('');
+      if (error === 404) setName(query);
+      else setName('');
     }
-  }, [query, isLoading, data, error]);
+  }, [setName, query, isLoading, data, error]);
 
   const handleChange = (event) => setQuery(event.target.value);
 
diff --git a/client/src/components/buttons.js b/client/src/components/buttons.js
index 0f7666e..7d80ec8 100644
--- a/client/src/components/buttons.js
+++ b/client/src/components/buttons.js
@@ -205,7 +205,7 @@
   width: '20px',
 }));
 
-export const SelectEmojiButton = (props) => {
+export const SelectEmojiButton = ({ onEmojiSelected, ...props }) => {
   const [anchorEl, setAnchorEl] = useState(null);
 
   const handleOpenEmojiPicker = useCallback((e) => setAnchorEl(anchorEl ? null : e.currentTarget), [anchorEl]);
@@ -214,10 +214,10 @@
 
   const onEmojiClick = useCallback(
     (e, emojiObject) => {
-      props.onEmojiSelected(emojiObject.emoji);
+      onEmojiSelected(emojiObject.emoji);
       handleClose();
     },
-    [handleClose, props.onEmojiSelected]
+    [handleClose, onEmojiSelected]
   );
 
   const open = Boolean(anchorEl);
diff --git a/client/src/components/inputs.js b/client/src/components/inputs.js
index a607a31..cbcb951 100644
--- a/client/src/components/inputs.js
+++ b/client/src/components/inputs.js
@@ -19,7 +19,7 @@
 const StyledPersonIconLight = styled(PersonIcon)({ height: iconsHeight, color: '#03B9E9' });
 const StyledLockIcon = styled(LockIcon)({ height: iconsHeight, color: '#03B9E9' });
 
-export const UsernameInput = ({ infoButtonProps, ...props }) => {
+export const UsernameInput = ({ infoButtonProps, onChange: _onChange, ...props }) => {
   const [isSelected, setIsSelected] = useState(false);
   const [input, setInput] = useState(props.defaultValue);
   const [startAdornment, setStartAdornment] = useState();
@@ -27,9 +27,9 @@
   const onChange = useCallback(
     (event) => {
       setInput(event.target.value);
-      props.onChange?.(event);
+      _onChange?.(event);
     },
-    [props.onChange]
+    [_onChange]
   );
 
   useEffect(() => {
@@ -63,7 +63,7 @@
   );
 };
 
-export const PasswordInput = ({ infoButtonProps, ...props }) => {
+export const PasswordInput = ({ infoButtonProps, onChange: _onChange, ...props }) => {
   const [showPassword, setShowPassword] = useState(false);
   const [isSelected, setIsSelected] = useState(false);
   const [input, setInput] = useState(props.defaultValue);
@@ -76,9 +76,9 @@
   const onChange = useCallback(
     (event) => {
       setInput(event.target.value);
-      props.onChange?.(event);
+      _onChange?.(event);
     },
-    [props.onChange]
+    [_onChange]
   );
 
   useEffect(() => {
@@ -119,7 +119,7 @@
   );
 };
 
-export const NickNameInput = (props) => {
+export const NickNameInput = ({ onChange: _onChange, ...props }) => {
   const [isSelected, setIsSelected] = useState(false);
   const [input, setInput] = useState(props.defaultValue);
   const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
@@ -127,9 +127,9 @@
   const onChange = useCallback(
     (event) => {
       setInput(event.target.value);
-      props.onChange?.(event);
+      _onChange?.(event);
     },
-    [props.onChange]
+    [_onChange]
   );
 
   useEffect(() => {
@@ -152,7 +152,7 @@
   );
 };
 
-export const RegularInput = (props) => {
+export const RegularInput = ({ onChange: _onChange, ...props }) => {
   const [isSelected, setIsSelected] = useState(false);
   const [input, setInput] = useState(props.defaultValue);
   const [startAdornmentVisibility, setStartAdornmentVisibility] = useState();
@@ -161,9 +161,9 @@
   const onChange = useCallback(
     (event) => {
       setInput(event.target.value);
-      props.onChange?.(event);
+      _onChange?.(event);
     },
-    [props.onChange]
+    [_onChange]
   );
 
   useEffect(() => {
diff --git a/client/src/index.js b/client/src/index.js
index 51e6676..2d4d46b 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -43,6 +43,8 @@
 if (import.meta.webpackHot)
   import.meta.webpackHot.accept('./App', () => {
     try {
+      // TODO: This needs be fixed
+      // eslint-disable-next-line no-undef
       render(App);
     } catch (e) {
       location.reload();
diff --git a/client/src/pages/accountCreation.jsx b/client/src/pages/accountCreation.jsx
index cd948a2..b8c323b 100644
--- a/client/src/pages/accountCreation.jsx
+++ b/client/src/pages/accountCreation.jsx
@@ -14,7 +14,7 @@
           <Typography variant="body2" color="textSecondary" component="p">
             Welcome to the Jami web node setup.
             <br />
-            Let's start by creating a new administrator account to control access to the server configuration.
+            Let&apos;s start by creating a new administrator account to control access to the server configuration.
           </Typography>
         </CardContent>
 
diff --git a/client/src/pages/accountSelection.jsx b/client/src/pages/accountSelection.jsx
index 8d96885..e8bbf1e 100644
--- a/client/src/pages/accountSelection.jsx
+++ b/client/src/pages/accountSelection.jsx
@@ -45,7 +45,7 @@
       )
       .catch((e) => console.log(e));
     // return () => controller.abort() // crash on React18
-  }, []);
+  }, [navigate]);
 
   if (!loaded) return <LoadingPage />;
   return (
diff --git a/client/src/pages/accountSettings.jsx b/client/src/pages/accountSettings.jsx
index ed580e2..10dab29 100644
--- a/client/src/pages/accountSettings.jsx
+++ b/client/src/pages/accountSettings.jsx
@@ -11,7 +11,10 @@
 
 const AccountSettings = (props) => {
   console.log('ACCOUNT SETTINGS', props.account);
-  const accountId = props.accountId || useParams().accountId;
+  let accountId = useParams().accountId;
+  if (props.accountId) {
+    accountId = props.accountId;
+  }
   const dispatch = useAppDispatch();
 
   const [state, setState] = useState({ loaded: false });
@@ -31,7 +34,7 @@
       })
       .catch((e) => console.log(e));
     // return () => controller.abort() // crash on React18
-  }, [accountId]);
+  }, [accountId, dispatch]);
 
   return (
     <Container maxWidth="sm">
diff --git a/client/src/pages/jamiAccountCreation.jsx b/client/src/pages/jamiAccountCreation.jsx
index fbff909..09f8612 100644
--- a/client/src/pages/jamiAccountCreation.jsx
+++ b/client/src/pages/jamiAccountCreation.jsx
@@ -43,7 +43,7 @@
           <Typography variant="body2" color="textSecondary" component="p">
             Welcome to the Jami web node setup.
             <br />
-            Let's start by creating a new administrator account to control access to the server configuration.
+            Let&apos;s start by creating a new administrator account to control access to the server configuration.
           </Typography>
 
           <Box>
diff --git a/client/src/pages/serverConfiguration.jsx b/client/src/pages/serverConfiguration.jsx
index da6250a..829977e 100644
--- a/client/src/pages/serverConfiguration.jsx
+++ b/client/src/pages/serverConfiguration.jsx
@@ -1,5 +1,6 @@
 import CircularProgress from '@mui/material/CircularProgress';
 import Container from '@mui/material/Container';
+import { useEffect, useState } from 'react';
 
 import Account from '../../../model/Account';
 import authManager from '../AuthManager';
@@ -7,7 +8,9 @@
 import Header from '../components/Header';
 
 const ServerOverview = (props) => {
-  this.accountId = props.accountId || props.match.params.accountId;
+  const [loaded, setLoaded] = useState(false);
+  const [account, setAccount] = useState();
+  const accountId = props.accountId || props.match.params.accountId;
 
   useEffect(() => {
     const controller = new AbortController();
@@ -16,7 +19,8 @@
       .then((res) => res.json())
       .then((result) => {
         console.log(result);
-        setState({ loaded: true, account: Account.from(result) });
+        setLoaded(true);
+        setAccount(Account.from(result));
       })
       .catch((e) => console.log(e));
     // return () => controller.abort() // crash on React18
@@ -25,7 +29,7 @@
   return (
     <Container maxWidth="sm" className="app">
       <Header />
-      {this.state.loaded ? <AccountPreferences account={this.state.account} /> : <CircularProgress />}
+      {loaded ? <AccountPreferences account={account} /> : <CircularProgress />}
     </Container>
   );
 };
diff --git a/client/src/pages/serverSetup.jsx b/client/src/pages/serverSetup.jsx
index 95fc032..b7f79a7 100644
--- a/client/src/pages/serverSetup.jsx
+++ b/client/src/pages/serverSetup.jsx
@@ -28,7 +28,7 @@
           <Typography variant="body2" color="textSecondary" component="p">
             Welcome to the Jami web node setup.
             <br />
-            Let's start by creating a new administrator account to control access to the server configuration.
+            Let&apos;s start by creating a new administrator account to control access to the server configuration.
           </Typography>
 
           <Box style={{ textAlign: 'center', marginTop: 8, marginBottom: 16 }}>