diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js
index bc34c7a73e1074e0d67d3984207a157cc13fc550..fbfcf2db03ad8928dbf383f8b80c010fb256d2a0 100644
--- a/packages/component-faraday-selectors/src/index.js
+++ b/packages/component-faraday-selectors/src/index.js
@@ -163,6 +163,18 @@ export const getAdminUsers = state =>
     .reverse()
     .value()
 
+export const pendingHEInvitation = (state, collectionId) =>
+  chain(state)
+    .get('collections', [])
+    .find(c => c.id === collectionId)
+    .get('invitations', [])
+    .find(
+      i =>
+        i.userId === get(state, 'currentUser.user.id', '') &&
+        i.role === 'handlingEditor' &&
+        !i.hasAnswer,
+    )
+
 const hideCustomIdStatuses = ['draft', 'technicalChecks']
 export const newestFirstParseCustomId = items =>
   chain(items)
diff --git a/packages/component-faraday-ui/src/ContextualBox.js b/packages/component-faraday-ui/src/ContextualBox.js
index 32ff2966e40f3884d0069955ea65d619a1e8c689..016b6618f4e3bf09e7c92d4c7f246a6ecbfe7a70 100644
--- a/packages/component-faraday-ui/src/ContextualBox.js
+++ b/packages/component-faraday-ui/src/ContextualBox.js
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { Fragment } from 'react'
 import { has } from 'lodash'
 import styled from 'styled-components'
 import { Icon, H3 } from '@pubsweet/ui'
