Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
NewWizard.js 7.90 KiB
import React, { Fragment } from 'react'
import { connect } from 'react-redux'
import { reduxForm } from 'redux-form'
import { th } from '@pubsweet/ui-toolkit'
import { actions } from 'pubsweet-client'
import { withJournal } from 'xpub-journal'
import { ConnectPage } from 'xpub-connect'
import { required } from 'xpub-validators'
import { DragDropContext } from 'react-dnd'
import { get, debounce, omit } from 'lodash'
import styled, { css } from 'styled-components'
import HTML5Backend from 'react-dnd-html5-backend'
import { selectCollection, selectFragment } from 'xpub-selectors'
import { Icon, Checkbox, ValidatedField, Menu, Button } from '@pubsweet/ui'
import { withStateHandlers, compose, toClass, withProps } from 'recompose'
import {
  Steps,
  FormItems,
  AuthorList,
} from 'pubsweet-components-faraday/src/components'

import { autosaveRequest } from '../redux/autosave'

const {
  Row,
  Label,
  Title,
  RowItem,
  Subtitle,
  TextField,
  TextAreaField,
} = FormItems

// #region StepOne
const NewStepOne = () => (
  <Fragment>
    <Title>1. Pre-Submission Checklist</Title>
    <Subtitle>
      Before moving forward make sure you have all the required files prepared
      and the items on the list below reviewed.
    </Subtitle>
    <Row justify="flex-start">
      <Text>
        I have the email addresses of all the co-authors of the manuscript.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I have the manuscript file in Microsoft Word or Adobe PDF format with
        the tables and figures integrated in the manuscript body.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I have the electronic files of any supplementary materials (e.g.,
        datasest, images, audio, video) that I want to submit with the
        manuscript.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I am aware that accepted manuscripts are subject to{' '}
        <a
          href="https://www.google.com"
          rel="noopener noreferrer"
          target="_blank"
        >
          Article Processing Charges
        </a>.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I am aware that an ORCID ID is required for the corresponding author
        before the article can be published (if accepted). The ORCID ID should
        be added via your user account.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I am aware that if my submission is covered by an institutional
        membership, Hindawi will share details of the manuscript with the
        administrator of the membership.
      </Text>
    </Row>
    <Row justify="flex-start">
      <Text>
        I am aware of the Hindawi article processing charges tax of $1000.
      </Text>
    </Row>
    <Row justify="flex-start">
      <ValidatedField
        component={input => (
          <Checkbox
            checked={input.value}
            {...input}
            label={`I've reviewed and understood all the above items.`}
          />
        )}
        name="agree"
        validate={[required]}
      />
    </Row>
  </Fragment>
)
// #endregion

// #region StepTwo
const NewStepTwo = ({ version, project, manuscriptTypes }) => (
  <Fragment>
    <Title>2. Manuscript & Authors Details</Title>
    <Subtitle>
      Please provide the details of all the authors of this manuscript, in the
      order that they appear on the manuscript. Your details are already
      prefiled since, in order to submit a manuscript you must be one of the
      authors.
    </Subtitle>
    <Row className="row">
      <RowItem flex={3} vertical withRightMargin>
        <Label>MANUSCRIPT TITLE*</Label>
        <ValidatedField
          component={input => <TextField {...input} />}
          name="metadata.title"
          validate={[required]}
        />
      </RowItem>
      <RowItem vertical>
        <Label>MANUSCRIPT TYPE*</Label>
        <ValidatedField
          component={input => <Menu options={manuscriptTypes} {...input} />}
          name="metadata.type"
          validate={[required]}
        />
      </RowItem>
    </Row>
    <Row className="row">
      <RowItem vertical>
        <Label>ABSTRACT*</Label>
        <ValidatedField
          component={TextAreaField}
          name="metadata.abstract"
          validate={[required]}
        />
      </RowItem>
    </Row>
    <Row className="row">
      <RowItem vertical>
        <Label>AUTHORS DETAILS*</Label>
        <AuthorList
          parentForm="submission"
          project={project}
          version={version}
        />
      </RowItem>
    </Row>
  </Fragment>
)
// #endregion

