diff --git a/public/index.html b/public/index.html index dd1ccfd4cd30a29aaa08b295d99be29cdeb29cf9..624e8a0d931011a538149b4b305ddba45719f1d1 100644 --- a/public/index.html +++ b/public/index.html @@ -23,6 +23,7 @@ </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> + <div id="form"></div> <div id="root"></div> <!-- This HTML file is a template. diff --git a/src/App.css b/src/App.css index b0f08dddfc38b5c27752c025dbfe8113491b93d2..dd6464757b7cba9f96157c84695c6e0fca4db7dc 100644 --- a/src/App.css +++ b/src/App.css @@ -51,7 +51,7 @@ div.header button:hover { div.fade-main { position: fixed; top: 0; - z-index: 1000; + z-index: 1020; height: 100vh; width: 100vw; margin: auto; @@ -138,3 +138,20 @@ div.login button:hover { background-color: darkblue; cursor: pointer; } + +.login .formDate { + width: 30%; +} + +.login label.formDate { + color: white; + width: 10%; + margin-left: 10%; + font-size: 180%; +} + +.login .formTime { + width: 30%; + margin-right: 20%; +} + diff --git a/src/App.js b/src/App.js index 7342088361a7e2c36e0cf4cd71d5a6b7e269817b..a7f472449d5ddaf41c517bc9b63b969e042843c7 100644 --- a/src/App.js +++ b/src/App.js @@ -31,6 +31,7 @@ class App extends Component { <div> <UserMap position={initialPosition} zoom={this.state.zoom} mapUrl={this.state.mapUrl} />, <Header handleLayerChange={this.handleLayerChange} /> + </div> ); } diff --git a/src/components/Header.js b/src/components/Header.js index 4470acded0097b3d3b6252af0effd9dbb578064e..49152eb42ac5a1b62098ffeee278301bb6b4263d 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -3,21 +3,19 @@ import React from 'react'; import LoginForm from './LoginForm'; import RegisterForm from './RegisterForm'; import GameList from './GameList'; +import NewGameForm from './NewGameForm'; class Header extends React.Component { state = { - login: false, - register: false, + form: "", // Popup form (login, register etc.) username: null, token: null }; // toggles the login/register view toggleView = view => { - this.setState(prevState => { - return { - [view]: view === 'login' ? !prevState.login : !prevState.register - }; + this.setState({ + form: view }); }; @@ -36,7 +34,7 @@ class Header extends React.Component { componentDidMount() { let token = sessionStorage.getItem('token'); if (token) { - fetch('http://localhost:5000/user/verify', { + fetch('http://172.20.2.143:5000/user/verify', { headers: { Authorization: 'Bearer ' + token } @@ -74,6 +72,9 @@ class Header extends React.Component { {!this.state.username && ( <button onClick={() => this.toggleView('login')}>login</button> )} + {this.state.username && ( + <button onClick={() => this.toggleView('newgame')}>New Game</button> + )} {this.state.username && ( <button onClick={this.handleLogout}>logout</button> )} @@ -81,16 +82,23 @@ class Header extends React.Component { <button onClick={this.props.handleLayerChange}>change layer</button> <GameList /> </div> - {this.state.register && ( + {this.state.form === 'register' && ( <RegisterForm - view='register' + view='' handleState={this.handleState} toggleView={this.toggleView} /> )} - {this.state.login && ( + {this.state.form === 'login' && ( <LoginForm - view='login' + view='' + handleState={this.handleState} + toggleView={this.toggleView} + /> + )} + {this.state.form === 'newgame' && ( + <NewGameForm + view='' handleState={this.handleState} toggleView={this.toggleView} /> diff --git a/src/components/NewGameForm.js b/src/components/NewGameForm.js new file mode 100644 index 0000000000000000000000000000000000000000..3dcf6a585e2bb08e3ca31ba1df46ca28a8f25387 --- /dev/null +++ b/src/components/NewGameForm.js @@ -0,0 +1,191 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { + Map, + TileLayer, + ZoomControl, + Marker, + Popup +} from 'react-leaflet' + +export class NewGameForm extends React.Component{ + constructor(props){ + super(props); + + this.state = { + gamename: "", + description: "", + startDate: "", + startTime: "", + endDate: "", + endTime: "", + passwords: [], + zoom: 13, + mapCenter: { + lat: 62.2416479, + lng: 25.7597186 + } + } + + this.handleMapDrag = this.handleMapDrag.bind(this); + } + + handleError = error => { + this.setState({ errorMsg: error }); + }; + + handleChange = e => { + const { name, value } = e.target; + this.setState({ [name]: value }); + }; + + // show/hide this form + handleView = e => { + this.props.toggleView(this.props.view); + }; + + // remove view with ESC + handleEsc = e => { + if (e.keyCode === 27) { + this.handleView(); + } + }; + + handleMapDrag = e => { + this.setState({ + mapCenter: e.target.getCenter() + }); + } + + handleMapScroll = e => { + this.setState({ + zoom: e.target.getZoom() + }); + } + + handleGameCreation = e => { + let startDate = new Date(this.state.startDate + " " + this.state.startTime); + let endDate = new Date(this.state.endDate + " " + this.state.endTime); + + const gameObject = { + name: this.state.gamename, + desc: this.state.description, + map: "", //TODO: map json + startdate: startDate.toISOString(), + enddate: endDate.toISOString(), + passwords: [this.state.password], + center: this.state.mapCenter + } + + e.preventDefault(); + + let token = sessionStorage.getItem('token'); + + // Send Game info to the server + fetch('http://localhost:5000/game/new', { + method: 'POST', + headers: { + Authorization: 'Bearer ' + token, + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(gameObject) + }).then(res => res.json()) + .then(result => { + this.handleView(); + }) + .catch(error => console.log('Error: ', error)); + }; + + componentDidMount() { + document.addEventListener('keyup', this.handleEsc); + } + + componentWillUnmount() { + document.removeEventListener('keyup', this.handleEsc); + } + + render() { + return ReactDOM.createPortal ( + <div className='fade-main'> + <div className='sticky'> + <span className='close' onClick={this.handleView}> + × + </span> + </div> + <div className=''> + <form onSubmit={this.handleGameCreation}> + <h1>Demo Game Creation</h1> + <br /> + <input + placeholder='Game name' + name='gamename' + value={this.state.gamename} + onChange={this.handleChange} + required + /> + <br /> + <input + placeholder='Description' + type='text' + name='description' + value={this.state.description} + onChange={this.handleChange} + required + /> + <br /> + <label className=''>Start:</label> + <input + className='formDate' + type='date' + name='startDate' + value={this.state.startDate} + onChange={this.handleChange} + required + /> + <input + className='formTime' + type='time' + name='startTime' + onChange={this.handleChange} + required + /> + <br /> + <label className=''>End:</label> + <input + className='formDate' + type='date' + name='endDate' + value={this.state.endDate} + onChange={this.handleChange} + min={this.state.startDate} + required + /> + <input + className='formTime' + type='time' + name='endTime' + onChange={this.handleChange} + required + /> + <br /> + <label>Map things</label> + <br /> + <Map className='' center={[this.state.mapCenter.lat, this.state.mapCenter.lng]} zoom={this.state.zoom} style={{height: '400px', width: '400px'} } onmoveend={this.handleMapDrag} onzoomend={this.handleMapScroll}> + <TileLayer + attribution='Maanmittauslaitoksen kartta' + url=' https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg' + /> + </Map> + <br /> + <button type='submit'>Submit</button> + <h2>{this.state.errorMsg}</h2> + </form> + </div> + </div> + ,document.getElementById('form') + ); + } +} + +export default NewGameForm; \ No newline at end of file