Skip to content

Commit

Permalink
feat(client/register): add register
Browse files Browse the repository at this point in the history
  • Loading branch information
sepehrhosseini committed Feb 2, 2020
1 parent 70333b0 commit af00d0e
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 12 deletions.
41 changes: 40 additions & 1 deletion client/app/containers/RegisterPage/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,49 @@
*
*/

import { DEFAULT_ACTION } from './constants';
import Actions, { DEFAULT_ACTION } from './constants';

export function defaultAction() {
return {
type: DEFAULT_ACTION,
};
}

export function register() {
return {
type: Actions.REGISTER.REQUEST,
};
}

export function registerSucceed() {
return {
type: Actions.REGISTER.SUCCEED,
};
}

export function registerFailed() {
return {
type: Actions.REGISTER.FAILED,
};
}

export function inputEmailChanged({ email }) {
return {
type: Actions.INPUT.EMAIL_CHANGED,
email,
};
}

export function inputPasswordChanged({ password }) {
return {
type: Actions.INPUT.PASSWORD_CHANGED,
password,
};
}

export function inputPasswordConfChanged({ passwordConf }) {
return {
type: Actions.INPUT.PASSWORD_CONF_CHANGED,
passwordConf,
};
}
13 changes: 13 additions & 0 deletions client/app/containers/RegisterPage/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,16 @@
*/

export const DEFAULT_ACTION = 'app/RegisterPage/DEFAULT_ACTION';

export default {
REGISTER: {
REQUEST: 'app/RegisterPage/REGISTER_REQUEST',
SUCCEED: 'app/RegisterPage/REGISTER_SUCCEED',
FAILED: 'app/RegisterPage/REGISTER_FAILED',
},
INPUT: {
EMAIL_CHANGED: 'app/RegisterPage/INPUT_EMAIL_CHANGED',
PASSWORD_CHANGED: 'app/RegisterPage/INPUT_PASSWORD_CHANGED',
PASSWORD_CONF_CHANGED: 'app/RegisterPage/INPUT_PASSWORD_CONF_CHANGED',
},
};
63 changes: 55 additions & 8 deletions client/app/containers/RegisterPage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,32 @@ import Typography from '@material-ui/core/Typography';

import { useInjectSaga } from 'utils/injectSaga';
import { useInjectReducer } from 'utils/injectReducer';
import makeSelectRegisterPage from './selectors';
import makeSelectRegisterPage, {
makeSelectEmail,
makeSelectPassword,
makeSelectPasswordConf,
} from './selectors';
import {
register,
inputEmailChanged,
inputPasswordChanged,
inputPasswordConfChanged,
} from './actions';
import reducer from './reducer';
import saga from './saga';
import messages from './messages';

import { Wrapper, Card, FormRow, TextField } from './styled';
import { Wrapper, Card, CardHeader, FormRow, TextField } from './styled';

