Connect create user to the API

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-05-19 06:55:06 +02:00 committed by Alexandre Bodin
parent 256540c3ec
commit 899ecc9fe3
4 changed files with 126 additions and 105 deletions

View File

@ -6,16 +6,19 @@ import { Duplicate } from '@buffetjs/icons';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import basename from '../../../utils/basename';
import IconWrapper from './IconWrapper';
import Envelope from './Envelope';
import Wrapper from './Wrapper';
const MagicLink = ({ link }) => {
const MagicLink = ({ registrationToken }) => {
const { formatMessage } = useIntl();
const handleCopy = () => {
strapi.notification.info('notification.link-copied');
};
const link = `${window.location.origin}${basename}auth/register?code=${registrationToken}`;
return (
<Wrapper>
<IconWrapper>
@ -37,11 +40,11 @@ const MagicLink = ({ link }) => {
};
MagicLink.defaultProps = {
link: 'http://my-app.com/admin/registration?code=1234567827654576856789',
registrationToken: '',
};
MagicLink.propTypes = {
link: PropTypes.string,
registrationToken: PropTypes.string,
};
export default MagicLink;

View File

@ -1,7 +1,8 @@
import React, { forwardRef, useReducer, useImperativeHandle, useRef } from 'react';
import PropTypes from 'prop-types';
import { ModalSection } from 'strapi-helper-plugin';
import { ModalSection, request } from 'strapi-helper-plugin';
import { FormattedMessage } from 'react-intl';
import { get } from 'lodash';
import { Padded, Text } from '@buffetjs/core';
import { Col, Row } from 'reactstrap';
import checkFormValidity from '../../../utils/users/checkFormValidity';
@ -14,121 +15,135 @@ import Wrapper from './Wrapper';
import MagicLink from '../MagicLink';
// This component accepts a ref so we can have access to the submit handler.
const ModalCreateBody = forwardRef(({ isDisabled, onSubmit, showMagicLink }, ref) => {
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
const { formErrors, modifiedData } = reducerState;
const buttonSubmitRef = useRef(null);
const ModalCreateBody = forwardRef(
({ isDisabled, onSubmit, registrationToken, showMagicLink }, ref) => {
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
const { formErrors, modifiedData } = reducerState;
const buttonSubmitRef = useRef(null);
useImperativeHandle(ref, () => ({
submit: () => {
buttonSubmitRef.current.click();
},
}));
useImperativeHandle(ref, () => ({
submit: () => {
buttonSubmitRef.current.click();
},
}));
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name,
value,
});
};
const handleChange = ({ target: { name, value } }) => {
dispatch({
type: 'ON_CHANGE',
keys: name,
value,
});
};
const handleSubmit = async e => {
e.persist();
e.preventDefault();
const errors = await checkFormValidity(modifiedData);
const handleSubmit = async e => {
e.persist();
e.preventDefault();
const errors = await checkFormValidity(modifiedData);
if (!errors) {
onSubmit(e, modifiedData);
if (!errors) {
try {
const requestURL = '/admin/users';
// TODO post request with errors handling
}
const { data } = await request(requestURL, { method: 'POST', body: modifiedData });
dispatch({
type: 'SET_ERRORS',
errors: errors || {},
});
};
onSubmit(e, data);
} catch (err) {
const message = get(err, ['response', 'payload', 'message'], 'An error occured');
return (
<form onSubmit={handleSubmit}>
{/* TODO magic link with token when api ready */}
{showMagicLink && (
strapi.notification.error(message);
}
// TODO post request with errors handling
}
dispatch({
type: 'SET_ERRORS',
errors: errors || {},
});
};
return (
<form onSubmit={handleSubmit}>
{/* TODO magic link with token when api ready */}
{showMagicLink && (
<ModalSection>
<MagicLink registrationToken={registrationToken} />
</ModalSection>
)}
<ModalSection>
<MagicLink />
<Padded top size="18px">
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.details">
{txt => txt}
</FormattedMessage>
</Text>
</Padded>
</ModalSection>
)}
<ModalSection>
<Padded top size="18px">
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.details">
{txt => txt}
</FormattedMessage>
</Text>
</Padded>
</ModalSection>
<ModalSection>
<Wrapper>
<Padded top size="20px">
<Row>
{Object.keys(form).map((inputName, i) => (
<Input
key={inputName}
{...form[inputName]}
autoFocus={i === 0}
disabled={isDisabled}
error={formErrors[inputName]}
name={inputName}
onChange={handleChange}
value={modifiedData[inputName]}
/>
))}
</Row>
<ModalSection>
<Wrapper>
<Padded top size="20px">
<Row>
{Object.keys(form).map((inputName, i) => (
<Input
key={inputName}
{...form[inputName]}
autoFocus={i === 0}
disabled={isDisabled}
error={formErrors[inputName]}
name={inputName}
onChange={handleChange}
value={modifiedData[inputName]}
/>
))}
</Row>
</Padded>
</Wrapper>
</ModalSection>
<ModalSection>
<Padded top size="3px">
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.roles">
{txt => txt}
</FormattedMessage>
</Text>
</Padded>
</Wrapper>
</ModalSection>
<ModalSection>
<Padded top size="3px">
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.roles">
{txt => txt}
</FormattedMessage>
</Text>
</Padded>
</ModalSection>
<ModalSection>
<Wrapper>
<Padded top size="12px">
<Row>
<Col xs="6">
<SelectRoles
isDisabled={isDisabled}
name="roles"
onChange={handleChange}
value={modifiedData.roles}
error={formErrors.roles}
/>
</Col>
</Row>
</Padded>
</Wrapper>
</ModalSection>
<button type="submit" style={{ display: 'none' }} ref={buttonSubmitRef}>
hidden button to use the native form event
</button>
</form>
);
});
</ModalSection>
<ModalSection>
<Wrapper>
<Padded top size="12px">
<Row>
<Col xs="6">
<SelectRoles
isDisabled={isDisabled}
name="roles"
onChange={handleChange}
value={modifiedData.roles}
error={formErrors.roles}
/>
</Col>
</Row>
</Padded>
</Wrapper>
</ModalSection>
<button type="submit" style={{ display: 'none' }} ref={buttonSubmitRef}>
hidden button to use the native form event
</button>
</form>
);
}
);
ModalCreateBody.defaultProps = {
isDisabled: false,
onSubmit: e => e.preventDefault(),
registrationToken: '',
showMagicLink: false,
};
ModalCreateBody.propTypes = {
isDisabled: PropTypes.bool,
onSubmit: PropTypes.func,
registrationToken: PropTypes.string,
showMagicLink: PropTypes.bool,
};

