Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions admin-panel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"history": "^4.7.2",
"immutable": "^3.8.2",
"logger": "^0.0.1",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
Expand Down
10 changes: 9 additions & 1 deletion admin-panel/src/components/auth/SignInForm.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React, { Component } from 'react'
import {reduxForm, Field} from 'redux-form'
import PropTypes from "prop-types"

class SignInForm extends Component {
static propTypes = {

authError: PropTypes.object,
authLoading: PropTypes.bool.isRequired
};

render() {
const {authError, authLoading} = this.props;

return (
<div>
<h3>Sign In</h3>
Expand All @@ -17,6 +21,10 @@ class SignInForm extends Component {
<div>
password: <Field name='password' component='input' type='password'/>
</div>

{authLoading && <p>Loading...</p>}
{authError && <p style={{color: 'red'}}>{authError.message}</p>}

<input type='submit' />
</form>

Expand Down
17 changes: 15 additions & 2 deletions admin-panel/src/components/routes/Admin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React, { Component } from 'react'
import React, { Component } from 'react';
import {Route, NavLink} from 'react-router-dom';
import {connect} from 'react-redux';

import {addUser} from '../../ducks/user';
import NewUserForm from '../../components/user/NewUserForm';

class Admin extends Component {
static propTypes = {
Expand All @@ -9,9 +14,17 @@ class Admin extends Component {
return (
<div>
<h2>Admin Page</h2>
<ul>
<li><NavLink to = '/admin/new-user' activeStyle={{color: 'red'}}>Create user</NavLink></li>
</ul>
<Route path='/admin/new-user' render={() => <NewUserForm onSubmit={this.onAddNewUser} />} />
</div>
)
}

onAddNewUser = ({firstName, lastName, email}) => {
this.props.addUser(firstName, lastName, email);
}
}

export default Admin
export default connect(null, {addUser})(Admin);
15 changes: 12 additions & 3 deletions admin-panel/src/components/routes/auth/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {Route, NavLink} from 'react-router-dom'
import {connect} from 'react-redux'

import {signIn, signUp} from '../../../ducks/auth'
import {errorSelector, loadingSelector} from '../../../ducks/auth'
import SignInForm from '../../auth/SignInForm'
import SignUpForm from '../../auth/SignUpForm'

class Auth extends Component {
static propTypes = {

authError: PropTypes.object,
authLoading: PropTypes.bool.isRequired
};

render() {
const {authLoading, authError} = this.props;

return (
<div>
<h2>Auth page</h2>
<ul>
<li><NavLink to = '/auth/sign-in' activeStyle={{color: 'red'}}>Sign In</NavLink></li>
<li><NavLink to = '/auth/sign-up' activeStyle={{color: 'red'}}>Sign Up</NavLink></li>
</ul>
<Route path='/auth/sign-in' render={() => <SignInForm onSubmit={this.onSignIn}/>} />
<Route path='/auth/sign-in' render={() => <SignInForm onSubmit={this.onSignIn} authError={authError} authLoading={authLoading} />} />
<Route path='/auth/sign-up' render={() => <SignUpForm onSubmit={this.onSignUp}/>} />
</div>
)
Expand All @@ -29,4 +35,7 @@ class Auth extends Component {

}

export default connect(null, { signIn, signUp })(Auth)
export default connect(state => ({
authError: errorSelector(state),
authLoading: loadingSelector(state)
}), { signIn, signUp })(Auth)
50 changes: 50 additions & 0 deletions admin-panel/src/components/user/NewUserForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {reduxForm, Field} from 'redux-form';
import validator from 'email-validator';

import ErrorField from '../common/ErrorField';

class NewUserForm extends Component {
static propTypes = {
handleSubmit: PropTypes.func.isRequired
};

render() {
return (
<div>
<h3>Add user</h3>
<form onSubmit={this.props.handleSubmit}>
<div>
First name: <Field name='firstName' component={ErrorField} />
</div>
<div>
Last name: <Field name='lastName' component={ErrorField} />
</div>
<div>
Email: <Field name='email' component={ErrorField} type='email' />
</div>
<input type='submit' />
</form>

</div>
)
}
}

const validate = ({ firstName, lastName, email }) => {
const errors = {};

if (!email) errors.email = 'Email is a required field';
if (email && !validator.validate(email)) errors.email = 'Incorrect email format';

if (!firstName) errors.firstName = 'First name is a required field';
if (!lastName) errors.lastName = 'Last name is a required field';

return errors;
}

export default reduxForm({
form: 'new-user',
validate
})(NewUserForm)
16 changes: 8 additions & 8 deletions admin-panel/src/config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import firebase from 'firebase'
import firebase from 'firebase';

export const appName = 'advreact-04-12'
export const appName = 'adv-react-8c4fb';

const config = {
apiKey: "AIzaSyCmDWlgYIhtEr1pWjgKYds3iXKWBl9wbjE",
apiKey: "AIzaSyCPlodrXJgpCXqDWklsFc_V5vHGiD6G2Uc",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: "",
messagingSenderId: "95255462276"
}
projectId: {appName},
storageBucket: "adv-react-8c4fb.appspot.com",
messagingSenderId: "47356959167"
};

firebase.initializeApp(config)
firebase.initializeApp(config);
11 changes: 11 additions & 0 deletions admin-panel/src/ducks/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const prefix = `${appName}/${moduleName}`

export const SIGN_IN_START = `${prefix}/SIGN_IN_START`
export const SIGN_IN_SUCCESS = `${prefix}/SIGN_IN_SUCCESS`
export const SIGN_IN_FAILURE = `${prefix}/SIGN_IN_FAILURE`
export const SIGN_UP_START = `${prefix}/SIGN_UP_START`
export const SIGN_UP_SUCCESS = `${prefix}/SIGN_UP_SUCCESS`

Expand All @@ -35,6 +36,10 @@ export default function reducer(state = new ReducerRecord(), action) {
return state
.set('loading', false)
.set('user', payload.user)
case SIGN_IN_FAILURE:
return state
.set('loading', false)
.set('error', payload.error)
default:
return state
}
Expand All @@ -45,6 +50,8 @@ export default function reducer(state = new ReducerRecord(), action) {
* */

export const userSelector = state => state[moduleName].user
export const errorSelector = state => state[moduleName].error
export const loadingSelector = state => state[moduleName].loading

/**
* Action Creators
Expand All @@ -61,6 +68,10 @@ export function signIn(email, password) {
type: SIGN_IN_SUCCESS,
payload: { user }
}))
.catch(error => dispatch({
type: SIGN_IN_FAILURE,
payload: { error }
}))
}
}

Expand Down
57 changes: 57 additions & 0 deletions admin-panel/src/ducks/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {appName} from '../config';
import {Record} from 'immutable';
import firebase from 'firebase';

/**
* Constants
* */
export const moduleName = 'user';
const prefix = `${appName}/${moduleName}`;

export const ADD_USER_START = `${prefix}/ADD_USER_START`;
export const ADD_USER_SUCCESS = `${prefix}/ADD_USER_SUCCESS`;

/**
* Reducer
* */
export const ReducerRecord = Record({
user: null,
loading: false,
error: null
})

export default function reducer(state = new ReducerRecord(), action) {
const {type, payload} = action

switch (type) {
case ADD_USER_START:
return state.set('loading', true)

case ADD_USER_SUCCESS:
return state
.set('loading', false)
.set('user', payload.user)
default:
return state
}
}

/**
* Selectors
* */

export const userSelector = state => state[moduleName].user

/**
* Action Creators
* */

export function addUser(firstName, lastName, email) {
return (dispatch) => {
dispatch({
type: ADD_USER_START
})

console.log('addUser', firstName, lastName, email);
}
}
35 changes: 25 additions & 10 deletions admin-panel/src/redux/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import {createStore, applyMiddleware} from 'redux'
import logger from 'redux-logger'
import {routerMiddleware} from 'react-router-redux'
import thunk from 'redux-thunk'
import reducer from './reducer'
import history from '../history'
import {createStore, applyMiddleware, compose} from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import {routerMiddleware} from 'react-router-redux';

const store = createStore(reducer, applyMiddleware(thunk, routerMiddleware(history), logger))
import reducer from './reducer';
import history from '../history';

//dev only
window.store = store
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose;
/* eslint-enable */

export default store
const enhancer = composeEnhancers(
applyMiddleware(thunk, routerMiddleware(history), logger)
);

const store = createStore(reducer, enhancer);

if (process.env.NODE_ENV !== 'production') {
window.store = store;
}

export default store;