diff --git a/README.md b/README.md
index c5ec467..b52568d 100644
--- a/README.md
+++ b/README.md
@@ -15,10 +15,23 @@ Now you can visit `localhost:3000` from your browser.
The environment variables are embedded during the build time. For more information, please refer to the [docs](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables).
-| Environment Variable | Default Value | Description |
-| ------------------------- |:-------------------------:| -------------------:|
-| `REACT_APP_API_ENDPOINT` | `"http://localhost:8000"` | Server API endpoint |
-| `REACT_APP_REDUX_LOGGING` | ` ` | Set for Redux Log |
+| Environment Variable | Default Value | Description |
+| ------------------------- |:-------------------------:| -------------------------------:|
+| `REACT_APP_API_ENDPOINT` | `"http://localhost:8000"` | Server API endpoint |
+| `REACT_APP_REDUX_LOGGING` | ` ` | Set any value for Redux logging |
+
+
+## Production
+
+To build the production instance of this application, run the following:
+
+```bash
+export REACT_APP_API_ENDPOINT="http://dev.tannercollin.com:8000/" && yarn build
+
+# then, to serve the production site locally
+yarn global add serve
+serve -s build --port 3000
+```
## Testing
diff --git a/src/actions/user/reducer.actions.js b/src/actions/user/reducer.actions.js
index ed4316b..f53527b 100644
--- a/src/actions/user/reducer.actions.js
+++ b/src/actions/user/reducer.actions.js
@@ -4,7 +4,12 @@ import {
CLEAR_USER_REQUEST_ERROR,
SET_USER_REQUEST_SUCCESS,
CLEAR_USER_REQUEST_SUCCESS,
- SET_SELF_USER
+ SET_SELF_USER,
+ SET_COMPLETE_REGISTRATION_STEP,
+ SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER,
+ SET_FORM_PHONE_NUMBER,
+ SET_FORM_BUSINESS_NUMBER,
+ SET_FORM_SOCIAL_INSURANCE_NUMBER
} from "../../constants/user.constants";
import { parseError } from "../common.actions";
@@ -48,3 +53,38 @@ export function setSelfUser(selfUser) {
data: selfUser
};
}
+
+export function setCompleteRegistrationStep(step) {
+ return {
+ type: SET_COMPLETE_REGISTRATION_STEP,
+ data: step
+ };
+}
+
+export function setCompleteRegistrationClientOrProvider(clientOrProvider) {
+ return {
+ type: SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER,
+ data: clientOrProvider
+ };
+}
+
+export function setFormPhoneNumber(phoneNumber) {
+ return {
+ type: SET_FORM_PHONE_NUMBER,
+ data: phoneNumber
+ };
+}
+
+export function setFormBusinessNumber(businessNumber) {
+ return {
+ type: SET_FORM_BUSINESS_NUMBER,
+ data: businessNumber
+ };
+}
+
+export function setFormSocialInsuranceNumber(socialInsuranceNumber) {
+ return {
+ type: SET_FORM_SOCIAL_INSURANCE_NUMBER,
+ data: socialInsuranceNumber
+ };
+}
diff --git a/src/components/App.jsx b/src/components/App.jsx
index 2130649..cad0395 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -7,6 +7,7 @@ import Register from "./Auth/Register";
import ResetPassword from "./Auth/ResetPassword";
import Settings from "./Auth/Settings";
import VerifyEmail from "./Auth/VerifyEmail";
+import CompleteRegistration from "./User/CompleteRegistration";
import Profile from "./User/Profile";
import PrivateRoute from "./Shared/PrivateRoute";
import About from "./Static/About";
@@ -17,15 +18,16 @@ import Navbar from "./Navbar";
class App extends Component {
render() {
- const footSmash = {
- display: "flex",
- minHeight: "calc(100vh - 1px)",
- flexDirection: "column"
- };
return (
-
+
@@ -44,8 +46,10 @@ class App extends Component {
component={ResetPassword}
/>
+
+
diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx
index 31728b2..1c2a602 100644
--- a/src/components/Navbar.jsx
+++ b/src/components/Navbar.jsx
@@ -3,9 +3,18 @@ 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 { sendLogoutRequest } from "../actions/auth/saga.actions";
class Navbar extends Component {
+ componentWillMount() {
+ 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());
+ }
+ }
+
dispatchLogoutRequest = () => {
this.props.dispatch(sendLogoutRequest());
};
@@ -22,7 +31,10 @@ class Navbar extends Component {
}
function mapStateToProps(state) {
- return { ...state.auth };
+ return {
+ userToken: state.auth.userToken,
+ selfUser: state.user.selfUser
+ };
}
const NavbarView = ({ isAuthenticated, dispatchLogoutRequest }) => (
diff --git a/src/components/Shared/PrivateRoute.jsx b/src/components/Shared/PrivateRoute.jsx
index 1665d43..460fa8c 100644
--- a/src/components/Shared/PrivateRoute.jsx
+++ b/src/components/Shared/PrivateRoute.jsx
@@ -33,16 +33,23 @@ class PrivateRoute extends Component {
component,
...rest
} = this.props;
- // If the user token exists and
+ // If the user token exists and
// * self user object isn't loaded yet or
// * we are still sending user request
// show loading spinner
if (
- !!userToken &&
- (Object.keys(selfUser).length === 0 || isSendingUserRequest)
+ userToken && (Object.keys(selfUser).length === 0 || isSendingUserRequest)
) {
return
;
}
+ // If the user exists but they aren't a client or provider yet, confirm-registration
+ if (
+ userToken &&
+ Object.keys(selfUser).length &&
+ (!selfUser.client || !selfUser.provider)
+ ) {
+ return
;
+ }
return (
{
+ event.preventDefault();
+ this.props.dispatch(setCompleteRegistrationStep(data.step));
+ };
+
+ render() {
+ const {
+ userToken,
+ completeRegistrationCurrentStep,
+ completeRegistrationMaxStep,
+ completeRegistrationClientOrProvider
+ } = this.props;
+ if (!userToken) return ;
+ return (
+
+ );
+ }
+}
+
+function mapStateToProps(state) {
+ return {
+ ...state.user,
+ userToken: state.auth.userToken
+ };
+}
+
+const CompleteRegistrationView = ({
+ currentStep,
+ maxStep,
+ completeRegistrationClientOrProvider,
+ onChangeStep
+}) => (
+
+ Complete Registration
+
+
+
+
+
+ USER_INFO_STEP}
+ active={currentStep === USER_INFO_STEP}
+ title="Basic User Info"
+ description="Fill out your user information"
+ onClick={onChangeStep}
+ disabled={maxStep < USER_INFO_STEP}
+ step={USER_INFO_STEP}
+ />
+ CLIENT_OR_PROVIDER_STEP}
+ active={currentStep === CLIENT_OR_PROVIDER_STEP}
+ title="Client or Provider"
+ description="Choose to be a Client or a Provider"
+ onClick={onChangeStep}
+ disabled={maxStep < CLIENT_OR_PROVIDER_STEP}
+ step={CLIENT_OR_PROVIDER_STEP}
+ />
+ COMPLETE_INFORMATION_STEP}
+ active={currentStep === COMPLETE_INFORMATION_STEP}
+ title="Complete Information"
+ description="Fill out the client or provider information"
+ onClick={onChangeStep}
+ disabled={maxStep < COMPLETE_INFORMATION_STEP}
+ step={COMPLETE_INFORMATION_STEP}
+ />
+
+
+
+
+ {currentStep === USER_INFO_STEP && User Info
}
+ {currentStep === CLIENT_OR_PROVIDER_STEP && Client or Provider
}
+ {currentStep === COMPLETE_INFORMATION_STEP && Complete Info
}
+
+
+
+
+);
+
+export default connect(mapStateToProps)(CompleteRegistration);
diff --git a/src/components/User/Profile.jsx b/src/components/User/Profile.jsx
index ba3ed08..c83c03f 100644
--- a/src/components/User/Profile.jsx
+++ b/src/components/User/Profile.jsx
@@ -29,7 +29,7 @@ const ProfileView = ({ user }) => (
{user.userinfo &&
{Object.keys(user.userinfo).map(function(key) {
return (
- {user.userinfo[key]}
+ {key}: {user.userinfo[key]}
)
})}
}
diff --git a/src/constants/user.constants.js b/src/constants/user.constants.js
index 54ee206..7cf5ae8 100644
--- a/src/constants/user.constants.js
+++ b/src/constants/user.constants.js
@@ -5,6 +5,20 @@ export const CLEAR_USER_REQUEST_ERROR = "CLEAR_USER_REQUEST_ERROR";
export const SET_USER_REQUEST_SUCCESS = "SET_USER_REQUEST_SUCCESS";
export const CLEAR_USER_REQUEST_SUCCESS = "CLEAR_USER_REQUEST_SUCCESS";
export const SET_SELF_USER = "SET_SELF_USER";
+export const SET_COMPLETE_REGISTRATION_STEP = "SET_COMPLETE_REGISTRATION_STEP";
+export const SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER =
+ "SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER";
+export const SET_FORM_PHONE_NUMBER = "SET_FORM_PHONE_NUMBER";
+export const SET_FORM_BUSINESS_NUMBER = "SET_FORM_BUSINESS_NUMBER";
+export const SET_FORM_SOCIAL_INSURANCE_NUMBER =
+ "SET_FORM_SOCIAL_INSURANCE_NUMBER";
// Saga User Action Constants
export const SEND_GET_SELF_USER_REQUEST = "SEND_GET_SELF_USER_REQUEST";
+
+// Misc. User Constants (int so we can mark prior as completed)
+export const USER_INFO_STEP = 1;
+export const CLIENT_OR_PROVIDER_STEP = 2;
+export const COMPLETE_INFORMATION_STEP = 3;
+export const CLIENT = "CLIENT";
+export const PROVIDER = "PROVIDER";
diff --git a/src/reducers/userReducer.js b/src/reducers/userReducer.js
index 23c7df5..d484a7b 100644
--- a/src/reducers/userReducer.js
+++ b/src/reducers/userReducer.js
@@ -4,14 +4,26 @@ import {
CLEAR_USER_REQUEST_ERROR,
SET_USER_REQUEST_SUCCESS,
CLEAR_USER_REQUEST_SUCCESS,
- SET_SELF_USER
+ SET_SELF_USER,
+ SET_COMPLETE_REGISTRATION_STEP,
+ SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER,
+ SET_FORM_PHONE_NUMBER,
+ SET_FORM_BUSINESS_NUMBER,
+ SET_FORM_SOCIAL_INSURANCE_NUMBER,
+ USER_INFO_STEP
} from "../constants/user.constants";
const initialState = {
isSendingUserRequest: false,
userRequestError: "",
userRequestSuccess: "",
- selfUser: {}
+ selfUser: {},
+ completeRegistrationCurrentStep: USER_INFO_STEP,
+ completeRegistrationMaxStep: USER_INFO_STEP,
+ completeRegistrationClientOrProvider: "",
+ phoneNumber: "",
+ businessNumber: "",
+ socialInsuranceNumber: ""
};
function userReducer(state = initialState, action) {
@@ -46,6 +58,35 @@ function userReducer(state = initialState, action) {
...state,
selfUser: action.data
};
+ case SET_COMPLETE_REGISTRATION_STEP:
+ return {
+ ...state,
+ completeRegistrationCurrentStep: action.data,
+ completeRegistrationMaxStep: Math.max(
+ action.data,
+ state.completeRegistrationMaxStep
+ )
+ };
+ case SET_COMPLETE_REGISTRATION_CLIENT_OR_PROVIDER:
+ return {
+ ...state,
+ completeRegistrationClientOrProvider: action.data
+ };
+ case SET_FORM_PHONE_NUMBER:
+ return {
+ ...state,
+ phoneNumber: action.data
+ };
+ case SET_FORM_BUSINESS_NUMBER:
+ return {
+ ...state,
+ businessNumber: action.data
+ };
+ case SET_FORM_SOCIAL_INSURANCE_NUMBER:
+ return {
+ ...state,
+ socialInsuranceNumber: action.data
+ };
default:
return state;
}