View File

@ -9,6 +9,7 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
// Little trick to focus the first input
// Without this the focus is lost
const [showBody, setShowBody] = useState(false);
const [registrationToken, setRegistrationToken] = useState(null);
const { formatMessage } = useGlobalContext();
const ref = useRef(null);
const { buttonSubmitLabel, Component, isDisabled, next } = stepper[currentStep];
@ -35,7 +36,10 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
setShowBody(false);
};
const handleSubmit = () => {
const handleSubmit = (e, data) => {
const { registrationToken } = data;
setRegistrationToken(registrationToken);
goNext();
};
@ -57,6 +61,7 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
isDisabled={isDisabled}
onSubmit={handleSubmit}
ref={currentStep === 'create' ? ref : null}
registrationToken={registrationToken}
showMagicLink={currentStep === 'magic-link'}
/>
)}

View File

@ -5,17 +5,15 @@ const stepper = {
buttonSubmitLabel: 'app.containers.Users.ModalForm.footer.button-success',
Component: ModalCreateBody,
isDisabled: false,
// next: 'magic-link',
// TODO: set it back to magic-link
next: null,
next: 'magic-link',
},
'magic-link': {
buttonSubmitLabel: 'form.button.continue',
Component: ModalCreateBody,
isDisabled: true,
next: 'summary',
next: null,
},
// TODO: I am not sure this step is needed we might need to delete it
summary: {
buttonSubmitLabel: 'form.button.done',
Component: () => 'COMING SOON',