diff --git a/app/Root.jsx b/app/Root.js
similarity index 96%
rename from app/Root.jsx
rename to app/Root.js
index 583822f5cbe1a4e8d325121d9b1d71290e46c9b3..315a8ad28dcedbce804aba0a50cf2a3f5f5a9811 100644
--- a/app/Root.jsx
+++ b/app/Root.js
@@ -32,11 +32,13 @@ export function stripTypenames(obj) {
   })
   return obj
 }
+
 // Construct an ApolloClient. If a function is passed as the first argument,
 // it will be called with the default client config as an argument, and should
 // return the desired config.
 const makeApolloClient = (makeConfig, connectToWebSocket) => {
   const uploadLink = createUploadLink()
+
   const authLink = setContext((_, { headers }) => {
     const token = localStorage.getItem('token')
     return {
@@ -51,6 +53,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
     if (operation.variables) {
       operation.variables = stripTypenames(operation.variables)
     }
+
     return forward(operation)
   })
 
@@ -58,6 +61,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
 
   if (connectToWebSocket) {
     const wsProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
+
     const wsLink = new WebSocketLink({
       uri: `${wsProtocol}://${window.location.host}/subscriptions`,
       options: {
@@ -65,6 +69,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
         connectionParams: () => ({ authToken: localStorage.getItem('token') }),
       },
     })
+
     link = split(
       ({ query }) => {
         const { kind, operation } = getMainDefinition(query)
@@ -74,6 +79,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
       link,
     )
   }
+
   const config = {
     link,
     cache: new InMemoryCache({
@@ -87,7 +93,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
               read(existing, { cache, args, readField }) {
                 const currentRoles = currentRolesVar()
                 const currentId = readField('id')
-                const r = currentRoles.find(r => r.id === currentId)
+                const r = currentRoles.find(ro => ro.id === currentId)
                 return (r && r.roles) || []
               },
             },
@@ -99,7 +105,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
               read(existing, { cache, args, readField }) {
                 const currentRoles = currentRolesVar()
                 const currentId = readField('id')
-                const r = currentRoles.find(r => r.id === currentId)
+                const r = currentRoles.find(ro => ro.id === currentId)
                 return (r && r.roles) || []
               },
             },
@@ -108,6 +114,7 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
       },
     }),
   }
+
   return new ApolloClient(makeConfig ? makeConfig(config) : config)
 }
 
diff --git a/app/components/NextPageButton/index.js b/app/components/NextPageButton/index.js
index ae43bf089a3f1c61d404c1ba50a470d03bcf002e..141c4e43e98a57181a6c23dd564db025649baf35 100644
--- a/app/components/NextPageButton/index.js
+++ b/app/components/NextPageButton/index.js
@@ -1,7 +1,7 @@
 import VisibilitySensor from 'react-visibility-sensor'
 import { Link } from 'react-router-dom'
 import React from 'react'
-// import PropTypes from 'prop-types'
+import PropTypes from 'prop-types'
 import { Spinner } from '../shared'
 import { HasNextPage, NextPageButton } from './style'
 
@@ -11,14 +11,16 @@ const NextPageButtonWrapper = props => {
     fetchMore,
     href,
     children,
-    automatic = true,
-    topOffset = -250,
-    bottomOffset = -250,
+    automatic,
+    topOffset,
+    bottomOffset,
   } = props
+
   const onChange = isVisible => {
     if (isFetchingMore || !isVisible) return undefined
     return fetchMore()
   }
