Add create profile secion
This commit is contained in:
parent
156b78ca39
commit
6c807dcc30
@ -4,7 +4,7 @@ import {Skeleton} from "@material-ui/lab";
|
|||||||
|
|
||||||
const Loader = () => {
|
const Loader = () => {
|
||||||
return (
|
return (
|
||||||
<React.Element>
|
<div>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Button variant="text" fullWidth>
|
<Button variant="text" fullWidth>
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
@ -20,7 +20,7 @@ const Loader = () => {
|
|||||||
<Skeleton />
|
<Skeleton />
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</React.Element>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ const GoalForm = () => {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
Your goal { JSON.stringify(error) }
|
Your goal
|
||||||
</Typography>
|
</Typography>
|
||||||
<RadioGroup defaultValue={1} onChange={handleChangeGoal}>
|
<RadioGroup defaultValue={1} onChange={handleChangeGoal}>
|
||||||
<Grid container spacing={3} direction="column">
|
<Grid container spacing={3} direction="column">
|
||||||
@ -45,10 +45,10 @@ const GoalForm = () => {
|
|||||||
<Loader />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{goals.map(({ label, value }, index) => (
|
{goals.map(({ name, value }, index) => (
|
||||||
<Grid item xs={12} key={index}>
|
<Grid item xs={12} key={index}>
|
||||||
<Button variant="text" fullWidth>
|
<Button variant="text" fullWidth>
|
||||||
{label}
|
{name}
|
||||||
<Radio color="secondary" name="goal" value={value} />
|
<Radio color="secondary" name="goal" value={value} />
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -67,8 +67,8 @@ const PersonalDetailsForm = () => {
|
|||||||
onChange={handleChangeValue}
|
onChange={handleChangeValue}
|
||||||
value={gender}
|
value={gender}
|
||||||
>
|
>
|
||||||
{genders.map(({ label, value }) => (
|
{genders.map(({ id, name }) => (
|
||||||
<MenuItem value={value}>{label}</MenuItem>
|
<MenuItem value={id} key={id}>{name}</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
@ -128,7 +128,10 @@ const PersonalDetailsForm = () => {
|
|||||||
value={activity}
|
value={activity}
|
||||||
min={0}
|
min={0}
|
||||||
max={4}
|
max={4}
|
||||||
marks={activities}
|
marks={activities.map(({ name, factor, id }) => ({
|
||||||
|
name,
|
||||||
|
value: factor
|
||||||
|
}))}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -5,15 +5,31 @@ import {
|
|||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
import { LOGIN_SUCCESS } from 'pages/Login/constants'
|
import { LOGIN_SUCCESS } from 'pages/Login/constants'
|
||||||
|
import { REGISTER_SUCCESS } from 'pages/Register/constants'
|
||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
isLogged: false,
|
isLogged: true,
|
||||||
notifications: [],
|
notifications: [],
|
||||||
tokens: {},
|
tokens: {
|
||||||
user: {},
|
access: {
|
||||||
};
|
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZmQxMDExNGM3NDQ0MTJlZDQ3Y2IzZDEiLCJpYXQiOjE2MDc1MzI4MzUsImV4cCI6MTYwNzUzNDYzNSwidHlwZSI6ImFjY2VzcyJ9.S19wRggAiJYYK35dFWM_gIWuf5ULajJ2cOaA2V2vwtY',
|
||||||
|
expires: '2020-12-09T17:23:55.763Z'
|
||||||
|
},
|
||||||
|
refresh: {
|
||||||
|
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZmQxMDExNGM3NDQ0MTJlZDQ3Y2IzZDEiLCJpYXQiOjE2MDc1MzI4MzUsImV4cCI6MTYxMDEyNDgzNSwidHlwZSI6InJlZnJlc2gifQ.NC6BJUDKR3WBUVxo62Swytx4nkc6QtUQ7oYdJHqgDY0',
|
||||||
|
expires: '2021-01-08T16:53:55.763Z'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
role: 'admin',
|
||||||
|
email: 'admin@admin.com',
|
||||||
|
id: '5fd10114c744412ed47cb3d1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const appReducer = produce((draft, action) => {
|
const appReducer = produce((draft, action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
|
case REGISTER_SUCCESS:
|
||||||
case LOGIN_SUCCESS:
|
case LOGIN_SUCCESS:
|
||||||
draft.isLogged = true;
|
draft.isLogged = true;
|
||||||
draft.tokens = action.tokens;
|
draft.tokens = action.tokens;
|
||||||
|
@ -11,13 +11,13 @@ const initialState = {};
|
|||||||
const store = configureStore(initialState, history);
|
const store = configureStore(initialState, history);
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
// <React.StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConnectedRouter history={history}>
|
<ConnectedRouter history={history}>
|
||||||
<App />
|
<App />
|
||||||
</ConnectedRouter>
|
</ConnectedRouter>
|
||||||
</Provider>
|
</Provider>,
|
||||||
</React.StrictMode>,
|
// </React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -21,12 +21,6 @@ import { loginInputChange, loginAction } from './actions'
|
|||||||
import {routes} from "../../utils";
|
import {routes} from "../../utils";
|
||||||
import {makeStyles} from "@material-ui/core/styles";
|
import {makeStyles} from "@material-ui/core/styles";
|
||||||
|
|
||||||
const stateSelector = createStructuredSelector({
|
|
||||||
email: makeSelectEmail(),
|
|
||||||
password: makeSelectPassword(),
|
|
||||||
loading: makeSelectLoading(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
paper: {
|
paper: {
|
||||||
marginTop: theme.spacing(8),
|
marginTop: theme.spacing(8),
|
||||||
@ -43,6 +37,12 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const stateSelector = createStructuredSelector({
|
||||||
|
email: makeSelectEmail(),
|
||||||
|
password: makeSelectPassword(),
|
||||||
|
loading: makeSelectLoading(),
|
||||||
|
});
|
||||||
|
|
||||||
const key = 'loginPage'
|
const key = 'loginPage'
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
@ -2,7 +2,7 @@ import produce from 'immer';
|
|||||||
import {LOGIN_INPUT_CHANGE, LOGIN_ERROR, LOGIN_REQUEST, LOGIN_SUCCESS} from './constants';
|
import {LOGIN_INPUT_CHANGE, LOGIN_ERROR, LOGIN_REQUEST, LOGIN_SUCCESS} from './constants';
|
||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
loading: false,
|
isLoading: false,
|
||||||
error: {},
|
error: {},
|
||||||
email: 'admin@admin.com',
|
email: 'admin@admin.com',
|
||||||
password: 'Kox32113@#$',
|
password: 'Kox32113@#$',
|
||||||
@ -11,15 +11,15 @@ export const initialState = {
|
|||||||
const loginPageReducer = produce((draft, action) => {
|
const loginPageReducer = produce((draft, action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case LOGIN_SUCCESS:
|
case LOGIN_SUCCESS:
|
||||||
draft.loading = false;
|
draft.isLoading = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOGIN_REQUEST:
|
case LOGIN_REQUEST:
|
||||||
draft.loading = true;
|
draft.isLoading = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOGIN_ERROR:
|
case LOGIN_ERROR:
|
||||||
draft.loading = false;
|
draft.isLoading = false;
|
||||||
draft.error = action.error;
|
draft.error = action.error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ export function* getActivities() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { activities } = yield call(request, requestURL, requestParameters);
|
const { results } = yield call(request, requestURL, requestParameters);
|
||||||
yield put(getActivitiesSuccessAction({ activities }));
|
yield put(getActivitiesSuccessAction({ activities: results }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put(getActivitiesErrorAction({error: error.message}));
|
yield put(getActivitiesErrorAction({error: error.message}));
|
||||||
}
|
}
|
||||||
@ -94,8 +94,8 @@ export function* getGenders() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { genders } = yield call(request, requestURL, requestParameters);
|
const { results } = yield call(request, requestURL, requestParameters);
|
||||||
yield put(getGendersSuccessAction({ genders }));
|
yield put(getGendersSuccessAction({ genders: results }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put(getGendersErrorAction({ error: error.message }));
|
yield put(getGendersErrorAction({ error: error.message }));
|
||||||
}
|
}
|
||||||
@ -113,8 +113,8 @@ export function* getGoals() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { goals } = yield call(request, requestURL, requestParameters);
|
const { results } = yield call(request, requestURL, requestParameters);
|
||||||
yield put(getGoalsSuccessAction({ goals }));
|
yield put(getGoalsSuccessAction({ goals: results }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
yield put(getGoalsErrorAction({ error: error.message }));
|
yield put(getGoalsErrorAction({ error: error.message }));
|
||||||
}
|
}
|
||||||
|
22
src/pages/Register/actions.js
Normal file
22
src/pages/Register/actions.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { REGISTER_INPUT_CHANGE, REGISTER_REQUEST, REGISTER_SUCCESS, REGISTER_ERROR } from './constants';
|
||||||
|
|
||||||
|
export const registerInputChange = ({name, value}) => ({
|
||||||
|
type: REGISTER_INPUT_CHANGE,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const registerAction = () => ({
|
||||||
|
type: REGISTER_REQUEST,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const registerSuccessAction = ({user, tokens}) => ({
|
||||||
|
type: REGISTER_SUCCESS,
|
||||||
|
user,
|
||||||
|
tokens,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const registerErrorAction = ({error}) => ({
|
||||||
|
type: REGISTER_ERROR,
|
||||||
|
error,
|
||||||
|
})
|
5
src/pages/Register/constants.js
Normal file
5
src/pages/Register/constants.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const REGISTER_REQUEST = 'app/registerPage/REGISTER_REQUEST';
|
||||||
|
export const REGISTER_SUCCESS = 'app/registerPage/REGISTER_SUCCESS';
|
||||||
|
export const REGISTER_ERROR = 'app/registerPage/REGISTER_ERROR';
|
||||||
|
|
||||||
|
export const REGISTER_INPUT_CHANGE = 'app/registerPage/REGISTER_INPUT_CHANGE';
|
@ -1,7 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import {Container, Typography, Grid, Button, TextField, FormControlLabel, Checkbox, Link} from '@material-ui/core';
|
import {Container, Typography, Grid, Button, TextField, Link} from '@material-ui/core';
|
||||||
import { routes } from 'utils';
|
import { routes } from 'utils';
|
||||||
|
import {useInjectReducer, useInjectSaga} from "redux-injectors";
|
||||||
|
import {useDispatch, useSelector} from "react-redux";
|
||||||
|
import reducer from "./reducer";
|
||||||
|
import saga from "./saga";
|
||||||
|
import {registerAction, registerInputChange} from "./actions";
|
||||||
|
import {createStructuredSelector} from "reselect";
|
||||||
|
import {makeSelectEmail, makeSelectIsLoading, makeSelectPassword} from "./selectors";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
paper: {
|
paper: {
|
||||||
@ -19,8 +26,28 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const stateSelector = createStructuredSelector({
|
||||||
|
email: makeSelectEmail(),
|
||||||
|
password: makeSelectPassword(),
|
||||||
|
isLoading: makeSelectIsLoading(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const key = 'registerPage'
|
||||||
const RegisterPage = () => {
|
const RegisterPage = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
useInjectReducer({ key, reducer });
|
||||||
|
useInjectSaga({ key, saga });
|
||||||
|
const { email, password, isLoading } = useSelector(stateSelector)
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const onChangeInput = ({target: { name, value }}) => {
|
||||||
|
dispatch(registerInputChange({name, value}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = (event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
dispatch(registerAction())
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container component="main" maxWidth="xs">
|
<Container component="main" maxWidth="xs">
|
||||||
@ -28,7 +55,7 @@ const RegisterPage = () => {
|
|||||||
<Typography component="h1" variant="h5">
|
<Typography component="h1" variant="h5">
|
||||||
Create Account
|
Create Account
|
||||||
</Typography>
|
</Typography>
|
||||||
<form className={classes.form} noValidate>
|
<form className={classes.form} onSubmit={handleSubmit} noValidate>
|
||||||
<TextField
|
<TextField
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
margin="normal"
|
margin="normal"
|
||||||
@ -38,6 +65,8 @@ const RegisterPage = () => {
|
|||||||
label="Email Address"
|
label="Email Address"
|
||||||
name="email"
|
name="email"
|
||||||
autoComplete="email"
|
autoComplete="email"
|
||||||
|
value={email}
|
||||||
|
onChange={onChangeInput}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
@ -49,15 +78,14 @@ const RegisterPage = () => {
|
|||||||
label="Password"
|
label="Password"
|
||||||
type="password"
|
type="password"
|
||||||
id="password"
|
id="password"
|
||||||
|
value={password}
|
||||||
|
onChange={onChangeInput}
|
||||||
autoComplete="current-password"
|
autoComplete="current-password"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
|
||||||
control={<Checkbox value="remember" color="primary" />}
|
|
||||||
label="Remember me"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
fullWidth
|
fullWidth
|
||||||
|
disabled={isLoading}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="primary"
|
color="primary"
|
||||||
className={classes.submit}
|
className={classes.submit}
|
||||||
|
32
src/pages/Register/reducer.js
Normal file
32
src/pages/Register/reducer.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import produce from 'immer';
|
||||||
|
import {REGISTER_INPUT_CHANGE, REGISTER_ERROR, REGISTER_REQUEST, REGISTER_SUCCESS} from './constants';
|
||||||
|
|
||||||
|
export const initialState = {
|
||||||
|
isLoading: false,
|
||||||
|
error: {},
|
||||||
|
email: 'admin@admin.com',
|
||||||
|
password: 'Kox32113@#$',
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerPageReducer = produce((draft, action) => {
|
||||||
|
switch(action.type) {
|
||||||
|
case REGISTER_SUCCESS:
|
||||||
|
draft.isLoading = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_REQUEST:
|
||||||
|
draft.isLoading = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_ERROR:
|
||||||
|
draft.isLoading = false;
|
||||||
|
draft.error = action.error;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGISTER_INPUT_CHANGE:
|
||||||
|
draft[action.name] = action.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, initialState);
|
||||||
|
|
||||||
|
export default registerPageReducer;
|
30
src/pages/Register/saga.js
Normal file
30
src/pages/Register/saga.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { takeLatest, call, put, select } from 'redux-saga/effects';
|
||||||
|
import { push } from 'connected-react-router';
|
||||||
|
import { api, request, routes } from 'utils';
|
||||||
|
import { REGISTER_REQUEST } from './constants';
|
||||||
|
import { makeSelectPassword, makeSelectEmail } from './selectors';
|
||||||
|
import { registerSuccessAction, registerErrorAction } from './actions';
|
||||||
|
|
||||||
|
export function* register() {
|
||||||
|
const email = yield select(makeSelectEmail());
|
||||||
|
const password = yield select(makeSelectPassword());
|
||||||
|
|
||||||
|
const requestURL = api.auth.register;
|
||||||
|
const requestParameters = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ email, password }),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { user, tokens } = yield call(request, requestURL, requestParameters);
|
||||||
|
yield put(registerSuccessAction({user, tokens}));
|
||||||
|
yield put(push(routes.profile.path));
|
||||||
|
} catch (error) {
|
||||||
|
yield put(registerErrorAction({ error: error.message }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function* registerPageSaga() {
|
||||||
|
yield takeLatest(REGISTER_REQUEST, register);
|
||||||
|
}
|
19
src/pages/Register/selectors.js
Normal file
19
src/pages/Register/selectors.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import { initialState } from './reducer';
|
||||||
|
|
||||||
|
const selectRegisterPageDomain = (state) => state.registerPage || initialState;
|
||||||
|
|
||||||
|
const makeSelectEmail = () =>
|
||||||
|
createSelector(selectRegisterPageDomain, (substate) => substate.email);
|
||||||
|
|
||||||
|
const makeSelectPassword = () =>
|
||||||
|
createSelector(selectRegisterPageDomain, (substate) => substate.password);
|
||||||
|
const makeSelectIsLoading = () =>
|
||||||
|
createSelector(selectRegisterPageDomain, (substate) => substate.isLoading);
|
||||||
|
|
||||||
|
export {
|
||||||
|
selectRegisterPageDomain,
|
||||||
|
makeSelectEmail,
|
||||||
|
makeSelectPassword,
|
||||||
|
makeSelectIsLoading,
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user