diff --git a/packages/component-manuscript/package.json b/packages/component-manuscript/package.json
index 110b73775085837e6e623990f86fde486d961003..2aab328d2fff84cd41d153d4b86c4663a54304e2 100644
--- a/packages/component-manuscript/package.json
+++ b/packages/component-manuscript/package.json
@@ -2,5 +2,17 @@
   "name": "pubsweet-component-manuscript",
   "version": "0.0.1",
   "main": "src",
-  "license": "MIT"
+  "license": "MIT",
+  "dependencies": {
+    "prop-types": "^15.5.10",
+    "recompose": "^0.26.0",
+    "xpub-connect": "^0.0.10",
+    "xpub-selectors": "^0.0.5"
+  },
+  "peerDependencies": {
+    "pubsweet-client": ">=2.1.0",
+    "react": ">=16",
+    "react-redux": ">=5.0.2",
+    "react-router-dom": ">=4.2.2"
+  }
 }
diff --git a/packages/component-manuscript/src/atoms/index.js b/packages/component-manuscript/src/atoms/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..69667e73d9e7019faeb0e2117e287be51cfc5b61
--- /dev/null
+++ b/packages/component-manuscript/src/atoms/index.js
@@ -0,0 +1,60 @@
+import { th } from '@pubsweet/ui'
+import styled, { css } from 'styled-components'
+
+const defaultText = css`
+  color: ${th('colorText')};
+  font-family: ${th('fontReading')};
+  font-size: ${th('fontSizeBaseSmall')};
+`
+const Root = styled.div`
+  display: flex;
+  flex-direction: column;
+  margin: auto;
+  max-width: 60em;
+`
+const Title = styled.div`
+  ${defaultText};
+  font-size: ${th('fontSizeBase')};
+  color: ${th('colorPrimary')};
+  margin-bottom: ${th('gridUnit')};
+  text-align: left;
+`
+
+const Header = styled.div`
+  align-items: center;
+  display: flex;
+  flex-direction: row;
+`
+
+const BreadCrumbs = styled.div`
+  & span {
+    color: ${th('colorPrimary')};
+    cursor: pointer;
+    font-size: ${th('fontSizeBase')};
+    text-align: left;
+    
+    &:after {
+      content: '>';
+      padding: 0 calc(${th('subGridUnit')}*2);
+    }
+
+    &:last-child {
+      font-size: ${th('fontSizeBase')};
+      font-weight: bold;
+      margin-right: ${th('subGridUnit')};
+      &:after {
+        display: none;
+    }
+  }
+`
+const ManuscriptId = styled.div`
+  ${defaultText};
+  color: ${th('colorPrimary')};
+  font-size: ${th('fontSizeBase')};
+  margin-right: 8px;
+  text-align: left;
+  text-transform: uppercase;
+  white-space: nowrap;
+`
+
+export { Root, BreadCrumbs, Header, Title, ManuscriptId }
diff --git a/packages/component-manuscript/src/components/Details.js b/packages/component-manuscript/src/components/Details.js
deleted file mode 100644
index 1445da287ee2c392472c5a823cb2cf6bccaee221..0000000000000000000000000000000000000000
--- a/packages/component-manuscript/src/components/Details.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react'
-import { connect } from 'react-redux'
-import { replace } from 'react-router-redux'
-import { compose, lifecycle } from 'recompose'
-import { selectCurrentUser } from 'xpub-selectors'
-
-import { parseSearchParams } from './utils'
-import { reviewerDecision } from '../../../components-faraday/src/redux/reviewers'
-
-const Details = () => <div>eu sunt manuscript details</div>
-
-export default compose(
-  connect(
-    state => ({
-      currentUser: selectCurrentUser(state),
-    }),
-    { reviewerDecision, replace },
-  ),
-  lifecycle({
-    componentDidMount() {
-      const { reviewerDecision, location, match, replace } = this.props
-      const collectionId = match.params.project
-      const { agree, invitationId } = parseSearchParams(location.search)
-      if (agree === 'true') {
-        reviewerDecision(invitationId, collectionId, true)
-        replace(location.pathname)
-      }
-    },
-  }),
-)(Details)
diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
new file mode 100644
index 0000000000000000000000000000000000000000..3935b6404e23fe80020d82f550e8106cf7e66973
--- /dev/null
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -0,0 +1,23 @@
+import React from 'react'
+
+import { Root, BreadCrumbs, Title, Header, ManuscriptId } from '../atoms'
+
+const ManuscriptLayout = ({
+  currentUser,
+  updateManuscript,
+  project,
+  version,
+}) => (
+  <Root>
+    <Header>
+      <BreadCrumbs>
+        <span>Dashboard</span>
+        <span>Manuscript Details</span>
+      </BreadCrumbs>
+      <ManuscriptId>{`- ID ${project.customId}`}</ManuscriptId>
+    </Header>
+    <Title dangerouslySetInnerHTML={{ __html: version.metadata.title }} />
+  </Root>
+)
+
+export default ManuscriptLayout
diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..091de333fb7acdc054de6f5cb42156ec29ce8030
--- /dev/null
+++ b/packages/component-manuscript/src/components/ManuscriptPage.js
@@ -0,0 +1,52 @@
+import { connect } from 'react-redux'
+import { actions } from 'pubsweet-client'
+import { ConnectPage } from 'xpub-connect'
+import {
+  selectCurrentUser,
+  selectCollection,
+  selectFragment,
+} from 'xpub-selectors'
+import { replace } from 'react-router-redux'
+import { compose, lifecycle, withHandlers } from 'recompose'
+
+import ManuscriptLayout from './ManuscriptLayout'
+import { parseSearchParams, redirectToError } from './utils'
+import { reviewerDecision } from '../../../components-faraday/src/redux/reviewers'
+
+export default compose(
+  ConnectPage(({ match }) => [
+    actions.getCollection({ id: match.params.project }),
+    actions.getFragment(
+      { id: match.params.project },
+      { id: match.params.version },
+    ),
+  ]),
+  connect(
+    (state, { match }) => ({
+      currentUser: selectCurrentUser(state),
+      project: selectCollection(state, match.params.project),
+      version: selectFragment(state, match.params.version),
+    }),
+    { reviewerDecision, replace, updateVersion: actions.updateFragment },
+  ),
+  lifecycle({
+    componentDidMount() {
+      const { reviewerDecision, replace, location, match } = this.props
+      const collectionId = match.params.project
+      const { agree, invitationId } = parseSearchParams(location.search)
+      if (agree === 'true') {
+        replace(location.pathname)
+        reviewerDecision(invitationId, collectionId, true).catch(
+          redirectToError(replace),
+        )
+      }
+    },
+  }),
+  withHandlers({
+    updateManuscript: ({ updateVersion, project, version }) => data =>
+      updateVersion(project, {
+        id: version.id,
+        ...data,
+      }),
+  }),
+)(ManuscriptLayout)
diff --git a/packages/component-manuscript/src/components/index.js b/packages/component-manuscript/src/components/index.js
index 08c9ae9088c3f3a1256b067abdab21339cf04098..e2e5b2d910d00c3a5fa12f0d7ebaf5363ea8d28f 100644
--- a/packages/component-manuscript/src/components/index.js
+++ b/packages/component-manuscript/src/components/index.js
@@ -1 +1 @@
-export { default as ManuscriptDetails } from './Details'
+export { default as ManuscriptPage } from './ManuscriptPage'
diff --git a/packages/component-manuscript/src/components/utils.js b/packages/component-manuscript/src/components/utils.js
index 4f264402c54df9f81ce41908b74ce063b72d3e73..9aed3777b03c8afb27cc7556190c9f7d1130ae83 100644
--- a/packages/component-manuscript/src/components/utils.js
+++ b/packages/component-manuscript/src/components/utils.js
@@ -1,4 +1,5 @@
 /* eslint-disable */
