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
2 changes: 2 additions & 0 deletions src/components/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import {Route} from 'react-router-dom'
import AdminPage from './routes/AdminPage'
import AuthPage from './routes/AuthPage'
import PeoplePage from './routes/PeoplePage'
import ProtectedRoute from './common/ProtectedRoute'

class Root extends Component {
Expand All @@ -13,6 +14,7 @@ class Root extends Component {
return (
<div>
<ProtectedRoute path="/admin" component={AdminPage}/>
<Route path="/people" component={PeoplePage}/>
<Route path="/auth" component={AuthPage}/>
</div>
)
Expand Down
6 changes: 3 additions & 3 deletions src/components/auth/SignUpForm.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Component } from 'react'
import {reduxForm, Field} from 'redux-form'
import emailValidator from 'email-validator'
import ErrorField from '../common/ErrorField'
import { getEmailFieldError } from '../../helpers'

class SignUpForm extends Component {
static propTypes = {
Expand All @@ -28,8 +28,8 @@ class SignUpForm extends Component {
const validate = ({email, password}) => {
const errors = {}

if (!email) errors.email = 'email is required'
else if (!emailValidator.validate(email)) errors.email = 'invalid email'
const emailError = getEmailFieldError(email)
if (emailError) errors.email = emailError

if (!password) errors.password = 'password is required'
else if (password.length < 8) errors.password = 'to short'
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/ErrorField.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'

function ErrorField(props) {
const {input, type, meta: {error, touched}} = props
const {input, type, meta: {error, touched}, label} = props
const errorText = touched && error && <div style={{color: 'red'}}>{error}</div>
return (
<div>
<label>{input.name}</label>
<label>{label || input.name}</label>
<input {...input} type={type}/>
{errorText}
</div>
Expand Down
40 changes: 40 additions & 0 deletions src/components/people/NewPersonForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import ErrorField from '../common/ErrorField';
import { getEmailFieldError } from '../../helpers';

class NewPersonForm extends Component {
render() {
return (
<div>
<h2>New Person</h2>
<form onSubmit={this.props.handleSubmit}>
<Field name="firstName" label="First Name" component={ErrorField} />
<Field name="lastName" label="Last Name" component={ErrorField} />
<Field name="email" label="Email" component={ErrorField} />
<input type="submit" />
</form>
</div>
);
}
}

NewPersonForm.propTypes = {};
NewPersonForm.defaultProps = {};

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

if (!firstName) errors.firstName = 'first name is required'
if (!lastName) errors.lastName = 'last name is required'

const emailError = getEmailFieldError(email)
if (emailError) errors.email = emailError

return errors;
}

export default reduxForm({
form: 'newPerson',
validate
})(NewPersonForm);
20 changes: 20 additions & 0 deletions src/components/people/PeopleList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { Component } from 'react';

class PeopleList extends Component {
render() {
const { people } = this.props
return (
<div>
<h2>People List</h2>
{people.map(({id, ...rest}) => (
<div key={id}>{Object.values(rest).join(' ')}</div>
))}
</div>
);
}
}

PeopleList.propTypes = {};
PeopleList.defaultProps = {};

export default PeopleList;
29 changes: 29 additions & 0 deletions src/components/routes/PeoplePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addPerson, moduleName } from '../../ducks/people';
import NewPersonForm from '../people/NewPersonForm';
import PeopleList from '../people/PeopleList';

class PeoplePage extends Component {
handleNewPerson = (person) => {
console.log('---', person);
this.props.addPerson(person)
}

render() {
return (
<div>
<h1>People Page</h1>
<NewPersonForm onSubmit = {this.handleNewPerson}/>
<PeopleList people={this.props.people} />
</div>
);
}
}

PeoplePage.propTypes = {};
PeoplePage.defaultProps = {};

export default connect(state => ({
people: state[moduleName]
}), {addPerson})(PeoplePage);
21 changes: 11 additions & 10 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import firebase from 'firebase'
import firebase from 'firebase';

export const appName = "adv-react";

export const appName = "advreact-21-08"
export const firebaseConfig = {
apiKey: "AIzaSyDjA6CeIHuni5lNm4ML1b-TSxJltsYUO8g",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: `${appName}.appspot.com`,
messagingSenderId: "789814589283"
}
apiKey: "AIzaSyBX5UU94QPTl4P3WaKwTYU-RLMqSzuThAI",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: `${appName}.appspot.com`,
messagingSenderId: "825625171274"
};

firebase.initializeApp(firebaseConfig)
firebase.initializeApp(firebaseConfig);
24 changes: 24 additions & 0 deletions src/ducks/people.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { appName } from '../config';

export const moduleName = 'people'
export const ADD_PERSON = `${appName}/${moduleName}/ADD_PERSON`

export default (state = [], action) => {
const { type, payload } = action

switch (type) {
case ADD_PERSON:
return state.concat({
id: Date.now(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это плохая практика, редюсер должен быть чистой функцией

...payload.person
})

default:
return state
}
};

export const addPerson = (person) => ({
type: ADD_PERSON,
payload: { person }
})
7 changes: 7 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import emailValidator from 'email-validator'

export const getEmailFieldError = (email) => {
if (!email) return 'email is required'
else if (!emailValidator.validate(email)) return 'invalid email'
return null;
};
4 changes: 3 additions & 1 deletion src/redux/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import {combineReducers} from 'redux'
import {routerReducer as router} from 'react-router-redux'
import {reducer as form} from 'redux-form'
import authReducer, {moduleName as authModule} from '../ducks/auth'
import peopleReducer, {moduleName as peopleModule} from '../ducks/people'

export default combineReducers({
router, form,
[authModule]: authReducer
[authModule]: authReducer,
[peopleModule]: peopleReducer
})