-
Notifications
You must be signed in to change notification settings - Fork 14
Homework 2 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Homework 2 #13
Changes from all commits
faeb4c4
061fe7c
86e8bf2
12318ba
bd00972
65e1ed2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,69 @@ | ||
| import React, { Component } from 'react' | ||
| import {Route, NavLink} from 'react-router-dom' | ||
| import {connect} from 'react-redux' | ||
| import firebase from 'firebase' | ||
| import ProtectedRoute from './common/ProtectedRoute' | ||
| import AdminPage from './routes/Admin' | ||
| import AuthPage from './routes/Auth' | ||
| import PersonPage from './routes/PersonPage' | ||
| import Submenu from './common/Submenu' | ||
| import {userAuthorized} from '../ducks/auth' | ||
| import history from '../history' | ||
|
|
||
| class App extends Component { | ||
| static propTypes = { | ||
|
|
||
| }; | ||
|
|
||
| componentDidMount() { | ||
| history.push(this.props.authorized ? '/people' : '/auth/signin') | ||
| } | ||
|
|
||
| render() { | ||
| return ( | ||
| <div> | ||
| <h1>Hello world</h1> | ||
| <ul> | ||
| <li><NavLink to='/admin' activeStyle = {{color: 'red'}}>admin</NavLink></li> | ||
| <li><NavLink to='/people' activeStyle = {{color: 'red'}}>people</NavLink></li> | ||
| </ul> | ||
| {this.renderSubmenu()} | ||
| <ProtectedRoute path = '/admin' component = {AdminPage}/> | ||
| <ProtectedRoute path = '/people' component={PersonPage}/> | ||
| <Route path = '/auth' component = {AuthPage}/> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| renderSubmenu() { | ||
| const links = [] | ||
|
|
||
| if (this.props.authorized) { | ||
| links.push({ | ||
| to: '/admin', | ||
| title: 'Admin', | ||
| }, { | ||
| to: '/people', | ||
| title: 'People', | ||
| }, { | ||
| to: '/logout', | ||
| title: 'Logout', | ||
| }) | ||
| } | ||
| else { | ||
| links.push({ | ||
| to: '/auth/signin', | ||
| title: 'Sign in', | ||
| }, { | ||
| to: '/auth/signup', | ||
| title: 'Sign up', | ||
| }) | ||
| } | ||
|
|
||
| const props = { | ||
| links, | ||
| } | ||
|
|
||
| return <Submenu {...props} /> | ||
| } | ||
| } | ||
|
|
||
| export default App | ||
| export default connect(state => ({ | ||
| authorized: userAuthorized(state) | ||
| }), null, null, { pure: false })(App) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь pure: false не нужен |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,15 @@ class SignIn extends Component { | |
|
|
||
| }; | ||
|
|
||
| shouldComponentUpdate(nextProps) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. вот этого совсем не понял |
||
| if (nextProps.shouldReset) { | ||
| this.props.reset() | ||
| return false | ||
| } | ||
|
|
||
| return true | ||
| } | ||
|
|
||
| render() { | ||
| return ( | ||
| <div> | ||
|
|
@@ -20,12 +29,23 @@ class SignIn extends Component { | |
| <div> | ||
| <input type = 'submit'/> | ||
| </div> | ||
| {this.renderError()} | ||
| </form> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| renderError() { | ||
| const { signInError } = this.props | ||
|
|
||
| if (!signInError) { | ||
| return null | ||
| } | ||
|
|
||
| return <p className="error">{signInError}</p> | ||
| } | ||
| } | ||
|
|
||
| export default reduxForm({ | ||
| form: 'auth' | ||
| })(SignIn) | ||
| })(SignIn) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import React, { Component } from 'react' | ||
| import { NavLink } from 'react-router-dom' | ||
|
|
||
| class Submenu extends Component { | ||
| render() { | ||
| return ( | ||
| <nav className="submenu"> | ||
| {this.props.links.map(this.renderSubmenuItem.bind(this))} | ||
| </nav> | ||
| ) | ||
| } | ||
|
|
||
| renderSubmenuItem(item, index) { | ||
| const { to, title } = item | ||
|
|
||
| const props = { | ||
| key: index, | ||
| activeClassName: 'active', | ||
| to, | ||
| } | ||
|
|
||
| return ( | ||
| <NavLink {...props}> | ||
| {title} | ||
| </NavLink> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default Submenu |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,12 @@ | ||
| import firebase from 'firebase' | ||
|
|
||
| export const appName = 'advreact-1610' | ||
| export const appName = 'advreact-1610-9cb0c' | ||
|
|
||
| firebase.initializeApp({ | ||
| apiKey: "AIzaSyB31xpTtp4Jln_hb2kAbE4PGf6Mi8EgLyA", | ||
| apiKey: "AIzaSyBNaOQkLL75ZGoeaNtqbe63wEjjWLzLOPY", | ||
| authDomain: `${appName}.firebaseapp.com`, | ||
| databaseURL: `https://${appName}.firebaseio.com`, | ||
| projectId: appName, | ||
| storageBucket: "", | ||
| messagingSenderId: "397157634637" | ||
| messagingSenderId: "266748171955" | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import {Record} from 'immutable' | |
| import firebase from 'firebase' | ||
| import {createSelector} from 'reselect' | ||
| import {call, put, all, take} from 'redux-saga/effects' | ||
| import history from '../history' | ||
|
|
||
| /** | ||
| * Constants | ||
|
|
@@ -14,7 +15,10 @@ export const SIGN_UP_START = `${prefix}/SIGN_UP_START` | |
| export const SIGN_UP_SUCCESS = `${prefix}/SIGN_UP_SUCCESS` | ||
| export const SIGN_UP_ERROR = `${prefix}/SIGN_UP_ERROR` | ||
|
|
||
| export const SIGN_IN_START = `${prefix}/SIGN_IN_START` | ||
| export const SIGN_IN_SUCCESS = `${prefix}/SIGN_IN_SUCCESS` | ||
| export const SIGN_IN_ERROR = `${prefix}/SIGN_IN_ERROR` | ||
|
|
||
|
|
||
| /** | ||
| * Reducer | ||
|
|
@@ -30,14 +34,23 @@ export default function reducer(state = new ReducerRecord(), action) { | |
|
|
||
| switch (type) { | ||
| case SIGN_UP_START: | ||
| return state.set('loading', true) | ||
| case SIGN_IN_START: | ||
| return state | ||
| .set('loading', true) | ||
| .set('error', null) | ||
|
|
||
| case SIGN_UP_SUCCESS: | ||
| case SIGN_IN_SUCCESS: | ||
| return state | ||
| .set('user', payload.user) | ||
| .set('loading', false) | ||
|
|
||
| case SIGN_UP_ERROR: | ||
| case SIGN_IN_ERROR: | ||
| return state | ||
| .set('error', payload.error) | ||
| .set('loading', false) | ||
|
|
||
| default: | ||
| return state | ||
| } | ||
|
|
@@ -49,6 +62,8 @@ export default function reducer(state = new ReducerRecord(), action) { | |
|
|
||
| export const stateSelector = state => state[moduleName] | ||
| export const userSelector = createSelector(stateSelector, state => state.user) | ||
| export const userAuthorized = createSelector(stateSelector, state => !!state.user) | ||
| export const errorMessage = createSelector(stateSelector, state => state.error && state.error.message || '') | ||
|
|
||
| /** | ||
| * Action Creators | ||
|
|
@@ -60,6 +75,13 @@ export function signUp(email, password) { | |
| } | ||
| } | ||
|
|
||
| export function signIn(email, password) { | ||
| return { | ||
| type: SIGN_IN_START, | ||
| payload: { email, password } | ||
| } | ||
| } | ||
|
|
||
| firebase.auth().onAuthStateChanged(user => { | ||
| if (!user) return | ||
|
|
||
|
|
@@ -96,8 +118,35 @@ export function * signUpSaga() { | |
| } | ||
| } | ||
|
|
||
| export function * signInSaga() { | ||
| const auth = firebase.auth() | ||
|
|
||
| while (true) { | ||
| const action = yield take(SIGN_IN_START) | ||
| const { email, password } = action.payload | ||
|
|
||
| try { | ||
| const user = yield call([auth, auth.signInWithEmailAndPassword], email, password) | ||
|
|
||
| yield put({ | ||
| type: SIGN_IN_SUCCESS, | ||
| payload: {user}, | ||
| }) | ||
|
|
||
| yield call([history, history.push], '/people') | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. возьми push как AC из react-router-redux, сделай put |
||
| } | ||
| catch (error) { | ||
| yield put({ | ||
| type: SIGN_IN_ERROR, | ||
| payload: {error}, | ||
| }) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export function * saga() { | ||
| yield all([ | ||
| signUpSaga() | ||
| signUpSaga(), | ||
| signInSaga(), | ||
| ]) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
а если статус может(и будет) позже меняться. Стоило делать в утке