-
Bogdan Cochior authoredc1c9fa66
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
/* eslint-disable handle-callback-err */
import React, { Fragment } from 'react'
import countrylist from 'country-list'
import styled from 'styled-components'
import { reduxForm } from 'redux-form'
import { th } from '@pubsweet/ui-toolkit'
import { required as requiredValidator } from 'xpub-validators'
import { compose, withStateHandlers, withProps } from 'recompose'
import { H3, Spinner, ValidatedField, TextField, Menu } from '@pubsweet/ui'
import {
ShadowedBox,
IconButton,
Row,
Item,
Label,
Text,
ActionLink,
RowOverrideAlert,
} from './'
const countries = countrylist()
const countryList = countries
.getNames()
.map(c => ({ value: countries.getCode(c), label: c }))
const Profile = ({
title,
toggleEdit,
user: { affiliation, firstName, lastName, title: userTitle, country = '' },
...rest
}) => (
<ShadowedBox position="relative" {...rest}>
<IconButton
icon="edit-2"
iconSize={2}
onClick={toggleEdit}
right={8}
top={12}
/>
<Fragment>
<Row alignItems="center">
<Item>
<H3>Account Details</H3>
</Item>
<Item>
<ActionLink internal to="/change-password">
Change password
</ActionLink>
</Item>
</Row>
<Row alignItems="baseline" mt={2}>
<Item vertical>
<Label>First Name</Label>
<Text secondary>{firstName}</Text>
</Item>
<Item vertical>
<Label>Last Name</Label>
<Text secondary>{lastName}</Text>
</Item>
</Row>
<Row alignItems="baseline" mt={2}>
<Item vertical>
<Label>Title</Label>
<Text secondary>{title.find(t => t.value === userTitle).label}</Text>
</Item>
<Item vertical>
<Label>Country</Label>
<Text secondary>{countries.getName(country)}</Text>
</Item>
</Row>
<Row alignItems="baseline" mt={2}>
<Item vertical>
<Label>Affiliation</Label>
<Text secondary>{affiliation}</Text>
</Item>
</Row>
</Fragment>
</ShadowedBox>
)
const EditModeIcons = ({ toggleEdit, onSaveChanges }) => (
<Fragment>
<IconButton
icon="x-circle"
iconSize={2}
onClick={toggleEdit}
right={36}
top={12}
/>
<IconButton
icon="check-circle"
iconSize={2}
onClick={onSaveChanges}
right={8}
top={12}
/>
</Fragment>
)
const EditUserProfile = compose(
withProps(
({
user: { affiliation, firstName, lastName, title: userTitle, country },
}) => ({
initialValues: {
country,
lastName,
firstName,
affiliation,
title: userTitle,
},
}),
),
reduxForm({
form: 'profile',
onSubmit: (values, dispatch, { onSave, ...props }) => {
typeof onSave === 'function' && onSave(values, props)
},
}),
)(({ toggleEdit, title, handleSubmit, loading, errorMessage, ...rest }) => (
<ShadowedBox position="relative" {...rest}>
{loading ? (
<StyledSpinner>
<Spinner />
</StyledSpinner>
) : (
<EditModeIcons onSaveChanges={handleSubmit} toggleEdit={toggleEdit} />
)}
<Fragment>
<Row>
<Item>
<H3>Edit Account Details</H3>
</Item>
</Row>
<Row alignItems="baseline" mt={2}>
<Item mr={1} vertical>
<Label required>First Name</Label>
<ValidatedField
component={TextField}
name="firstName"
validate={[requiredValidator]}
/>
</Item>
<Item ml={1} vertical>
<Label required>Last Name</Label>
<ValidatedField
component={TextField}
name="lastName"
validate={[requiredValidator]}
/>
</Item>
</Row>
<RowOverrideAlert alignItems="baseline" mt={2}>
<Item mr={1} vertical>
<Label required>Title</Label>
<ValidatedField
component={input => <Menu {...input} options={title} />}
name="title"
validate={[requiredValidator]}
/>
</Item>
<Item ml={1} vertical>
<Label required>Country</Label>
<ValidatedField
component={input => <Menu {...input} options={countryList} />}
name="country"
validate={[requiredValidator]}
/>
</Item>
</RowOverrideAlert>
<Row alignItems="baseline" mt={2}>
<Item vertical>
<Label required>Affiliation</Label>
<ValidatedField
component={TextField}
name="affiliation"
validate={[requiredValidator]}
/>
</Item>
</Row>
{errorMessage && (
<Row alignItems="center" mt={2}>
<Text error>{errorMessage}</Text>
</Row>
)}
</Fragment>
</ShadowedBox>
))
const UserProfile = ({
user,
onSave,
loading,
editMode,
setError,
toggleEdit,
setLoading,
errorMessage,
journal: { title = [] },
...rest
}) =>
!editMode ? (
<Profile title={title} toggleEdit={toggleEdit} user={user} {...rest} />
) : (
<EditUserProfile
errorMessage={errorMessage}
loading={loading}
onSave={onSave}
setError={setError}
setLoading={setLoading}
title={title}
toggleEdit={toggleEdit}
user={user}
{...rest}
/>
)
export default compose(
withStateHandlers(
{
loading: false,
editMode: false,
errorMessage: '',
},
{
toggleEdit: ({ editMode }) => () => ({
editMode: !editMode,
errorMessage: '',
loading: false,
}),
setError: ({ errorMessage }) => msg => ({
errorMessage: msg,
loading: false,
}),
setLoading: ({ loading }) => value => ({
loading: value,
}),
},
),
)(UserProfile)
// #region styles
const StyledSpinner = styled.div`
position: absolute;
top: ${th('gridUnit')};
right: ${th('gridUnit')};
`
// #endregion