import React, { Fragment } from 'react' import { connect } from 'react-redux' import styled, { css } from 'styled-components' import { Icon, Button, th, Spinner } from '@pubsweet/ui' import { compose, withHandlers, lifecycle } from 'recompose' import { ConfirmationModal, withModal, } from 'pubsweet-component-modal/src/components' import { ReviewerForm, ReviewersList } from './' import { ReviewerBreakdown } from '../Invitations' import { selectReviewers, clearReviewersError, selectFetchingInvite, selectReviewersError, getCollectionReviewers, selectFetchingReviewers, } from '../../redux/reviewers' const InviteReviewers = ({ showInviteModal }) => ( <AssignButton onClick={showInviteModal}>Invite</AssignButton> ) const InviteReviewersModal = compose( connect( state => ({ reviewers: selectReviewers(state), reviewerError: selectReviewersError(state), fetchingInvite: selectFetchingInvite(state), fetchingReviewers: selectFetchingReviewers(state), }), { getCollectionReviewers }, ), withHandlers({ getReviewers: ({ collectionId, setReviewers, getCollectionReviewers, }) => () => { getCollectionReviewers(collectionId) }, }), lifecycle({ componentDidMount() { const { getReviewers } = this.props getReviewers() }, }), )( ({ hideModal, onConfirm, showModal, versionId, collectionId, getReviewers, reviewerError, fetchingInvite, fetchingReviewers, reviewers = [], invitations = [], }) => ( <Root> <CloseIcon data-test="icon-modal-hide" onClick={hideModal}> <Icon primary>x</Icon> </CloseIcon> <Title>Invite Reviewers</Title> <Subtitle>Invite reviewer</Subtitle> <ReviewerForm collectionId={collectionId} getReviewers={getReviewers} isFetching={fetchingInvite} reviewerError={reviewerError} reviewers={reviewers} /> <Row> {reviewers.length > 0 && ( <Fragment> <Subtitle>Reviewers Info</Subtitle> <ReviewerBreakdown collectionId={collectionId} versionId={versionId} /> </Fragment> )} {fetchingReviewers && <Spinner size={3} />} </Row> <ReviewersList collectionId={collectionId} reviewers={reviewers} showModal={showModal} versionId={versionId} /> </Root> ), ) const ModalSwitcher = compose( connect(state => ({ fetchingInvite: selectFetchingInvite(state), })), )(({ type, fetchingInvite, ...rest }) => { switch (type) { case 'invite-reviewers': return <InviteReviewersModal {...rest} /> default: return <ConfirmationModal {...rest} isFetching={fetchingInvite} /> } }) export default compose( connect(null, { clearReviewersError }), withModal(props => ({ modalComponent: ModalSwitcher, })), withHandlers({ showInviteModal: ({ project, version, hideModal, showModal, clearReviewersError, }) => () => { clearReviewersError() showModal({ type: 'invite-reviewers', collectionId: project.id, versionId: version.id, invitations: project.invitations, onConfirm: () => { hideModal() }, }) }, }), )(InviteReviewers) // #region styled-components const defaultText = css` color: ${th('colorText')}; font-family: ${th('fontReading')}; font-size: ${th('fontSizeBaseSmall')}; ` const CloseIcon = styled.div` cursor: pointer; position: absolute; top: ${th('subGridUnit')}; right: ${th('subGridUnit')}; ` const Subtitle = styled.span` ${defaultText}; align-self: flex-start; opacity: ${({ hidden }) => (hidden ? 0 : 1)}; margin-bottom: ${th('subGridUnit')}; text-transform: uppercase; ` const Title = styled.span` color: ${th('colorText')}; font-family: ${th('fontHeading')}; font-size: ${th('fontSizeHeading5')}; margin-bottom: ${th('gridUnit')}; ` const Row = styled.div` align-self: stretch; align-items: center; display: flex; flex-direction: row; justify-content: space-between; ` const Root = styled.div` align-items: center; background-color: ${th('backgroundColorReverse')}; display: flex; flex-direction: column; padding: calc(${th('subGridUnit')} * 6); position: relative; width: 580px; ` const AssignButton = styled(Button)` ${defaultText}; align-items: center; background-color: ${th('colorPrimary')}; color: ${th('colorTextReverse')}; height: calc(${th('subGridUnit')} * 5); text-align: center; ` // #endregion