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 = () => {
|
||||
return (
|
||||
<React.Element>
|
||||
<div>
|
||||
<Grid item xs={12}>
|
||||
<Button variant="text" fullWidth>
|
||||
<Skeleton />
|
||||
@ -20,7 +20,7 @@ const Loader = () => {
|
||||
<Skeleton />
|
||||
</Button>
|
||||
</Grid>
|
||||
</React.Element>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ const GoalForm = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Your goal { JSON.stringify(error) }
|
||||
Your goal
|
||||
</Typography>
|
||||
<RadioGroup defaultValue={1} onChange={handleChangeGoal}>
|
||||
<Grid container spacing={3} direction="column">
|
||||
@ -45,10 +45,10 @@ const GoalForm = () => {
|
||||
<Loader />
|
||||
) : (
|
||||
<React.Fragment>
|
||||
{goals.map(({ label, value }, index) => (
|
||||
{goals.map(({ name, value }, index) => (
|
||||
<Grid item xs={12} key={index}>
|
||||
<Button variant="text" fullWidth>
|
||||
{label}
|
||||
{name}
|
||||
<Radio color="secondary" name="goal" value={value} />
|
||||
</Button>
|
||||
</Grid>
|
||||
|
@ -67,8 +67,8 @@ const PersonalDetailsForm = () => {
|
||||
onChange={handleChangeValue}
|
||||
value={gender}
|
||||
>
|
||||
{genders.map(({ label, value }) => (
|
||||
<MenuItem value={value}>{label}</MenuItem>
|
||||
{genders.map(({ id, name }) => (
|
||||
<MenuItem value={id} key={id}>{name}</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
@ -128,7 +128,10 @@ const PersonalDetailsForm = () => {
|
||||
value={activity}
|
||||
min={0}
|
||||
max={4}
|
||||
marks={activities}
|
||||
marks={activities.map(({ name, factor, id }) => ({
|
||||
name,
|
||||
value: factor
|
||||
}))}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
@ -5,15 +5,31 @@ import {
|
||||
} from './constants';
|
||||
|
||||
import { LOGIN_SUCCESS } from 'pages/Login/constants'
|
||||
import { REGISTER_SUCCESS } from 'pages/Register/constants'
|
||||
|
||||
export const initialState = {
|
||||
isLogged: false,
|
||||
isLogged: true,
|
||||
notifications: [],
|
||||
tokens: {},
|
||||
user: {},
|
||||
};
|
||||
tokens: {
|
||||
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) => {
|
||||
switch(action.type) {
|
||||
case REGISTER_SUCCESS:
|
||||
case LOGIN_SUCCESS:
|
||||
draft.isLogged = true;
|
||||
draft.tokens = action.tokens;
|
||||
|
@ -11,13 +11,13 @@ const initialState = {};
|
||||
const store = configureStore(initialState, history);
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
// <React.StrictMode>
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<App />
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
</React.StrictMode>,
|
||||
</Provider>,
|
||||
// </React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
|
@ -21,12 +21,6 @@ import { loginInputChange, loginAction } from './actions'
|
||||
import {routes} from "../../utils";
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
|
||||
const stateSelector = createStructuredSelector({
|
||||
email: makeSelectEmail(),
|
||||
password: makeSelectPassword(),
|
||||
loading: makeSelectLoading(),
|
||||
});
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
paper: {
|
||||
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 Login = () => {
|
||||
const classes = useStyles()
|
||||
|
@ -2,7 +2,7 @@ import produce from 'immer';
|
||||
import {LOGIN_INPUT_CHANGE, LOGIN_ERROR, LOGIN_REQUEST, LOGIN_SUCCESS} from './constants';
|
||||
|
||||
export const initialState = {
|
||||
loading: false,
|
||||
isLoading: false,
|
||||
error: {},
|
||||
email: 'admin@admin.com',
|
||||
password: 'Kox32113@#$',
|
||||
@ -11,15 +11,15 @@ export const initialState = {
|
||||
const loginPageReducer = produce((draft, action) => {
|
||||
switch(action.type) {
|
||||
case LOGIN_SUCCESS:
|
||||
draft.loading = false;
|
||||
draft.isLoading = false;
|
||||
break;
|
||||
|
||||
case LOGIN_REQUEST:
|
||||
draft.loading = true;
|
||||
draft.isLoading = true;
|
||||
break;
|
||||
|
||||
case LOGIN_ERROR:
|
||||
draft.loading = false;
|
||||
draft.isLoading = false;
|
||||
draft.error = action.error;
|
||||
break;
|
||||
|
||||
|
@ -74,8 +74,8 @@ export function* getActivities() {
|
||||
};
|
||||
|
||||
try {
|
||||
const { activities } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getActivitiesSuccessAction({ activities }));
|
||||
const { results } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getActivitiesSuccessAction({ activities: results }));
|
||||
} catch (error) {
|
||||
yield put(getActivitiesErrorAction({error: error.message}));
|
||||
}
|
||||
@ -94,8 +94,8 @@ export function* getGenders() {
|
||||
};
|
||||
|
||||
try {
|
||||
const { genders } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getGendersSuccessAction({ genders }));
|
||||
const { results } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getGendersSuccessAction({ genders: results }));
|
||||
} catch (error) {
|
||||
yield put(getGendersErrorAction({ error: error.message }));
|
||||
}
|
||||
@ -113,8 +113,8 @@ export function* getGoals() {
|
||||
};
|
||||
|
||||
try {
|
||||
const { goals } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getGoalsSuccessAction({ goals }));
|
||||
const { results } = yield call(request, requestURL, requestParameters);
|
||||
yield put(getGoalsSuccessAction({ goals: results }));
|
||||
} catch (error) {
|
||||
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 { 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 {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) => ({
|
||||
paper: {
|
||||
@ -19,8 +26,28 @@ const useStyles = makeStyles((theme) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const stateSelector = createStructuredSelector({
|
||||
email: makeSelectEmail(),
|
||||
password: makeSelectPassword(),
|
||||
isLoading: makeSelectIsLoading(),
|
||||
});
|
||||
|
||||
const key = 'registerPage'
|
||||
const RegisterPage = () => {
|
||||
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 (
|
||||
<Container component="main" maxWidth="xs">
|
||||
@ -28,7 +55,7 @@ const RegisterPage = () => {
|
||||
<Typography component="h1" variant="h5">
|
||||
Create Account
|
||||
</Typography>
|
||||
<form className={classes.form} noValidate>
|
||||
<form className={classes.form} onSubmit={handleSubmit} noValidate>
|
||||
<TextField
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
@ -38,6 +65,8 @@ const RegisterPage = () => {
|
||||
label="Email Address"
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
value={email}
|
||||
onChange={onChangeInput}
|
||||
autoFocus
|
||||
/>
|
||||
<TextField
|
||||
@ -49,15 +78,14 @@ const RegisterPage = () => {
|
||||
label="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
value={password}
|
||||
onChange={onChangeInput}
|
||||
autoComplete="current-password"
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={<Checkbox value="remember" color="primary" />}
|
||||
label="Remember me"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
disabled={isLoading}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
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