diff --git a/packages/components-faraday/src/components/Admin/Admin.js b/packages/components-faraday/src/components/Admin/Admin.js index 8bb2efb4763a63d6895a9e2eb109a9b8c88655b7..c0ad599e3ca23dee2d4a675bef8863f0dbbb890a 100644 --- a/packages/components-faraday/src/components/Admin/Admin.js +++ b/packages/components-faraday/src/components/Admin/Admin.js @@ -1,18 +1,195 @@ import React from 'react' -import PropTypes from 'prop-types' - -import classes from './Admin.local.scss' - -const Admin = ({ users }) => ( - <div className={classes.root}> - <h2>Admin</h2> - <ul> - {users.map((u, i) => ( - <li key={i}> - {u.username} - {u.email} - </li> - ))} - </ul> +import styled from 'styled-components' +import { Icon, Menu } from '@pubsweet/ui' + +import { Pagination } from './' + +const AddButton = styled.button` + align-items: center; + border: none; + cursor: pointer; + display: flex; + font-family: Helvetica; + font-size: 12px; + text-align: left; + color: #667080; + + &:active, + &:focus { + outline: none; + } +` + +const Header = styled.div` + display: flex; + flex-direction: row; + align-items: center; + + & span { + font-family: Helvetica; + font-size: 24px; + font-weight: bold; + text-align: left; + color: #667080; + } +` + +const SubHeader = styled.div` + align-items: center; + border-bottom: 1px solid #667080; + display: flex; + flex-direction: row; + justify-content: space-between; + margin-top: 20px; + padding-bottom: 10px; + + > div:first-child { + display: flex; + align-items: center; + } + + span { + font-family: Helvetica; + font-size: 14px; + text-align: left; + color: #667080; + } +` + +const Table = styled.table` + border-spacing: 0; + border-collapse: collapse; + margin-top: 10px; + width: 100vw; + + & thead tr { + height: 40px; + border-bottom: 1px solid #667080; + font-family: Helvetica; + font-size: 14px; + font-weight: bold; + text-align: left; + color: #667080; + } +` + +const Row = styled.tr` + border-bottom: 1px solid #667080; + color: #667080; + font-family: Helvetica; + font-size: 14px; + height: 40px; + text-align: left; +` + +const Status = styled.td` + & span { + border: solid 1px #667080; + text-transform: uppercase; + font-family: Helvetica; + font-size: 12px; + font-weight: bold; + text-align: left; + color: #667080; + padding: 2px 10px; + } +` + +const Input = styled.input` + height: 20px; + width: 20px; +` + +const TableRow = ({ toggleUser, selected, email, username, type }) => ( + <Row> + <td> + <Input checked={selected} onClick={toggleUser} type="checkbox" /> + </td> + <td>{email}</td> + <td>{username}</td> + <td>affiliation here</td> + <td>country here</td> + <td>{type}</td> + <Status> + <span>status</span> + </Status> + </Row> +) + +const Admin = ({ + users, + toggleUser, + toggleAllUsers, + incrementPage, + decrementPage, + page, + itemsPerPage, +}) => ( + <div> + <Header> + <span>Users</span> + <AddButton> + <Icon color="#667080">plus-circle</Icon> + Add User + </AddButton> + </Header> + <SubHeader> + <div> + <span>Bulk actions: </span> + <Menu + onChange={value => value} + options={[ + { value: 'deactivate', label: 'Deactivate' }, + { value: 'activate', label: 'Activate' }, + ]} + value="activate" + /> + + <Menu + onChange={value => value} + options={[ + { value: 'sort', label: 'SORT' }, + { value: 'unsort', label: 'UNSORT' }, + ]} + value="sort" + /> + + <Icon color="#667080" size={24}> + search + </Icon> + </div> + <Pagination + decrementPage={decrementPage} + incrementPage={incrementPage} + itemsPerPage={itemsPerPage} + page={page} + /> + </SubHeader> + + <Table> + <thead> + <tr> + <td> + <Input + checked={users.every(u => u.selected)} + onClick={toggleAllUsers} + type="checkbox" + /> + </td> + <td>Email</td> + <td>Full name</td> + <td>Affiliation</td> + <td>Country</td> + <td>Roles</td> + <td>Status</td> + </tr> + </thead> + <tbody> + {users.map(u => ( + <TableRow key={u.id} {...u} toggleUser={toggleUser(u)} /> + ))} + </tbody> + </Table> </div> ) diff --git a/packages/components-faraday/src/components/Admin/Admin.local.scss b/packages/components-faraday/src/components/Admin/Admin.local.scss deleted file mode 100644 index 6ea81ade44fa58f18373e06c91eed42c61da4037..0000000000000000000000000000000000000000 --- a/packages/components-faraday/src/components/Admin/Admin.local.scss +++ /dev/null @@ -1,6 +0,0 @@ -.root { - display: flex; - flex-direction: column; - margin: auto; - max-width: 60em; -} diff --git a/packages/components-faraday/src/components/Admin/AdminPage.js b/packages/components-faraday/src/components/Admin/AdminPage.js index 40a751d36ae83c6d0e7dde55ce75ef8c08ce2539..cfc2d61e7c4c03ccde7f50db2d267b3ec84c60bf 100644 --- a/packages/components-faraday/src/components/Admin/AdminPage.js +++ b/packages/components-faraday/src/components/Admin/AdminPage.js @@ -1,15 +1,35 @@ import { get } from 'lodash' -import PropTypes from 'prop-types' -import { compose } from 'recompose' import { connect } from 'react-redux' import { actions } from 'pubsweet-client' import { ConnectPage } from 'xpub-connect' import { withRouter } from 'react-router-dom' +import { compose, withState, withHandlers } from 'recompose' import Admin from './Admin' export default compose( ConnectPage(() => [actions.getUsers()]), withRouter, - connect(state => ({ users: get(state, 'users.users') })), + connect(state => ({ currentUsers: get(state, 'users.users') })), + withState('users', 'setUsers', props => + props.currentUsers.map(u => ({ ...u, selected: false })), + ), + withState('itemsPerPage', 'setItemsPerPage', 50), + withState('page', 'setPage', 0), + withHandlers({ + incrementPage: ({ setPage }) => () => { + setPage(p => p + 1) + }, + decrementPage: ({ setPage }) => () => { + setPage(p => (p > 0 ? p - 1 : p)) + }, + toggleUser: ({ setUsers }) => user => () => { + setUsers(prev => + prev.map(u => (u.id === user.id ? { ...u, selected: !u.selected } : u)), + ) + }, + toggleAllUsers: ({ setUsers }) => () => { + setUsers(users => users.map(u => ({ ...u, selected: !u.selected }))) + }, + }), )(Admin) diff --git a/packages/components-faraday/src/components/Admin/Pagination.js b/packages/components-faraday/src/components/Admin/Pagination.js new file mode 100644 index 0000000000000000000000000000000000000000..df4373a0d4f4fe2e93df637c90e8664c4060bde9 --- /dev/null +++ b/packages/components-faraday/src/components/Admin/Pagination.js @@ -0,0 +1,70 @@ +import React from 'react' +import styled from 'styled-components' +import { Icon } from '@pubsweet/ui' + +const Root = styled.div` + display: flex; + align-items: center; +` + +const Chevrons = styled.div` + display: flex; + align-items: center; +` + +const IconButton = styled.button` + align-items: center; + border: none; + cursor: pointer; + display: flex; + font-family: Helvetica; + font-size: 12px; + text-align: left; + color: #667080; + + &:active, + &:focus { + outline: none; + } +` + +const Showing = styled.div` + display: flex; + align-items: center; + + span:first-child { + font-family: Helvetica; + font-size: 14px; + text-align: left; + color: #667080; + margin-right: 10px; + } + span:last-child { + border: solid 1px #667080; + padding: 2px 10px; + } +` + +const Pagination = ({ page, itemsPerPage, incrementPage, decrementPage }) => ( + <Root> + <Showing> + <span>Showing:</span> + <span>50</span> + </Showing> + <Chevrons> + <IconButton onClick={decrementPage}> + <Icon color="#667080" size={18}> + chevron-left + </Icon> + </IconButton> + <span>{`${page * itemsPerPage + 1} to ${page * itemsPerPage + 50}`}</span> + <IconButton onClick={incrementPage}> + <Icon color="#667080" size={18}> + chevron-right + </Icon> + </IconButton> + </Chevrons> + </Root> +) + +export default Pagination diff --git a/packages/components-faraday/src/components/Admin/index.js b/packages/components-faraday/src/components/Admin/index.js index f623059ef006ec5d6c516c651bdaa474feb4f073..4f1e2831e6e6710d184684b30b4257f9493ea47a 100644 --- a/packages/components-faraday/src/components/Admin/index.js +++ b/packages/components-faraday/src/components/Admin/index.js @@ -1,3 +1,4 @@ import AdminPage from './AdminPage' export default AdminPage +export { default as Pagination } from './Pagination' diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.js b/packages/components-faraday/src/components/Dashboard/Dashboard.js index 29ba564fd069e3d25afe4247899b5f5917afd15f..110f39981fe79f44e7671d3c02fec67ebd76e666 100644 --- a/packages/components-faraday/src/components/Dashboard/Dashboard.js +++ b/packages/components-faraday/src/components/Dashboard/Dashboard.js @@ -23,14 +23,24 @@ const Dashboard = ({ filterItems, abstractModal, setModal, + history, ...rest }) => ( <div className={classes.root}> <div className={classes.header}> <div className={classes.heading}>Manuscripts</div> - <Button onClick={createDraftSubmission} primary> - New - </Button> + <div className={classes.headerButtons}> + <Button + className={classes['admin-button']} + onClick={() => history.push('admin')} + primary + > + Admin dashboard + </Button> + <Button onClick={createDraftSubmission} primary> + New + </Button> + </div> </div> <DashboardFilters changeFilterValue={changeFilterValue} diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss b/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss index 5a2dc6819b679b6e45fd78737c23c00a77787a86..b4fb082487cd95ba901f0c2dcfb120d20b300312 100644 --- a/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss +++ b/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss @@ -67,6 +67,14 @@ justify-content: space-between; } +.headerButtons { + display: flex; + + .admin-button { + margin-right: 15px; + } +} + .heading { color: var(--color-primary); font-size: 1.6em; diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index d41444fcc32124eeb24639c80380e9f2536f3204..3cafabc6a12877337794cf1647cc29330eca4d59 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -25,7 +25,7 @@ module.exports = { 'pubsweet-client': { API_ENDPOINT: '/api', 'login-redirect': '/', - 'redux-log': false, + 'redux-log': true, theme: process.env.PUBSWEET_THEME, }, 'mail-transport': {