mirror of
https://github.com/strapi/strapi.git
synced 2025-11-17 10:38:30 +00:00
Connect create user to the API
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
256540c3ec
commit
899ecc9fe3
@ -6,16 +6,19 @@ import { Duplicate } from '@buffetjs/icons';
|
|||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
|
import basename from '../../../utils/basename';
|
||||||
import IconWrapper from './IconWrapper';
|
import IconWrapper from './IconWrapper';
|
||||||
import Envelope from './Envelope';
|
import Envelope from './Envelope';
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
const MagicLink = ({ link }) => {
|
const MagicLink = ({ registrationToken }) => {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const handleCopy = () => {
|
const handleCopy = () => {
|
||||||
strapi.notification.info('notification.link-copied');
|
strapi.notification.info('notification.link-copied');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const link = `${window.location.origin}${basename}auth/register?code=${registrationToken}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<IconWrapper>
|
<IconWrapper>
|
||||||
@ -37,11 +40,11 @@ const MagicLink = ({ link }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
MagicLink.defaultProps = {
|
MagicLink.defaultProps = {
|
||||||
link: 'http://my-app.com/admin/registration?code=1234567827654576856789',
|
registrationToken: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
MagicLink.propTypes = {
|
MagicLink.propTypes = {
|
||||||
link: PropTypes.string,
|
registrationToken: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MagicLink;
|
export default MagicLink;
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import React, { forwardRef, useReducer, useImperativeHandle, useRef } from 'react';
|
import React, { forwardRef, useReducer, useImperativeHandle, useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ModalSection } from 'strapi-helper-plugin';
|
import { ModalSection, request } from 'strapi-helper-plugin';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
import { get } from 'lodash';
|
||||||
import { Padded, Text } from '@buffetjs/core';
|
import { Padded, Text } from '@buffetjs/core';
|
||||||
import { Col, Row } from 'reactstrap';
|
import { Col, Row } from 'reactstrap';
|
||||||
import checkFormValidity from '../../../utils/users/checkFormValidity';
|
import checkFormValidity from '../../../utils/users/checkFormValidity';
|
||||||
@ -14,121 +15,135 @@ import Wrapper from './Wrapper';
|
|||||||
import MagicLink from '../MagicLink';
|
import MagicLink from '../MagicLink';
|
||||||
|
|
||||||
// This component accepts a ref so we can have access to the submit handler.
|
// This component accepts a ref so we can have access to the submit handler.
|
||||||
const ModalCreateBody = forwardRef(({ isDisabled, onSubmit, showMagicLink }, ref) => {
|
const ModalCreateBody = forwardRef(
|
||||||
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
({ isDisabled, onSubmit, registrationToken, showMagicLink }, ref) => {
|
||||||
const { formErrors, modifiedData } = reducerState;
|
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
||||||
const buttonSubmitRef = useRef(null);
|
const { formErrors, modifiedData } = reducerState;
|
||||||
|
const buttonSubmitRef = useRef(null);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
submit: () => {
|
submit: () => {
|
||||||
buttonSubmitRef.current.click();
|
buttonSubmitRef.current.click();
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const handleChange = ({ target: { name, value } }) => {
|
const handleChange = ({ target: { name, value } }) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ON_CHANGE',
|
type: 'ON_CHANGE',
|
||||||
keys: name,
|
keys: name,
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async e => {
|
const handleSubmit = async e => {
|
||||||
e.persist();
|
e.persist();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const errors = await checkFormValidity(modifiedData);
|
const errors = await checkFormValidity(modifiedData);
|
||||||
|
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
onSubmit(e, modifiedData);
|
try {
|
||||||
|
const requestURL = '/admin/users';
|
||||||
|
|
||||||
// TODO post request with errors handling
|
const { data } = await request(requestURL, { method: 'POST', body: modifiedData });
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({
|
onSubmit(e, data);
|
||||||
type: 'SET_ERRORS',
|
} catch (err) {
|
||||||
errors: errors || {},
|
const message = get(err, ['response', 'payload', 'message'], 'An error occured');
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
strapi.notification.error(message);
|
||||||
<form onSubmit={handleSubmit}>
|
}
|
||||||
{/* TODO magic link with token when api ready */}
|
|
||||||
{showMagicLink && (
|
// 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>
|
<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>
|
||||||
)}
|
<ModalSection>
|
||||||
<ModalSection>
|
<Wrapper>
|
||||||
<Padded top size="18px">
|
<Padded top size="20px">
|
||||||
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
|
<Row>
|
||||||
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.details">
|
{Object.keys(form).map((inputName, i) => (
|
||||||
{txt => txt}
|
<Input
|
||||||
</FormattedMessage>
|
key={inputName}
|
||||||
</Text>
|
{...form[inputName]}
|
||||||
</Padded>
|
autoFocus={i === 0}
|
||||||
</ModalSection>
|
disabled={isDisabled}
|
||||||
<ModalSection>
|
error={formErrors[inputName]}
|
||||||
<Wrapper>
|
name={inputName}
|
||||||
<Padded top size="20px">
|
onChange={handleChange}
|
||||||
<Row>
|
value={modifiedData[inputName]}
|
||||||
{Object.keys(form).map((inputName, i) => (
|
/>
|
||||||
<Input
|
))}
|
||||||
key={inputName}
|
</Row>
|
||||||
{...form[inputName]}
|
</Padded>
|
||||||
autoFocus={i === 0}
|
</Wrapper>
|
||||||
disabled={isDisabled}
|
</ModalSection>
|
||||||
error={formErrors[inputName]}
|
<ModalSection>
|
||||||
name={inputName}
|
<Padded top size="3px">
|
||||||
onChange={handleChange}
|
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
|
||||||
value={modifiedData[inputName]}
|
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.roles">
|
||||||
/>
|
{txt => txt}
|
||||||
))}
|
</FormattedMessage>
|
||||||
</Row>
|
</Text>
|
||||||
</Padded>
|
</Padded>
|
||||||
</Wrapper>
|
</ModalSection>
|
||||||
</ModalSection>
|
<ModalSection>
|
||||||
<ModalSection>
|
<Wrapper>
|
||||||
<Padded top size="3px">
|
<Padded top size="12px">
|
||||||
<Text fontSize="xs" color="grey" fontWeight="bold" textTransform="uppercase">
|
<Row>
|
||||||
<FormattedMessage id="app.components.Users.ModalCreateBody.block-title.roles">
|
<Col xs="6">
|
||||||
{txt => txt}
|
<SelectRoles
|
||||||
</FormattedMessage>
|
isDisabled={isDisabled}
|
||||||
</Text>
|
name="roles"
|
||||||
</Padded>
|
onChange={handleChange}
|
||||||
</ModalSection>
|
value={modifiedData.roles}
|
||||||
<ModalSection>
|
error={formErrors.roles}
|
||||||
<Wrapper>
|
/>
|
||||||
<Padded top size="12px">
|
</Col>
|
||||||
<Row>
|
</Row>
|
||||||
<Col xs="6">
|
</Padded>
|
||||||
<SelectRoles
|
</Wrapper>
|
||||||
isDisabled={isDisabled}
|
</ModalSection>
|
||||||
name="roles"
|
<button type="submit" style={{ display: 'none' }} ref={buttonSubmitRef}>
|
||||||
onChange={handleChange}
|
hidden button to use the native form event
|
||||||
value={modifiedData.roles}
|
</button>
|
||||||
error={formErrors.roles}
|
</form>
|
||||||
/>
|
);
|
||||||
</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 = {
|
ModalCreateBody.defaultProps = {
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
onSubmit: e => e.preventDefault(),
|
onSubmit: e => e.preventDefault(),
|
||||||
|
registrationToken: '',
|
||||||
showMagicLink: false,
|
showMagicLink: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
ModalCreateBody.propTypes = {
|
ModalCreateBody.propTypes = {
|
||||||
isDisabled: PropTypes.bool,
|
isDisabled: PropTypes.bool,
|
||||||
onSubmit: PropTypes.func,
|
onSubmit: PropTypes.func,
|
||||||
|
registrationToken: PropTypes.string,
|
||||||
showMagicLink: PropTypes.bool,
|
showMagicLink: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
|
|||||||
// Little trick to focus the first input
|
// Little trick to focus the first input
|
||||||
// Without this the focus is lost
|
// Without this the focus is lost
|
||||||
const [showBody, setShowBody] = useState(false);
|
const [showBody, setShowBody] = useState(false);
|
||||||
|
const [registrationToken, setRegistrationToken] = useState(null);
|
||||||
const { formatMessage } = useGlobalContext();
|
const { formatMessage } = useGlobalContext();
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
const { buttonSubmitLabel, Component, isDisabled, next } = stepper[currentStep];
|
const { buttonSubmitLabel, Component, isDisabled, next } = stepper[currentStep];
|
||||||
@ -35,7 +36,10 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
|
|||||||
setShowBody(false);
|
setShowBody(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = (e, data) => {
|
||||||
|
const { registrationToken } = data;
|
||||||
|
|
||||||
|
setRegistrationToken(registrationToken);
|
||||||
goNext();
|
goNext();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,6 +61,7 @@ const ModalForm = ({ isOpen, onClosed, onToggle }) => {
|
|||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
ref={currentStep === 'create' ? ref : null}
|
ref={currentStep === 'create' ? ref : null}
|
||||||
|
registrationToken={registrationToken}
|
||||||
showMagicLink={currentStep === 'magic-link'}
|
showMagicLink={currentStep === 'magic-link'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -5,17 +5,15 @@ const stepper = {
|
|||||||
buttonSubmitLabel: 'app.containers.Users.ModalForm.footer.button-success',
|
buttonSubmitLabel: 'app.containers.Users.ModalForm.footer.button-success',
|
||||||
Component: ModalCreateBody,
|
Component: ModalCreateBody,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
// next: 'magic-link',
|
next: 'magic-link',
|
||||||
|
|
||||||
// TODO: set it back to magic-link
|
|
||||||
next: null,
|
|
||||||
},
|
},
|
||||||
'magic-link': {
|
'magic-link': {
|
||||||
buttonSubmitLabel: 'form.button.continue',
|
buttonSubmitLabel: 'form.button.continue',
|
||||||
Component: ModalCreateBody,
|
Component: ModalCreateBody,
|
||||||
isDisabled: true,
|
isDisabled: true,
|
||||||
next: 'summary',
|
next: null,
|
||||||
},
|
},
|
||||||
|
// TODO: I am not sure this step is needed we might need to delete it
|
||||||
summary: {
|
summary: {
|
||||||
buttonSubmitLabel: 'form.button.done',
|
buttonSubmitLabel: 'form.button.done',
|
||||||
Component: () => 'COMING SOON',
|
Component: () => 'COMING SOON',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user