@ -2,46 +2,71 @@ import React, { Component } from 'react';
import Categories from './Categories' ;
import Categories from './Categories' ;
import Category from './Category' ;
import Category from './Category' ;
import Tool from './Tool' ;
import Tool from './Tool' ;
import { Container , Dimmer , Dropdown , Header , Icon , Item , Loader , Menu , Segment , Input } from 'semantic-ui-react' ;
import { Button , Confirm , Container , Dimmer , Form , Header , Icon , Item , Label , L oader , Menu , Message , Segment , Input } from 'semantic-ui-react' ;
import { Link , Route } from 'react-router-dom' ;
import { Link , Route } from 'react-router-dom' ;
import io from 'socket.io-client' ;
import io from 'socket.io-client' ;
// Move to env var
// Move to env var
const SERVER _URL = 'http://localhost:8080' ;
const SOCKET _SERVER _URL = 'http://localhost:8080' ;
const AUTH _SERVER _URL = 'http://localhost:8000' ;
class App extends Component {
class App extends Component {
constructor ( ) {
constructor ( ) {
super ( ) ;
super ( ) ;
this . socket = io ( SERVER _URL ) ;
this . socket = io ( SOCKET _SERVER _URL ) ;
this . storage = typeof localStorage !== 'undefined' ;
let token = this . storage ? localStorage . getItem ( 'token' ) : null ;
this . state = {
this . state = {
login : { token : token , error : null , username : '' , password : '' , confirmLogout : false } ,
user : null ,
user : null ,
toolData : null ,
toolData : null ,
toolStatus : null ,
toolStatus : null ,
connected : false ,
connected : false ,
network : true ,
} ;
} ;
}
}
getUser = ( ) => {
fetch ( AUTH _SERVER _URL + '/user/' , {
headers : { 'Authorization' : 'Token ' + this . state . login . token } ,
} )
. then ( response => {
if ( response . ok ) {
response . json ( ) . then ( data => this . setState ( { user : data [ 0 ] } ) ) ;
} else {
this . handleLogout ( ) ;
}
} )
. catch ( error => {
console . log ( error )
} ) ;
}
componentDidMount ( ) {
componentDidMount ( ) {
fetch ( SERVER _URL + '/api/tooldata' )
fetch ( AUTH _ SERVER_URL + '/tooldata/ ' )
. then ( response => response . json ( ) )
. then ( response => response . json ( ) )
. then ( data => this . setState ( { toolData : data } ) ) ;
. then ( data => this . setState ( { toolData : data } ) )
fetch ( SERVER _URL + '/api/user' )
. catch ( error => {
. then ( response => response . json ( ) )
console . log ( error )
. then ( data => this . setState ( { user : data } ) ) ;
this . setState ( { network : false } ) ;
} ) ;
if ( this . state . login . token ) this . getUser ( ) ;
this . socket . on ( 'toolStatus' , toolStatus =>
this . socket . on ( 'toolStatus' , toolStatus =>
this . setState ( { toolStatus : toolStatus } )
this . setState ( { toolStatus : toolStatus } )
) ;
) ;
this . socket . on ( 'connect' , toolStatus =>
this . socket . on ( 'connect' , ( ) =>
this . setState ( { connected : true } )
this . setState ( { connected : true } )
) ;
) ;
this . socket . on ( 'disconnect' , toolStatus =>
this . socket . on ( 'disconnect' , ( ) => {
this . setState ( { toolStatus : null , connected : false } )
this . setState ( { toolStatus : null , connected : false } ) ;
) ;
} ) ;
}
}
componentWillUnmount ( ) {
componentWillUnmount ( ) {
@ -50,63 +75,161 @@ class App extends Component {
requestInterlock = change => {
requestInterlock = change => {
this . socket . emit ( 'requestInterlock' , {
this . socket . emit ( 'requestInterlock' , {
username : this . state . user . username ,
token : this . state . login . token ,
change : change ,
change : change ,
} ) ;
} ) ;
}
}
handleChange = event => {
const name = event . target . name ;
const value = event . target . value ;
this . setState ( {
login : { ... this . state . login , [ name ] : value }
} ) ;
}
handleSubmit = ( ) => {
const login = this . state . login ;
fetch ( AUTH _SERVER _URL + '/login/' , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json; charset=utf-8' } ,
body : JSON . stringify ( { 'username' : login . username , 'password' : login . password } )
} )
. then ( response => {
if ( response . ok ) {
response . json ( ) . then ( data => {
this . setState ( { login : { ... login , ... data , error : false } } ) ;
if ( this . storage ) localStorage . setItem ( 'token' , data . token ) ;
this . getUser ( ) ;
} ) ;
} else {
this . setState ( { login : { ... login , error : true } } ) ;
}
} )
. catch ( error => {
console . log ( error )
this . setState ( { network : false } ) ;
} ) ;
}
confirmLogout = ( ) => {
if ( this . state . login . token ) {
this . setState ( {
login : { ... this . state . login , confirmLogout : true }
} ) ;
}
}
cancelLogout = ( ) => {
this . setState ( {
login : { ... this . state . login , confirmLogout : false }
} ) ;
}
handleLogout = ( ) => {
this . setState ( {
login : { ... this . state . login , token : null , confirmLogout : false }
} ) ;
localStorage . removeItem ( 'token' ) ;
}
handleRefresh = ( ) => {
window . location . reload ( ) ;
}
render ( ) {
render ( ) {
const login = this . state . login ;
const user = this . state . user ;
const toolData = this . state . toolData ;
const toolData = this . state . toolData ;
const toolStatus = this . state . toolStatus ;
const toolStatus = this . state . toolStatus ;
const user = this . state . user ;
const connected = this . state . connected ;
const connected = this . state . connected ;
const network = this . state . network ;
return (
return (
< div >
network ?
< Menu fixed = 'top' borderless inverted >
< div >
< Menu . Item >
< Menu fixed = 'top' borderless inverted >
< Icon name = 'bars' size = 'big' / >
< Menu . Item onClick = { this . confirmLogout } >
< / M e n u . I t e m >
< Icon name = 'user close' size = 'big' / >
< Menu . Item as = { Link } to = '/' >
< Icon name = 'home' size = 'big' / >
< / M e n u . I t e m >
< Menu . Item >
< Icon name = 'circle' color = { connected ? 'green' : 'red' } / >
< / M e n u . I t e m >
< Menu . Menu position = 'right' >
< Menu . Item position = 'right' >
< Input transparent inverted placeholder = 'Search...' icon = 'search' / >
< / M e n u . I t e m >
< / M e n u . I t e m >
< / M e n u . M e n u >
< Menu . Item as = { Link } to = '/' >
< / M e n u >
< Icon name = 'home' size = 'big' / >
< div style = { { height : '70px' , display : 'inline-block' } } / >
< / M e n u . I t e m >
< Menu . Item >
< Icon name = 'circle' color = { connected && toolStatus ? 'green' : 'red' } / >
{ toolData && user ?
{ connected && toolStatus ? 'Connected' : 'Disconnected' }
< div >
< / M e n u . I t e m >
< Route exact path = '/' render = { props =>
< / M e n u >
< Categories { ... props } data = { toolData } / >
< div style = { { height : '70px' , display : 'inline-block' } } / >
} / >
< Confirm
< Route exact path = '/:category' render = { props =>
open = { login . confirmLogout }
< Category { ... props } data = { toolData } user = { user } / >
header = 'Logout'
} / >
onCancel = { this . cancelLogout }
onConfirm = { this . handleLogout }
< Route exact path = '/:category/:id' render = { props =>
/ >
< Tool { ... props }
data = { toolData }
{ login . token ?
user = { user }
< div >
toolStatus = { toolStatus }
{ toolData && user ?
requestInterlock = { this . requestInterlock }
< div >
/ >
< Route exact path = '/' render = { props =>
} / >
< Categories { ... props } data = { toolData } / >
< / d i v >
} / >
:
< Dimmer active >
< Route exact path = '/:category' render = { props =>
< Loader > Loading < / L o a d e r >
< Category { ... props } data = { toolData } user = { user } / >
< / D i m m e r >
} / >
}
< / d i v >
< Route exact path = '/:category/:slug' render = { props =>
< Tool { ... props }
data = { toolData }
user = { user }
toolStatus = { toolStatus }
requestInterlock = { this . requestInterlock }
/ >
} / >
< / d i v >
:
< Dimmer active >
< Loader > Loading < / L o a d e r >
< / D i m m e r >
}
< / d i v >
:
< Container text >
< Form size = 'large' onSubmit = { this . handleSubmit } >
{ login . error ?
< Message visible error header = 'Invalid username / password!' / >
:
< Message visible warning header = 'Please log in to access the tools!' / >
}
< Form . Field >
< label > Protospace Username < / l a b e l >
< input name = 'username' placeholder = 'Username' value = { login . username } onChange = { this . handleChange } / >
< / F o r m . F i e l d >
< Form . Field >
< label > Password < / l a b e l >
< input name = 'password' type = 'password' value = { login . password } onChange = { this . handleChange } / >
< / F o r m . F i e l d >
< Button type = 'submit' > Submit < / B u t t o n >
< / F o r m >
< / C o n t a i n e r >
}
< / d i v >
:
< Dimmer active >
< Header inverted icon >
< Icon color = 'red' name = 'wifi' / >
Please connect to the "Protospace" wifi
< / H e a d e r >
< br / >
< Button size = 'big' inverted icon labelPosition = 'left' onClick = { this . handleRefresh } >
< Icon name = 'refresh' / >
Refresh
< / B u t t o n >
< / D i m m e r >
) ;
) ;
}
}
}
}