Functionally complete full registration workflow
This commit is contained in:
@@ -3,7 +3,7 @@ import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Dropdown, Menu } from "semantic-ui-react";
|
||||
|
||||
import { sendGetSelfUserRequest } from "../actions/user/saga.actions";
|
||||
import { getSelfUserRequest } from "../actions/user/saga.actions";
|
||||
import { sendLogoutRequest } from "../actions/auth/saga.actions";
|
||||
|
||||
class Navbar extends Component {
|
||||
@@ -11,7 +11,7 @@ class Navbar extends Component {
|
||||
const { dispatch, userToken, selfUser } = this.props;
|
||||
// If the user token exists and the self user object isn't loaded, dispatch
|
||||
if (userToken && Object.keys(selfUser).length === 0) {
|
||||
dispatch(sendGetSelfUserRequest());
|
||||
dispatch(getSelfUserRequest());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import { connect } from "react-redux";
|
||||
import { Redirect, Route } from "react-router-dom";
|
||||
import { Loader } from "semantic-ui-react";
|
||||
|
||||
import { sendGetSelfUserRequest } from "../../actions/user/saga.actions";
|
||||
import { getSelfUserRequest } from "../../actions/user/saga.actions";
|
||||
|
||||
const propTypes = {
|
||||
userToken: PropTypes.string.isRequired,
|
||||
@@ -21,7 +21,7 @@ class PrivateRoute extends Component {
|
||||
const { dispatch, userToken, selfUser } = this.props;
|
||||
// If the user token exists and the self user object isn't loaded, dispatch
|
||||
if (userToken && Object.keys(selfUser).length === 0) {
|
||||
dispatch(sendGetSelfUserRequest());
|
||||
dispatch(getSelfUserRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class PrivateRoute extends Component {
|
||||
if (
|
||||
userToken &&
|
||||
Object.keys(selfUser).length &&
|
||||
(!selfUser.client || !selfUser.provider)
|
||||
(!selfUser.client && !selfUser.provider)
|
||||
) {
|
||||
return <Redirect to="/user/complete-registration" />;
|
||||
}
|
||||
|
41
src/components/User/ClientFormView.jsx
Normal file
41
src/components/User/ClientFormView.jsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
import { Container, Form, Header, Message } from "semantic-ui-react";
|
||||
|
||||
import Error from "../Shared/Error";
|
||||
|
||||
const ClientFormView = ({
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
businessNumber,
|
||||
changeBusinessNumber,
|
||||
onSubmitClient
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>Complete Client Information</Header>
|
||||
<Form
|
||||
loading={isSendingUserRequest}
|
||||
onSubmit={onSubmitClient}
|
||||
error={!!userRequestError}
|
||||
success={!!userRequestSuccess}
|
||||
>
|
||||
<Form.Field>
|
||||
<label>Business Number</label>
|
||||
<input
|
||||
placeholder="12345"
|
||||
type="text"
|
||||
value={businessNumber}
|
||||
onChange={changeBusinessNumber}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Error header="Modify Client failed!" error={userRequestError} />
|
||||
<Message success>
|
||||
<Message.Header>Modify Client successful!</Message.Header>
|
||||
<p>Set client successfully.</p>
|
||||
</Message>
|
||||
<Form.Button>Submit Client</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default ClientFormView;
|
64
src/components/User/ClientOrProviderForm.jsx
Normal file
64
src/components/User/ClientOrProviderForm.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Container, Form, Header } from "semantic-ui-react";
|
||||
|
||||
import {
|
||||
setCompleteRegistrationClientOrProvider,
|
||||
setCompleteRegistrationStep
|
||||
} from "../../actions/user/reducer.actions";
|
||||
import { CLIENT, PROVIDER, COMPLETE_INFORMATION_STEP } from "../../constants/user.constants";
|
||||
|
||||
class ClientOrProviderForm extends Component {
|
||||
changeClientOrProvider = (event, { value }) => {
|
||||
this.props.dispatch(setCompleteRegistrationClientOrProvider(value));
|
||||
}
|
||||
|
||||
onSelectClientOrProvider = event => {
|
||||
this.props.dispatch(setCompleteRegistrationStep(COMPLETE_INFORMATION_STEP));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { completeRegistrationClientOrProvider } = this.props;
|
||||
return (
|
||||
<ClientOrProviderFormView
|
||||
clientOrProvider={completeRegistrationClientOrProvider}
|
||||
changeClientOrProvider={this.changeClientOrProvider}
|
||||
onSelectClientOrProvider={this.onSelectClientOrProvider}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { ...state.user };
|
||||
}
|
||||
|
||||
const ClientOrProviderFormView = ({
|
||||
clientOrProvider,
|
||||
changeClientOrProvider,
|
||||
onSelectClientOrProvider
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>Client or Provider</Header>
|
||||
<Form onSubmit={onSelectClientOrProvider}>
|
||||
<Form.Group inline>
|
||||
<label>Client or Provider</label>
|
||||
<Form.Radio
|
||||
label="Client"
|
||||
value={CLIENT}
|
||||
checked={clientOrProvider === CLIENT}
|
||||
onChange={changeClientOrProvider}
|
||||
/>
|
||||
<Form.Radio
|
||||
label="Provider"
|
||||
value={PROVIDER}
|
||||
checked={clientOrProvider === PROVIDER}
|
||||
onChange={changeClientOrProvider}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Button>Continue</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps)(ClientOrProviderForm);
|
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { Grid, Modal, Step } from "semantic-ui-react";
|
||||
import { Dimmer, Grid, Loader, Modal, Step } from "semantic-ui-react";
|
||||
|
||||
import {
|
||||
setCompleteRegistrationStep
|
||||
@@ -9,8 +9,14 @@ import {
|
||||
import {
|
||||
USER_INFO_STEP,
|
||||
CLIENT_OR_PROVIDER_STEP,
|
||||
COMPLETE_INFORMATION_STEP
|
||||
COMPLETE_INFORMATION_STEP,
|
||||
CLIENT,
|
||||
PROVIDER
|
||||
} from "../../constants/user.constants";
|
||||
import ClientOrProviderForm from "./ClientOrProviderForm";
|
||||
import InitializeClientForm from "./InitializeClientForm";
|
||||
import InitializeProviderForm from "./InitializeProviderForm";
|
||||
import InitializeUserInfoForm from "./InitializeUserInfoForm";
|
||||
|
||||
class CompleteRegistration extends Component {
|
||||
onChangeStep = (event, data) => {
|
||||
@@ -21,11 +27,16 @@ class CompleteRegistration extends Component {
|
||||
render() {
|
||||
const {
|
||||
userToken,
|
||||
selfUser,
|
||||
completeRegistrationCurrentStep,
|
||||
completeRegistrationMaxStep,
|
||||
completeRegistrationClientOrProvider
|
||||
} = this.props;
|
||||
if (!userToken) return <Redirect to="/auth/login" />;
|
||||
if (Object.keys(selfUser).length === 0)
|
||||
return <Dimmer active><Loader /></Dimmer>;
|
||||
if (selfUser.client || selfUser.provider)
|
||||
return <Redirect to="/user/profile" />;
|
||||
return (
|
||||
<CompleteRegistrationView
|
||||
currentStep={completeRegistrationCurrentStep}
|
||||
@@ -90,9 +101,14 @@ const CompleteRegistrationView = ({
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
{currentStep === USER_INFO_STEP && <p>User Info</p>}
|
||||
{currentStep === CLIENT_OR_PROVIDER_STEP && <p>Client or Provider</p>}
|
||||
{currentStep === COMPLETE_INFORMATION_STEP && <p>Complete Info</p>}
|
||||
{currentStep === USER_INFO_STEP && <InitializeUserInfoForm />}
|
||||
{currentStep === CLIENT_OR_PROVIDER_STEP && <ClientOrProviderForm />}
|
||||
{currentStep === COMPLETE_INFORMATION_STEP &&
|
||||
completeRegistrationClientOrProvider === CLIENT &&
|
||||
<InitializeClientForm />}
|
||||
{currentStep === COMPLETE_INFORMATION_STEP &&
|
||||
completeRegistrationClientOrProvider === PROVIDER &&
|
||||
<InitializeProviderForm />}
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</Modal.Content>
|
||||
|
54
src/components/User/InitializeClientForm.jsx
Normal file
54
src/components/User/InitializeClientForm.jsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import {
|
||||
clearUserRequestError,
|
||||
clearUserRequestSuccess,
|
||||
setFormBusinessNumber
|
||||
} from "../../actions/user/reducer.actions";
|
||||
import { createClientRequest } from "../../actions/user/saga.actions";
|
||||
import ClientFormView from "./ClientFormView";
|
||||
|
||||
class InitializeClientForm extends Component {
|
||||
componentWillMount() {
|
||||
this.props.dispatch(clearUserRequestError());
|
||||
this.props.dispatch(clearUserRequestSuccess());
|
||||
}
|
||||
|
||||
changeBusinessNumber = event => {
|
||||
this.props.dispatch(setFormBusinessNumber(event.target.value));
|
||||
}
|
||||
|
||||
onSubmitClient = event => {
|
||||
event.preventDefault();
|
||||
const { businessNumber } = this.props;
|
||||
this.props.dispatch(
|
||||
createClientRequest({ business_number: businessNumber })
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
businessNumber
|
||||
} = this.props;
|
||||
return (
|
||||
<ClientFormView
|
||||
isSendingUserRequest={isSendingUserRequest}
|
||||
userRequestError={userRequestError}
|
||||
userRequestSuccess={userRequestSuccess}
|
||||
businessNumber={businessNumber}
|
||||
changeBusinessNumber={this.changeBusinessNumber}
|
||||
onSubmitClient={this.onSubmitClient}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { ...state.user };
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(InitializeClientForm);
|
54
src/components/User/InitializeProviderForm.jsx
Normal file
54
src/components/User/InitializeProviderForm.jsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import {
|
||||
clearUserRequestError,
|
||||
clearUserRequestSuccess,
|
||||
setFormSocialInsuranceNumber
|
||||
} from "../../actions/user/reducer.actions";
|
||||
import { createProviderRequest } from "../../actions/user/saga.actions";
|
||||
import ProviderFormView from "./ProviderFormView";
|
||||
|
||||
class InitializeProviderForm extends Component {
|
||||
componentWillMount() {
|
||||
this.props.dispatch(clearUserRequestError());
|
||||
this.props.dispatch(clearUserRequestSuccess());
|
||||
}
|
||||
|
||||
changeSocialInsuranceNumber = event => {
|
||||
this.props.dispatch(setFormSocialInsuranceNumber(event.target.value));
|
||||
}
|
||||
|
||||
onSubmitProvider = event => {
|
||||
event.preventDefault();
|
||||
const { socialInsuranceNumber } = this.props;
|
||||
this.props.dispatch(
|
||||
createProviderRequest({ sin: socialInsuranceNumber })
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
socialInsuranceNumber
|
||||
} = this.props;
|
||||
return (
|
||||
<ProviderFormView
|
||||
isSendingUserRequest={isSendingUserRequest}
|
||||
userRequestError={userRequestError}
|
||||
userRequestSuccess={userRequestSuccess}
|
||||
socialInsuranceNumber={socialInsuranceNumber}
|
||||
changeSocialInsuranceNumber={this.changeSocialInsuranceNumber}
|
||||
onSubmitProvider={this.onSubmitProvider}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { ...state.user };
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(InitializeProviderForm);
|
76
src/components/User/InitializeUserInfoForm.jsx
Normal file
76
src/components/User/InitializeUserInfoForm.jsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
|
||||
import {
|
||||
clearUserRequestError,
|
||||
clearUserRequestSuccess,
|
||||
setFormPhoneNumber
|
||||
} from "../../actions/user/reducer.actions";
|
||||
import {
|
||||
createUserInfoRequest,
|
||||
updateUserInfoRequest
|
||||
} from "../../actions/user/saga.actions";
|
||||
|
||||
import UserInfoFormView from "./UserInfoFormView";
|
||||
|
||||
class InitializeUserInfoForm extends Component {
|
||||
componentWillMount() {
|
||||
this.props.dispatch(clearUserRequestError());
|
||||
this.props.dispatch(clearUserRequestSuccess());
|
||||
}
|
||||
|
||||
changePhoneNumber = event => {
|
||||
this.props.dispatch(setFormPhoneNumber(event.target.value));
|
||||
};
|
||||
|
||||
onSubmitUserInfo = event => {
|
||||
event.preventDefault();
|
||||
const { selfUser, phoneNumber } = this.props;
|
||||
const phoneNumberVal =
|
||||
phoneNumber || (selfUser.userinfo || {}).phone_number;
|
||||
|
||||
if (selfUser.userinfo) {
|
||||
this.props.dispatch(
|
||||
updateUserInfoRequest({
|
||||
...selfUser.userinfo,
|
||||
username: selfUser.username,
|
||||
phone_number: phoneNumberVal
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.props.dispatch(
|
||||
createUserInfoRequest({
|
||||
phone_number: phoneNumberVal
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
selfUser,
|
||||
phoneNumber
|
||||
} = this.props;
|
||||
const phoneNumberVal =
|
||||
phoneNumber || (selfUser.userinfo || {}).phone_number;
|
||||
return (
|
||||
<UserInfoFormView
|
||||
isSendingUserRequest={isSendingUserRequest}
|
||||
userRequestError={userRequestError}
|
||||
userRequestSuccess={userRequestSuccess}
|
||||
phoneNumber={phoneNumberVal}
|
||||
changePhoneNumber={this.changePhoneNumber}
|
||||
onSubmitUserInfo={this.onSubmitUserInfo}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { ...state.user };
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(InitializeUserInfoForm);
|
41
src/components/User/ProviderFormView.jsx
Normal file
41
src/components/User/ProviderFormView.jsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
import { Container, Form, Header, Message } from "semantic-ui-react";
|
||||
|
||||
import Error from "../Shared/Error";
|
||||
|
||||
const ProviderFormView = ({
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
socialInsuranceNumber,
|
||||
changeSocialInsuranceNumber,
|
||||
onSubmitProvider
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>Complete Provider Information</Header>
|
||||
<Form
|
||||
loading={isSendingUserRequest}
|
||||
onSubmit={onSubmitProvider}
|
||||
error={!!userRequestError}
|
||||
success={!!userRequestSuccess}
|
||||
>
|
||||
<Form.Field>
|
||||
<label>Social Insurance Number</label>
|
||||
<input
|
||||
placeholder="98765"
|
||||
type="text"
|
||||
value={socialInsuranceNumber}
|
||||
onChange={changeSocialInsuranceNumber}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Error header="Modify Provider failed!" error={userRequestError} />
|
||||
<Message success>
|
||||
<Message.Header>Modify Provider successful!</Message.Header>
|
||||
<p>Set provider successfully.</p>
|
||||
</Message>
|
||||
<Form.Button>Submit Provider</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default ProviderFormView;
|
41
src/components/User/UserInfoFormView.jsx
Normal file
41
src/components/User/UserInfoFormView.jsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
import { Container, Form, Header, Message } from "semantic-ui-react";
|
||||
|
||||
import Error from "../Shared/Error";
|
||||
|
||||
const UserInfoFormView = ({
|
||||
isSendingUserRequest,
|
||||
userRequestError,
|
||||
userRequestSuccess,
|
||||
phoneNumber,
|
||||
changePhoneNumber,
|
||||
onSubmitUserInfo
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>User Info</Header>
|
||||
<Form
|
||||
loading={isSendingUserRequest}
|
||||
onSubmit={onSubmitUserInfo}
|
||||
error={!!userRequestError}
|
||||
success={!!userRequestSuccess}
|
||||
>
|
||||
<Form.Field>
|
||||
<label>Phone Number</label>
|
||||
<input
|
||||
placeholder="780-999-9999"
|
||||
type="tel"
|
||||
value={phoneNumber}
|
||||
onChange={changePhoneNumber}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Error header="Modify User Info failed!" error={userRequestError} />
|
||||
<Message success>
|
||||
<Message.Header>Modify User Info successful!</Message.Header>
|
||||
<p>Set user info successfully.</p>
|
||||
</Message>
|
||||
<Form.Button>Submit User Info</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default UserInfoFormView;
|
Reference in New Issue
Block a user