@@ -21,12 +21,12 @@ const CustomHeader = ({
     onClick={toggle}
     transparent={transparent}
   >
-    <div>
+    <Fragment>
       <Icon secondary size={2}>
         {expanded ? 'minus' : 'plus'}
       </Icon>
       <H3>{label}</H3>
-    </div>
+    </Fragment>
     {typeof rightChildren === 'function'
       ? rightChildren({ ...props, expanded, transparent })
       : rightChildren}
diff --git a/packages/component-faraday-ui/src/PersonInvitation.js b/packages/component-faraday-ui/src/PersonInvitation.js
index 563573c38875e01e88d532f813c9f57cb92b522c..89676c26a54b867889d5f10c65ca33741fcc62ea 100644
--- a/packages/component-faraday-ui/src/PersonInvitation.js
+++ b/packages/component-faraday-ui/src/PersonInvitation.js
@@ -5,6 +5,7 @@ import { compose, withHandlers, defaultProps, setDisplayName } from 'recompose'
 import { Text, OpenModal, IconButton, marginHelper } from './'
 
 const PersonInvitation = ({
+  withName,
   hasAnswer,
   isFetching,
   person: { name },
@@ -13,7 +14,7 @@ const PersonInvitation = ({
   ...rest
 }) => (
   <Root {...rest}>
-    <Text>{name}</Text>
+    {withName && <Text>{name}</Text>}
     {!hasAnswer &&
       name !== 'Unassigned' && (
         <Fragment>
diff --git a/packages/component-faraday-ui/src/RemoteOpener.js b/packages/component-faraday-ui/src/RemoteOpener.js
index 3cec7f5f23bf907061e008e6e719bee94d85b900..44bcb785bdb7be2d1db3e3a9bab8f951c4e002c2 100644
--- a/packages/component-faraday-ui/src/RemoteOpener.js
+++ b/packages/component-faraday-ui/src/RemoteOpener.js
@@ -1,7 +1,7 @@
 import { withStateHandlers } from 'recompose'
 
 const RemoteOpener = ({ expanded, toggle, children }) =>
-  children(expanded, toggle)
+  children({ expanded, toggle })
 
 export default withStateHandlers(
   ({ startExpanded }) => ({ expanded: startExpanded }),
diff --git a/packages/component-faraday-ui/src/ReviewerBreakdown.js b/packages/component-faraday-ui/src/ReviewerBreakdown.js
index 6c64361e64408acca148bbf44e58eedf5d4478b1..7c181f90968c9751a32cc48458241fda72bbd246 100644
--- a/packages/component-faraday-ui/src/ReviewerBreakdown.js
+++ b/packages/component-faraday-ui/src/ReviewerBreakdown.js
@@ -1,11 +1,8 @@
-import React, { Fragment } from 'react'
+import React from 'react'
 import { get } from 'lodash'
-import { H4 } from '@pubsweet/ui'
-import styled from 'styled-components'
-import { th } from '@pubsweet/ui-toolkit'
 import { compose, withHandlers, withProps } from 'recompose'
 
-import { Text } from './'
+import { Text, Row } from './'
 
 const ReviewerBreakdown = ({ getReportBreakdown }) => getReportBreakdown()
 
@@ -26,11 +23,7 @@ export default compose(
     recommendations: get(fragment, 'recommendations', []),
   })),
   withHandlers({
-    getReportBreakdown: ({
-      invitations,
-      recommendations,
-      label = '',
-    }) => () => {
+    getReportBreakdown: ({ invitations, recommendations, ...rest }) => () => {
       const reviewerInvitations = invitations.filter(roleFilter('reviewer'))
       const invitationsWithRecommendations = reviewerInvitations.map(r => ({
         ...r,
@@ -41,27 +34,31 @@ export default compose(
         declined: 0,
         submitted: 0,
       })
-      return (
-        <Fragment>
-          {!!label && <Label>{label}</Label>}
-          {reviewerInvitations.length ? (
-            <Text>
-              {`${reviewerInvitations.length} invited, ${
-                report.accepted
-              } agreed, ${report.declined} declined, ${
-                report.submitted
-              } submitted`}
-            </Text>
-          ) : (
-            <Text> {`${reviewerInvitations.length} invited`}</Text>
-          )}
-        </Fragment>
+      return reviewerInvitations.length ? (
+        <Row justify="flex-end" {...rest}>
+          <Text customId mr={1 / 2}>
+            {reviewerInvitations.length}
+          </Text>
+          <Text mr={1 / 2}> invited,</Text>
+
+          <Text customId mr={1 / 2}>
+            {report.accepted}
+          </Text>
+          <Text mr={1 / 2}> agreed,</Text>
+
+          <Text customId mr={1 / 2}>
+            {report.declined}
+          </Text>
+          <Text mr={1 / 2}> declined,</Text>
+
+          <Text customId mr={1 / 2}>
+            {report.submitted}
+          </Text>
+          <Text mr={1 / 2}> submitted</Text>
+        </Row>
+      ) : (
+        <Text> {`${reviewerInvitations.length} invited`}</Text>
       )
     },
   }),
 )(ReviewerBreakdown)
-
-const Label = styled(H4)`
-  display: inline-block;
-  margin-right: ${th('gridUnit')};
-`
diff --git a/packages/component-faraday-ui/src/ReviewerBreakdown.md b/packages/component-faraday-ui/src/ReviewerBreakdown.md
index d14eaaf2ce307b2ebb091b25cd220ac2084906ba..64df75b1fe57fee03dcc52137520dd676415a0d5 100644
--- a/packages/component-faraday-ui/src/ReviewerBreakdown.md
+++ b/packages/component-faraday-ui/src/ReviewerBreakdown.md
@@ -85,8 +85,3 @@ Without invitations
 ```js
 <ReviewerBreakdown fragment={{}} />
 ```
-
-With label
-```js
-<ReviewerBreakdown fragment={{}} label='Reviewer Reports' />
-```
diff --git a/packages/component-faraday-ui/src/ReviewerReport.js b/packages/component-faraday-ui/src/ReviewerReport.js
new file mode 100644
index 0000000000000000000000000000000000000000..401f3818edffd6781810f1e5f2e7c3456d984f32
--- /dev/null
+++ b/packages/component-faraday-ui/src/ReviewerReport.js
@@ -0,0 +1,69 @@
+import React from 'react'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+import { DateParser } from '@pubsweet/ui'
+
+import { Label, Item, FileItem, Row, Text } from './'
+
+const ReviewerReport = ({
+  report: {
+    report,
+    files = [],
+    submittedOn,
+    recommendation,
+    confidentialNote,
+    reviewer: { fullName, reviewerNumber },
+  },
+}) => (
+  <Root>
+    <Row justify="space-between" mb={2}>
+      <Item vertical>
+        <Label mb={1 / 2}>Recommendation</Label>
+        <Text>{recommendation}</Text>
+      </Item>
+
+      <Item justify="flex-end">
+        <Text>{fullName}</Text>
+        <Text customId ml={1} mr={1}>
+          {`Reviewer ${reviewerNumber}`}
+        </Text>
+        <DateParser timestamp={submittedOn}>
+          {date => <Text>{date}</Text>}
+        </DateParser>
+      </Item>
+    </Row>
+
+    <Row mb={2}>
+      <Item vertical>
+        <Label mb={1 / 2}>Report</Label>
+        <Text>{report}</Text>
+      </Item>
+    </Row>
+
+    <Label mb={1 / 2}>Files</Label>
+    <Row justify="flex-start" mb={2}>
+      {files.map(file => (
+        <Item flex={0} key={file.id} mr={1}>
+          <FileItem item={file} />
+        </Item>
+      ))}
+    </Row>
+
+    <Row mb={2}>
+      <Item vertical>
+        <Label mb={1 / 2}>Confidential note for the Editorial Team</Label>
+        <Text>{confidentialNote}</Text>
+      </Item>
+    </Row>
+  </Root>
+)
+
+export default ReviewerReport
+
+// #region styles
+const Root = styled.div`
+  box-shadow: ${th('boxShadow')};
+  padding: calc(${th('gridUnit')} * 2);
+  margin: ${th('gridUnit')};
+`
+// #endregion
diff --git a/packages/component-faraday-ui/src/ReviewerReport.md b/packages/component-faraday-ui/src/ReviewerReport.md
new file mode 100644
index 0000000000000000000000000000000000000000..e16f2bc1a28bc427029e6c9388d8f8288f031112
--- /dev/null
+++ b/packages/component-faraday-ui/src/ReviewerReport.md
@@ -0,0 +1,26 @@
+Reviewer report.
+
+```js
+<ReviewerReport
+  report={{
+    submittedOn: Date.now(),
+    recommendation: 'Reject',
+    report: `Of all of the celestial bodies that capture our attention and
+      fascination as astronomers, none has a greater influence on life on
+      planet Earth than it’s own satellite, the moon. When you think about
+      it, we regard the moon with such powerful significance that unlike the
+      moons of other planets which we give names, we only refer to our one
+      and only orbiting orb as THE moon. It is not a moon. To us, it is the
+      one and only moon.`,
+    reviewer: {
+      fullName: 'Kenny Hudson',
+      reviewerNumber: 1,
+    },
+    confidentialNote: `First 10 pages feel very familiar, you should check for       plagarism.`,
+    files: [
+      { id: 'file1', name: 'file1.pdf', size: 12356 },
+      { id: 'file2', name: 'file2.pdf', size: 76421 },
+    ],
+  }}
+/>
+```
diff --git a/packages/component-faraday-ui/src/ReviewersTable.js b/packages/component-faraday-ui/src/ReviewersTable.js
new file mode 100644
index 0000000000000000000000000000000000000000..e0bdabb2722aa52c0e0fcf9bd5382c43bcba6bb9
--- /dev/null
+++ b/packages/component-faraday-ui/src/ReviewersTable.js
@@ -0,0 +1,207 @@
+import React from 'react'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+import { DateParser } from '@pubsweet/ui'
+
+import { Label, PersonInvitation, Text } from '../'
+
+const invitation = {
+  id: 'b4305ab6-84e6-48a3-9eb9-fbe0ec80c694',
+  role: 'handlingEditor',
+  type: 'invitation',
+  reason: 'because',
+  userId: 'cb7e3e26-6a09-4b79-a6ff-4d1235ee2381',
+  hasAnswer: false,
+  invitedOn: 713919119,
+  isAccepted: false,
+  respondedOn: 1533714034932,
+  person: {
+    id: 'cb7e3e26-6a09-4b79-a6ff-4d1235ee2381',
+    name: 'Toto Schilacci',
+  },
+}
+
+const reviewers = [
+  {
+    id: 1,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 2,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 11,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 21,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 12,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 22,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 13,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 23,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 113,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 213,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 123,
+    fullName: 'Gica Hagi',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+  {
+    id: 223,
+    fullName: 'Cosmin Contra',
+    invitedOn: Date.now(),
+    respondedOn: Date.now(),
+    submittedOn: Date.now() - 3000000000,
+  },
+]
+
+const ReviewersTable = () => (
+  <Table>
+    <thead>
+      <tr>
+        <th>
+          <Label>Full Name</Label>
+        </th>
+        <th>
+          <Label>Invited on</Label>
+        </th>
+        <th>
+          <Label>Responded on</Label>
+        </th>
+        <th>
+          <Label>Submitted on</Label>
+        </th>
+        <th>&nbsp;</th>
+      </tr>
+    </thead>
+    <tbody>
+      {reviewers.map((r, index) => (
+        <TableRow key={r.id}>
+          <td>
+            <Text>{r.fullName}</Text>
+            <Text customId ml={1}>{`Reviewer ${index + 1}`}</Text>
+          </td>
+          <td>
+            <DateParser timestamp={r.invitedOn}>
+              {timestamp => <Text>{timestamp}</Text>}
+            </DateParser>
+          </td>
+          <td>
+            <DateParser timestamp={r.respondedOn}>
+              {timestamp => <Text>{timestamp}</Text>}
+            </DateParser>
+            <Text ml={1} secondary>
+              ACCEPTED
+            </Text>
+          </td>
+          <td>
+            <DateParser timestamp={r.submittedOn}>
+              {timestamp => <Text>{timestamp}</Text>}
+            </DateParser>
+          </td>
+          <HiddenCell>
+            <PersonInvitation {...invitation} />
+          </HiddenCell>
+        </TableRow>
+      ))}
+    </tbody>
+  </Table>
+)
+
+export default ReviewersTable
+
+// #region styles
+const Table = styled.table`
+  border-collapse: collapse;
+  padding: ${th('gridUnit')};
+
+  & thead {
+    border-bottom: 1px solid ${th('colorBorder')};
+  }
+
+  & th,
+  & td {
+    border: none;
+    padding-left: ${th('gridUnit')};
+    text-align: start;
+    vertical-align: middle;
+
+    height: calc(${th('gridUnit')} * 5);
+    min-width: calc(${th('gridUnit')} * 12);
+  }
+`
+
+const HiddenCell = styled.td`
+  opacity: 0;
+`
+
+const TableRow = styled.tr`
+  background-color: ${th('colorBackgroundHue2')};
+  border-bottom: 1px solid ${th('colorBorder')};
+
+  & td:first-child {
+    min-width: calc(${th('gridUnit')} * 30);
+  }
+
+  &:hover {
+    background-color: #eeeeee;
+
+    ${HiddenCell} {
+      opacity: 1;
+    }
+  }
+`
+// #endregion
diff --git a/packages/component-faraday-ui/src/ReviewersTable.md b/packages/component-faraday-ui/src/ReviewersTable.md
new file mode 100644
index 0000000000000000000000000000000000000000..dbab1725a9cb9c5744460e1f95dcd814a378b7fa
--- /dev/null
+++ b/packages/component-faraday-ui/src/ReviewersTable.md
@@ -0,0 +1,5 @@
+A list of reviewers.
+
+```js
+<ReviewersTable />
+```
diff --git a/packages/component-faraday-ui/src/Tabs.js b/packages/component-faraday-ui/src/Tabs.js
new file mode 100644
index 0000000000000000000000000000000000000000..76d0699c166690707ae38dc344f0cfa5f0833d44
--- /dev/null
+++ b/packages/component-faraday-ui/src/Tabs.js
@@ -0,0 +1,15 @@
+import { compose, withStateHandlers } from 'recompose'
+
+const Tabs = ({ items, selectedTab, changeTab, children }) =>
+  children({ selectedTab, changeTab })
+
+export default compose(
+  withStateHandlers(
+    { selectedTab: 0 },
+    {
+      changeTab: () => selectedTab => ({
+        selectedTab,
+      }),
+    },
+  ),
+)(Tabs)
diff --git a/packages/component-faraday-ui/src/Tabs.md b/packages/component-faraday-ui/src/Tabs.md
new file mode 100644
index 0000000000000000000000000000000000000000..a213cb4aec658c0d3f50dea84688c2f0ec7c07aa
--- /dev/null
+++ b/packages/component-faraday-ui/src/Tabs.md
@@ -0,0 +1,22 @@
+A component to render tabs.
+
+```js
+const tabItems = [
+  { content: () => <div>Tab one content</div> },
+  { content: () => <div>Tab two content</div> },
+  { content: () => <div>Tab three content</div> },
+]
+;<Tabs>
+  {({ selectedTab, changeTab }) => (
+    <div>
+      <div>
+        <button onClick={() => changeTab(0)}>Tab 1</button>
+        <button onClick={() => changeTab(1)}>Tab 2</button>
+        <button onClick={() => changeTab(2)}>Tab 3</button>
+      </div>
+
+      {tabItems[selectedTab].content()}
+    </div>
+  )}
+</Tabs>
+```
diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
new file mode 100644
index 0000000000000000000000000000000000000000..cca9baae989cda6722630bc6a91e37984aa23b3b
--- /dev/null
+++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
@@ -0,0 +1,107 @@
+import React, { Fragment } from 'react'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+
+import {
+  Tag,
+  Tabs,
+  Label,
+  marginHelper,
+  ContextualBox,
+  ReviewersTable,
+  ReviewerReport,
+  ReviewerBreakdown,
+} from '../'
+
+const report = {
+  submittedOn: Date.now(),
+  recommendation: 'Reject',
+  report: `Of all of the celestial bodies that capture our attention and
+    fascination as astronomers, none has a greater influence on life on
+    planet Earth than it’s own satellite, the moon. When you think about
+    it, we regard the moon with such powerful significance that unlike the
+    moons of other planets which we give names, we only refer to our one
+    and only orbiting orb as THE moon. It is not a moon. To us, it is the
+    one and only moon.`,
+  reviewer: {
+    fullName: 'Kenny Hudson',
+    reviewerNumber: 1,
+  },
+  confidentialNote: `First 10 pages feel very familiar, you should check for       plagarism.`,
+  files: [
+    { id: 'file1', name: 'file1.pdf', size: 12356 },
+    { id: 'file2', name: 'file2.pdf', size: 76421 },
+  ],
+}
+
+const ReviewerDetails = ({ fragment }) => (
+  <ContextualBox
+    label="Reviewer details"
+    rightChildren={<ReviewerBreakdown fitContent fragment={fragment} mr={1} />}
+    startExpanded
+  >
+    <Tabs>
+      {({ selectedTab, changeTab }) => (
+        <Fragment>
+          <TabsHeader>
+            <TabButton
+              ml={1}
+              mr={1}
+              onClick={() => changeTab(0)}
+              selected={selectedTab === 0}
+            >
+              <Label>Reviewer Details</Label>
+            </TabButton>
+            <TabButton
+              ml={1}
+              mr={1}
+              onClick={() => changeTab(1)}
+              selected={selectedTab === 1}
+            >
+              <Label>Reviewer Reports</Label>
+              <Tag ml={1}>12</Tag>
+            </TabButton>
+          </TabsHeader>
+          {selectedTab === 0 && <ReviewersTable />}
+          {selectedTab === 1 && (
+            <Fragment>
+              <ReviewerReport report={report} />
+              <ReviewerReport report={report} />
+              <ReviewerReport report={report} />
+            </Fragment>
+          )}
+        </Fragment>
+      )}
+    </Tabs>
+  </ContextualBox>
+)
+
+export default ReviewerDetails
+
+// #region styles
+const TabButton = styled.div`
+  align-items: center;
+  border-bottom: ${props =>
+    props.selected
+      ? `4px solid ${props.theme.colorFurnitureHue}`
+      : '4px solid transparent'};
+  box-sizing: border-box;
+  cursor: pointer;
+  display: flex;
+  justify-content: center;
+  height: calc(${th('gridUnit')} * 5);
+
+  ${marginHelper};
+`
+
+const TabsHeader = styled.div`
+  align-items: center;
+  border-bottom: 1px solid ${th('colorFurniture')};
+  box-sizing: border-box;
+  display: flex;
+  justify-content: flex-start;
+
+  margin-bottom: ${th('gridUnit')};
+  padding: 0 calc(${th('gridUnit')} * 3);
+`
+// #endregion
diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.md b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.md
new file mode 100644
index 0000000000000000000000000000000000000000..49bb54a7d348719cc44c2b822edcaf016d163d5c
--- /dev/null
+++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.md
@@ -0,0 +1,83 @@
+The ReviewerDetails contextual box.
+
+```js
+const fragment = {
+  invitations: [
+    {
+      id: 'a69c1273-4073-4529-9e65-5424ad8034ea',
+      role: 'reviewer',
+      type: 'invitation',
+      userId: '9c79c3bf-ccba-4540-aad8-ce4609325826',
+      hasAnswer: false,
+      invitedOn: 1534506511008,
+      isAccepted: false,
+      respondedOn: null,
+    },
+    {
+      id: 'ca1c08bb-4da6-4cb4-972d-d16e3b66b884',
+      role: 'reviewer',
+      type: 'invitation',
+      userId: 'd3ab9a0b-d8e8-41e5-ab3b-72b13f84fba1',
+      hasAnswer: true,
+      invitedOn: 1534506542522,
+      isAccepted: true,
+      respondedOn: 1534506569565,
+    },
+  ],
+  recommendations: [
+    {
+      id: '87fb2c45-2685-47cc-9952-d58435ff8f3a',
+      userId: 'd3ab9a0b-d8e8-41e5-ab3b-72b13f84fba1',
+      comments: [
+        {
+          files: [],
+          public: true,
+          content: 'This is a great manuscript',
+        },
+      ],
+      createdOn: 1534506583815,
+      updatedOn: 1534506592527,
+      submittedOn: 1534506591684,
+      recommendation: 'publish',
+      recommendationType: 'review',
+    },
+    {
+      id: '9853453f-1049-4369-8543-1b812930430d',
+      userId: 'ede6770d-8dbf-4bf9-bbe2-98facfd0a114',
+      comments: [
+        {
+          public: true,
+          content: 'nice job',
+        },
+        {
+          public: false,
+          content: 'please publish this',
+        },
+      ],
+      createdOn: 1534506624583,
+      updatedOn: 1534506624583,
+      recommendation: 'publish',
+      recommendationType: 'editorRecommendation',
+    },
+    {
+      id: '64c5b596-fbfc-485c-9068-f3a58306efd7',
+      userId: '5b53da0d-3f88-4e94-b8f9-7eae6a754168',
+      createdOn: 1534506644873,
+      updatedOn: 1534506644873,
+      recommendation: 'publish',
+      recommendationType: 'editorRecommendation',
+    },
+    {
+      id: '3d43ff74-9a20-479d-a218-23bf8eac0b6a',
+      userId: '5b53da0d-3f88-4e94-b8f9-7eae6a754168',
+      createdOn: 1534506813446,
+      updatedOn: 1534506813446,
+      recommendation: 'publish',
+      recommendationType: 'editorRecommendation',
+    },
+  ],
+}
+;
+
+<ReviewerDetails fragment={fragment} />
+```
diff --git a/packages/component-faraday-ui/src/contextualBoxes/index.js b/packages/component-faraday-ui/src/contextualBoxes/index.js
index 671406c817a82b42d530a58972edea909458800f..d8e24b485b0ed222d8380682efb5fd3f90b838fc 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/index.js
+++ b/packages/component-faraday-ui/src/contextualBoxes/index.js
@@ -1 +1,2 @@
 export { default as AssignHE } from './AssignHE'
+export { default as ReviewerDetails } from './ReviewerDetails'
diff --git a/packages/component-faraday-ui/src/gridItems/Row.js b/packages/component-faraday-ui/src/gridItems/Row.js
index c39f27891ecc259a8bfc6de114038e673463e9ab..794ed2b3f00faf6c82f720745b3826eed63bc3f2 100644
--- a/packages/component-faraday-ui/src/gridItems/Row.js
+++ b/packages/component-faraday-ui/src/gridItems/Row.js
@@ -14,7 +14,7 @@ export default styled.div.attrs({
   justify-content: ${props => get(props, 'justify', 'space-evenly')};
   height: ${props => get(props, 'height', 'auto')};
 
-  width: 100%;
+  width: ${props => (props.fitContent ? 'fit-content' : '100%')};
 
   ${heightHelper};
   ${marginHelper};
diff --git a/packages/component-faraday-ui/src/index.js b/packages/component-faraday-ui/src/index.js
index 0d6361a425da1a76ad28d1a2eca5eecc99a32dd3..b186e2a8a42a0312a827520948661dfa5d57c348 100644
--- a/packages/component-faraday-ui/src/index.js
+++ b/packages/component-faraday-ui/src/index.js
@@ -30,10 +30,13 @@ export { default as PersonInfo } from './PersonInfo'
 export { default as PersonInvitation } from './PersonInvitation'
 export { default as PreviewFile } from './PreviewFile'
 export { default as RadioWithComments } from './RadioWithComments'
+export { default as ReviewerReport } from './ReviewerReport'
+export { default as ReviewersTable } from './ReviewersTable'
 export { default as RemoteOpener } from './RemoteOpener'
 export { default as ShadowedBox } from './ShadowedBox'
 export { default as SortableList } from './SortableList'
 export { default as Tag } from './Tag'
+export { default as Tabs } from './Tabs'
 export { default as Text } from './Text'
 export { default as Textarea } from './Textarea'
 export { default as UserProfile } from './UserProfile'
diff --git a/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.js b/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.js
index b35630fb209118e1123edb9f55335db3555a381f..53f4ca16822becf9cc9eeb0927ad6021ec45a9aa 100644
--- a/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.js
+++ b/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.js
@@ -1,7 +1,8 @@
 import React from 'react'
 import { reduxForm } from 'redux-form'
 import { get, has, capitalize } from 'lodash'
-import { compose, withProps } from 'recompose'
+import { required } from 'xpub-validators'
+import { compose, withHandlers, withProps } from 'recompose'
 import { Button, RadioGroup, ValidatedField } from '@pubsweet/ui'
 
 import {
@@ -22,13 +23,22 @@ const options = [
 ]
 
 const HandlingEditorAnswer = ({
-  disabled,
+  toggle,
+  expanded,
   decision,
   isFetching,
   handleSubmit,
+  onSubmitForm,
   shouldShowComments,
 }) => (
-  <ContextualBox label="Respond to Editorial Invitation">
+  <ContextualBox
+    expanded={expanded}
+    highlight
+    label="Respond to Editorial Invitation"
+    mb={2}
+    scrollIntoView
+    toggle={toggle}
+  >
     <RowOverrideAlert justify="flex-start" ml={1} mt={1}>
       <Item vertical>
         <Label required>
@@ -39,12 +49,13 @@ const HandlingEditorAnswer = ({
             <RadioGroup inline name="decision" options={options} {...input} />
           )}
           name="decision"
+          validate={[required]}
         />
       </Item>
     </RowOverrideAlert>
 
     {shouldShowComments && (
-      <RowOverrideAlert ml={1} mt={2}>
+      <RowOverrideAlert ml={1} mt={2} pr={2}>
         <Item vertical>
           <Label>
             Decline Reason{' '}
@@ -66,7 +77,7 @@ const HandlingEditorAnswer = ({
         title={`${decision} this invitation?`}
       >
         {showModal => (
-          <Button disabled={disabled} onClick={showModal} primary size="medium">
+          <Button onClick={onSubmitForm(showModal)} primary size="medium">
             RESPOND TO INVITATION
           </Button>
         )}
@@ -84,8 +95,18 @@ export default compose(
   })),
   reduxForm({
     form: 'he-answer-invitation',
+    destroyOnUnmount: false,
     onSubmit: (values, dispatch, { onResponse, setFetching }) => modalProps => {
       onResponse(values, { ...modalProps, setFetching })
     },
   }),
+  withHandlers({
+    onSubmitForm: ({ disabled, handleSubmit }) => showModal => () => {
+      if (!disabled) {
+        showModal()
+      } else {
+        handleSubmit()
+      }
+    },
+  }),
 )(HandlingEditorAnswer)
diff --git a/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.md b/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.md
index fed5d02bf8525c9fe5f7cd0e374c5385c7727332..21d5d620c87fbf2b1d69e8ff8c616e4a8cc75013 100644
--- a/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.md
+++ b/packages/component-faraday-ui/src/manuscriptDetails/HandlingEditorAnswer.md
@@ -3,12 +3,19 @@ Handling Editor answer invitation.
 ```js
 const formValues = {
   decision: 'decline',
-}
+};
 
-;<HandlingEditorAnswer
-  formValues={formValues}
-  onResponse={(values, { setFetching }) => {
-    setFetching(true)
-  }}
-/>
+<RemoteOpener>
+{
+  ({toggle, expanded}) =>
+    <HandlingEditorAnswer
+      formValues={formValues}
+      expanded={expanded}
+      toggle={toggle}
+      onResponse={(values, { setFetching }) => {
+        setFetching(true)
+      }}
+    />
+}
+</RemoteOpener>
 ```
diff --git a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
index 267ab5774524680b6d9e435f0a48efe8d7185ca1..6927e7ba41b1ffb70b1158a9382b06651d4c0c46 100644
--- a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
+++ b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
@@ -115,6 +115,7 @@ export default compose(
           <PersonInvitation
             isFetching={isFetching}
             ml={1}
+            withName
             {...pendingInvitation}
             onResend={resendInvitation}
             onRevoke={revokeInvitation}
diff --git a/packages/component-faraday-ui/src/manuscriptDetails/index.js b/packages/component-faraday-ui/src/manuscriptDetails/index.js
index 85b997fa07bced9f74be3d428c2c80772d12f365..f19644c15e01a55ec224789fa52896398f7a4afd 100644
--- a/packages/component-faraday-ui/src/manuscriptDetails/index.js
+++ b/packages/component-faraday-ui/src/manuscriptDetails/index.js
@@ -1,3 +1,4 @@
+export { default as HandlingEditorAnswer } from './HandlingEditorAnswer'
 export { default as ManuscriptDetailsTop } from './ManuscriptDetailsTop'
 export { default as ManuscriptVersion } from './ManuscriptVersion'
 export { default as ManuscriptHeader } from './ManuscriptHeader'
diff --git a/packages/component-manuscript/package.json b/packages/component-manuscript/package.json
index 33efbb8b3a9ef3360bb95e0667c272a228ca5961..458f0a07fcdb726ae1724b51f0e63862a8bca9bd 100644
--- a/packages/component-manuscript/package.json
+++ b/packages/component-manuscript/package.json
@@ -5,7 +5,7 @@
   "license": "MIT",
   "dependencies": {
     "prop-types": "^15.5.10",
-    "recompose": "^0.26.0",
+    "recompose": "^0.30.0",
     "xpub-edit": "^2.4.1",
     "xpub-connect": "1.0.0",
     "xpub-selectors": "^0.1.0"
diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
index cbe37e432e311717ed6af777c235baf82096ee25..b1fc53ae09426250b0ebf3c4552d6cdd06e8875e 100644
--- a/packages/component-manuscript/src/components/ManuscriptLayout.js
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -3,10 +3,10 @@ import styled from 'styled-components'
 import { isEmpty, get, last } from 'lodash'
 import {
   Text,
-  RemoteOpener,
   ManuscriptHeader,
   ManuscriptAssignHE,
   ManuscriptMetadata,
+  HandlingEditorAnswer,
   ManuscriptDetailsTop,
   ManuscriptEicDecision,
   paddingHelper,
@@ -41,66 +41,76 @@ const ManuscriptLayout = ({
   permissions,
   isFetching,
   formValues,
+  toggleAssignHE,
+  heExpanded,
+  toggleHEResponse,
+  heResponseExpanded,
+  onHEResponse,
 }) => (
   <Root pb={1}>
     {!isEmpty(collection) && !isEmpty(fragment) ? (
-      <RemoteOpener>
-        {(expanded, toggle) => (
-          <Fragment>
-            <ManuscriptDetailsTop
-              collection={collection}
-              currentUser={currentUser}
-              fragment={fragment}
-              getSignedUrl={getSignedUrl}
-              history={history}
-              {...permissions}
-            />
+      <Fragment>
+        <ManuscriptDetailsTop
+          collection={collection}
+          currentUser={currentUser}
+          fragment={fragment}
+          getSignedUrl={getSignedUrl}
+          history={history}
+          {...permissions}
+        />
 
-            <ManuscriptHeader
-              collection={collection}
-              currentUser={currentUser}
-              editorInChief={editorInChief}
-              fragment={fragment}
-              handlingEditors={handlingEditors}
-              inviteHE={toggle}
-              isFetching={isFetching.editorsFetching}
-              journal={journal}
-              resendInvitation={assignHE}
-              revokeInvitation={revokeHE}
-            />
+        <ManuscriptHeader
+          collection={collection}
+          currentUser={currentUser}
+          editorInChief={editorInChief}
+          fragment={fragment}
+          handlingEditors={handlingEditors}
+          inviteHE={toggleAssignHE}
+          isFetching={isFetching.editorsFetching}
+          journal={journal}
+          resendInvitation={assignHE}
+          revokeInvitation={revokeHE}
+        />
 
-            <ManuscriptMetadata
-              currentUser={currentUser}
-              fragment={fragment}
-              getSignedUrl={getSignedUrl}
-            />
+        <ManuscriptMetadata
+          currentUser={currentUser}
+          fragment={fragment}
+          getSignedUrl={getSignedUrl}
+        />
 
-            <ManuscriptAssignHE
-              assignHE={assignHE}
-              currentUser={currentUser}
-              expanded={expanded}
-              handlingEditors={handlingEditors}
-              isFetching={isFetching.editorsFetching}
-              toggle={toggle}
-            />
+        {permissions.isInvitedHE && (
+          <HandlingEditorAnswer
+            expanded={heResponseExpanded}
+            formValues={formValues.heInvitation}
+            onResponse={onHEResponse}
+            toggle={toggleHEResponse}
+          />
+        )}
+
+        <ManuscriptAssignHE
+          assignHE={assignHE}
+          currentUser={currentUser}
+          expanded={heExpanded}
+          handlingEditors={handlingEditors}
+          isFetching={isFetching.editorsFetching}
+          toggle={toggleAssignHE}
+        />
 
-            {permissions.canMakeDecision && (
-              <ManuscriptEicDecision
-                formValues={get(formValues, 'eicDecision')}
-                isFetching={isFetching.recommendationsFetching}
-                messagesLabel={messagesLabel}
-                mt={2}
-                options={
-                  get(collection, 'status', 'submitted') === 'submitted'
-                    ? [last(eicDecisions)]
-                    : eicDecisions
-                }
-                submitDecision={createRecommendation}
-              />
-            )}
-          </Fragment>
+        {permissions.canMakeDecision && (
+          <ManuscriptEicDecision
+            formValues={get(formValues, 'eicDecision')}
+            isFetching={isFetching.recommendationsFetching}
+            messagesLabel={messagesLabel}
+            mt={2}
+            options={
+              get(collection, 'status', 'submitted') === 'submitted'
+                ? [last(eicDecisions)]
+                : eicDecisions
+            }
+            submitDecision={createRecommendation}
+          />
         )}
-      </RemoteOpener>
+      </Fragment>
     ) : (
       <Text>Loading...</Text>
     )}
diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js
index 9ab87ac35d061a3f4b0dc6fbf085b6ef08f57633..fb18e691bd87ebc10877a2f9959d71c5e573b368 100644
--- a/packages/component-manuscript/src/components/ManuscriptPage.js
+++ b/packages/component-manuscript/src/components/ManuscriptPage.js
@@ -2,10 +2,10 @@ import { connect } from 'react-redux'
 import { actions } from 'pubsweet-client'
 import { ConnectPage } from 'xpub-connect'
 import { withJournal } from 'xpub-journal'
-import { head, get, isEmpty } from 'lodash'
+import { getFormValues } from 'redux-form'
 import { replace } from 'react-router-redux'
 import { withRouter } from 'react-router-dom'
-import { getFormValues } from 'redux-form'
+import { head, get, isEmpty, isUndefined } from 'lodash'
 import {
   selectFragment,
   selectCollection,
@@ -19,6 +19,7 @@ import {
   withProps,
   withHandlers,
   setDisplayName,
+  fromRenderProps,
 } from 'recompose'
 import { getSignedUrl } from 'pubsweet-components-faraday/src/redux/files'
 import { reviewerDecision } from 'pubsweet-components-faraday/src/redux/reviewers'
@@ -33,10 +34,12 @@ import {
   canMakeRevision,
   canMakeDecision,
   canEditManuscript,
+  pendingHEInvitation,
   currentUserIsReviewer,
   canMakeRecommendation,
   canOverrideTechnicalChecks,
 } from 'pubsweet-component-faraday-selectors'
+import { RemoteOpener } from 'pubsweet-component-faraday-ui'
 
 import ManuscriptLayout from './ManuscriptLayout'
 import { parseEicDecision, parseSearchParams, redirectToError } from './utils'
@@ -47,6 +50,7 @@ import {
   assignHandlingEditor,
   revokeHandlingEditor,
   selectHandlingEditors,
+  handlingEditorDecision,
 } from '../redux/editors'
 import {
   createRecommendation,
@@ -69,6 +73,7 @@ export default compose(
       hasManuscriptFailure: hasManuscriptFailure(state),
       fragment: selectFragment(state, match.params.version),
       collection: selectCollection(state, match.params.project),
+      pendingHEInvitation: pendingHEInvitation(state, match.params.project),
       editorialRecommendations: selectEditorialRecommendations(
         state,
         match.params.version,
@@ -87,36 +92,58 @@ export default compose(
       updateVersion: actions.updateFragment,
     },
   ),
-  connect((state, { currentUser, match, collection, fragment }) => ({
-    currentUser: {
-      ...currentUser,
-      token: getUserToken(state),
-      isEIC: currentUserIs(state, 'adminEiC'),
-      isHE: currentUserIs(state, 'isHE'),
-      isReviewer: currentUserIsReviewer(state),
-      canAssignHE: canAssignHE(state, match.params.project),
-    },
-    isFetching: {
-      editorsFetching: selectFetching(state),
-      recommendationsFetching: recommendationsFetching(state),
-    },
-    permissions: {
-      canMakeRevision: canMakeRevision(state, collection, fragment),
-      canMakeDecision: canMakeDecision(state, collection, fragment),
-      canEditManuscript: canEditManuscript(state, collection, fragment),
-      canOverrideTechChecks: canOverrideTechnicalChecks(state, collection),
-      canMakeRecommendation: canMakeRecommendation(state, collection, fragment),
-    },
-    formValues: {
-      eicDecision: getFormValues('eic-decision')(state),
-    },
-  })),
+  connect(
+    (
+      state,
+      { pendingHEInvitation, currentUser, match, collection, fragment },
+    ) => ({
+      currentUser: {
+        ...currentUser,
+        token: getUserToken(state),
+        isEIC: currentUserIs(state, 'adminEiC'),
+        isHE: currentUserIs(state, 'isHE'),
+        isReviewer: currentUserIsReviewer(state),
+        canAssignHE: canAssignHE(state, match.params.project),
+      },
+      isFetching: {
+        editorsFetching: selectFetching(state),
+        recommendationsFetching: recommendationsFetching(state),
+      },
+      permissions: {
+        isInvitedHE: !isUndefined(pendingHEInvitation),
+        canMakeRevision: canMakeRevision(state, collection, fragment),
+        canMakeDecision: canMakeDecision(state, collection, fragment),
+        canEditManuscript: canEditManuscript(state, collection, fragment),
+        canOverrideTechChecks: canOverrideTechnicalChecks(state, collection),
+        canMakeRecommendation: canMakeRecommendation(
+          state,
+          collection,
+          fragment,
+        ),
+      },
+      formValues: {
+        eicDecision: getFormValues('eic-decision')(state),
+        heInvitation: getFormValues('he-answer-invitation')(state),
+      },
+    }),
+  ),
   ConnectPage(({ currentUser, handlingEditors, collection }) => {
     if (currentUser.isEIC) {
       return [getHandlingEditors()]
     }
     return []
   }),
+  withHandlers({
+    fetchUpdatedCollection: ({
+      fragment,
+      collection,
+      getFragment,
+      getCollection,
+    }) => () => {
+      getCollection({ id: collection.id })
+      getFragment(collection, fragment)
+    },
+  }),
   withHandlers({
     updateManuscript: ({ updateVersion, collection, fragment }) => data =>
       updateVersion(collection, {
@@ -130,11 +157,8 @@ export default compose(
       }
     },
     assignHE: ({
-      fragment,
-      collection,
-      getFragment,
-      getCollection,
       assignHandlingEditor,
+      fetchUpdatedCollection,
       collection: { id: collectionId },
     }) => (email, modalProps) =>
       assignHandlingEditor({
@@ -142,8 +166,7 @@ export default compose(
         collectionId,
       })
         .then(() => {
-          getCollection({ id: collectionId })
-          getFragment(collection, fragment)
+          fetchUpdatedCollection()
           modalProps.hideModal()
         })
         .catch(() => modalProps.setModalError('Oops! Something went wrong.')),
@@ -164,8 +187,7 @@ export default compose(
     createRecommendation: ({
       fragment,
       collection,
-      getFragment,
-      getCollection,
+      fetchUpdatedCollection,
       createRecommendation,
     }) => (values, modalProps) => {
       const recommendation = parseEicDecision(values)
@@ -175,15 +197,50 @@ export default compose(
         collectionId: collection.id,
       })
         .then(() => {
-          getCollection({ id: collection.id })
-          getFragment(collection, fragment)
+          fetchUpdatedCollection()
           modalProps.hideModal()
         })
         .catch(() => {
           modalProps.setModalError('Oops! Something went wrong.')
         })
     },
+    onHEResponse: ({
+      history,
+      collection,
+      pendingHEInvitation,
+      fetchUpdatedCollection,
+    }) => (values, { hideModal, setModalError, setFetching }) => {
+      const isAccepted = get(values, 'decision', 'decline') === 'accept'
+      setFetching(true)
+      return handlingEditorDecision({
+        isAccepted,
+        collectionId: collection.id,
+        reason: get(values, 'reason', ''),
+        invitationId: pendingHEInvitation.id,
+      })
+        .then(() => {
+          setFetching(false)
+          hideModal()
+          if (isAccepted) {
+            fetchUpdatedCollection()
+          } else {
+            history.replace('/')
+          }
+        })
+        .catch(() => {
+          setFetching(false)
+          setModalError('Something went wrong...')
+        })
+    },
   }),
+  fromRenderProps(RemoteOpener, ({ toggle, expanded }) => ({
+    toggleAssignHE: toggle,
+    heExpanded: expanded,
+  })),
+  fromRenderProps(RemoteOpener, ({ toggle, expanded }) => ({
+    toggleHEResponse: toggle,
+    heResponseExpanded: expanded,
+  })),
   lifecycle({
     componentDidMount() {
       const {
@@ -197,6 +254,7 @@ export default compose(
         setEditorInChief,
         clearCustomError,
         hasManuscriptFailure,
+        permissions: { isInvitedHE },
       } = this.props
       if (hasManuscriptFailure) {
         history.push('/not-found')
@@ -219,6 +277,10 @@ export default compose(
       apiGet(`/users?editorInChief=true`).then(res =>
         setEditorInChief(head(res.users)),
       )
+
+      if (isInvitedHE) {
+        this.props.toggleHEResponse()
+      }
     },
   }),
   withProps(({ fragment }) => ({
diff --git a/packages/component-manuscript/src/redux/editors.js b/packages/component-manuscript/src/redux/editors.js
index b9b322422845e209260a194a3a0dc9155dd80598..e39a801a48fc179f638dfb1c36d16a50dd664401 100644
--- a/packages/component-manuscript/src/redux/editors.js
+++ b/packages/component-manuscript/src/redux/editors.js
@@ -17,7 +17,11 @@ const setHandlingEditors = editors => ({
 })
 
 export const selectFetching = state => get(state, 'editors.isFetching', false)
-export const selectHandlingEditors = state => get(state, 'editors.editors', [])
+export const selectHandlingEditors = state =>
+  chain(state)
+    .get('editors.editors', [])
+    .filter(editor => editor.isActive && editor.isConfirmed)
+    .value()
 
 export const canAssignHE = (state, collectionId = '') => {
   const isEIC = currentUserIs(state, 'adminEiC')
@@ -74,12 +78,12 @@ export const revokeHandlingEditor = ({
   )
 }
 
-export const handlingEditorDecision = (
+export const handlingEditorDecision = ({
   invitationId,
   collectionId,
   isAccepted,
   reason,
-) =>
+}) =>
   update(`/collections/${collectionId}/invitations/${invitationId}`, {
     isAccepted,
     reason,
diff --git a/packages/component-sortable-list/package.json b/packages/component-sortable-list/package.json
index 8914a5d0f541bf321de91e75057f723d645dae43..d32847a790e669e0afea31fab3b85895b28ace8c 100644
--- a/packages/component-sortable-list/package.json
+++ b/packages/component-sortable-list/package.json
@@ -7,6 +7,6 @@
     "react": "^16.4.2",
     "react-dnd": "^2.5.4",
     "react-dom": "^15.6.1",
-    "recompose": "^0.26.0"
+    "recompose": "^0.30.0"
   }
 }
diff --git a/packages/component-wizard/package.json b/packages/component-wizard/package.json
index a3d6410b2dd57c3e85be63dae36dbe1c261993d2..42283d163cdb6f874c3e1946fcdce4a0f1755b8d 100644
--- a/packages/component-wizard/package.json
+++ b/packages/component-wizard/package.json
@@ -19,7 +19,7 @@
     "react-router-dom": "^4.2.2",
     "redux": "^3.6.0",
     "redux-form": "7.0.3",
-    "recompose": "^0.26.0",
+    "recompose": "^0.30.0",
     "xpub-validators": "^0.0.5",
     "xpub-connect": "1.0.0",
     "xpub-journal": "^0.0.6",
diff --git a/packages/components-faraday/package.json b/packages/components-faraday/package.json
index 6fb598298b6ea6f787d9332b4f96514f4bf616d5..4a1e80ac4b0382d52f4f85b040b63723f1392ab8 100644
--- a/packages/components-faraday/package.json
+++ b/packages/components-faraday/package.json
@@ -17,7 +17,7 @@
     "react-dom": "^16.1.0",
     "react-router-dom": "^4.2.2",
     "react-tippy": "^1.2.2",
-    "recompose": "^0.26.0",
+    "recompose": "^0.30.0",
     "redux": "^3.6.0",
     "redux-form": "7.0.3",
     "styled-components": "^3.4.2",
diff --git a/packages/components-faraday/src/components/Login/LoginPage.js b/packages/components-faraday/src/components/Login/LoginPage.js
index b2bf3b19c045e197331d8f12204a5c488014fd73..55893a41090cf2a321853163a28edad365e6e8c1 100644
--- a/packages/components-faraday/src/components/Login/LoginPage.js
+++ b/packages/components-faraday/src/components/Login/LoginPage.js
@@ -1,6 +1,7 @@
 import React from 'react'
-import styled from 'styled-components'
+import { get } from 'lodash'
 import { connect } from 'react-redux'
+import styled from 'styled-components'
 import { reduxForm } from 'redux-form'
 import { th } from '@pubsweet/ui-toolkit'
 import { withProps, lifecycle, compose } from 'recompose'
@@ -88,8 +89,9 @@ const LoginPage = compose(
   reduxForm({
     form: 'login',
     enableReinitialize: false,
-    onSubmit: (values, dispatch) => {
-      dispatch(loginUser(values, '/dashboard'))
+    onSubmit: (values, dispatch, { location }) => {
+      const redirectTo = get(location, 'state.from.pathname', '/dashboard')
+      dispatch(loginUser(values, redirectTo))
     },
   }),
 )(Login)
diff --git a/packages/hindawi-theme/src/elements/Accordion.js b/packages/hindawi-theme/src/elements/Accordion.js
index 75707f3e6c145485c7e5385c11ec95c3812a05b5..f6c4a305aa75621270886ac78bccfa32a59b5e6e 100644
--- a/packages/hindawi-theme/src/elements/Accordion.js
+++ b/packages/hindawi-theme/src/elements/Accordion.js
@@ -1,14 +1,33 @@
 import { css } from 'styled-components'
 import { th } from '@pubsweet/ui-toolkit'
 
+const boxShadow = props => {
+  if (props.transparent) {
+    return css`
+      box-shadow: transparent;
+    `
+  }
+
+  if (props.highlight) {
+    return css`
+      border: 1px solid ${th('colorPrimary')};
+      box-shadow: 0 0 2px 0 ${th('colorPrimary')};
+    `
+  }
+
+  return css`
+    box-shadow: ${th('boxShadow')};
+  `
+}
+
 export default {
   Root: css`
     background-color: ${props =>
       props.transparent ? 'transparent' : th('accordion.backgroundColor')};
     border-radius: ${th('borderRadius')};
-    box-shadow: ${props =>
-      props.transparent ? 'transparent' : th('boxShadow')};
     flex: 1;
+
+    ${boxShadow};
   `,
   Header: {
     Root: css`
diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json
index 62a5b6e75d408ff3e8e47b45b3e80f4aebb5c2c5..4e30ddde8745944893f2ed9601603be229ba84e8 100644
--- a/packages/xpub-faraday/package.json
+++ b/packages/xpub-faraday/package.json
@@ -36,7 +36,7 @@
     "react-dnd-html5-backend": "^2.5.4",
     "react-dom": "^16.2.0",
     "react-router-dom": "^4.2.2",
-    "recompose": "^0.26.0",
+    "recompose": "^0.30.0",
     "redux": "^3.6.0",
     "redux-form": "7.0.3",
     "redux-logger": "^3.0.1",
diff --git a/yarn.lock b/yarn.lock
index 246baf960a5f324070ad21e75f203c5701510145..fe67b55014801df66d22fb2c6483d23c18545666 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -40,6 +40,12 @@
     esutils "^2.0.2"
     js-tokens "^3.0.0"
 
+"@babel/runtime@^7.0.0":
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
+  dependencies:
+    regenerator-runtime "^0.12.0"
+
 "@babel/runtime@^7.0.0-beta.38":
   version "7.0.0-beta.41"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.41.tgz#776ce13391b8154ccfdea71018a47b63e4d97e74"
@@ -9357,7 +9363,7 @@ react-is@^16.3.1:
   version "16.3.2"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.2.tgz#f4d3d0e2f5fbb6ac46450641eb2e25bf05d36b22"
 
-react-lifecycles-compat@^3.0.4:
+react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
 
@@ -9678,6 +9684,17 @@ recompose@^0.26.0:
     hoist-non-react-statics "^2.3.1"
     symbol-observable "^1.0.4"
 
+recompose@^0.30.0:
+  version "0.30.0"
+  resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.30.0.tgz#82773641b3927e8c7d24a0d87d65aeeba18aabd0"
+  dependencies:
+    "@babel/runtime" "^7.0.0"
+    change-emitter "^0.1.2"
+    fbjs "^0.8.1"
+    hoist-non-react-statics "^2.3.1"
+    react-lifecycles-compat "^3.0.2"
+    symbol-observable "^1.0.4"
+
 recursive-readdir@2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99"
@@ -9778,6 +9795,10 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
   version "0.11.1"
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
 
+regenerator-runtime@^0.12.0:
+  version "0.12.1"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
+
 regenerator-transform@^0.10.0:
   version "0.10.1"
   resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"