+
   return (
     <HasNextPage
       as={href ? Link : 'div'}
@@ -54,14 +56,23 @@ const NextPageButtonWrapper = props => {
 }
 
 // TODO: Set default props
-// NextPageButtonWrapper.propTypes = {
-//   isFetchingMore: PropTypes.bool,
-//   href: PropTypes.object,
-//   fetchMore: PropTypes.func.isRequired,
-//   children: PropTypes.string,
-//   automatic: PropTypes.bool,
-//   topOffset: PropTypes.number,
-//   bottomOffset: PropTypes.number,
-// }
+NextPageButtonWrapper.propTypes = {
+  isFetchingMore: PropTypes.bool,
+  href: PropTypes.string,
+  fetchMore: PropTypes.func.isRequired,
+  children: PropTypes.string,
+  automatic: PropTypes.bool,
+  topOffset: PropTypes.number,
+  bottomOffset: PropTypes.number,
+}
+
+NextPageButtonWrapper.defaultProps = {
+  isFetchingMore: false,
+  href: undefined,
+  children: undefined,
+  automatic: true,
+  topOffset: -250,
+  bottomOffset: -250,
+}
 
 export default NextPageButtonWrapper
diff --git a/app/components/RolesUpdater.js b/app/components/RolesUpdater.js
index dce467a47eac319b4a66ff2bf1fd4763fbb4d936..34c52248ce8724b5fb7f0cde030507b9f1c280f1 100644
--- a/app/components/RolesUpdater.js
+++ b/app/components/RolesUpdater.js
@@ -6,18 +6,21 @@ import currentRolesVar from '../shared/currentRolesVar'
 
 const updateStuff = data => {
   if (data?.currentUser) {
+    // eslint-disable-next-line no-underscore-dangle
     return currentRolesVar(data.currentUser._currentRoles)
   }
+
+  return null
 }
 
-const RolesUpdater = ({ children, history, match }) => {
+const RolesUpdater = ({ children }) => {
   // This updates the current roles app-wide using Apollo's makeVar
   const { data, error, loading } = useQuery(GET_CURRENT_USER, {
     pollInterval: 5000,
     notifyOnNetworkStatusChange: true,
     fetchPolicy: 'network-only',
     // TODO: useCallback used because of bug: https://github.com/apollographql/apollo-client/issues/6301
-    onCompleted: useCallback(data => updateStuff(data), []),
+    onCompleted: useCallback(dataCompleted => updateStuff(dataCompleted), []),
   })
 
   if ((error && !error.networkError) || (!loading && !data?.currentUser)) {
diff --git a/app/components/component-dashboard/src/components/JournalLink.js b/app/components/component-dashboard/src/components/JournalLink.js
index 0eebff3df893cb5b0309bb629b077db72259c9d6..2e10e69566c62857d64c42fa1a4ac42d3e42c3ee 100644
--- a/app/components/component-dashboard/src/components/JournalLink.js
+++ b/app/components/component-dashboard/src/components/JournalLink.js
@@ -1,7 +1,8 @@
 import React from 'react'
 import { Link } from '@pubsweet/ui'
+import PropTypes from 'prop-types'
 
-const projectUrl = ({ version, page, id }) => {
+const projectUrl = (version, page, id) => {
   const parts = []
 
   if (version) {
@@ -20,10 +21,23 @@ const projectUrl = ({ version, page, id }) => {
   return parts.join('/')
 }
 
-const JournalLink = props => (
-  <Link className={props.className} to={projectUrl(props)}>
-    {props.children}
+const JournalLink = ({ className, children, version, page, id }) => (
+  <Link className={className} to={projectUrl(version, page, id)}>
+    {children}
   </Link>
 )
 
+JournalLink.propTypes = {
+  version: PropTypes.shape({
+    id: PropTypes.string,
+  }),
+  page: PropTypes.string,
+  id: PropTypes.string,
+}
+
+JournalLink.defaultProps = {
+  version: undefined,
+  page: undefined,
+  id: undefined,
+}
 export default JournalLink
diff --git a/app/storage/forms/submit.json b/app/storage/forms/submit.json
index 5c2ee38643601527a32152a779caf567a9dafae0..0370ab6a1d229b7f7986641a6d82defc3e2ca748 100644
--- a/app/storage/forms/submit.json
+++ b/app/storage/forms/submit.json
@@ -408,5 +408,5 @@
   "description": "<p>Aperture is now accepting Research Object Submissions. Please fill out the form below to complete your submission.</p>",
   "haspopup": "true",
   "popuptitle": "By submitting the manuscript, you agree to the following statements.",
-  "popupdescription": "<p>The corresponding author confirms that all co-authors are included, and that everyone listed as a co-author agrees to that role and all the following requirements and acknowledgements.</p><p></p><p>The submission represents original work and that sources are given proper attribution. The journal employs CrossCheck to compare submissions against a large and growing database of published scholarly content. If in the judgment of a senior editor a submission is genuinely suspected of plagiarism, it will be returned to the author(s) with a request for explanation.</p><p></p><p>The research was conducted in accordance with ethical principles.</p><p></p><p>There is a Data Accessibility Statement, containing information about the location of open data and materials, in the manuscript.</p><p></p><p>A conflict of interest statement is present in the manuscript, even if to state no conflicts of interest.</p>"
-}
+  "popupdescription": "<p>The corresponding author confirms that all co-authors are included, and that everyone listed as a co-author agrees to that role and all the following requirements and acknowledgements.</p><p></p><p>The submission represents original work and that sources are given proper attribution. The journal employs CrossCheck to compare submissions against a large and growing database of published scholarly content. If in the judgment of a senior editor a submission is genuinely suspected of plagiarism, it will be returned to the author(s) with a request for explanation.</p><p></p><p>The research was conducted in accordance with ethical principles.</p><p></p><p>There is a Data Accessibility Statement, containing information about the location of open data and materials, in the manuscript.</p><p>n</p><p>A conflict of interest statement is present in the manuscript, even if to state no conflicts of interest.</p>"
+}
\ No newline at end of file