export function RegisterPage() {
export function RegisterPage({ dispatch, register }) {
useInjectReducer({ key: 'registerPage', reducer });
useInjectSaga({ key: 'registerPage', saga });

const formSubmit = e => {
e.preventDefault();
register();
};

return (
<div>
<Helmet>
Expand All @@ -38,26 +53,54 @@ export function RegisterPage() {
</Helmet>
<Wrapper>
<Card>
<form noValidate>
<CardHeader>
<Typography variant="h4" component="h1" gutterBottom>
Currency Rate
</Typography>
</CardHeader>
<form noValidate onSubmit={formSubmit}>
<Grid container>
<Grid item xs={12}>
<FormRow>
<TextField label="Email" />
<TextField
label="Email"
onChange={e =>
dispatch(inputEmailChanged({ email: e.target.value }))
}
/>
</FormRow>
</Grid>
<Grid item xs={12}>
<FormRow>
<TextField label="Password" />
<TextField
label="Password"
type="password"
onChange={e =>
dispatch(
inputPasswordChanged({ password: e.target.value }),
)
}
/>
</FormRow>
</Grid>
<Grid item xs={12}>
<FormRow>
<TextField label="Password Confirmation" />
<TextField
label="Password Confirmation"
type="password"
onChange={e =>
dispatch(
inputPasswordConfChanged({
passwordConf: e.target.value,
}),
)
}
/>
</FormRow>
</Grid>
<Grid item xs={12}>
<FormRow>
<Button variant="contained" color="primary">
<Button variant="contained" color="primary" type="submit">
Register
</Button>
<Button
Expand All @@ -83,11 +126,15 @@ RegisterPage.propTypes = {

const mapStateToProps = createStructuredSelector({
registerPage: makeSelectRegisterPage(),
email: makeSelectEmail(),
password: makeSelectPassword(),
passwordConf: makeSelectPasswordConf(),
});

function mapDispatchToProps(dispatch) {
return {
dispatch,
register: () => dispatch(register()),
};
}

Expand Down
22 changes: 20 additions & 2 deletions client/app/containers/RegisterPage/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,32 @@
*
*/
import produce from 'immer';
import { DEFAULT_ACTION } from './constants';
import Actions, { DEFAULT_ACTION } from './constants';

export const initialState = {};

/* eslint-disable default-case, no-param-reassign */
const registerPageReducer = (state = initialState, action) =>
produce(state, (/* draft */) => {
produce(state, draft => {
switch (action.type) {
case Actions.REGISTER.REQUEST:
draft.isLoading = true;
break;
case Actions.REGISTER.SUCCEED:
draft.isLoading = false;
break;
case Actions.REGISTER.FAILED:
draft.isLoading = false;
break;
case Actions.INPUT.EMAIL_CHANGED:
draft.email = action.email;
break;
case Actions.INPUT.PASSWORD_CHANGED:
draft.password = action.password;
break;
case Actions.INPUT.PASSWORD_CONF_CHANGED:
draft.passwordConf = action.passwordConf;
break;
case DEFAULT_ACTION:
break;
}
Expand Down
29 changes: 28 additions & 1 deletion client/app/containers/RegisterPage/saga.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
// import { take, call, put, select } from 'redux-saga/effects';
import { put, select, takeLatest } from 'redux-saga/effects';
import Actions from './constants';
import { registerSucceed, registerFailed } from './actions';
import {
makeSelectEmail,
makeSelectPassword,
makeSelectPasswordConf,
} from './selectors';

function* register() {
try {
const email = yield select(makeSelectEmail());
const password = yield select(makeSelectPassword());
const passwordConf = yield select(makeSelectPasswordConf());

console.log({
email,
password,
passwordConf,
});

yield put(registerSucceed());
} catch (e) {
console.log('saga failed', e);
yield put(registerFailed());
}
}

// Individual exports for testing
export default function* registerPageSaga() {
yield takeLatest(Actions.REGISTER.REQUEST, register);
// See example in containers/HomePage/saga.js
}
23 changes: 23 additions & 0 deletions client/app/containers/RegisterPage/selectors.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createSelector } from 'reselect';
import { get } from 'lodash';
import { initialState } from './reducer';

/**
Expand All @@ -11,6 +12,13 @@ const selectRegisterPageDomain = state => state.registerPage || initialState;
* Other specific selectors
*/

const selectEmail = state =>
get(state, 'registerPage.email', initialState.email);
const selectPassword = state =>
get(state, 'registerPage.password', initialState.password);
const selectPasswordConf = state =>
get(state, 'registerPage.passwordConf', initialState.passwordConf);

/**
* Default selector used by RegisterPage
*/
Expand All @@ -20,6 +28,21 @@ const makeSelectRegisterPage = () =>
selectRegisterPageDomain,
substate => substate,
);
export const makeSelectEmail = () =>
createSelector(
selectEmail,
substate => substate,
);
export const makeSelectPassword = () =>
createSelector(
selectPassword,
substate => substate,
);
export const makeSelectPasswordConf = () =>
createSelector(
selectPasswordConf,
substate => substate,
);

export default makeSelectRegisterPage;
export { selectRegisterPageDomain };
5 changes: 5 additions & 0 deletions client/app/containers/RegisterPage/styled.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export const Card = styled(CardUI)`
min-width: 300px;
`;

export const CardHeader = styled.div`
padding: 15px;
padding-bottom: 0;
`;

export const Wrapper = styled.div`
display: flex;
align-items: center;
Expand Down

0 comments on commit af00d0e

Please sign in to comment.