+import { get } from 'lodash'
 
 export const parseSearchParams = url => {
   const params = new URLSearchParams(url)
@@ -8,3 +9,13 @@ export const parseSearchParams = url => {
   }
   return parsedObject
 }
+
+const alreadyAnswered = `You have already answered this invitation.`
+export const redirectToError = redirectFn => err => {
+  const errorText = get(JSON.parse(err.response), 'error')
+  if (errorText.includes('has already been answered')) {
+    redirectFn('/error-page', alreadyAnswered)
+  } else {
+    redirectFn('/error-page', 'Oops! Something went wrong.')
+  }
+}
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
index 12c52f0f6965cbf72b563858f1220453ae3807f4..dfcffae0388b09700a6f4b1eeda3fe7202a171b1 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js
@@ -92,7 +92,7 @@ const DashboardCard = ({
                 data-test="button-details"
                 onClick={() =>
                   history.push(
-                    `/projects/${project.id}/versions/${version.id}/manuscript`,
+                    `/projects/${project.id}/versions/${version.id}/details`,
                   )
                 }
               >
diff --git a/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js b/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js
index 882d92fafe1dc296174320b9c01f87660fb9836a..ac8a194935f891a00f10b28d39bd2d1eeac4e6c2 100644
--- a/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js
+++ b/packages/components-faraday/src/components/Dashboard/ReviewerDecision.js
@@ -14,7 +14,7 @@ const ReviewerDecision = ({ showAcceptModal, showDeclineModal, ...rest }) => (
   <div>
     <DecisionButton onClick={showDeclineModal}>Decline</DecisionButton>
     <DecisionButton onClick={showAcceptModal} primary>
-      Accept
+      Agree
     </DecisionButton>
   </div>
 )
@@ -49,6 +49,7 @@ export default compose(
     }) => () => {
       showModal({
         title: 'Agree to review Manuscript?',
+        confirmText: 'Agree',
         onConfirm: () => {
           reviewerDecision(invitation.id, project.id, true).then(
             decisionSuccess,
@@ -65,6 +66,7 @@ export default compose(
     }) => () => {
       showModal({
         title: 'Decline to review Manuscript?',
+        confirmText: 'Decline',
         onConfirm: () => {
           reviewerDecision(invitation.id, project.id, false).then(
             decisionSuccess,
diff --git a/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js b/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js
index d75c2509f721ca4a3e92c817e9bf7371bd4eb5fb..7aa400252509bd60d01abca4765389e05cd34785 100644
--- a/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js
+++ b/packages/components-faraday/src/components/Invitations/ReviewerBreakdown.js
@@ -24,7 +24,7 @@ const reviewerReduce = (acc, r) => ({
 })
 
 const invitationReduce = (acc, i) => {
-  const key = i.isAccepted ? 'accepted' : 'refused'
+  const key = i.isAccepted ? 'accepted' : 'declined'
   return {
     ...acc,
     [key]: acc[key] + 1,
@@ -60,7 +60,7 @@ export default compose(
         type === BREAKDOWN_TYPES.invitation ? invitationReduce : reviewerReduce,
         {
           accepted: 0,
-          refused: 0,
+          declined: 0,
         },
       )
 
@@ -68,7 +68,7 @@ export default compose(
         <BreakdownText>
           <b>{values.length}</b> invited,
           <b> {report.accepted}</b> agreed,
-          <b> {report.refused}</b> declined
+          <b> {report.declined}</b> declined
         </BreakdownText>
       )
     },
diff --git a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
index bd8722dc070371a724e8511b9b1512349267b61a..600d264a07f23873b542267d0abc5ea2cc50949d 100644
--- a/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
+++ b/packages/components-faraday/src/components/Reviewers/InviteReviewers.js
@@ -75,7 +75,7 @@ const InviteReviewersModal = compose(
       />
 
       <Row>
-        {reviewers.length && (
+        {reviewers.length > 0 && (
           <Fragment>
             <Subtitle>Reviewers Info</Subtitle>
             <ReviewerBreakdown type="review" values={reviewers} />
diff --git a/packages/components-faraday/src/components/SignUp/FormItems.js b/packages/components-faraday/src/components/SignUp/FormItems.js
index 26db2ecb4473a8ce079a968a741f98d19c30a7bb..22089ca2c007dc4899737333d059efa744b5f0bd 100644
--- a/packages/components-faraday/src/components/SignUp/FormItems.js
+++ b/packages/components-faraday/src/components/SignUp/FormItems.js
@@ -22,7 +22,7 @@ export const Title = styled.div`
 `
 export const Subtitle = styled.div`
   font-family: ${th('fontReading')};
-  font-size: ${th('fontSizeBaseSmall')};
+  font-size: ${th('fontSizeBase')};
   font-weight: normal;
   margin: 10px auto;
   text-align: center;
@@ -56,8 +56,10 @@ export const Label = styled.div`
   font-size: ${th('fontSizeBaseSmall')};
   text-transform: uppercase;
 `
-export const Err = styled.div`
+export const Err = styled.span`
   color: ${th('colorError')};
+  font-family: ${th('fontReading')};
+  font-size: ${th('fontSizeBase')};
   margin-top: calc(${th('gridUnit')}*-1);
-  text-align: left;
+  text-align: center;
 `
diff --git a/packages/components-faraday/src/components/SignUp/ReviewerInviteDecision.js b/packages/components-faraday/src/components/SignUp/ReviewerInviteDecision.js
index c6db91452b20104118524357941cdaaf968326f9..8065fa65e51127e6eebe88734ec3f6e0866f3cc0 100644
--- a/packages/components-faraday/src/components/SignUp/ReviewerInviteDecision.js
+++ b/packages/components-faraday/src/components/SignUp/ReviewerInviteDecision.js
@@ -1,9 +1,9 @@
 import React from 'react'
 import { get } from 'lodash'
 import { connect } from 'react-redux'
-import { reduxForm, SubmissionError } from 'redux-form'
-import { push } from 'react-router-redux'
+import { push, replace } from 'react-router-redux'
 import { required, minChars } from 'xpub-validators'
+import { reduxForm, SubmissionError } from 'redux-form'
 import { compose, withState, lifecycle } from 'recompose'
 import { loginUser } from 'pubsweet-component-login/actions'
 import { Button, ValidatedField, TextField } from '@pubsweet/ui'
@@ -20,16 +20,18 @@ import {
   FormContainer,
 } from './FormItems'
 import { reviewerDecision, setReviewerPassword } from '../../redux/reviewers'
+import { redirectToError } from '../utils'
 
 const agreeText = `You have been invited to review a manuscript on the Hindawi platform. Please set a password and proceed to the manuscript.`
 const declineText = `You have decline to work on a manuscript.`
 
 const min8Chars = minChars(8)
 const ReviewerInviteDecision = ({
-  handleSubmit,
+  agree,
   error,
+  handleSubmit,
   reviewerEmail,
-  agree,
+  errorMessage,
 }) => (
   <RootContainer>
     <Title>Hindawi Invitation</Title>
@@ -61,18 +63,24 @@ const ReviewerInviteDecision = ({
         </Row>
       </FormContainer>
     )}
-    {agree === 'false' && <div>nu i-a placut</div>}
   </RootContainer>
 )
 
 export default compose(
   withState('reviewerEmail', 'setEmail', ''),
-  connect(null, { push, loginUser, setReviewerPassword, reviewerDecision }),
+  connect(null, {
+    push,
+    replace,
+    loginUser,
+    setReviewerPassword,
+    reviewerDecision,
+  }),
   lifecycle({
     componentDidMount() {
       const {
         agree,
         email,
+        replace,
         setEmail,
         collectionId,
         invitationId,
@@ -81,7 +89,9 @@ export default compose(
       setEmail(email)
 
       if (agree === 'false') {
-        reviewerDecision(invitationId, collectionId, false)
+        reviewerDecision(invitationId, collectionId, false).catch(
+          redirectToError(replace),
+        )
       }
     },
   }),
diff --git a/packages/components-faraday/src/components/UIComponents/ErrorPage.js b/packages/components-faraday/src/components/UIComponents/ErrorPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..4022bd8a95394667db65658d8d43217a69d044c4
--- /dev/null
+++ b/packages/components-faraday/src/components/UIComponents/ErrorPage.js
@@ -0,0 +1,34 @@
+import React from 'react'
+import { Button } from '@pubsweet/ui'
+import styled from 'styled-components'
+
+const ErrorPage = ({ location: { state }, history }) => (
+  <Root>
+    <Title>{state}</Title>
+    <Button onClick={() => history.push('/')} primary>
+      Go to Dashboard
+    </Button>
+  </Root>
+)
+
+export default ErrorPage
+
+// #region styles
+const Root = styled.div`
+  margin: 0 auto;
+  text-align: center;
+  width: 70vw;
+  color: ${({ theme }) => theme.colorText};
+
+  a {
+    color: ${({ theme }) => theme.colorText};
+  }
+`
+
+const Title = styled.div`
+  font-size: ${({ theme }) => theme.fontSizeHeading5};
+  font-family: ${({ theme }) => theme.fontHeading};
+  color: ${({ theme }) => theme.colorPrimary};
+  margin: 10px auto;
+`
+// #endregion
diff --git a/packages/components-faraday/src/components/UIComponents/index.js b/packages/components-faraday/src/components/UIComponents/index.js
index 0f79f62b6f773549c5da460c041232e47820dfb3..0b3250328118937d535b00e72bb038c6c45fb863 100644
--- a/packages/components-faraday/src/components/UIComponents/index.js
+++ b/packages/components-faraday/src/components/UIComponents/index.js
@@ -1,3 +1,6 @@
 export { default as Logo } from './Logo'
 export { default as Spinner } from './Spinner'
+export { default as NotFound } from './NotFound'
 export { default as Dropdown } from './Dropdown'
+export { default as ErrorPage } from './ErrorPage'
+export { default as ConfirmationPage } from './ConfirmationPage'
diff --git a/packages/components-faraday/src/components/utils.js b/packages/components-faraday/src/components/utils.js
index a6d5812e37cd28eb845dc1bcef44b5e4a0eb9d63..54cd85c4ada4e7724bf918000267b8019a442a3c 100644
--- a/packages/components-faraday/src/components/utils.js
+++ b/packages/components-faraday/src/components/utils.js
@@ -75,3 +75,13 @@ const emailRegex = new RegExp(
 
 export const emailValidator = value =>
   emailRegex.test(value) ? undefined : 'Invalid email'
+
+const alreadyAnswered = `You have already answered this invitation.`
+export const redirectToError = redirectFn => err => {
+  const errorText = get(JSON.parse(err.response), 'error')
+  if (errorText.includes('has already been answered')) {
+    redirectFn('/error-page', alreadyAnswered)
+  } else {
+    redirectFn('/error-page', 'Oops! Something went wrong.')
+  }
+}
diff --git a/packages/components-faraday/src/redux/utils.js b/packages/components-faraday/src/redux/utils.js
index 2f7f9cdca4a2f3b65a248f0ad1bb67d4fe300f04..14560f9260f6bfeec3f768e7a47b2c2147c1d111 100644
--- a/packages/components-faraday/src/redux/utils.js
+++ b/packages/components-faraday/src/redux/utils.js
@@ -4,7 +4,7 @@ export const orderReviewers = r => {
       return -1
     case 'accepted':
       return 0
-    case 'refused':
+    case 'declined':
     default:
       return 1
   }
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index 4eca5f8fc8556beca13751bca253bd7b6e50e648..bf161391ab7e1d48ff2c7d2241929e5160a7e68c 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -6,10 +6,13 @@ import Login from 'pubsweet-component-login/LoginContainer'
 import Signup from 'pubsweet-component-signup/SignupContainer'
 
 import { Wizard } from 'pubsweet-component-wizard/src/components'
-import { ManuscriptDetails } from 'pubsweet-component-manuscript/src/components'
+import { ManuscriptPage } from 'pubsweet-component-manuscript/src/components'
 import DashboardPage from 'pubsweet-components-faraday/src/components/Dashboard'
-import NotFound from 'pubsweet-components-faraday/src/components/UIComponents/NotFound'
-import ConfirmationPage from 'pubsweet-components-faraday/src/components/UIComponents/ConfirmationPage'
+import {
+  NotFound,
+  ConfirmationPage,
+  ErrorPage,
+} from 'pubsweet-components-faraday/src/components/UIComponents/'
 import {
   AdminDashboard,
   AdminUsers,
@@ -63,10 +66,12 @@ const Routes = () => (
       <Route component={SignUpInvitationPage} exact path="/invite" />
       <Route component={ReviewerSignUp} exact path="/invite-reviewer" />
       <PrivateRoute
-        component={ManuscriptDetails}
+        component={ManuscriptPage}
         exact
         path="/projects/:project/versions/:version/details"
       />
+
+      <Route component={ErrorPage} exact path="/error-page" />
       <Route component={NotFound} />
     </Switch>
   </FaradayApp>