Browse Source

[IMP] auth reducers

Gogs 7 years ago
parent
commit
71176286e1

+ 7 - 6
src/components/common/Base.js

@@ -31,7 +31,7 @@ const styles = theme => ({
 
 class Base extends Component {
     render() {
-        const { classes, app, onHideNotification } = this.props
+        const { notification, spinner, onHideNotification, classes } = this.props
 
         return (
             <div className={classes.root}>
@@ -51,14 +51,14 @@ class Base extends Component {
                     {this.props.children}
                 </main>
                 <Snackbar 
-                    open={app.notification.isOpen} 
+                    open={notification.isVisible} 
                     autoHideDuration={2000} 
                     onClose={onHideNotification} 
-                    message={app.notification.message} 
+                    message={notification.message} 
                 />
                 <Spinner 
-                    open={app.spinner.isOpen}
-                    message={app.spinner.message || 'Cargando, espere...'}
+                    open={spinner.isVisible}
+                    message={spinner.message || 'Cargando, espere...'}
                 />
             </div>
         )
@@ -72,7 +72,8 @@ class Base extends Component {
  */
 const mapStateToProps = (state, props) => {
     return {
-        app: state.app
+        spinner: state.spinner,
+        notification: state.notification
     }
 }
 

+ 1 - 1
src/components/common/Routes.js

@@ -40,7 +40,7 @@ class Routes extends Component {
  */
 const mapStateToProps = (state, props) => {
     return {
-        isAuthenticated: state.app.isAuthenticated
+        isAuthenticated: state.auth.isAuthenticated
     }
 }
 

+ 48 - 16
src/components/pages/Login.js

@@ -5,8 +5,9 @@ import Paper from 'material-ui/Paper'
 import Typography from 'material-ui/Typography'
 import TextField from 'material-ui/TextField'
 import Button from 'material-ui/Button'
+import Snackbar from 'material-ui/Snackbar'
 import { AUTH } from '../../constants/ResourceNames'
-import { post } from '../../actions'
+import { post, notify } from '../../actions'
 import { getToken } from '../../utils/auth'
 import { withStyles } from 'material-ui/styles'
 
@@ -69,14 +70,28 @@ class Login extends Component {
     handleChangeInput = e => {
         this.setState({
             [e.target.id]: e.target.value
-        }, this.handleChangeState)
+        })
     }
 
     /**
      * 
      */
-    handleChangeState = () => {
-        // console.log(this.state)
+    handleSubmit = e => {
+        const { username, password } = this.state
+
+        this.props.submit(e, username, password)
+
+        this.setState({
+            username: '',
+            password: ''
+        }, this.handleFormReset)
+    }
+
+    /**
+     * 
+     */
+    handleFormReset = () => {
+        this.authForm.reset()
     }
 
     /**
@@ -84,8 +99,8 @@ class Login extends Component {
      */
     render() {
         const { from } = this.props.location.state || { from: { pathname: '/' }}
-        const { isAuthenticated, submit, classes } = this.props
-        const { username, password, hasError } = this.state
+        const { isAuthenticated, notification, onHideNotification, classes } = this.props
+        const { hasError } = this.state
 
         if (isAuthenticated) {
             return <Redirect to={from} />
@@ -95,7 +110,7 @@ class Login extends Component {
             <div className={classes.root}>
                 <Paper className={classes.paper} elevation={4}>
                     <Typography className={classes.formHeading} variant='display1' color='primary' align='center'>Eiru Automation</Typography>
-                    <form className={classes.form} noValidate autoComplete='off'>
+                    <form className={classes.form} noValidate autoComplete='off' ref={el => this.authForm = el}>
                         <TextField
                             id='username'
                             className={classes.txtField} 
@@ -112,9 +127,15 @@ class Login extends Component {
                             label='Contraseña' 
                             type='password' 
                         />
-                        <Button className={classes.submitBtn} variant='raised' color='primary' onClick={e => submit(e, username, password)}>Acceder</Button>
+                        <Button className={classes.submitBtn} variant='raised' color='primary' onClick={this.handleSubmit}>Acceder</Button>
                     </form>
                 </Paper>
+                <Snackbar 
+                    open={notification.isVisible} 
+                    autoHideDuration={2000} 
+                    onClose={onHideNotification} 
+                    message={notification.message} 
+                />
             </div>
         )
     }
@@ -127,7 +148,8 @@ class Login extends Component {
  */
 const mapStateToProps = (state, props) => {
     return {
-        isAuthenticated: state.app.isAuthenticated
+        isAuthenticated: state.auth.isAuthenticated,
+        notification: state.notification
     }
 }
 
@@ -137,6 +159,9 @@ const mapStateToProps = (state, props) => {
  * @param {*} props 
  */
 const mapDispatchToProps = (dispatch, props) => ({
+    /**
+     * 
+     */
     check() {
         const token = getToken()
 
@@ -146,14 +171,21 @@ const mapDispatchToProps = (dispatch, props) => ({
 
         dispatch(post(`${AUTH}check_token/`, { token }))
     },
+    /**
+     * 
+     * @param {*} e 
+     * @param {*} username 
+     * @param {*} password 
+     */
     submit(e, username, password) {
-        console.log(username, password)
-
-        dispatch(post(`${AUTH}get_token/`, {
-            username,
-            password
-        }))
-    }
+        dispatch(post(`${AUTH}get_token/`, { username, password }))
+    },
+    /**
+     * 
+     */
+    onHideNotification() {
+        dispatch(notify(null))
+    },
 })
 
 Login = withStyles(styles)(Login)

+ 13 - 13
src/reducers/app.js

@@ -23,7 +23,7 @@ const initialState = {
         isOpen: false,
         message: null
     },
-    isAuthenticated: false
+    isAuthenticated: true
 }
 
 /**
@@ -83,19 +83,19 @@ export const app = (state = initialState, action) => {
         }
     }
 
-    if (isEqual(action.type, REQUEST_KO)) {
-        const status = action.payload.status
+    // if (isEqual(action.type, REQUEST_KO)) {
+    //     const status = action.payload.status
         
-        if (status === 401) {
-            return {
-                ...state,
-                spinner: {
-                    isOpen: false
-                },
-                isAuthenticated: false
-            }
-        }
-    }
+    //     if (status === 401) {
+    //         return {
+    //             ...state,
+    //             spinner: {
+    //                 isOpen: false
+    //             },
+    //             isAuthenticated: false
+    //         }
+    //     }
+    // }
 
     if (isEqual(action.type, SHOW_NOTIFICATION)) {
         state = {

+ 43 - 0
src/reducers/auth.js

@@ -0,0 +1,43 @@
+import { createReducer } from '../utils/reducer'
+import { REQUEST_OK, REQUEST_KO } from '../constants/ActionTypes'
+import { has, isEqual } from 'lodash'
+
+const initialState = {
+    isAuthenticated: false
+}
+
+/**
+ * 
+ * @param {*} state 
+ * @param {*} action 
+ */
+const checkAuthentication = (isAuthenticated, action) => {
+    if (!has(action.payload, 'status')) {
+        return isAuthenticated
+    }
+
+    if (isEqual(action.payload.status, 401)) {
+        return false
+    }
+
+    return isAuthenticated
+}
+
+/**
+ * 
+ */
+const authenticationCheckReducer = createReducer(initialState, {
+    [REQUEST_OK]: checkAuthentication,
+    [REQUEST_KO]: checkAuthentication
+})
+
+/**
+ * 
+ * @param {*} state 
+ * @param {*} action 
+ */
+export const auth = (state = initialState, action) => {
+    return {
+        isAuthenticated: authenticationCheckReducer(state.isAuthenticated, action)
+    }
+}

+ 3 - 1
src/reducers/index.js

@@ -4,6 +4,7 @@ import createBrowserHistory from 'history/createBrowserHistory'
 import ThunkMiddleware from  'redux-thunk'
 import LoggerMiddleware from 'redux-logger'
 
+import { auth } from './auth'
 import { spinner } from './spinner'
 import { notification } from './notification'
 import { app } from './app'
@@ -13,9 +14,10 @@ import { requests } from './requests'
 const history = createBrowserHistory()
 
 const rootReducer = combineReducers({
+    auth,
     spinner,
     notification,
-    app,
+    // app,
     containers,
     requests,
     router: routerReducer

+ 36 - 4
src/reducers/notification.js

@@ -1,5 +1,6 @@
 import { createReducer } from '../utils/reducer'
-import { REQUEST_KO } from '../constants/ActionTypes'
+import { REQUEST_OK, REQUEST_KO, HIDE_NOTIFICATION } from '../constants/ActionTypes'
+import { has, isEqual } from 'lodash'
 
 const initialState = {
     isVisible: false,
@@ -11,16 +12,47 @@ const initialState = {
  * @param {*} state 
  * @param {*} action 
  */
-const setNotificationState = (state, action) => {
+const showNotification = (state, action) => {
+    if (!has(action.payload, 'status')) {
+        return {
+            isVisible: true,
+            message: action.payload.message
+        }
+    }
 
-    return false
+    if (isEqual(action.payload.status, 401)) {
+        if (has(action.payload, 'error_message')) {
+            return {
+                isVisible: true,
+                message: 'Fallo en la autenticación del usuario'
+            }
+        }
+
+        return state
+    }
+
+    return state
+}
+
+/**
+ * 
+ * @param {*} state 
+ * @param {*} action 
+ */
+const hideNotification = (state, action) => {
+    return {
+        isVisible: false,
+        message: null
+    }
 }
 
 /**
  * 
  */
 const notificationReducer = createReducer(initialState, {
-    [REQUEST_KO]: setNotificationState
+    [REQUEST_OK]: showNotification,
+    [REQUEST_KO]: showNotification,
+    [HIDE_NOTIFICATION]: hideNotification
 })
 
 /**

+ 1 - 1
src/reducers/spinner.js

@@ -11,7 +11,7 @@ const initialState = {
  * @param {*} action 
  */
 const setSpinnerVisibility = (visibilityState, action) => {
-    return true
+    return !visibilityState
 }
 
 /**