import React, { Fragment } from 'react' import { get } from 'lodash' import { Button } from '@pubsweet/ui' import { connect } from 'react-redux' import styled from 'styled-components' import { th } from '@pubsweet/ui-toolkit' import { actions } from 'pubsweet-client' import { ConnectPage } from 'xpub-connect' import { withJournal } from 'xpub-journal' import { compose, withHandlers, withProps } from 'recompose' import { getAdminUsers } from 'pubsweet-component-faraday-selectors' import { Row, Text, Item, Label, OpenModal, Pagination, ActionLink, handleError, withFetching, withPagination, } from 'pubsweet-component-faraday-ui' import { AddUser } from './' import { updateUserStatus, onSubmit } from './utils' const Users = ({ page, users, theme, history, journal, getUsers, isFetching, getUserRoles, itemsPerPage, deactivateUser, getStatusLabel, paginatedItems, toggleUserStatus, ...rest }) => ( <Fragment> <Row alignItems="center" justify="space-between" mb={1}> <Item alignItems="center"> <ActionLink icon="arrow-left" mr={2} onClick={history.goBack}> Admin Dashboard </ActionLink> <AddUser form="add-user" getUsers={getUsers} modalKey="addUser" onSubmit={onSubmit} /> </Item> <Pagination {...rest} itemsPerPage={itemsPerPage} page={page} /> </Row> <Table> <thead> <tr> <th> <Label>Full Name</Label> </th> <th colSpan={2}> <Label>Email</Label> </th> <th> <Label>Affiliation</Label> </th> <th> <Label>Roles</Label> </th> <th> <Label>Status</Label> </th> <th> </th> </tr> </thead> <tbody> {paginatedItems.map(user => ( <UserRow key={user.id}> <td> <Text pl={1}>{`${get(user, 'firstName', '')} ${get( user, 'lastName', '', )}`}</Text> </td> <td colSpan={2}> <Text>{user.email}</Text> </td> <td> <Text>{user.affiliation}</Text> </td> <td> <Text customId>{getUserRoles(user)}</Text> </td> <td> <Text secondary>{getStatusLabel(user)}</Text> </td> <HiddenCell> <Item alignItems="center" justify="flex-end"> <AddUser edit getUsers={getUsers} modalKey={`edit-${user.id}`} onSubmit={onSubmit} user={user} /> <OpenModal isFetching={isFetching} modalKey={`deactivate-${user.id}`} onConfirm={deactivateUser(user)} subtitle={`${user.firstName} ${user.lastName}`} title={`Are you sure to ${ !user.isActive ? 'activate' : 'deactivate' } user?`} > {showModal => ( <ActivateButton ml={1} mr={1} onClick={showModal} size="small" > {!user.isActive ? 'ACTIVATE' : 'DEACTIVATE'} </ActivateButton> )} </OpenModal> </Item> </HiddenCell> </UserRow> ))} </tbody> </Table> </Fragment> ) export default compose( ConnectPage(() => [actions.getUsers()]), connect( state => ({ items: getAdminUsers(state), }), { getUsers: actions.getUsers, }, ), withJournal, withFetching, withPagination, withProps(({ journal: { roles = {} } }) => ({ roles: Object.keys(roles), })), withHandlers({ getStatusLabel: () => ({ isConfirmed, isActive = true }) => { if (!isActive) { return 'INACTIVE' } return isConfirmed ? 'ACTIVE' : 'INVITED' }, deactivateUser: ({ setFetching, getUsers }) => user => ({ hideModal, setModalError, }) => { setFetching(true) updateUserStatus(user) .then(() => { setFetching(false) getUsers() hideModal() }) .catch(err => { setFetching(false) handleError(setModalError)(err) }) }, getUserRoles: ({ journal: { roles = {} } }) => user => { const parsedRoles = Object.entries(roles) .reduce((acc, role) => (user[role[0]] ? [...acc, role[1]] : acc), []) .join(', ') return parsedRoles || 'Author' }, }), )(Users) // #region styled-components const Table = styled.table` border-collapse: collapse; & th, & td { border: none; text-align: start; vertical-align: middle; height: calc(${th('gridUnit')} * 5); } ` const HiddenCell = styled.td` opacity: 0; ` const UserRow = styled.tr` background-color: ${th('colorBackgroundHue2')}; border-bottom: 1px solid ${th('colorBorder')}; &:hover { background-color: ${th('colorBackgroundHue3')}; ${HiddenCell} { opacity: 1; } } ` const ActivateButton = styled(Button)` width: 90px; ` // #endregion