Design edit user page

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-05-19 16:07:03 +02:00 committed by Alexandre Bodin
parent 0f43a5dd02
commit ccadbc9c21
6 changed files with 170 additions and 24 deletions

View File

@ -1,13 +1,13 @@
import React from 'react';
import { Padded } from '@buffetjs/core';
import { Padded, Text } from '@buffetjs/core';
import { LoadingIndicator, Row } from 'strapi-helper-plugin';
import PropTypes from 'prop-types';
import BaselineAlignement from '../BaselineAlignement';
import Bloc from '../Bloc';
const FormBloc = ({ children, isLoading }) => (
const FormBloc = ({ children, isLoading, title }) => (
<Bloc>
<BaselineAlignement top size="22px" />
<BaselineAlignement top size={title ? '18px' : '22px'} />
<Padded left right size="sm">
{isLoading ? (
<>
@ -15,7 +15,21 @@ const FormBloc = ({ children, isLoading }) => (
<BaselineAlignement bottom size="22px" />
</>
) : (
<Row>{children}</Row>
<>
{title && (
<>
<Padded left right size="xs">
<Padded left right size="sm">
<Text fontSize="lg" fontWeight="bold">
{title}
</Text>
</Padded>
</Padded>
<BaselineAlignement top size="18px" />
</>
)}
<Row>{children}</Row>
</>
)}
</Padded>
</Bloc>
@ -23,11 +37,13 @@ const FormBloc = ({ children, isLoading }) => (
FormBloc.defaultProps = {
isLoading: false,
title: null,
};
FormBloc.propTypes = {
children: PropTypes.node.isRequired,
isLoading: PropTypes.bool,
title: PropTypes.string,
};
export default FormBloc;

View File

@ -13,7 +13,7 @@ import MultiValueContainer from './MultiValueContainer';
const SelectRoles = ({ error, isDisabled, name, onChange, value }) => {
const [options, setOptions] = useState([]);
const { formatMessage } = useGlobalContext();
const translatedError = error ? formatMessage(error) : null;
const translatedError = error && error.id ? formatMessage(error) : null;
useEffect(() => {
// TODO

View File

@ -1,22 +1,33 @@
import React, { useReducer } from 'react';
import React, { useEffect, useReducer } from 'react';
import { useRouteMatch } from 'react-router-dom';
import { useIntl } from 'react-intl';
import { get } from 'lodash';
import {
// BackHeader,
// LoadingIndicator,
// Row,
// auth,
// request,
useGlobalContext,
} from 'strapi-helper-plugin';
import { Col } from 'reactstrap';
import { Padded } from '@buffetjs/core';
import BaselineAlignement from '../../../components/BaselineAlignement';
import ContainerFluid from '../../../components/ContainerFluid';
import FormBloc from '../../../components/FormBloc';
import SizedInput from '../../../components/SizedInput';
import Header from '../../../components/Users/Header';
import SelectRoles from '../../../components/Users/SelectRoles';
import form from './utils/form';
import fakeData from './utils/tempData';
import { initialState, reducer } from './reducer';
import init from './init';
const EditPage = () => {
const { settingsBaseURL } = useGlobalContext();
const [{ isLoading }, dispatch] = useReducer(reducer, initialState, init);
const [{ formErrors, isLoading, modifiedData }, dispatch] = useReducer(
reducer,
initialState,
init
);
const { formatMessage } = useIntl();
const {
params: { id },
@ -25,12 +36,40 @@ const EditPage = () => {
? 'app.containers.Users.EditPage.header.label-loading'
: 'app.containers.Users.EditPage.header.label';
const headerLabel = formatMessage({ id: headerLabelId }, { name: 'soup' });
console.log({ dispatch, id });
useEffect(() => {
const getData = () => {
return new Promise(resolve => {
setTimeout(() => {
dispatch({
type: 'GET_DATA_SUCCEEDED',
data: fakeData,
});
resolve();
}, 1000);
});
};
getData();
}, []);
console.log({ id });
const handleChange = ({ target: { name, value, type: inputType } }) => {
dispatch({
type: 'ON_CHANGE',
inputType,
keys: name,
value,
});
};
const handleSubmit = e => {
e.preventDefault();
};
console.log({ modifiedData });
return (
<>
<form onSubmit={handleSubmit}>
@ -42,6 +81,45 @@ const EditPage = () => {
modifiedData={{}}
onCancel={() => {}}
/>
<BaselineAlignement top size="3px" />
<FormBloc
isLoading={isLoading}
title={formatMessage({
id: 'app.components.Users.ModalCreateBody.block-title.details',
})}
>
{Object.keys(form).map(key => {
return (
<SizedInput
{...form[key]}
key={key}
error={formErrors[key]}
name={key}
onChange={handleChange}
value={get(modifiedData, key, '')}
/>
);
})}
</FormBloc>
<BaselineAlignement top size="32px" />
{!isLoading && (
<FormBloc
title={formatMessage({ id: 'app.containers.Users.EditPage.roles-bloc-title' })}
>
<Col xs="6">
<Padded top size="sm">
<SelectRoles
name="roles"
onChange={handleChange}
error={formErrors.roles}
value={get(modifiedData, 'roles', [])}
/>
{/* TODO fix padding for error */}
<BaselineAlignement top size="17px" />
</Padded>
</Col>
</FormBloc>
)}
</ContainerFluid>
</form>
</>

View File

@ -1,6 +1,6 @@
/* eslint-disable consistent-return */
import produce from 'immer';
// import { pick, set, unset } from 'lodash';
import { set, unset } from 'lodash';
const initialState = {
formErrors: {},
@ -16,24 +16,24 @@ const reducer = (state, action) =>
case 'GET_DATA_SUCCEEDED': {
draftState.isLoading = false;
draftState.showHeaderLoader = false;
// draftState.initialData = pick(action.data, ['email', 'firstname', 'lastname', 'username']);
// draftState.modifiedData = pick(action.data, ['email', 'firstname', 'lastname', 'username']);
draftState.initialData = action.data;
draftState.modifiedData = action.data;
break;
}
case 'ON_CANCEL': {
draftState.modifiedData = state.initialData;
break;
}
// case 'ON_CHANGE': {
// if (action.inputType === 'password' && !action.value) {
// unset(draftState.modifiedData, action.keys.split('.'));
// } else if (action.keys.includes('username')) {
// set(draftState.modifiedData, action.keys.split('.'), null);
// } else {
// set(draftState.modifiedData, action.keys.split('.'), action.value);
// }
// break;
// }
case 'ON_CHANGE': {
if (action.inputType === 'password' && !action.value) {
unset(draftState.modifiedData, action.keys.split('.'));
} else if (action.keys.includes('username')) {
set(draftState.modifiedData, action.keys.split('.'), null);
} else {
set(draftState.modifiedData, action.keys.split('.'), action.value);
}
break;
}
// case 'ON_SUBMIT': {
// draftState.showHeaderLoader = true;
// break;

View File

@ -0,0 +1,50 @@
const form = {
firstname: {
autoFocus: true,
label: 'Settings.permissions.users.form.firstname',
placeholder: 'e.g. John',
type: 'text',
validations: {
required: true,
},
},
lastname: {
label: 'Settings.permissions.users.form.lastname',
placeholder: 'e.g. Doe',
type: 'text',
validations: {
required: true,
},
},
email: {
label: 'Settings.permissions.users.form.email',
placeholder: 'e.g. john.doe@strapi.io',
type: 'email',
validations: {
required: true,
},
},
username: {
label: 'Auth.form.username.label',
placeholder: 'e.g. John_Doe',
type: 'text',
validations: {},
},
password: {
label: 'Auth.form.password.label',
type: 'password',
validations: {},
},
confirmPassword: {
label: 'Auth.form.confirmPassword.label',
type: 'password',
validations: {},
},
active: {
label: 'app.containers.Users.EditPage.form.active.label',
type: 'bool',
validations: {},
},
};
export default form;

View File

@ -324,5 +324,7 @@
"app.components.Users.SortPicker.sortby.username_asc": "Username (A to Z)",
"app.components.Users.SortPicker.sortby.username_desc": "Username (Z to A)",
"app.containers.Users.EditPage.header.label-loading": "Edit user",
"app.containers.Users.EditPage.header.label": "Edit {name}"
"app.containers.Users.EditPage.header.label": "Edit {name}",
"app.containers.Users.EditPage.roles-bloc-title": "Attributed roles",
"app.containers.Users.EditPage.form.active.label": "Active"
}