Kaynağa Gözat

changed to new react router version.

Tomi Cvetic 6 yıl önce
ebeveyn
işleme
235f51fa29

+ 73 - 1
client/package-lock.json

@@ -2895,6 +2895,15 @@
       "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
       "dev": true
     },
+    "connected-react-router": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/connected-react-router/-/connected-react-router-4.3.0.tgz",
+      "integrity": "sha512-HUXyhpA2EyOcxKftkrETWwGIsJ/PQ6yjtWMAYPfwqnjVVmMOex0RfkPpub8e+/VAU/XV+DZ62YjFeDvPo6boZw==",
+      "requires": {
+        "immutable": "^3.8.1",
+        "react-router": "^4.2.0"
+      }
+    },
     "console-browserify": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
@@ -5948,6 +5957,18 @@
       "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
       "dev": true
     },
+    "history": {
+      "version": "4.7.2",
+      "resolved": "https://registry.npmjs.org/history/-/history-4.7.2.tgz",
+      "integrity": "sha512-1zkBRWW6XweO0NBcjiphtVJVsIQ+SXF29z9DVkceeaSLVMFXHool+fdCZD4spDCfZJCILPILc3bm7Bc+HRi0nA==",
+      "requires": {
+        "invariant": "^2.2.1",
+        "loose-envify": "^1.2.0",
+        "resolve-pathname": "^2.2.0",
+        "value-equal": "^0.4.0",
+        "warning": "^3.0.0"
+      }
+    },
     "hmac-drbg": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -6510,6 +6531,11 @@
       "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
       "dev": true
     },
+    "immutable": {
+      "version": "3.8.2",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+      "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
+    },
     "import-lazy": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
@@ -10901,6 +10927,43 @@
         "prop-types": "^15.6.0"
       }
     },
+    "react-router": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
+      "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==",
+      "requires": {
+        "history": "^4.7.2",
+        "hoist-non-react-statics": "^2.5.0",
+        "invariant": "^2.2.4",
+        "loose-envify": "^1.3.1",
+        "path-to-regexp": "^1.7.0",
+        "prop-types": "^15.6.1",
+        "warning": "^4.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "path-to-regexp": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+          "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+          "requires": {
+            "isarray": "0.0.1"
+          }
+        },
+        "warning": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.1.tgz",
+          "integrity": "sha512-rAVtTNZw+cQPjvGp1ox0XC5Q2IBFyqoqh+QII4J/oguyu83Bax1apbo2eqB8bHRS+fqYUBagys6lqUoVwKSmXQ==",
+          "requires": {
+            "loose-envify": "^1.0.0"
+          }
+        }
+      }
+    },
     "react-scripts": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.1.4.tgz",
@@ -11579,6 +11642,11 @@
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
       "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
     },
+    "resolve-pathname": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
+      "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
+    },
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -13396,6 +13464,11 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "value-equal": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
+      "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
+    },
     "vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -13444,7 +13517,6 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
       "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
-      "dev": true,
       "requires": {
         "loose-envify": "^1.0.0"
       }

+ 2 - 0
client/package.json

@@ -12,6 +12,7 @@
     "blob": "^0.0.4",
     "body-parser": "^1.17.2",
     "bootstrap": "3",
+    "connected-react-router": "^4.3.0",
     "debug": "^2.6.8",
     "dotenv": "^4.0.0",
     "express": "^4.15.3",
@@ -25,6 +26,7 @@
     "react": "^15.5.4",
     "react-dom": "^15.5.4",
     "react-redux": "^5.0.5",
+    "react-router": "^4.3.1",
     "redux": "^3.6.0",
     "redux-saga": "^0.15.4",
     "request": "^2.81.0",

+ 6 - 21
client/src/Main.js