const NewWizard = ({
  step,
  version,
  project,
  nextStep,
  prevStep,
  handleSubmit,
  journal: { manuscriptTypes = [] },
}) => (
  <Fragment>
    <Steps currentStep={step} margin="0 20px 60px 0">
      <Steps.Step key="step-one" title="Pre-submission Checklist" />
      <Steps.Step key="step-two" title="Manuscript & Author Details" />
      <Steps.Step key="step-three" title="Files Upload" />
    </Steps>

    <StepRoot className="wizard-root">
      <IconButton>
        <Icon primary size={4}>
          x
        </Icon>
      </IconButton>
      {step === 0 && <NewStepOne />}
      {step === 1 && (
        <NewStepTwo
          manuscriptTypes={manuscriptTypes}
          project={project}
          version={version}
        />
      )}
      <Row centered>
        <ButtonContainer>
          <Button onClick={prevStep}>{`< BACK`}</Button>
          <Button onClick={handleSubmit} primary>
            {`NEXT STEP >`}
          </Button>
        </ButtonContainer>
      </Row>
    </StepRoot>
  </Fragment>
)

const onChange = (values, dispatch, { project, version }) => {
  const newValues = omit(values, ['agree', 'authorForm'])
  dispatch(autosaveRequest())
  dispatch(
    actions.updateFragment(project, {
      ...version,
      ...newValues,
    }),
  )
}

// #region export
export default compose(
  ConnectPage(({ match }) => [
    actions.getCollection({ id: match.params.project }),
    actions.getFragment(
      { id: match.params.project },
      { id: match.params.version },
    ),
  ]),
  withJournal,
  connect((state, { match }) => ({
    version: selectFragment(state, get(match, 'params.version')),
    project: selectCollection(state, get(match, 'params.project')),
  })),
  withStateHandlers(
    { step: 1 },
    {
      nextStep: ({ step }) => () => ({ step: step + 1 }),
      prevStep: ({ step }) => () => ({ step: step - 1 }),
    },
  ),
  withProps(({ version }) => ({
    initialValues: {
      metadata: get(version, 'metadata', {}),
    },
  })),
  reduxForm({
    form: 'submission',
    onChange: debounce(onChange, 1000, { maxWait: 5000 }),
    onSubmit: (values, dispatch, { step, nextStep }) => {
      if (step < 2) {
        nextStep()
      }
    },
  }),
  DragDropContext(HTML5Backend),
  toClass,
)(NewWizard)
// #endregion

// #region styled-components
const defaultText = css`
  color: ${th('colorPrimary')};
  font-size: ${th('fontSizeBase')};
  font-family: ${th('fontReading')};
`
const Text = styled.span`
  ${defaultText};
`

const StepRoot = styled.div`
  align-items: flex-start;
  background-color: ${th('colorBackground')};
  border: ${th('borderDefault')};
  display: flex;
  flex-direction: column;
  padding: 30px;
  position: relative;
`

const IconButton = styled.button`
  align-items: center;
  background-color: ${th('colorBackground')};
  border: none;
  color: ${th('colorPrimary')};
  cursor: ${({ hide }) => (hide ? 'auto' : 'pointer')};
  display: flex;
  font-family: ${th('fontInterface')};
  font-size: ${th('fontSizeBaseSmall')};
  opacity: ${({ hide }) => (hide ? 0 : 1)};
  text-align: left;

  position: absolute;
  top: 10px;
  right: 10px;

  &:active,
  &:focus {
    outline: none;
  }
  &:hover {
    opacity: 0.7;
  }
`

const ButtonContainer = styled.div`
  align-items: center;
  display: flex;
  flex-direction: row;
  justify-content: space-between;

  width: calc(${th('gridUnit')} * 14);
`
// #endregion