Skip to content

Commit

Permalink
feat(client/auth): add auth pages
Browse files Browse the repository at this point in the history
  • Loading branch information
sepehrhosseini committed Feb 2, 2020
1 parent b36cf3e commit 1ac7006
Show file tree
Hide file tree
Showing 33 changed files with 12,244 additions and 3 deletions.
4 changes: 4 additions & 0 deletions client/app/containers/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ import { Switch, Route } from 'react-router-dom';

import HomePage from 'containers/HomePage/Loadable';
import NotFoundPage from 'containers/NotFoundPage/Loadable';
import LoginPage from 'containers/LoginPage/Loadable';
import RegisterPage from 'containers/RegisterPage/Loadable';

import GlobalStyle from '../../global-styles';

export default function App() {
return (
<div>
<Switch>
<Route exact path="/register" component={RegisterPage} />
<Route exact path="/login" component={LoginPage} />
<Route exact path="/" component={HomePage} />
<Route component={NotFoundPage} />
</Switch>
Expand Down
9 changes: 9 additions & 0 deletions client/app/containers/LoginPage/Loadable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
*
* Asynchronously loads the component for LoginPage
*
*/

import loadable from 'utils/loadable';

export default loadable(() => import('./index'));
13 changes: 13 additions & 0 deletions client/app/containers/LoginPage/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
*
* LoginPage actions
*
*/

import { DEFAULT_ACTION } from './constants';

export function defaultAction() {
return {
type: DEFAULT_ACTION,
};
}
7 changes: 7 additions & 0 deletions client/app/containers/LoginPage/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
*
* LoginPage constants
*
*/

export const DEFAULT_ACTION = 'app/LoginPage/DEFAULT_ACTION';
102 changes: 102 additions & 0 deletions client/app/containers/LoginPage/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
*
* LoginPage
*
*/

import React, { memo } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import { FormattedMessage } from 'react-intl';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';
import { Link as RouterLink } from 'react-router-dom';

import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';

import { useInjectSaga } from 'utils/injectSaga';
import { useInjectReducer } from 'utils/injectReducer';
import makeSelectLoginPage from './selectors';
import reducer from './reducer';
import saga from './saga';
import messages from './messages';

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

export function LoginPage() {
useInjectReducer({ key: 'loginPage', reducer });
useInjectSaga({ key: 'loginPage', saga });

return (
<div>
<Helmet>
<title>Login</title>
<meta name="description" content="Login to currency rate profile" />
</Helmet>
<Wrapper>
<Card>
<CardHeader>
<Typography variant="h4" component="h1" gutterBottom>
Currency Rate
</Typography>
</CardHeader>
<form noValidate>
<Grid container>
<Grid item xs={12}>
<FormRow>
<TextField label="Email" />
</FormRow>
</Grid>
<Grid item xs={12}>
<FormRow>
<TextField label="Password" />
</FormRow>
</Grid>
<Grid item xs={12}>
<FormRow>
<Button variant="contained" color="primary">
Login
</Button>
<Button
style={{ marginLeft: 10 }}
component={RouterLink}
to="/register"
>
Register
</Button>
</FormRow>
</Grid>
</Grid>
</form>
</Card>
</Wrapper>
</div>
);
}

LoginPage.propTypes = {
dispatch: PropTypes.func.isRequired,
};

const mapStateToProps = createStructuredSelector({
loginPage: makeSelectLoginPage(),
});

function mapDispatchToProps(dispatch) {
return {
dispatch,
};
}

const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);

export default compose(
withConnect,
memo,
)(LoginPage);
16 changes: 16 additions & 0 deletions client/app/containers/LoginPage/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* LoginPage Messages
*
* This contains all the text for the LoginPage container.
*/

import { defineMessages } from 'react-intl';

export const scope = 'app.containers.LoginPage';

export default defineMessages({
header: {
id: `${scope}.header`,
defaultMessage: 'This is the LoginPage container!',
},
});
20 changes: 20 additions & 0 deletions client/app/containers/LoginPage/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
*
* LoginPage reducer
*
*/
import produce from 'immer';
import { DEFAULT_ACTION } from './constants';

export const initialState = {};

/* eslint-disable default-case, no-param-reassign */
const loginPageReducer = (state = initialState, action) =>
produce(state, (/* draft */) => {
switch (action.type) {
case DEFAULT_ACTION:
break;
}
});

export default loginPageReducer;
6 changes: 6 additions & 0 deletions client/app/containers/LoginPage/saga.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// import { take, call, put, select } from 'redux-saga/effects';

// Individual exports for testing
export default function* loginPageSaga() {
// See example in containers/HomePage/saga.js
}
25 changes: 25 additions & 0 deletions client/app/containers/LoginPage/selectors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { createSelector } from 'reselect';
import { initialState } from './reducer';

/**
* Direct selector to the loginPage state domain
*/

const selectLoginPageDomain = state => state.loginPage || initialState;

/**
* Other specific selectors
*/

/**
* Default selector used by LoginPage
*/

const makeSelectLoginPage = () =>
createSelector(
selectLoginPageDomain,
substate => substate,
);

export default makeSelectLoginPage;
export { selectLoginPageDomain };
33 changes: 33 additions & 0 deletions client/app/containers/LoginPage/styled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styled from 'styled-components';
import CardUI from '@material-ui/core/Card';
import TextFieldUI from '@material-ui/core/TextField';

export const Card = styled(CardUI)`
max-width: 360px;
min-width: 300px;
`;

export const Wrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
@media (min-width: 960px) {
padding: 10px;
}
`;

export const TextField = styled(TextFieldUI)`
width: 100%;
`;

export const FormRow = styled.div`
padding: 15px;
`;

export const CardHeader = styled.div`
padding: 15px;
padding-bottom: 0;
`;
13 changes: 13 additions & 0 deletions client/app/containers/LoginPage/tests/actions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defaultAction } from '../actions';
import { DEFAULT_ACTION } from '../constants';

describe('LoginPage actions', () => {
describe('Default Action', () => {
it('has a type of DEFAULT_ACTION', () => {
const expected = {
type: DEFAULT_ACTION,
};
expect(defaultAction()).toEqual(expected);
});
});
});
48 changes: 48 additions & 0 deletions client/app/containers/LoginPage/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
*
* Tests for LoginPage
*
* @see https://github.com/react-boilerplate/react-boilerplate/tree/master/docs/testing
*
*/

import React from 'react';
import { render } from 'react-testing-library';
import { IntlProvider } from 'react-intl';
// import 'jest-dom/extend-expect'; // add some helpful assertions

import { LoginPage } from '../index';
import { DEFAULT_LOCALE } from '../../../i18n';

describe('<LoginPage />', () => {
it('Expect to not log errors in console', () => {
const spy = jest.spyOn(global.console, 'error');
const dispatch = jest.fn();
render(
<IntlProvider locale={DEFAULT_LOCALE}>
<LoginPage dispatch={dispatch} />
</IntlProvider>,
);
expect(spy).not.toHaveBeenCalled();
});

it('Expect to have additional unit tests specified', () => {
expect(true).toEqual(false);
});

/**
* Unskip this test to use it
*
* @see {@link https://jestjs.io/docs/en/api#testskipname-fn}
*/
it.skip('Should render and match the snapshot', () => {
const {
container: { firstChild },
} = render(
<IntlProvider locale={DEFAULT_LOCALE}>
<LoginPage />
</IntlProvider>,
);
expect(firstChild).toMatchSnapshot();
});
});
32 changes: 32 additions & 0 deletions client/app/containers/LoginPage/tests/reducer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// import produce from 'immer';
import loginPageReducer from '../reducer';
// import { someAction } from '../actions';

/* eslint-disable default-case, no-param-reassign */
describe('loginPageReducer', () => {
let state;
beforeEach(() => {
state = {
// default state params here
};
});

it('returns the initial state', () => {
const expectedResult = state;
expect(loginPageReducer(undefined, {})).toEqual(expectedResult);
});

/**
* Example state change comparison
*
* it('should handle the someAction action correctly', () => {
* const expectedResult = produce(state, draft => {
* draft.loading = true;
* draft.error = false;
* draft.userData.nested = false;
* });
*
* expect(appReducer(state, someAction())).toEqual(expectedResult);
* });
*/
});
15 changes: 15 additions & 0 deletions client/app/containers/LoginPage/tests/saga.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Test sagas
*/

/* eslint-disable redux-saga/yield-effects */
// import { take, call, put, select } from 'redux-saga/effects';
// import loginPageSaga from '../saga';

// const generator = loginPageSaga();

describe('loginPageSaga Saga', () => {
it('Expect to have unit tests specified', () => {
expect(true).toEqual(false);
});
});
7 changes: 7 additions & 0 deletions client/app/containers/LoginPage/tests/selectors.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// import { selectLoginPageDomain } from '../selectors';

describe('selectLoginPageDomain', () => {
it('Expect to have unit tests specified', () => {
expect(true).toEqual(false);
});
});
9 changes: 9 additions & 0 deletions client/app/containers/RegisterPage/Loadable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
*
* Asynchronously loads the component for RegisterPage
*
*/

import loadable from 'utils/loadable';

export default loadable(() => import('./index'));
Loading

0 comments on commit 1ac7006

Please sign in to comment.