Add create profile secion

This commit is contained in:
= 2020-12-09 18:06:05 +01:00
parent 156b78ca39
commit 6c807dcc30
14 changed files with 192 additions and 37 deletions

View File

@ -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>
);
};

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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')
);

View File

@ -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()

View File

@ -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;

View File

@ -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 }));
}

View 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,
})

View 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';

View File

@ -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}

View 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;

View 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);
}

View 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,
};