import React, { Fragment } from 'react' import styled from 'styled-components' import { th } from '@pubsweet/ui-toolkit' import { DateParser } from '@pubsweet/ui' import { get, isEqual, orderBy } from 'lodash' import { compose, shouldUpdate, withHandlers, withProps } from 'recompose' import { Label, PersonInvitation, Text } from '../' const ReviewersTable = ({ invitations, getInvitationStatus, renderAcceptedLabel, onResendReviewerInvite, onRevokeReviewerInvite, }) => invitations.length > 0 && ( <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> </th> </tr> </thead> <tbody> {invitations.map((invitation, index) => ( <TableRow key={invitation.id}> <td> <Text>{`${get(invitation, 'person.firstName', '')} ${get( invitation, 'person.lastName', )}`}</Text> {invitation.isAccepted && ( <Text customId ml={1}> {renderAcceptedLabel(index)} </Text> )} </td> <td> <DateParser timestamp={invitation.invitedOn}> {timestamp => <Text>{timestamp}</Text>} </DateParser> </td> <td> <Fragment> {invitation.respondedOn && ( <DateParser timestamp={invitation.respondedOn}> {timestamp => <Text>{timestamp}</Text>} </DateParser> )} <Text ml={invitation.respondedOn ? 1 : 0} secondary> {getInvitationStatus(invitation)} </Text> </Fragment> </td> <td> <DateParser timestamp={get(invitation, 'review.submittedOn', '')}> {timestamp => <Text>{timestamp}</Text>} </DateParser> </td> <HiddenCell> {!invitation.hasAnswer && ( <PersonInvitation {...invitation} onResend={onResendReviewerInvite} onRevoke={onRevokeReviewerInvite} /> )} </HiddenCell> </TableRow> ))} </tbody> </Table> ) const orderInvitations = i => { if (!i.hasAnswer) return -1 if (i.isAccepted) return 0 return 1 } export default compose( shouldUpdate( ({ invitations }, { invitations: nextInvitations }) => !isEqual(invitations, nextInvitations), ), withProps(({ invitations = [] }) => ({ invitations: orderBy(invitations, orderInvitations), })), withProps(({ invitations = [] }) => ({ firstAccepted: invitations.findIndex(i => i.hasAnswer && i.isAccepted), })), withHandlers({ renderAcceptedLabel: ({ firstAccepted, invitations }) => index => `Reviewer ${index - firstAccepted + 1}`, getInvitationStatus: () => ({ hasAnswer, isAccepted }) => { if (!hasAnswer) return 'PENDING' if (isAccepted) return 'ACCEPTED' return 'DECLINED' }, }), )(ReviewersTable) // #region styles const Table = styled.table` border-collapse: collapse; width: 100%; & thead { border-bottom: 1px solid ${th('colorBorder')}; background-color: ${th('colorBackgroundHue2')}; } & th, & td { border: none; padding-left: calc(${th('gridUnit')} * 2); text-align: start; vertical-align: middle; height: calc(${th('gridUnit')} * 5); min-width: calc(${th('gridUnit')} * 12); } ` const HiddenCell = styled.td` opacity: 0; padding-top: ${th('gridUnit')}; ` 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: ${th('colorBackgroundHue3')}; ${HiddenCell} { opacity: 1; } } ` // #endregion