@@ -1,34 +1,19 @@
-import React from 'react'           // React to manage the GUI
-
-/** Import sub-modules */
-import StartPage from './startPage/components/StartPage'
-import UserList from './users/components/UserList'
-import PlayerList from './playerList/components/PlayerList'       // Everything that has to do with players
-import MatchList from './calendar/components/MatchList'         // Everything that has to do with matches
-import AppLayout from './layout/components/AppLayout'
-import AlertList from './alerts/components/AlertList'
+import React from 'react'
+import Header from './layout/components/Header'
+import Routes from './routes'
 
 /** Import CSS Styles */
 import 'bootstrap/dist/css/bootstrap.min.css'
 import './App.css'
 
-// console.log(layout)
-
 /** Main application */
 class Main extends React.Component {
   render () {
     return (
       <div className='container'>
-        <AppLayout
-          state={this.props}
-          components={{
-            PlayerList,
-            MatchList,
-            StartPage,
-            UserList
-          }}
-        />
-        <AlertList alerts={this.props.alerts} alertsActions={this.props.alertsActions} />
+        {console.log('Main route', this)}
+        <Header />
+        <Routes {...this.props} />
       </div>
     )
   }

+ 33 - 27
client/src/index.js

@@ -8,10 +8,10 @@ import { Provider, connect } from 'react-redux'
 import createSagaMiddleware from 'redux-saga'
 import { all } from 'redux-saga/effects'
 
-/** react-router is not used in this project.
-import { browserHistory, Router, Route, IndexRoute } from 'react-router'
-import { syncHistoryWithStore, routerReducer } from 'react-router-redux'
-*/
+// React router
+import { Route, Switch, Link } from 'react-router'
+import { createBrowserHistory } from 'history'
+import { ConnectedRouter, connectRouter, routerMiddleware } from 'connected-react-router'
 
 // Import the main app
 import Main from './Main'
@@ -23,6 +23,13 @@ import layout from './layout'
 import scraper from './scraper'
 import alerts from './alerts'
 import users from './users'
+import player from './classes/player';
+
+/** 
+ * Browser History
+ */
+const history = createBrowserHistory()
+console.log('history:', history)
 
 /**
  * Redux Section
@@ -86,7 +93,8 @@ const middleware = [
   logger,
   crashReporter,
   alerts.middleware,
-  sagaMiddleware
+  sagaMiddleware,
+  routerMiddleware(history)
 ]
 /** The enhancer allows to use Redux development tools in Chrome */
 // see: https://github.com/zalmoxisus/redux-devtools-extension/issues/220
@@ -110,13 +118,9 @@ if (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) {
 console.log('Enhancers:', enhancer)
 
 /** Build the Redux store from the rootReducer, the defualtState and the enhancers. */
-const store = createStore(rootReducer, defaultState, enhancer)
+const store = createStore(connectRouter(history)(rootReducer), defaultState, enhancer)
 console.log('Store:', store)
 sagaMiddleware.run(rootSaga)
-/** react-route is not used in this project.
-const history = syncHistoryWithStore(browserHistory, store)
-console.log('history:', history)
-*/
 
 /** Collect the action creators from all modules in actionCreators */
 const actionCreators = {
@@ -154,26 +158,15 @@ const App = connect(mapStateToProps, mapDispatchToProps)(Main)
  * React-Router Section
  **/
 
-/** Combine the routes from all modules.
+// Combine the routes from all modules.
 const router = (
   <Provider store={store}>
-    <Router history={history}>
-      <Route component={App}>
-        <Route path='/'>
-          <IndexRoute component={demo_module.components.DemoModule} />
-          <Route path='/project/:projectId' component={project.components.Project} />
-          <Route path='/project' component={project.components.Project} />
-          <Route path='/registermap/:registermapId' component={registermap.components.Registermap} />
-          <Route path='/registermap' component={registermap.components.Registermap} />
-          <Route path='/sample' component={Sample} />
-        </Route>
-        {demo_module.routes}
-        <Route path='/login' />
-      </Route>
-    </Router>
+    <ConnectedRouter history={history}>
+      <App />
+    </ConnectedRouter>
   </Provider>
 )
-*/
+
 const provider = (
   <Provider store={store}>
     <App />
@@ -184,6 +177,19 @@ const provider = (
  * Render the app
  **/
 ReactDOM.render(
-  provider,
+  router,
   document.getElementById('root')
 )
+
+/**
+ * Hot module reloading
+if (module.hot) {
+  module.hot.accept('./App', () => {
+    render()
+  })
+
+  module.hot.accept('./reducers', () => {
+    store.replaceReducer(connectedRouter(history)(rootReducer))
+  })
+}
+ */

+ 0 - 0
client/src/layout/components/Footer.js


+ 24 - 0
client/src/layout/components/Header.js

@@ -0,0 +1,24 @@
+import React from 'react'
+
+class Header extends React.Component {
+    render () {
+        return (
+    <header>
+        <h1>SZTM Helfer</h1>
+        <p>Spiellisten und Zahllisten einfach gemacht</p>
+        <nav>
+            <a>Benutzer</a>
+            <a>Swisstennis</a>
+            <a>Spieler</a>
+            <a>Matches</a>
+            <a>Spielliste</a>
+            <a>Zahlliste</a>
+            <a>SMS</a>
+            <a>Emails</a>
+        </nav>
+    </header>
+        )
+    }
+}
+
+export default Header

+ 23 - 0
client/src/routes.js

@@ -0,0 +1,23 @@
+import React from 'react'
+import { Switch, Route } from 'react-router'
+import UserList from './users/components/UserList'
+import LoginForm from './users/components/LoginForm'
+
+class Routes extends React.Component {
+    render () {
+        return (
+    <main>
+        <Switch>
+            {console.log(this.props)}
+            <Route path='/users' render={() => (<UserList {...this.props}/>)} />
+            <Route path='/login' render={() => (<LoginForm {...this.props}/>)} />
+        </Switch>
+    </main>
+        )
+    }
+}
+/*const Routes = () => (
+    
+)*/
+
+export default Routes

+ 21 - 0
client/src/users/components/LoginForm.js

@@ -0,0 +1,21 @@
+import React from 'react'
+import { FormGroup, ControlLabel, FormControl, HelpBlock } from 'react-bootstrap'
+
+class LoginForm extends React.Component {
+
+  render () {
+      return (
+    <div>
+        <form ref='loginForm' onSubmit={this.handleSubmit}>
+        <label>Benutzername</label>
+        <input type='text' id='username' ref={(input) => {this.username = input}}/>
+        <label>Passwort</label>
+        <input type='password' id='password' ref={(input) => {this.password = input}}/>
+        <input type='submit' />
+        </form>
+    </div>
+      )
+  }
+}
+
+export default LoginForm

+ 81 - 12
client/src/users/components/UserList.js

@@ -1,31 +1,95 @@
 import React from 'react'
+//import bcrypt from 'bcrypt'
 
 class UserList extends React.Component {
   constructor () {
     super()
+    this.loadUser = this.loadUser.bind(this)
+    this.saveUser = this.saveUser.bind(this)
+    this.deleteUser = this.deleteUser.bind(this)
+    this.clearUser = this.clearUser.bind(this)
+    this.handleChange = this.handleChange.bind(this)
+
+    this.state = { user: {
+      _id: null,
+      name: "",
+      username: "",
+      newPassword: ""
+    }}
   }
 
-  render () {
-    const { state, actions } = this.props
-    console.log('UserList waka', state, actions)
+  componentDidMount () {
+    console.log('UserList did mount', this)
+    const { getUserList } = this.props.usersActions
+    getUserList()
+  }
+
+  loadUser (key, event) {
+    this.setState({user: 
+      { ...this.props.users.users[key], 
+        newPassword: "",
+        key
+      }
+    })
+    console.log(this.state, this.props.users.users[key], this.state.user === this.props.users.users[key])
+  }
+
+  saveUser (key, event) {
+    if (this.userid) {
+      // Save existing user
+    } else {
+      // Add new user
+    }
+  }
 
-    let user = null
+  deleteUser (key, event) {
+    console.log(key, event)
+  }
+
+  clearUser (event) {
+    console.log(event)
+    this.setState({user: {
+      _id: null,
+      name: "",
+      username: "",
+      newPassword: ""
+    }})
+  }
+
+  handleChange (event) {
+    console.log(this.name, this.name.value)
+    this.setState({ 
+      user: {
+        ...this.state.user,
+        name: this.name.value,
+        username: this.username.value,
+        newPassword: this.newPassword.value
+      }
+    })
+  }
+
+  render () {
+    const state = this.props.users
+    const actions = this.props.usersActions
+    const { user } = this.state
+    console.log('UserList', this)
 
     return (
       <div>
         <form>
-          <h2>{(user) ? "Benutzer editieren": "Neuer Benutzer"}</h2>
-          {user ? <input type="hidden" key="userid" value={user._id} ref={(input) => {this.name = input}} id="userid"/> : ""}
+          <h2>{(user._id) ? "Benutzer editieren" : "Neuer Benutzer"}</h2>
+          {user._id ? <input type="hidden" key="userid" value={user._id} ref={(input) => {this.userid = input}} id="userid"/> : null}
           <label htmlFor="name">Name</label>
-          <input type="input" ref={(input) => {this.name = input}} id="name"></input>
+          <input type="input" ref={(input) => {this.name = input}} id="name" value={user.name} placeholder="Name" onChange={this.handleChange}></input>
           <label htmlFor="username">Benutzername</label>
-          <input type="input" ref={(input) => {this.username = input}} id="username"></input>
+          <input type="input" ref={(input) => {this.username = input}} id="username" value={user.username} placeholder="Benutzername" onChange={this.handleChange}></input>
           <label htmlFor="password">Passwort</label>
-          <input type="password" ref={(input) => {this.password = input}} id="password"></input>
-          <input type="submit" value={user ? "Aenderungen speichern" : "Benutzer anlegen"} />
+          <input type="password" ref={(input) => {this.newPassword = input}} id="new_password" value={user.newPassword} placeholder="Neues Passwort" onChange={this.handleChange}></input>
+          <input type="submit" value={this.state.user._id ? "Aenderungen speichern" : "Benutzer anlegen"} onClick={(event) => this.loadUser(this.state.user.key, event)} />
+          <input type="reset" value={this.state.user._id ? "Abbrechen" : "Loeschen"} onClick={(event) => this.clearUser(event)} />
         </form>
         <input type="button" onClick={actions.getUserList} value="Aktualisieren" />
-        <table>
+        <table className='table table-bordered table-striped'>
           <thead>
             <tr>
               <th>Name</th><th>Benutzername</th><th>Aktionen</th>
@@ -34,7 +98,12 @@ class UserList extends React.Component {
           <tbody>
             {state.users ? state.users.map((user, key) => 
             <tr key={key}>
-              <td>{user.name}</td><td>{user.username}</td><td><a>editieren</a><a>loeschen</a></td>
+              <td>{user.name}</td>
+              <td>{user.username}</td>
+              <td>
+                <a onClick={(event) => this.loadUser(key, event)}>editieren</a>
+                <a onClick={(event) => this.deleteUser(key, event)}>loeschen</a>
+              </td>
             </tr>
             ) : ""}
           </tbody>

+ 9 - 3
client/src/users/state.js

@@ -65,13 +65,19 @@ export const actions = {
 console.log('State actions', actions)
 
 /** state definition */
+
+// Check, if there is a valid token.
+const token = localStorage.getItem('accessToken')
+const tokenData = JSON.parse(localStorage.getItem('accessTokenData'))
+const tokenValid = tokenData.expires > Date.now()
+
 export const state = {
     loginRequested: false,
     userListRequested: false,
     userListInitialized: false,
     users: [],
-    token: null,
-    tokenData: null
+    token: tokenValid ? token : null,
+    tokenData: tokenValid ? tokenData : null
 }
 console.log('State state', state)
 
@@ -132,7 +138,7 @@ function * getUserList (action) {
                 'Content-Type': 'application/json',
                 'x-access-token': token
             })
-        })
+        }) 
         console.log('Received response')
         const responseJson = yield response.json()
         if (response.status != 200) {