diff --git a/app/Root.jsx b/app/Root.jsx
index a5d986e00184a2ea4f36252602fab6ef270e5914..a9129436c9989311c4458aa6cb64dbf087af9709 100644
--- a/app/Root.jsx
+++ b/app/Root.jsx
@@ -1,26 +1,43 @@
 /* eslint-disable no-param-reassign */
 import React from 'react'
+// import { BrowserRouter } from 'react-router-dom'
+// import PropTypes from 'prop-types'
+// import { ThemeProvider } from 'styled-components'
+// import { ApolloProvider } from '@apollo/react-components'
+// import { ApolloClient } from 'apollo-client'
+// import { WebSocketLink } from 'apollo-link-ws'
+// import { split, ApolloLink } from 'apollo-link'
+// import { getMainDefinition } from 'apollo-utilities'
+// import { setContext } from 'apollo-link-context'
+// import {
+//   InMemoryCache,
+//   IntrospectionFragmentMatcher,
+// } from 'apollo-cache-inmemory'
+// import { createUploadLink } from 'apollo-upload-client'
+import GlobalStyle from './theme/elements/GlobalStyle'
+
+// import introspectionQueryResultData from './fragmentTypes.json'
+
 import { BrowserRouter } from 'react-router-dom'
 import PropTypes from 'prop-types'
 import { ThemeProvider } from 'styled-components'
-import { ApolloProvider } from '@apollo/react-components'
-import { ApolloClient } from 'apollo-client'
-import { WebSocketLink } from 'apollo-link-ws'
-import { split, ApolloLink } from 'apollo-link'
-import { getMainDefinition } from 'apollo-utilities'
-import { setContext } from 'apollo-link-context'
 import {
-  InMemoryCache,
-  IntrospectionFragmentMatcher,
-} from 'apollo-cache-inmemory'
+  ApolloProvider,
+  ApolloClient,
+  ApolloLink,
+  split,
+  gql,
+} from '@apollo/client'
+// import { ApolloClient } from 'apollo-client'
+import { WebSocketLink } from '@apollo/client/link/ws'
+// import { split, ApolloLink } from 'apollo-link'
+import { getMainDefinition } from '@apollo/client/utilities'
+import { setContext } from '@apollo/client/link/context'
+import { InMemoryCache } from '@apollo/client/cache'
 import { createUploadLink } from 'apollo-upload-client'
-import GlobalStyle from './theme/elements/GlobalStyle'
 
-import introspectionQueryResultData from './fragmentTypes.json'
-
-const fragmentMatcher = new IntrospectionFragmentMatcher({
-  introspectionQueryResultData,
-})
+import { GET_CURRENT_USER } from './queries'
+import currentRolesVar from './shared/currentRolesVar'
 
 // See https://github.com/apollographql/apollo-feature-requests/issues/6#issuecomment-465305186
 export function stripTypenames(obj) {
@@ -83,7 +100,25 @@ const makeApolloClient = (makeConfig, connectToWebSocket) => {
   }
   const config = {
     link,
-    cache: new InMemoryCache({ fragmentMatcher }),
+    cache: new InMemoryCache({
+      possibleTypes: {
+        Identity: ['LocalIdentity', 'ExternalIdentity'],
+      },
+      typePolicies: {
+        Manuscript: {
+          fields: {
+            _currentRoles: {
+              read(existing, { cache, args, readField }) {
+                const currentRoles = currentRolesVar()
+                const currentId = readField('id')
+                const r = currentRoles.find(r => r.id === currentId)
+                return (r && r.roles) || []
+              },
+            },
+          },
+        },
+      },
+    }),
   }
   return new ApolloClient(makeConfig ? makeConfig(config) : config)
 }
diff --git a/app/app.js b/app/app.js
index a2b58f454fc55c7c4f7b8ed7f3bd3eba4fb2dd6f..03597a268478f7cacbb2bf01c2cf25f89823327e 100644
--- a/app/app.js
+++ b/app/app.js
@@ -9,7 +9,7 @@ import theme from './theme'
 import { JournalProvider } from './components/xpub-journal'
 import { XpubProvider } from './components/xpub-with-context'
 
-import * as journal from './config/journal'
+import * as journal from '../config/journal'
 import routes from './routes'
 
 const history = createBrowserHistory()
diff --git a/app/components/AdminPage.js b/app/components/AdminPage.js
index fef8ac26882c663b4deba29a80dc9fa7dc2f4dae..8b71c88b2037cad8fe2480d5c27682d25c239d7e 100644
--- a/app/components/AdminPage.js
+++ b/app/components/AdminPage.js
@@ -1,7 +1,7 @@
-import React, { useContext } from 'react'
+import React, { useContext, useCallback, useRef } from 'react'
 import styled from 'styled-components'
 import { compose } from 'recompose'
-import { useQuery, useApolloClient } from '@apollo/react-hooks'
+import { useQuery, useApolloClient, gql } from '@apollo/client'
 import {
   withRouter,
   matchPath,
@@ -27,9 +27,12 @@ import FormBuilderPage from '../components/component-formbuilder/src/components/
 import NewSubmissionPage from '../components/component-submit/src/components/NewSubmissionPage'
 import { Profile } from '../components/component-profile/src'
 
-import queries from '../graphql'
+import { GET_CURRENT_USER } from '../queries'
 
 import Menu from './Menu'
+import { Spinner } from './shared'
+
+import currentRolesVar from '../shared/currentRolesVar'
 
 const getParams = routerPath => {
   const path = '/journal/versions/:version'
@@ -67,15 +70,46 @@ const PrivateRoute = ({ component: Component, ...rest }) => (
   />
 )
 
+const updateStuff = data => {
+  currentRolesVar(data.currentUser._currentRoles)
+  console.log('updating stuff')
+}
+
 const AdminPage = ({ children, history, match }) => {
   const client = useApolloClient()
 
   const journal = useContext(JournalContext)
   const [conversion] = useContext(XpubContext)
 
-  const { data } = useQuery(queries.currentUser)
+  // Get the current user every 5 seconds (this includes authorization info)
+  const { loading, error, data } = 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), []),
+  })
+
+  const previousDataRef = useRef(null)
+
+  // Do this to prevent polling-related flicker
+  if (loading && !previousDataRef.current) {
+    return <Spinner />
+  }
+
+  let notice = ''
+  if (error) {
+    if (error.networkError) {
+      notice = 'You are offline.'
+    } else {
+      return <Redirect to="/login" />
+    }
+  }
+
   const currentUser = data && data.currentUser
 
+  previousDataRef.current = data
+
   const { pathname } = history.location
   const showLinks = pathname.match(/^\/(submit|manuscript)/g)
   let links = []
