From 3ead16d79e66b61fd33066dca8b417fcf5483f80 Mon Sep 17 00:00:00 2001
From: Bogdan Cochior <bogdan.cochior@thinslices.com>
Date: Wed, 14 Feb 2018 10:21:37 +0200
Subject: [PATCH] feat(component): add form for create/edit user (without API
 calls)

---
 .../src/components/Admin/AddEditUser.js       | 79 +++++++++++++++++++
 .../src/components/Admin/AddUserForm.js       | 52 ++++++++++++
 .../src/components/Admin/EditUserForm.js      | 78 ++++++++++++++++++
 .../xpub-faraday/app/config/journal/roles.js  |  2 +
 packages/xpub-faraday/app/routes.js           |  7 ++
 5 files changed, 218 insertions(+)
 create mode 100644 packages/components-faraday/src/components/Admin/AddEditUser.js
 create mode 100644 packages/components-faraday/src/components/Admin/AddUserForm.js
 create mode 100644 packages/components-faraday/src/components/Admin/EditUserForm.js

diff --git a/packages/components-faraday/src/components/Admin/AddEditUser.js b/packages/components-faraday/src/components/Admin/AddEditUser.js
new file mode 100644
index 000000000..f273f5d76
--- /dev/null
+++ b/packages/components-faraday/src/components/Admin/AddEditUser.js
@@ -0,0 +1,79 @@
+import React from 'react'
+import { get, map } from 'lodash'
+import { connect } from 'react-redux'
+import { reduxForm } from 'redux-form'
+import styled from 'styled-components'
+import { actions } from 'pubsweet-client'
+import { withJournal } from 'xpub-journal'
+import { ConnectPage } from 'xpub-connect'
+import { selectUser } from 'xpub-selectors'
+import { Button } from '@pubsweet/ui'
+import { compose, withProps, withHandlers, withState } from 'recompose'
+
+import AddUserForm from './AddUserForm'
+import EditUserForm from './EditUserForm'
+
+const getRoleOptions = journal =>
+  map(journal.roles, (value, key) => ({ label: value, value: key }))
+
+const AddEditUser = ({ handleSubmit, journal, isEdit, user }) => (
+  <Root>
+    <FormContainer onSubmit={handleSubmit}>
+      {isEdit ? (
+        <EditUserForm roles={getRoleOptions(journal)} user={user} />
+      ) : (
+        <AddUserForm roles={getRoleOptions(journal)} />
+      )}
+      <Row>
+        <Button primary type="submit">
+          Save user
+        </Button>
+      </Row>
+    </FormContainer>
+  </Root>
+)
+
+export default compose(
+  withJournal,
+  withState('isEdit', 'setEdit', false),
+  withHandlers({
+    setEditMode: ({ setEdit }) => value => setEdit(value),
+  }),
+  ConnectPage(({ match, setEditMode }) => {
+    const id = get(match, 'params.userId')
+    const isEditingMode = match.path.includes('/edit/:userId')
+    if (isEditingMode && id) {
+      setEditMode(isEditingMode)
+      return [actions.getUser({ id })]
+    }
+    return []
+  }),
+  connect((state, { match }) => ({
+    user: selectUser(state, get(match, 'params.userId')),
+  })),
+  withProps(({ user }) => ({ initialValues: user })),
+  reduxForm({
+    form: 'userManagement',
+    onSubmit: values => values,
+  }),
+)(AddEditUser)
+
+const Root = styled.div`
+  display: flex;
+  flex-direction: column;
+  margin: auto;
+  max-width: 60em;
+`
+
+const FormContainer = styled.form`
+  border: 1px solid var(--color-pending);
+  margin: 0 auto;
+  min-width: 300px;
+  padding: 20px;
+`
+
+const Row = styled.div`
+  display: flex;
+  flex-direction: row;
+  margin: 10px 0;
+`
diff --git a/packages/components-faraday/src/components/Admin/AddUserForm.js b/packages/components-faraday/src/components/Admin/AddUserForm.js
new file mode 100644
index 000000000..fc043cc51
--- /dev/null
+++ b/packages/components-faraday/src/components/Admin/AddUserForm.js
@@ -0,0 +1,52 @@
+import React from 'react'
+import styled from 'styled-components'
+import { ValidatedField, TextField, Menu } from '@pubsweet/ui'
+
+import { required } from 'xpub-validators'
+
+const AddUserForm = ({ roles }) => {
+  const roleOptions = roles.filter(r => r.value === 'editorInChief')
+  return (
+    <div>
+      <h3>Add user</h3>
+      <Row>
+        <RowItem>
+          <Label> Email</Label>
+          <ValidatedField
+            component={TextField}
+            name="email"
+            validate={[required]}
+          />
+        </RowItem>
+      </Row>
+      <Row>
+        <RowItem>
+          <Label> Role</Label>
+          <ValidatedField
+            component={input => <Menu {...input} options={roleOptions} />}
+            name="role"
+            validate={[required]}
+          />
+        </RowItem>
+      </Row>
+    </div>
+  )
+}
+
+export default AddUserForm
+
+const Row = styled.div`
+  display: flex;
+  flex-direction: row;
+  margin: 20px 0;
+`
+
+const RowItem = styled.div`
+  flex: 1;
+  margin-right: 20px;
+`
+
+const Label = styled.div`
+  font-size: 14px;
+  text-transform: uppercase;
+`
diff --git a/packages/components-faraday/src/components/Admin/EditUserForm.js b/packages/components-faraday/src/components/Admin/EditUserForm.js
new file mode 100644
index 000000000..9020fbf3d
--- /dev/null
+++ b/packages/components-faraday/src/components/Admin/EditUserForm.js
@@ -0,0 +1,78 @@
+import React from 'react'
+import styled from 'styled-components'
+import { ValidatedField, TextField, Menu } from '@pubsweet/ui'
+
+import { required } from 'xpub-validators'
+
+const EditUserForm = ({ roles, user }) => {
+  const roleOptions = roles.filter(r =>
+    ['editorInChief', 'author'].includes(r.value),
+  )
+  return (
+    <div>
+      <h3>Edit user</h3>
+      <h5>{user.email}</h5>
+      <Row>
+        <RowItem>
+          <Label> First name </Label>
+          <ValidatedField
+            component={TextField}
+            name="firstName"
+            validate={[required]}
+          />
+        </RowItem>
+        <RowItem>
+          <Label> Middle name </Label>
+          <ValidatedField component={TextField} name="middleName" />
+        </RowItem>
+        <RowItem>
+          <Label> Last name </Label>
+          <ValidatedField
+            component={TextField}
+            name="lastName"
+            validate={[required]}
+          />
+        </RowItem>
+      </Row>
+      <Row>
+        <RowItem>
+          <Label> Affiliation </Label>
+          <ValidatedField
+            component={TextField}
+            name="affiliation"
+            validate={[required]}
+          />
+        </RowItem>
+        <RowItem>
+          <Label> Title </Label>
+          <ValidatedField component={TextField} name="title" />
+        </RowItem>
+        <RowItem>
+          <Label> Role</Label>
+          <ValidatedField
+            component={input => <Menu {...input} options={roleOptions} />}
+            name="role"
+          />
+        </RowItem>
+      </Row>
+    </div>
+  )
+}
+
+export default EditUserForm
+
+const Row = styled.div`
+  display: flex;
+  flex-direction: row;
+  margin: 20px 0;
+`
+
+const RowItem = styled.div`
+  flex: 1;
+  margin-right: 20px;
+`
+
+const Label = styled.div`
+  font-size: 14px;
+  text-transform: uppercase;
+`
diff --git a/packages/xpub-faraday/app/config/journal/roles.js b/packages/xpub-faraday/app/config/journal/roles.js
index 0f9334d4c..ffed8cef6 100644
--- a/packages/xpub-faraday/app/config/journal/roles.js
+++ b/packages/xpub-faraday/app/config/journal/roles.js
@@ -1,6 +1,8 @@
 export default {
   author: 'Author',
+  admin: 'Admin',
   handlingEditor: 'Handling Editor',
   managingEditor: 'Managing Editor',
   seniorEditor: 'Senior Editor',
+  editorInChief: 'Editor in Chief',
 }
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index b2bba7ac7..c9b780104 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -17,6 +17,7 @@ import ManuscriptPage from 'pubsweet-component-xpub-manuscript/src/components/Ma
 import ConfirmationPage from 'pubsweet-components-faraday/src/components/UIComponents/ConfirmationPage'
 import NotFound from 'pubsweet-components-faraday/src/components/UIComponents/NotFound'
 import AdminPage from 'pubsweet-components-faraday/src/components/Admin'
+import AddEditUser from 'pubsweet-components-faraday/src/components/Admin/AddEditUser'
 
 const Routes = () => (
   <App>
@@ -30,6 +31,12 @@ const Routes = () => (
         path="/confirmation-page"
       />
       <PrivateRoute component={AdminPage} exact path="/admin" />
+      <PrivateRoute component={AddEditUser} exact path="/admin/users/add" />
+      <PrivateRoute
+        component={AddEditUser}
+        exact
+        path="/admin/users/edit/:userId"
+      />
       <PrivateRoute component={LogoutPage} exact path="/logout" />
       <PrivateRoute
         component={Wizard}
-- 
GitLab