Newer
Older
import React from 'react'
import { get, isEqual } from 'lodash'
import { connect } from 'react-redux'
import { actions } from 'pubsweet-client'
import { ConnectPage } from 'xpub-connect'
import { withJournal } from 'xpub-journal'
import { Icon, th } from '@pubsweet/ui'
import { withRouter, Link } from 'react-router-dom'
import styled, { withTheme } from 'styled-components'
import { compose, withState, withHandlers } from 'recompose'
import {
withModal,
ConfirmationModal,
} from 'pubsweet-component-modal/src/components'
import { updateUserStatusModal } from './utils'
email,
firstName = '',
lastName = '',
toggleUserStatus,
getStatusLabel,
<td>{`${firstName} ${lastName}`}</td>
<td>{affiliation}</td>
<Role>{`Author${isEqual(editorInChief, true) ? ', Editor in Chief' : ''}${
isEqual(handlingEditor, true) ? ', Handling Editor' : ''
}${isEqual(admin, true) ? ', Admin' : ''}`}</Role>
<Action to={`/admin/users/edit/${id}`}>Edit</Action>
<ActionButton onClick={toggleUserStatus}>
{isActive ? 'Deactivate' : 'Reactivate'}
itemsPerPage,
incrementPage,
decrementPage,
getStatusLabel,
toggleUserStatus,
}) => {
const slicedUsers = users.slice(
page * itemsPerPage,
itemsPerPage * (page + 1),
)
return (
<div>
<Header>
<BreadCrumbs>
<span>Admin Dashboard</span>
<span>Users</span>
</BreadCrumbs>
<AddButton
data-test="button-add-user"
onClick={() => history.push('/admin/users/add')}
>
<Icon color={theme.colorPrimary} size={3}>
plus-circle
</Icon>
Add User
</AddButton>
</Header>
<SubHeader>
<Pagination
decrementPage={decrementPage}
hasMore={itemsPerPage * (page + 1) < users.length}
incrementPage={incrementPage}
itemsPerPage={itemsPerPage}
maxLength={users.length}
page={page}
/>
</SubHeader>
<td width="220">Roles</td>
</tr>
</thead>
<tbody>
{slicedUsers.map(u => (
<TableRow
key={u.id}
{...u}
getStatusLabel={getStatusLabel(u)}
toggleUserStatus={toggleUserStatus(u)}
))}
</tbody>
</Table>
</div>
)
}
export default compose(
ConnectPage(() => [actions.getUsers()]),
withRouter,
withModal(props => ({
modalComponent: ConfirmationModal,
})),
connect(state => ({ users: get(state, 'users.users') })),
withState('itemsPerPage', 'setItemsPerPage', 20),
withState('page', 'setPage', 0),
withHandlers({
incrementPage: ({ setPage, page, itemsPerPage, users }) => () => {
if (page * itemsPerPage + itemsPerPage < users.length) {
setPage(p => p + 1)
}
},
decrementPage: ({ setPage }) => () => {
setPage(p => (p > 0 ? p - 1 : p))
},
getStatusLabel: () => ({ isConfirmed, isActive = true }) => () => {
if (isConfirmed) {
return isActive ? 'Active' : 'Inactive'
}
return 'Invited'
toggleUserStatus: ({
dispatch,
showModal,
hideModal,
setModalError,
}) => user => () => {
updateUserStatusModal({
dispatch,
showModal,
hideModal,
setModalError,
user,
})
},
}),
)(Users)
// #region styled-components
const AddButton = styled.button`
align-items: center;
background-color: ${th('backgroundColor')};
border: none;
cursor: pointer;
color: ${th('colorPrimary')};
font-family: ${th('fontInterface')};
font-size: ${th('fontSizeBaseSmall')};
text-align: left;
&:active,
&:focus {
outline: none;
}
`
const Header = styled.div`
align-items: center;
flex-direction: row;
const BreadCrumbs = styled.div`
color: ${th('colorPrimary')};
cursor: pointer;
font-size: ${th('fontSizeBase')};
margin-left: calc(${th('subGridUnit')}*2);
text-align: left;
&:after {
content: '>';
padding: 0 calc(${th('subGridUnit')}*2);
}
&:last-child {
font-size: ${th('fontSizeBase')};
font-weight: bold;
&:after {
content: '';
}
}
`
const SubHeader = styled.div`
align-items: center;
border-bottom: ${th('borderDefault')};
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: ${th('gridUnit')};
padding-bottom: calc(${th('subGridUnit')}*2);
> div:first-child {
align-items: center;
display: flex;
> div {
margin-right: calc(${th('subGridUnit')});
}
color: ${th('colorPrimary')};
font-family: ${th('fontReading')};
font-size: ${th('fontSizeBaseSmall')};
margin-right: calc(${th('subGridUnit')});
text-align: left;
}
`
const Table = styled.table`
border-spacing: 0;
border-collapse: collapse;
border-bottom: ${th('borderDefault')};
color: ${th('colorPrimary')};
font-family: ${th('fontReading')};
font-size: ${th('fontSizeBaseSmall')};
height: 40px;
text-align: left;
}
`
const Row = styled.tr`
border-bottom: ${th('borderDefault')};
color: ${th('colorPrimary')};
font-family: ${th('fontReading')};
font-size: ${th('fontSizeBaseSmall')};
height: 40px;
text-align: left;
background-color: ${th('backgroundColorReverse')};
display: block;
}
}
const Tag = styled.span`
border: solid 1px #667080;
color: ${th('colorPrimary')};
font-family: ${th('fontReading')};
font-size: ${th('fontSizeBaseSmall')};
font-weight: bold;
margin-right: calc(${th('subGridUnit')});
padding: 2px calc(${th('subGridUnit')}*2);
text-align: left;
text-transform: uppercase;
const Role = styled.div`
color: ${th('colorPrimary')};
font-size: ${th('fontSizeBaseSmall')};
line-height: 1.5;
text-align: left;
text-transform: uppercase;
`
color: ${th('colorPrimary')};
const TD = styled.td`
display: inline-flex;
width: 100%;
min-height: 20px;
`
const ActionButton = styled.i`
cursor: pointer;
display: none;
font-style: unset;
text-decoration: underline;
margin: 0 calc(${th('subGridUnit')} * 2);