@@ -119,6 +153,7 @@ const AdminPage = ({ children, history, match }) => {
         brandLink="/journal/dashboard"
         loginLink="/login?next=/journal/dashboard"
         navLinkComponents={links}
+        notice={notice}
         user={currentUser}
       />
       <Switch>
diff --git a/app/components/Menu.js b/app/components/Menu.js
index ffb5e2e8fca6f51c210e3b4fd44b3889f5038b92..ea09642f9aa5a4876005873d9fdfa2e110b66658 100644
--- a/app/components/Menu.js
+++ b/app/components/Menu.js
@@ -108,11 +108,18 @@ const UserInfo = styled.div`
   margin-left: ${grid(1)};
 `
 
-const Menu = ({ className, loginLink = '/login', navLinkComponents, user }) => (
+const Menu = ({
+  className,
+  loginLink = '/login',
+  navLinkComponents,
+  user,
+  notice,
+}) => (
   <Root className={className}>
     <Section>
+      {/* TODO: Place this notice (used for offline notification) better */}
+      {notice}
       <UserComponent loginLink={loginLink} user={user} />
-
       {navLinkComponents &&
         navLinkComponents.map((navInfo, idx) => (
           <Item
@@ -129,7 +136,7 @@ const UserComponent = ({ user, loginLink }) => (
   <Section>
     {user && (
       <UserItem to="/journal/profile">
-        <UserAvatar user={user} size={64} />
+        <UserAvatar size={64} user={user} />
         <UserInfo>
           {user.defaultIdentity.name || user.username}
           {/* ({user.username}) */}
@@ -137,7 +144,7 @@ const UserComponent = ({ user, loginLink }) => (
         </UserInfo>
       </UserItem>
     )}
-    {!user && <Item name="Login" link={loginLink} />}
+    {!user && <Item link={loginLink} name="Login" />}
   </Section>
 )
 
diff --git a/app/components/component-avatar/src/UserAvatar.js b/app/components/component-avatar/src/UserAvatar.js
index 55f93f0e121c12507954bd131d6bd4a06cd6283c..1ea54d142ee4d74b6371e9db7cfa1bd055d74c18 100644
--- a/app/components/component-avatar/src/UserAvatar.js
+++ b/app/components/component-avatar/src/UserAvatar.js
@@ -1,6 +1,6 @@
 // @flow
 import * as React from 'react'
-import { useQuery } from '@apollo/react-hooks'
+import { useQuery } from '@apollo/client'
 import styled from 'styled-components'
 // import { GET_USER } from '../../queries'
 // import { UserHoverProfile } from 'src/components/hoverProfile';
diff --git a/app/components/component-dashboard/src/components/Dashboard.js b/app/components/component-dashboard/src/components/Dashboard.js
index 4edda6a4ee0b34c86cb195adb771939be5093c29..dc8adb343ef36e9d5c1e00d9525db6a41e39c6ee 100644
--- a/app/components/component-dashboard/src/components/Dashboard.js
+++ b/app/components/component-dashboard/src/components/Dashboard.js
@@ -1,5 +1,5 @@
 import React from 'react'
-import { useQuery, useMutation } from '@apollo/react-hooks'
+import { useQuery, useMutation } from '@apollo/client'
 import { Action, Button, Icon } from '@pubsweet/ui'
 // import Authorize from 'pubsweet-client/src/helpers/Authorize'
 
@@ -11,6 +11,7 @@ import {
   Heading,
   Content,
   HeadingWithAction,
+  Placeholder,
 } from '../style'
 import EditorItem from './sections/EditorItem'
 import OwnerItem from './sections/OwnerItem'
@@ -23,6 +24,8 @@ import {
   SectionContent,
 } from '../../../shared'
 
+import hasRole from '../../../../shared/hasRole'
+
 const updateReviewer = (proxy, { data: { reviewerResponse } }) => {
   const id = reviewerResponse.object.objectId
   const data = proxy.readQuery({
@@ -45,7 +48,7 @@ const Dashboard = ({ history, ...props }) => {
   // const uploadManuscript = upload()
   // const [conversion] = useContext(XpubContext)
 
-  const { loading, data } = useQuery(queries.dashboard)
+  const { loading, data, error } = useQuery(queries.dashboard)
   const [reviewerRespond] = useMutation(mutations.reviewerResponseMutation, {
     // variables: { currentUserId, action, teamId },
     update: updateReviewer,
@@ -65,27 +68,37 @@ const Dashboard = ({ history, ...props }) => {
   })
 
   if (loading) return <Spinner />
-
+  if (error) return error
   const dashboard = (data && data.manuscripts) || []
   const currentUser = data && data.currentUser
 
+  const mySubmissions = dashboard.filter(submission =>
+    hasRole(submission, 'author'),
+  )
+
+  const toReview = dashboard.filter(submission =>
+    hasRole(submission, 'reviewer'),
+  )
+
+  const manuscriptsImEditorOf = dashboard.filter(submission =>
+    hasRole(submission, ['seniorEditor', 'handlingEditor']),
+  )
+
   return (
     <Container>
       <HeadingWithAction>
         <Heading>Dashboard</Heading>
         <Button onClick={() => history.push('/journal/newSubmission')} primary>
-          {/* <Icon>plus</Icon> */}+ New submission
+          + New submission
         </Button>
       </HeadingWithAction>
 
-      {!dashboard.length && <Section>Nothing to do at the moment.</Section>}
-      {/* <Authorize object={dashboard} operation="can view my submission section"> */}
-      {dashboard.length > 0 ? (
-        <SectionContent>
-          <SectionHeader>
-            <Title>My Submissions</Title>
-          </SectionHeader>
-          {dashboard.map(submission => (
+      <SectionContent>
+        <SectionHeader>
+          <Title>My Submissions</Title>
+        </SectionHeader>
+        {dashboard.length > 0 ? (
+          mySubmissions.map(submission => (
             <SectionRow key={`submission-${submission.id}`}>
               <OwnerItem
                 deleteManuscript={() =>
@@ -97,18 +110,17 @@ const Dashboard = ({ history, ...props }) => {
                 version={submission}
               />
             </SectionRow>
-          ))}
-        </SectionContent>
-      ) : null}
-      {/* </Authorize>
-      <Authorize object={dashboard} operation="can view review section"> */}
-      {dashboard.length > 0 ? (
-        <SectionContent>
-          <SectionHeader>
-            <Title>To Review</Title>
-          </SectionHeader>
-
-          {dashboard.map(review => (
+          ))
+        ) : (
+          <Placeholder>You have not submitted any manuscripts yet</Placeholder>
+        )}
+      </SectionContent>
+      <SectionContent>
+        <SectionHeader>
+          <Title>To Review</Title>
+        </SectionHeader>
+        {toReview.length > 0 ? (
+          toReview.map(review => (
             <SectionRow key={review.id}>
               <ReviewerItem
                 currentUser={currentUser}
@@ -117,25 +129,30 @@ const Dashboard = ({ history, ...props }) => {
                 version={review}
               />
             </SectionRow>
-          ))}
-        </SectionContent>
-      ) : null}
-      {/* </Authorize> */}
+          ))
+        ) : (
+          <Placeholder>You have not been assigned any reviews yet</Placeholder>
+        )}
+      </SectionContent>
 
-      {/* <Authorize object={dashboard} operation="can view my manuscripts section"> */}
-      {dashboard.length > 0 ? (
-        <SectionContent>
-          <SectionHeader>
-            <Title>Manuscripts I'm editor of</Title>
-          </SectionHeader>
-          {dashboard.map(manuscript => (
+      <SectionContent>
+        <SectionHeader>
+          <Title>Manuscripts I'm editor of</Title>
+        </SectionHeader>
+        {manuscriptsImEditorOf.length > 0 ? (
+          manuscriptsImEditorOf.map(manuscript => (
             <SectionRow key={`manuscript-${manuscript.id}`}>
               <EditorItem version={manuscript} />
             </SectionRow>
-          ))}
-        </SectionContent>
-      ) : null}
-      {/* </Authorize> */}
+          ))
+        ) : (
+          <SectionRow>
+            <Placeholder>
+              You are not an editor of any manuscript yet
+            </Placeholder>
+          </SectionRow>
+        )}
+      </SectionContent>
     </Container>
   )
 }
diff --git a/app/components/component-dashboard/src/components/Reviews.js b/app/components/component-dashboard/src/components/Reviews.js
index 5a70702a70d667910401e01fc0fe27555c37d599..7d5356b147554d02569171398a50da6cf06dea34 100644
--- a/app/components/component-dashboard/src/components/Reviews.js
+++ b/app/components/component-dashboard/src/components/Reviews.js
@@ -29,7 +29,7 @@ const getUserFromTeam = (version, role) => {
 }
 
 const countStatus = (version, status) => {
-  const teamMember = getUserFromTeam(version, 'reviewerEditor')
+  const teamMember = getUserFromTeam(version, 'reviewer')
 
   if (status === 'rejected' || status === 'invited') {
     return sumBy(teamMember, member => (member.status === status ? 1 : 0))
diff --git a/app/components/component-dashboard/src/components/sections/OwnerItem.js b/app/components/component-dashboard/src/components/sections/OwnerItem.js
index 0fb2012fcb0e85eda8b2a511e89bb6e317ff314b..a548bd1caf887aad14d44baa455531c7277aa182 100644
--- a/app/components/component-dashboard/src/components/sections/OwnerItem.js
+++ b/app/components/component-dashboard/src/components/sections/OwnerItem.js
@@ -47,16 +47,15 @@ const OwnerItem = ({ version, journals, deleteManuscript }) => {
   )
 
   return (
-    // <Authorize object={[version]} operation="can view my submission section">
     <Item>
       <div>
         {' '}
         <StatusBadge minimal status={version.status} />
+        {JSON.stringify(version._currentRoles)}
         <VersionTitle version={version} />
       </div>
       {actions}
     </Item>
-    // </Authorize>
   )
 }
 
diff --git a/app/components/component-dashboard/src/components/sections/ReviewerItem.js b/app/components/component-dashboard/src/components/sections/ReviewerItem.js
index 344c1bfaae713d10ff07c3c570930f7865096902..ff657d39a4080fcd8069779d46fc016fb788c528 100644
--- a/app/components/component-dashboard/src/components/sections/ReviewerItem.js
+++ b/app/components/component-dashboard/src/components/sections/ReviewerItem.js
@@ -20,7 +20,7 @@ import VersionTitle from './VersionTitle'
 
 const ReviewerItem = ({ version, journals, currentUser, reviewerRespond }) => {
   const team =
-    (version.teams || []).find(team => team.role === 'reviewerEditor') || {}
+    (version.teams || []).find(team => team.role === 'reviewer') || {}
 
   const currentMember =
     team.members &&
@@ -29,7 +29,7 @@ const ReviewerItem = ({ version, journals, currentUser, reviewerRespond }) => {
 
   // Enable that when Team Models is updated
   // const { status } =
-  //   getUserFromTeam(version, 'reviewerEditor').filter(
+  //   getUserFromTeam(version, 'reviewer').filter(
   //     member => member.id === currentUser.id,
   //   )[0] || {}
 
diff --git a/app/components/component-dashboard/src/graphql/queries/index.js b/app/components/component-dashboard/src/graphql/queries/index.js
index 86cf636dfb4e1f90a57a84030dffee966be88164..1b45a6149ad022cf6d15961d793e6e9f506e7d68 100644
--- a/app/components/component-dashboard/src/graphql/queries/index.js
+++ b/app/components/component-dashboard/src/graphql/queries/index.js
@@ -59,6 +59,7 @@ export default {
             date
           }
         }
+        _currentRoles @client
       }
     }
   `,
diff --git a/app/components/component-dashboard/src/style.js b/app/components/component-dashboard/src/style.js
index da125ae71d89f1d274aba4fb617aefc0b5b5cb4e..a26994e622dc676cb09a5e561ae11289cfed7049 100644
--- a/app/components/component-dashboard/src/style.js
+++ b/app/components/component-dashboard/src/style.js
@@ -76,3 +76,11 @@ export const HeadingWithAction = styled.div`
 `
 
 export { StatusBadge } from '../../shared'
+
+export const Placeholder = styled.div`
+  display: grid;
+  place-items: center;
+  color: ${th('colorTextPlaceholder')};
+  height: 100%;
+  padding: 4em;
+`
diff --git a/app/components/component-formbuilder/src/components/FormBuilderPage.js b/app/components/component-formbuilder/src/components/FormBuilderPage.js
index 57c20bb5a80f40658b4f3cb38418e76f26360ea3..9cfb45edbf88a31a577329ef35ea428ac5dfa572 100644
--- a/app/components/component-formbuilder/src/components/FormBuilderPage.js
+++ b/app/components/component-formbuilder/src/components/FormBuilderPage.js
@@ -1,5 +1,5 @@
 import { compose, withState, withHandlers, withProps } from 'recompose'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 import { withLoader } from 'pubsweet-client'
 
diff --git a/app/components/component-login/src/Login.jsx b/app/components/component-login/src/Login.jsx
index dab9a14201a4eb806691b39b532ff2d2b730251d..9fd99f091f431bfbd4b8bbba646a120f0c80cc52 100644
--- a/app/components/component-login/src/Login.jsx
+++ b/app/components/component-login/src/Login.jsx
@@ -7,6 +7,7 @@ import { th, grid, lighten } from '@pubsweet/ui-toolkit'
 import { CenteredColumn, H1, Button } from '@pubsweet/ui'
 import styled from 'styled-components'
 import { Section } from '../../shared'
+import { Placeholder } from '../../component-chat/src/Messages/style'
 
 const getNextUrl = () => {
   const url = new URL(window.location.href)
@@ -56,7 +57,11 @@ const LoginButton = styled(Button)`
 
 // TODO: Shared?
 const Container = styled.div`
-  background: linear-gradient(134deg, ${th('colorPrimary')}, ${lighten('colorPrimary', 0.3)});
+  background: linear-gradient(
+    134deg,
+    ${th('colorPrimary')},
+    ${lighten('colorPrimary', 0.3)}
+  );
   height: 100vh;
   display: grid;
   place-items: center;
@@ -66,35 +71,39 @@ const Content = styled.div`
   border-radius: ${th('borderRadius')};
   box-shadow: ${th('boxShadow')};
   padding: ${grid(4)};
-  max-width: 30em;
+  max-width: 40em;
   background: ${th('colorBackground')};
   text-align: center;
 
   h1 {
     margin-bottom: ${grid(2)};
   }
+  margin-bottom: 1rem;
 `
 
+const Centered = styled.div`
+  text-align: center;
+`
 
-const ORCIDIcon = ({className}) => (
+const ORCIDIcon = ({ className }) => (
   <span className={className}>
-  <svg viewBox="0 0 256 256">
-    <path
-      d="M256,128c0,70.7-57.3,128-128,128C57.3,256,0,198.7,0,128C0,57.3,57.3,0,128,0C198.7,0,256,57.3,256,128z"
-      fill="#A6CE39"
-    />
-    <g>
-      <path d="M86.3,186.2H70.9V79.1h15.4v48.4V186.2z" fill="#FFFFFF" />
-      <path
-        d="M108.9,79.1h41.6c39.6,0,57,28.3,57,53.6c0,27.5-21.5,53.6-56.8,53.6h-41.8V79.1z M124.3,172.4h24.5   c34.9,0,42.9-26.5,42.9-39.7c0-21.5-13.7-39.7-43.7-39.7h-23.7V172.4z"
-        fill="#FFFFFF"
-      />
+    <svg viewBox="0 0 256 256">
       <path
-        d="M88.7,56.8c0,5.5-4.5,10.1-10.1,10.1c-5.6,0-10.1-4.6-10.1-10.1c0-5.6,4.5-10.1,10.1-10.1   C84.2,46.7,88.7,51.3,88.7,56.8z"
-        fill="#FFFFFF"
+        d="M256,128c0,70.7-57.3,128-128,128C57.3,256,0,198.7,0,128C0,57.3,57.3,0,128,0C198.7,0,256,57.3,256,128z"
+        fill="#A6CE39"
       />
-    </g>
-  </svg>
+      <g>
+        <path d="M86.3,186.2H70.9V79.1h15.4v48.4V186.2z" fill="#FFFFFF" />
+        <path
+          d="M108.9,79.1h41.6c39.6,0,57,28.3,57,53.6c0,27.5-21.5,53.6-56.8,53.6h-41.8V79.1z M124.3,172.4h24.5   c34.9,0,42.9-26.5,42.9-39.7c0-21.5-13.7-39.7-43.7-39.7h-23.7V172.4z"
+          fill="#FFFFFF"
+        />
+        <path
+          d="M88.7,56.8c0,5.5-4.5,10.1-10.1,10.1c-5.6,0-10.1-4.6-10.1-10.1c0-5.6,4.5-10.1,10.1-10.1   C84.2,46.7,88.7,51.3,88.7,56.8z"
+          fill="#FFFFFF"
+        />
+      </g>
+    </svg>
   </span>
 )
 
@@ -123,23 +132,31 @@ const Login = ({ logo = null, ...props }) => {
     return <Redirect to={redirectLink} />
   }
 
+  const journalName = config.journal.metadata.name
   return redirectLink ? (
     <Redirect to={redirectLink} />
   ) : (
     <Container>
-      <Content>
-      <H1>Login to Kotahi</H1>
-
-          Kotahi uses ORCID <StyledORCIDIcon /> to identify authors and staff. Login with your
-          ORCID account below or{' '}
+      <Centered>
+        <Content>
+          {journalName === 'Aperture' && (
+            <img src="/public/logo-aperture.png" />
+          )}
+          <H1>Login to {journalName}</H1>
+          {journalName} uses ORCID <StyledORCIDIcon /> to identify authors and
+          staff. Login with your ORCID account below or{' '}
           <a href="https://orcid.org/signin">register at the ORCID website.</a>
-        <LoginButton onClick={() => window.location = "/auth/orcid"} primary>
-          Login with ORCID
-        </LoginButton>
-      </Content>
-
+          <LoginButton
+            onClick={() => (window.location = '/auth/orcid')}
+            primary
+          >
+            Login with ORCID
+          </LoginButton>
+        </Content>
+        <div>Powered by Kotahi</div>
+      </Centered>
     </Container>
   )
 }
 
-export default Login
\ No newline at end of file
+export default Login
diff --git a/app/components/component-manuscript/src/components/ManuscriptPage.js b/app/components/component-manuscript/src/components/ManuscriptPage.js
index 39387f32b092fbca0da81276b225aebd08a28eef..2d1847f503119b2b5ea93811d549324d4b1a34c1 100644
--- a/app/components/component-manuscript/src/components/ManuscriptPage.js
+++ b/app/components/component-manuscript/src/components/ManuscriptPage.js
@@ -1,5 +1,5 @@
 import { compose, withProps } from 'recompose'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 import { withLoader } from 'pubsweet-client'
 
diff --git a/app/components/component-manuscripts/src/Manuscript.jsx b/app/components/component-manuscripts/src/Manuscript.jsx
index 95493e7e2e6b66e6edc164e2ede0698991555261..53e0e7f1350fd3c40f52e63d332960310af2674a 100644
--- a/app/components/component-manuscripts/src/Manuscript.jsx
+++ b/app/components/component-manuscripts/src/Manuscript.jsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import gql from 'graphql-tag'
-import { useMutation } from '@apollo/react-hooks'
+import { useMutation } from '@apollo/client'
 // import { Action } from '@pubsweet/ui'
 import { UserAvatar } from '../../component-avatar/src'
 import {
diff --git a/app/components/component-manuscripts/src/Manuscripts.jsx b/app/components/component-manuscripts/src/Manuscripts.jsx
index f3d89a8d8efebf2d252851ec5c6c2c5be33054de..dd3dee928e6f6d45e9e95c9b37c98c6e438ca810 100644
--- a/app/components/component-manuscripts/src/Manuscripts.jsx
+++ b/app/components/component-manuscripts/src/Manuscripts.jsx
@@ -1,6 +1,6 @@
 import React, { useState } from 'react'
 import gql from 'graphql-tag'
-import { useQuery } from '@apollo/react-hooks'
+import { useQuery } from '@apollo/client'
 
 import Manuscript from './Manuscript'
 import {
diff --git a/app/components/component-profile/src/ChangeUsername.jsx b/app/components/component-profile/src/ChangeUsername.jsx
index ea707cca30d53ca3a4b0f81e695661779c9a4397..6c981758d7d287104baa484b98804e245b2693e8 100644
--- a/app/components/component-profile/src/ChangeUsername.jsx
+++ b/app/components/component-profile/src/ChangeUsername.jsx
@@ -1,7 +1,7 @@
 import React, { useState } from 'react'
 import PropTypes from 'prop-types'
 import gql from 'graphql-tag'
-import { useMutation } from '@apollo/react-hooks'
+import { useMutation } from '@apollo/client'
 import { TextField, Button } from '@pubsweet/ui'
 import { th } from '@pubsweet/ui-toolkit'
 import styled from 'styled-components'
diff --git a/app/components/component-profile/src/Profile.jsx b/app/components/component-profile/src/Profile.jsx
index 957788567f94c52a5a6d3681283dffa57616cadd..a137940b612b238a9e0cd3986bba83dadf09d2be 100644
--- a/app/components/component-profile/src/Profile.jsx
+++ b/app/components/component-profile/src/Profile.jsx
@@ -3,7 +3,7 @@ import { Button, Action } from '@pubsweet/ui'
 // import { th } from '@pubsweet/ui-toolkit'
 // import styled from 'styled-components'
 import gql from 'graphql-tag'
-import { useQuery } from '@apollo/react-hooks'
+import { useQuery } from '@apollo/client'
 import { useDropzone } from 'react-dropzone'
 
 import { Spinner } from '../../shared'
diff --git a/app/components/component-review/src/components/DecisionPage.js b/app/components/component-review/src/components/DecisionPage.js
index 9e532ee08eb41b0f5064d8d1aa4db54a33d4426e..f8768a6bf649c9564dbd13cfaa27b57168b140ed 100644
--- a/app/components/component-review/src/components/DecisionPage.js
+++ b/app/components/component-review/src/components/DecisionPage.js
@@ -3,8 +3,7 @@ import moment from 'moment'
 
 import { Tabs } from '@pubsweet/ui'
 import { Formik } from 'formik'
-import gql from 'graphql-tag'
-import { useMutation, useQuery } from '@apollo/react-hooks'
+import { useMutation, useQuery, gql } from '@apollo/client'
 import DecisionForm from './decision/DecisionForm'
 import DecisionReviews from './decision/DecisionReviews'
 import AssignEditorsReviewers from './assignEditors/AssignEditorsReviewers'
diff --git a/app/components/component-review/src/components/ReviewPage.js b/app/components/component-review/src/components/ReviewPage.js
index 0acc2b86393b5c5387175031afeebbf782cb053c..cc8aef0165d5c4682248a6a55837c50dc9b436f1 100644
--- a/app/components/component-review/src/components/ReviewPage.js
+++ b/app/components/component-review/src/components/ReviewPage.js
@@ -1,9 +1,7 @@
 import React from 'react'
-// import { compose, withProps } from 'recompose'
-import { useMutation, useQuery } from '@apollo/react-hooks'
+import { useMutation, useQuery } from '@apollo/client'
 import gql from 'graphql-tag'
 import { Formik } from 'formik'
-// import { withLoader } from 'pubsweet-client'
 import { cloneDeep } from 'lodash'
 import { getCommentContent } from './review/util'
 import ReviewLayout from '../components/review/ReviewLayout'
@@ -247,8 +245,8 @@ export default ({ match, ...props }) => {
 
   const status = (
     (
-      (manuscript.teams.find(team => team.role === 'reviewerEditor') || {})
-        .status || []
+      (manuscript.teams.find(team => team.role === 'reviewer') || {}).status ||
+      []
     ).find(status => status.user === currentUser.id) || {}
   ).status
 
@@ -311,7 +309,7 @@ export default ({ match, ...props }) => {
 
   const completeReview = history => {
     const team = cloneDeep(manuscript.teams).find(
-      team => team.role === 'reviewerEditor',
+      team => team.role === 'reviewer',
     )
     team.members = team.members.map(m => {
       if (m.user.id === currentUser.id) {
@@ -434,7 +432,7 @@ export default ({ match, ...props }) => {
 //   ) || {},
 // status: (
 //   (
-//     (manuscript.teams.find(team => team.role === 'reviewerEditor') || {})
+//     (manuscript.teams.find(team => team.role === 'reviewer') || {})
 //       .status || []
 //   ).find(status => status.user === currentUser.id) || {}
 // ).status,
@@ -495,7 +493,7 @@ export default ({ match, ...props }) => {
 //   }),
 //     completeReview: history => {
 //       const team = cloneDeep(manuscript.teams).find(
-//         team => team.role === 'reviewerEditor',
+//         team => team.role === 'reviewer',
 //       )
 //       team.members = team.members.map(m => {
 //         if (m.user.id === currentUser.id) {
diff --git a/app/components/component-review/src/components/ReviewersPage.js b/app/components/component-review/src/components/ReviewersPage.js
index f94c6319f0fffc6c2293c7ce7cc4eb36521b5eb0..6331ff1f7fb497afcc8ad5f89de5ad5bb67da522 100644
--- a/app/components/component-review/src/components/ReviewersPage.js
+++ b/app/components/component-review/src/components/ReviewersPage.js
@@ -1,6 +1,6 @@
 import { compose, withProps } from 'recompose'
 import { withFormik } from 'formik'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 import { withLoader } from 'pubsweet-client'
 import { omit } from 'lodash'
@@ -142,15 +142,14 @@ const handleSubmit = (
   { user },
   { props: { manuscript, updateTeamMutation, createTeamMutation, match } },
 ) => {
-  const team =
-    manuscript.teams.find(team => team.role === 'reviewerEditor') || {}
+  const team = manuscript.teams.find(team => team.role === 'reviewer') || {}
 
   const teamAdd = {
     objectId: manuscript.id,
     objectType: 'Manuscript',
     // status: [{ user: user.id, status: 'invited' }],
-    name: 'Reviewer Editor',
-    role: 'reviewerEditor',
+    name: 'Reviewers',
+    role: 'reviewer',
     members: [{ user: { id: user.id }, status: 'invited' }],
   }
   if (team.id) {
@@ -207,7 +206,7 @@ export default compose(
       const reviewersTeam =
         teams.find(
           team =>
-            team.role === 'reviewerEditor' &&
+            team.role === 'reviewer' &&
             team.object.objectId === manuscript.id &&
             team.object.objectType === 'Manuscript',
         ) || {}
diff --git a/app/components/component-review/src/components/assignEditors/AssignEditor.js b/app/components/component-review/src/components/assignEditors/AssignEditor.js
index a7f634cd130b0888176aa0557558ff2af8e42b00..51cd4ab4d846021f406c697da7a401ad354a768d 100644
--- a/app/components/component-review/src/components/assignEditors/AssignEditor.js
+++ b/app/components/component-review/src/components/assignEditors/AssignEditor.js
@@ -3,7 +3,7 @@ import config from 'config'
 import { compose, withProps } from 'recompose'
 import { cloneDeep, get } from 'lodash'
 import { Menu } from '@pubsweet/ui'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 import { withLoader } from 'pubsweet-client'
 
diff --git a/app/components/component-review/src/components/assignEditors/AssignEditor.md b/app/components/component-review/src/components/assignEditors/AssignEditor.md
deleted file mode 100644
index 49085706311761ea72d1fda712a31c5b85ccf935..0000000000000000000000000000000000000000
--- a/app/components/component-review/src/components/assignEditors/AssignEditor.md
+++ /dev/null
@@ -1,92 +0,0 @@
-A drop-down menu for assigning an editor to a project.
-
-```js
-const { JournalProvider } = require('xpub-journal')
-const journal = require('@pubsweet/styleguide/config/journal')
-
-const project = {
-  id: faker.random.uuid(),
-}
-
-const team = {
-  members: [],
-}
-
-const manuscriptTemplate = () => ({
-  id: faker.random.uuid(),
-  teams: [
-    {
-      id: faker.random.uuid(),
-      role: 'reviewerEditor',
-      name: 'reviewer',
-      object: {
-        id: faker.random.uuid(),
-        __typename: 'Manuscript',
-      },
-      objectType: 'manuscript',
-      members: [
-        {
-          user: { id: 1 },
-        },
-      ],
-    },
-  ],
-  meta: {
-    title: faker.lorem.sentence(25),
-    abstract: faker.lorem.sentence(100),
-    articleType: 'original-research',
-    declarations: {
-      openData: 'yes',
-      openPeerReview: 'no',
-      preregistered: 'yes',
-      previouslySubmitted: 'yes',
-      researchNexus: 'no',
-      streamlinedReview: 'no',
-    },
-  },
-  decision: {
-    id: faker.random.uuid(),
-    comments: [{ type: 'note', content: 'this needs review' }],
-    created: 'Thu Oct 11 2018',
-    open: false,
-    status: '<p>This is a decision</p>',
-    user: { id: 1 },
-  },
-  reviews: [
-    {
-      comments: [{ content: 'this needs review' }],
-      created: 'Thu Oct 11 2018',
-      open: false,
-      recommendation: 'revise',
-      user: { id: 1, username: 'test user' },
-    },
-  ],
-})
-
-const manuscript = Object.assign({}, manuscriptTemplate())
-
-const options = [
-  {
-    value: faker.random.uuid(),
-    label: faker.internet.userName(),
-  },
-  {
-    value: faker.random.uuid(),
-    label: faker.internet.userName(),
-  },
-  {
-    value: faker.random.uuid(),
-    label: faker.internet.userName(),
-  },
-]
-;<JournalProvider journal={journal}>
-  <AssignEditor
-    manuscript={manuscript}
-    team={team}
-    teamName="Senior Editor"
-    teamTypeName="seniorEditor"
-    options={options}
-    addUserToTeam={value => console.log(value)}
-  />
-</JournalProvider>
-```
diff --git a/app/components/component-review/src/components/decision/DecisionReviews.js b/app/components/component-review/src/components/decision/DecisionReviews.js
index 0416fbc03ac441be6e0fa2baddf97b13b6ce6a74..38f957a6b0490d4c0a89ba14becc7f3212cbfa25 100644
--- a/app/components/component-review/src/components/decision/DecisionReviews.js
+++ b/app/components/component-review/src/components/decision/DecisionReviews.js
@@ -5,14 +5,13 @@ import { H1, Action } from '@pubsweet/ui'
 
 // TODO: read reviewer ordinal and name from project reviewer
 // const { status } =
-//     getUserFromTeam(manuscript, 'reviewerEditor').filter(
+//     getUserFromTeam(manuscript, 'reviewer').filter(
 //       member => member.user.id === currentUser.id,
 //     )[0] || {}
 //   return status
 
 const getCompletedReviews = (manuscript, currentUser) => {
-  const team =
-    manuscript.teams.find(team => team.role === 'reviewerEditor') || {}
+  const team = manuscript.teams.find(team => team.role === 'reviewer') || {}
   if (!team.members) {
     return null
   }
diff --git a/app/components/component-review/src/components/metadata/ReviewMetadata.md b/app/components/component-review/src/components/metadata/ReviewMetadata.md
deleted file mode 100644
index 7666b612eec17aaec702fcc2e584472effbb85d2..0000000000000000000000000000000000000000
--- a/app/components/component-review/src/components/metadata/ReviewMetadata.md
+++ /dev/null
@@ -1,63 +0,0 @@
-Project metadata, displayed at the top of the review form.
-
-```js
-const manuscriptTemplate = () => ({
-  id: faker.random.uuid(),
-  teams: [
-    {
-      id: faker.random.uuid(),
-      role: 'reviewerEditor',
-      name: 'Reviewer',
-      object: {
-        id: faker.random.uuid(),
-        __typename: 'Manuscript',
-      },
-      objectType: 'manuscript',
-      members: [
-        {
-          user: {
-            id: 1,
-            username: 'test user',
-          },
-          status: 'accepted',
-        },
-      ],
-    },
-  ],
-  meta: {
-    title: faker.lorem.sentence(25),
-    abstract: faker.lorem.sentence(100),
-    articleType: 'original-research',
-    declarations: {
-      openData: 'yes',
-      openPeerReview: 'no',
-      preregistered: 'yes',
-      previouslySubmitted: 'yes',
-      researchNexus: 'no',
-      streamlinedReview: 'no',
-    },
-  },
-  decision: {
-    id: faker.random.uuid(),
-    comments: [{ type: 'note', content: 'this needs review' }],
-    created: 'Thu Oct 11 2018',
-    open: false,
-    status: '<p>This is a decision</p>',
-    user: { id: 1 },
-  },
-  reviews: [
-    {
-      comments: [{ content: 'this needs review' }],
-      created: 'Thu Oct 11 2018',
-      open: false,
-      recommendation: 'revise',
-      user: { id: 1, username: 'test user' },
-    },
-  ],
-})
-
-const manuscript = Object.assign({}, manuscriptTemplate(), {
-  manuscriptVersions: [manuscriptTemplate()],
-})
-;<ReviewMetadata manuscript={manuscript} />
-```
diff --git a/app/components/component-review/src/components/reviewers/ReviewerForm.md b/app/components/component-review/src/components/reviewers/ReviewerForm.md
deleted file mode 100644
index 28ba3f44b2e30c6e50ac6e0bf0c41100539edef3..0000000000000000000000000000000000000000
--- a/app/components/component-review/src/components/reviewers/ReviewerForm.md
+++ /dev/null
@@ -1,40 +0,0 @@
-A form for inviting a reviewer to a version of a project.
-
-```js
-const { withFormik } = require('formik')
-
-const reviewerUsers = [
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-]
-
-const loadOptions = input => {
-  // TODO: filter users
-
-  return Promise.resolve({ options: reviewerUsers })
-}
-
-const ConnectedReviewerForm = withFormik({
-  initialValues: {},
-  mapPropsToValues: ({ manuscript }) => manuscript,
-  displayName: 'reviewers',
-  handleSubmit: () => {},
-})(ReviewerForm)
-;<ConnectedReviewerForm
-  loadOptions={loadOptions}
-  form={{ values: { teams: [] } }}
-/>
-```
diff --git a/app/components/component-review/src/components/reviewers/Reviewers.md b/app/components/component-review/src/components/reviewers/Reviewers.md
deleted file mode 100644
index af59ba8a78bd87cf531da1aca607646a3701194b..0000000000000000000000000000000000000000
--- a/app/components/component-review/src/components/reviewers/Reviewers.md
+++ /dev/null
@@ -1,146 +0,0 @@
-On the reviewers page, the handling editor can:
-
-- Search users by entering a username or email address.
-- Add a user as a reviewer of this version (which also adds them as a reviewer of the project, if not already present).
-- View a list of reviewers of this version and perform actions on each reviewer.
-
-```js
-const { withFormik } = require('formik')
-const { compose, withHandlers } = require('recompose')
-const Reviewer = require('./Reviewer').default
-const ReviewerForm = require('./ReviewerForm').default
-
-const journal = {
-  id: faker.random.uuid(),
-  reviewers: [
-    {
-      id: faker.random.uuid(),
-      user: faker.random.uuid(),
-    },
-  ],
-}
-
-const manuscriptTemplate = () => ({
-  id: faker.random.uuid(),
-  teams: [
-    {
-      id: faker.random.uuid(),
-      role: 'reviewerEditor',
-      name: 'reviewer',
-      object: {
-        id: faker.random.uuid(),
-        __typename: 'Manuscript',
-      },
-      objectType: 'manuscript',
-      members: [
-        {
-          user: { id: 1 },
-        },
-      ],
-    },
-  ],
-  meta: {
-    title: faker.lorem.sentence(25),
-    abstract: faker.lorem.sentence(100),
-    articleType: 'original-research',
-    declarations: {
-      openData: 'yes',
-      openPeerReview: 'no',
-      preregistered: 'yes',
-      previouslySubmitted: 'yes',
-      researchNexus: 'no',
-      streamlinedReview: 'no',
-    },
-  },
-  decision: {
-    id: faker.random.uuid(),
-    comments: [{ type: 'note', content: 'this needs review' }],
-    created: 'Thu Oct 11 2018',
-    open: false,
-    status: '<p>This is a decision</p>',
-    user: { id: 1 },
-  },
-  reviews: [
-    {
-      comments: [{ content: 'this needs review' }],
-      created: 'Thu Oct 11 2018',
-      open: false,
-      recommendation: 'revise',
-      user: { id: 1, username: 'test user' },
-    },
-  ],
-})
-
-const manuscript = Object.assign({}, manuscriptTemplate())
-
-const reviewers = [
-  {
-    status: 'invited',
-    user: { id: 1, username: 'test user' },
-  },
-]
-
-const reviewerUsers = [
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-  {
-    id: faker.random.uuid(),
-    email: faker.internet.email(),
-    username: faker.internet.userName(),
-  },
-]
-
-initialState = {
-  reviewers,
-}
-
-const ReviewerFormContainer = compose(
-  withFormik({
-    form: 'reviewers',
-    handleSubmit: ({ user }) => {
-      setState({
-        reviewers: state.reviewers.concat({
-          id: faker.random.uuid(),
-          reviewer: faker.random.uuid(),
-          events: {
-            invited: new Date().toISOString(),
-          },
-          _user: user,
-          _reviewer: {
-            ordinal: null,
-          },
-        }),
-      })
-    },
-  }),
-  withHandlers({
-    loadOptions: props => input =>
-      Promise.resolve({ options: props.reviewerUsers }),
-  }),
-)(ReviewerForm)
-
-const ReviewerContainer = withHandlers({
-  removeReviewer: props => () =>
-    setState({
-      reviewers: state.reviewers.filter(
-        reviewer => reviewer.id !== props.reviewer.id,
-      ),
-    }),
-})(Reviewer)
-;<Reviewers
-  ReviewerForm={ReviewerFormContainer}
-  Reviewer={ReviewerContainer}
-  journal={journal}
-  manuscript={manuscript}
-  reviewers={state.reviewers}
-  reviewerUsers={reviewerUsers}
-/>
-```
diff --git a/app/components/component-submit/src/components/NewSubmissionPage.jsx b/app/components/component-submit/src/components/NewSubmissionPage.jsx
index 96a65839dcbfe74e13b2316494d86e2a1dd7e067..2ce2b53f61730cc79c8d318ae341cf6313c0cdce 100644
--- a/app/components/component-submit/src/components/NewSubmissionPage.jsx
+++ b/app/components/component-submit/src/components/NewSubmissionPage.jsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import { useQuery, useMutation, ApolloConsumer } from '@apollo/react-hooks'
+import { useQuery, useMutation, ApolloConsumer } from '@apollo/client'
 // import Authorize from 'pubsweet-client/src/helpers/Authorize'
 
 import config from 'config'
diff --git a/app/components/component-submit/src/components/SubmitPage.js b/app/components/component-submit/src/components/SubmitPage.js
index 53814f4ee0947c7b40f0e9d7168d8eb4d098a4b6..6bd3e8adab5575cc305e712363ed75d521aafcf0 100644
--- a/app/components/component-submit/src/components/SubmitPage.js
+++ b/app/components/component-submit/src/components/SubmitPage.js
@@ -1,6 +1,6 @@
 import { debounce, cloneDeep, isEmpty, set } from 'lodash'
 import { compose, withProps, withState, withHandlers } from 'recompose'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 import { withFormik } from 'formik'
 import { withLoader } from 'pubsweet-client'
diff --git a/app/components/component-teams-manager/src/components/TeamsManagerPage.js b/app/components/component-teams-manager/src/components/TeamsManagerPage.js
index 58a52ce95a69843da8618505e8b050107e7cb468..9a4c7cd09b5e6a982bbc196665cd1bc6813261ae 100644
--- a/app/components/component-teams-manager/src/components/TeamsManagerPage.js
+++ b/app/components/component-teams-manager/src/components/TeamsManagerPage.js
@@ -1,7 +1,7 @@
 import { compose } from 'recompose'
 import { omit } from 'lodash'
 import config from 'config'
-import { graphql } from '@apollo/react-hoc'
+import { graphql } from '@apollo/client/react/hoc'
 import gql from 'graphql-tag'
 
 import queries from './graphql/queries'
diff --git a/app/components/component-users-manager/src/User.jsx b/app/components/component-users-manager/src/User.jsx
index 0d6341ba0017c25159be5b1c12285c708d1cbbae..31b144cbcfbed6efb2fd052f2f7974ea21a6e66b 100644
--- a/app/components/component-users-manager/src/User.jsx
+++ b/app/components/component-users-manager/src/User.jsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import gql from 'graphql-tag'
-import { useMutation } from '@apollo/react-hooks'
+import { useMutation } from '@apollo/client'
 import { Action } from '@pubsweet/ui'
 import { UserAvatar } from '../../component-avatar/src'
 import { Row, Cell, LastCell } from './style'
diff --git a/app/components/component-users-manager/src/UsersManager.jsx b/app/components/component-users-manager/src/UsersManager.jsx
index 83392a18c3d0eee04abc4bd0887dc74a60235678..5a09925c7978a4b2f0839064440df7e8c0540a9f 100644
--- a/app/components/component-users-manager/src/UsersManager.jsx
+++ b/app/components/component-users-manager/src/UsersManager.jsx
@@ -1,6 +1,6 @@
 import React, { useState } from 'react'
 import gql from 'graphql-tag'
-import { useQuery } from '@apollo/react-hooks'
+import { useQuery } from '@apollo/client'
 // import { Heading } from '@pubsweet/ui'
 
 import User from './User'
diff --git a/app/graphql/index.js b/app/graphql/index.js
deleted file mode 100644
index b980b81b6a6225ecbaa97d7ccc6576e7243d1afa..0000000000000000000000000000000000000000
--- a/app/graphql/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// TODO: Combine this with app/queries/index
-
-import gql from 'graphql-tag'
-
-export default {
-  currentUser: gql`
-    {
-      currentUser {
-        id
-        username
-        admin
-        profilePicture
-        defaultIdentity {
-          aff
-          name
-        }
-      }
-    }
-  `,
-}
diff --git a/app/hooks/useCurrentUser.js b/app/hooks/useCurrentUser.js
index 5a5ec77ce07fd2d226772200140dc16e0c81074f..6477060da8aa262b9b05798792ebe0205ab33c9b 100644
--- a/app/hooks/useCurrentUser.js
+++ b/app/hooks/useCurrentUser.js
@@ -1,4 +1,4 @@
-import { useQuery } from '@apollo/react-hooks'
+import { useQuery } from '@apollo/client'
 
 import { GET_CURRENT_USER } from '../queries'
 
diff --git a/app/queries/index.js b/app/queries/index.js
index 8aaf5dbb875500c0bcb0f6b06f7587f81ade91f2..17d6b3ba206f39b9addd2edd475969fc85f5c51a 100644
--- a/app/queries/index.js
+++ b/app/queries/index.js
@@ -6,6 +6,7 @@ export const GET_CURRENT_USER = gql`
       id
       profilePicture
       username
+      admin
       defaultIdentity {
         aff
         name
@@ -17,6 +18,11 @@ export const GET_CURRENT_USER = gql`
           email
         }
       }
+      online
+      _currentRoles {
+        id
+        roles
+      }
     }
   }
 `
diff --git a/app/shared/currentRolesVar.js b/app/shared/currentRolesVar.js
new file mode 100644
index 0000000000000000000000000000000000000000..7278c2abd93fc6a0f6a784c56b0682472910ca92
--- /dev/null
+++ b/app/shared/currentRolesVar.js
@@ -0,0 +1,5 @@
+import { makeVar } from '@apollo/client'
+
+const currenRolesVar = makeVar([])
+
+export default currenRolesVar
diff --git a/app/shared/hasRole.js b/app/shared/hasRole.js
new file mode 100644
index 0000000000000000000000000000000000000000..23a73b87ff2ef9413884e3ed0e4ca726b12063e9
--- /dev/null
+++ b/app/shared/hasRole.js
@@ -0,0 +1,11 @@
+const hasRole = (obj, role) => {
+  const currentRoles = (obj && obj._currentRoles) || []
+
+  // When multiple roles are provided it acts as an 'OR'
+  if (Array.isArray(role)) {
+    return role.some(r => currentRoles.includes(r))
+  }
+  return currentRoles.includes(role)
+}
+
+export default hasRole
diff --git a/app/theme/index.js b/app/theme/index.js
index 18926d361975fae7334586fcdac531a0be98550b..9ecac132a259087b9e7994fcc02f54b879b89b1e 100644
--- a/app/theme/index.js
+++ b/app/theme/index.js
@@ -17,7 +17,7 @@ const cokoTheme = {
   /* Colors */
   colorBackground: 'white',
   colorSecondaryBackground: '#f9fafb', // custom
-  colorPrimary: '#0D83DD',
+  colorPrimary: '#3AAE2A',
   colorSecondary: '#9e9e9e',
   colorFurniture: '#E8E8E8',
   colorBorder: '#AAA',