diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..2badae6b3fc04489905ce10c5ef15eb8f857f035
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+REACT_APP_API_URL="http://localhost:5000"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f21726c760680e64debfd1abbf4924a22e1fb12c..1787a6ddbfe06e31c9fed57c218ca390b70d5766 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
 
 # misc
 .DS_Store
+.env
 .env.local
 .env.development.local
 .env.test.local
diff --git a/public/favicon.ico b/public/favicon.ico
index a11777cc471a4344702741ab1c8a588998b1311a..024bc75ef8673d4c4be9d578c42c05be84569963 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a72cfc2ec3abcdf83a52fd53644a13f9844d6224
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/index.html b/public/index.html
index dd1ccfd4cd30a29aaa08b295d99be29cdeb29cf9..8b2f9d1cb04b63987cab6a5b0645beb0aeafff57 100644
--- a/public/index.html
+++ b/public/index.html
@@ -19,11 +19,12 @@
       work correctly both with client-side routing and a non-root public URL.
       Learn how to configure a non-root public URL by running `npm run build`.
     -->
-    <title>React App</title>
+    <title>TACS</title>
   </head>
   <body>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <div id="root"></div>
+    <div id="form"></div>
     <!--
       This HTML file is a template.
       If you open it directly in the browser, you will see an empty page.
diff --git a/src/App.css b/src/App.css
index b0f08dddfc38b5c27752c025dbfe8113491b93d2..7d7f9508468c0da993d1991880bbf8fde6c93677 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;
@@ -60,22 +60,22 @@ div.fade-main {
 }
 
 div.sticky {
-    position: fixed;
-    top: 0px;
-    right: 0px;
-    height: 100px;
-    width: 100px;
-    margin-right: 150px;
+  position: fixed;
+  top: 0px;
+  right: 0px;
+  height: 100px;
+  width: 100px;
+  margin-right: 150px;
 }
 
 .close {
-    position: fixed;
-    color: #f1f1f1;
-    height: 85px;
-    font-size: 100px;
-    font-weight: bold;
-    transition: transform 0.4s ease-in-out;
-    line-height: 70%;
+  position: fixed;
+  color: #f1f1f1;
+  height: 85px;
+  font-size: 100px;
+  font-weight: bold;
+  transition: transform 0.4s ease-in-out;
+  line-height: 70%;
 }
 
 .close:hover,
@@ -138,3 +138,62 @@ 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%;
+}
+
+/* Editing text button in the toolbar */
+.leaflet-draw-toolbar .leaflet-draw-draw-textbox {
+  background-image: url("icons/button-textbox.png");
+  background-size: 30px 30px;
+}
+
+/* Editing tooltips */
+.leaflet-tooltip {
+  font-size: 18px;
+  /* Overriding tooltip layout by making it invisible */
+  background-color: transparent;
+  box-shadow: none;
+  border: none;
+  padding: 0;
+}
+
+/* remove the small triangle on tooltip */
+.leaflet-tooltip-bottom:before {
+  border: 0;
+}
+
+/* Editing editable tooltips */
+.editable {
+  display: block;
+  cursor: text; /* the cursor icon doesn't change by default when hovering on top of the text; overriding */
+  min-width: 154px;
+  min-height: 18px;
+  color: #fff;
+  font-weight: bold;
+  /* text borders */
+  text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000,
+    1px 1px 0 #000;
+}
+
+/* placeholder text for tooltip */
+[contenteditable="true"]:empty:before {
+  content: attr(placeholder);
+  display: block; /* For Firefox */
+  color: #777;
+  text-shadow: none;
+  font-weight: normal;
+}
diff --git a/src/App.js b/src/App.js
index 7342088361a7e2c36e0cf4cd71d5a6b7e269817b..b2d8e87008ca309f10a6c6f85a8211ea6b313321 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,36 +1,62 @@
-import React, { Component } from 'react';
-import '../node_modules/leaflet-draw/dist/leaflet.draw.css'
-import './App.css';
-import UserMap from './components/UserMap';
-import Header from './components/Header';
+import React, { Component } from "react";
+import "../node_modules/leaflet-draw/dist/leaflet.draw.css";
+import "./App.css";
+import UserMap from "./components/UserMap";
+import Header from "./components/Header";
 
 class App extends Component {
   constructor() {
     super();
 
-    
     // set initial state
     this.state = {
       lat: 62.2416479,
       lng: 25.7597186,
       zoom: 13,
-      mapUrl: 'https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg'
+      mapUrl: "https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg",
+      currentGameId: null
     };
 
     this.handleLayerChange = this.handleLayerChange.bind(this);
+    this.handleGameChange = this.handleGameChange.bind(this);
   }
   // Toggles through the list and changes the mapUrl state
   handleLayerChange = () => {
-    const maps = ['https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg', 'https://tiles.kartat.kapsi.fi/peruskartta/{z}/{x}/{y}.jpg','https://tiles.kartat.kapsi.fi/ortokuva/{z}/{x}/{y}.jpg'];
-    this.setState({mapUrl: maps.indexOf(this.state.mapUrl) < maps.length - 1 ? maps[maps.indexOf(this.state.mapUrl) + 1] : maps[0]})
+    const maps = [
+      "https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg",
+      "https://tiles.kartat.kapsi.fi/peruskartta/{z}/{x}/{y}.jpg",
+      "https://tiles.kartat.kapsi.fi/ortokuva/{z}/{x}/{y}.jpg"
+    ];
+    this.setState({
+      mapUrl:
+        maps.indexOf(this.state.mapUrl) < maps.length - 1
+          ? maps[maps.indexOf(this.state.mapUrl) + 1]
+          : maps[0]
+    });
+  };
+
+  // function to be sent to Header -> GameList to get changed game ID
+  handleGameChange = gameId => {
+    this.setState({
+      currentGameId: gameId
+    });
   };
 
   render() {
     const initialPosition = [this.state.lat, this.state.lng];
     return (
       <div>
-        <UserMap position={initialPosition} zoom={this.state.zoom} mapUrl={this.state.mapUrl} />,
-        <Header handleLayerChange={this.handleLayerChange} />       
+        <UserMap
+          position={initialPosition}
+          zoom={this.state.zoom}
+          mapUrl={this.state.mapUrl}
+          currentGameId={this.state.currentGameId}
+        />
+        ,
+        <Header
+          handleLayerChange={this.handleLayerChange}
+          handleGameChange={this.handleGameChange}
+        />
       </div>
     );
   }
diff --git a/src/components/DrawTools.js b/src/components/DrawTools.js
index 0fbf85c1f2ad0fdf391b0b07dcee8350363e3fad..3de6eddbc6bd7478d33e7b8c49daeb2885646aca 100644
--- a/src/components/DrawTools.js
+++ b/src/components/DrawTools.js
@@ -1,79 +1,397 @@
-import React, {Component} from 'react';
-import { EditControl } from "react-leaflet-draw"
+import React, { Component } from "react";
+import { EditControl } from "react-leaflet-draw";
+import L from "leaflet";
+import "leaflet-draw";
 import {
-	FeatureGroup,
-} from 'react-leaflet'
+  FeatureGroup,
+  Circle,
+  Marker,
+  Polygon,
+  Polyline,
+  Rectangle,
+  Tooltip
+} from "react-leaflet";
+
+// an empty icon for textboxes
+let noIcon = L.divIcon({
+  className: "",
+  iconSize: [20, 20],
+  iconAnchor: [10, 20]
+});
+
+// class for text field
+L.Draw.MarkerTextBox = L.Draw.Marker.extend({
+  options: {
+    icon: noIcon,
+    repeatMode: false,
+    interactive: true
+  },
+  initialize: function(map, options) {
+    this.type = "textbox"; // important to have a unique type, so that it won't get mixed up with other elements
+    this.featureTypeCode = "textbox";
+    L.Draw.Feature.prototype.initialize.call(this, map, options);
+  }
+});
+
+// Overriding default toolbar
+// Just adding one new button though lol
+L.DrawToolbar.include({
+  getModeHandlers: function(map) {
+    return [
+      {
+        enabled: this.options.polyline,
+        handler: new L.Draw.Polyline(map, this.options.polyline),
+        title: L.drawLocal.draw.toolbar.buttons.polyline
+      },
+      {
+        enabled: this.options.polygon,
+        handler: new L.Draw.Polygon(map, this.options.polygon),
+        title: L.drawLocal.draw.toolbar.buttons.polygon
+      },
+      {
+        enabled: this.options.rectangle,
+        handler: new L.Draw.Rectangle(map, this.options.rectangle),
+        title: L.drawLocal.draw.toolbar.buttons.rectangle
+      },
+      {
+        enabled: this.options.circle,
+        handler: new L.Draw.Circle(map, this.options.circle),
+        title: L.drawLocal.draw.toolbar.buttons.circle
+      },
+      {
+        enabled: this.options.marker,
+        handler: new L.Draw.Marker(map, this.options.marker),
+        title: L.drawLocal.draw.toolbar.buttons.marker
+      },
+      {
+        enabled: this.options.marker,
+        handler: new L.Draw.MarkerTextBox(map, this.options.marker),
+        title: "Write text"
+      }
+    ];
+  }
+});
 
 class DrawTools extends Component {
-	constructor(props){
-	  super(props);
-	  this.state = {
-		  geoJSONAll: [] // property for all GeoJSON data in the map
-	  }
+  constructor(props) {
+    super(props);
+    this.state = {
+      geoJSONAll: [], // property for all GeoJSON data in the map
+      editModeActive: false
+    };
+  }
+
+  _onCreated = e => {
+    // check if a drawn polyline has just one point in it
+    if (e.layerType === "polyline" && e.layer.getLatLngs().length === 1) {
+      e.layer.remove();
+      return;
+    }
+
+    if (e.layerType === "textbox") {
+      // have to create tooltip as a DOM element to allow text selecting. maybe
+      let tooltip = L.DomUtil.create("div", "editable");
+
+      // need ids for tooltips to be able to add a blur event to them
+      tooltip.innerHTML =
+        '<div contenteditable="true" placeholder="Click out to save" id="' +
+        e.layer._leaflet_id +
+        '"></div>';
+
+      e.layer.bindTooltip(tooltip, {
+        permanent: true,
+        direction: "bottom",
+        interactive: true
+      });
+
+      // disable dragging when cursor is over marker (tooltip)
+      // clicking on tooltip fires the marker's click handler, hence e.layer.on
+      e.layer.on("mouseover", function() {
+        e.layer._map.dragging.disable();
+      });
+
+      // enable dragging again when cursor is out of marker (tooltip)
+      e.layer.on("mouseout", function() {
+        e.layer._map.dragging.enable();
+      });
+
+      // show placeholder text again upon emptying textbox
+      e.layer.on("keyup", function() {
+        // when the text area is emptied, a <br> appears
+        // manually removing it so that the placeholder text can show
+        if (
+          tooltip.innerHTML ===
+            '<div placeholder="Click out to save" contenteditable="true" id ="' +
+              e.layer._leaflet_id +
+              "><br></div>" ||
+          tooltip.innerHTML ===
+            '<div placeholder="Click out to save" contenteditable="true" id ="' +
+              e.layer._leaflet_id +
+              "><div><br></div></div>"
+        ) {
+          tooltip.innerHTML =
+            '<div placeholder="Click out to save" contenteditable="true" id ="' +
+            e.layer._leaflet_id +
+            "></div>";
+        }
+      });
+
+      // blur event listener can't be given straight to a layer
+      // getting element by ID and adding an event listener to the element
+      document
+        .getElementById(e.layer._leaflet_id)
+        .addEventListener(
+          "blur",
+          this.makeGeoJSON.bind(this, e.layerType, e.layer)
+        ); // can't put this.makeGeoJSON(e) straight, as it calls the function
+      document.getElementById(e.layer._leaflet_id).focus();
+
+      console.log(e.layer);
+
+      return; // only sending the textbox to database until text has been written
+    } // end if (e.layerType === "textbox")
+
+    this.makeGeoJSON(e.layerType, e.layer);
+  }; // end _onCreated
+
+  // turn layer to GeoJSON data
+  makeGeoJSON = (layerType, layer) => {
+    // setting the format in which the data will be sent
+    let geoJSON = {
+      data: layer.toGeoJSON(),
+      mapDrawingId: layer.options.id
+    };
+
+    // setting properties
+    if (layerType === "textbox") {
+      if (layer._tooltip._content.innerText) {
+        geoJSON.data.properties.text = layer._tooltip._content.innerText;
+      } else {
+        return;
+      }
+    } else if (layerType === "circle") {
+      geoJSON.data.properties.radius = layer._mRadius; // layer.options.radius doesn't update for some reason; need to use _mRadius instead
+    } else if (layerType === "rectangle") {
+      // rectangle is a simple true/false property to recognize a rectangle
+      // so that Polygons with this property can be inserted into map with rectangle functionalities instead of Polygon's
+      geoJSON.data.properties.rectangle = true;
+    }
+    geoJSON.data.properties.color = layer.options.color;
+
+    // send item to database, and receive an ID for the layer
+    this.props.sendGeoJSON(geoJSON, false);
+  };
+
+  _onEditDeleteStart = () => {
+    this.setState({ editModeActive: true });
+  };
+
+  _onEditDeleteStop = () => {
+    this.setState({ editModeActive: false });
+  };
+
+  _onEdited = e => {
+    // layers are saved in a rather curious format. they're not in an array, so need to make an array first
+    let editedLayers = e.layers;
+    let idsToEdit = [];
+    editedLayers.eachLayer(function(layer) {
+      idsToEdit.push(layer);
+    });
+
+    idsToEdit.map(layer => {
+      // checking the contents of the layer to determine its type, as it's not explicitly stated
+      if (layer.options.bounds) {
+        this.makeGeoJSON("rectangle", layer);
+      } else if (layer.options.radius) {
+        this.makeGeoJSON("circle", layer);
+      } else if (layer.options.text) {
+        this.makeGeoJSON("textbox", layer);
+      } else {
+        this.makeGeoJSON(null, layer);
+      }
+    });
+  };
+
+  _onDeleted = e => {
+    // layers are saved in a rather curious format. they're not in an array, so need to make an array first
+    let deletedLayers = e.layers;
+    let idsToDelete = [];
+    deletedLayers.eachLayer(function(layer) {
+      idsToDelete.push(layer);
+    });
+
+    idsToDelete.map(layer => {
+      let geoJSON = {
+        data: layer.toGeoJSON(),
+        mapDrawingId: layer.options.id
+      };
+
+      this.props.sendGeoJSON(geoJSON, true);
+    });
+  };
+
+  shouldComponentUpdate() {
+    // disable re-rendering when edit mode is active
+    return !this.state.editModeActive;
+  }
+
+  render() {
+    return (
+      // "It's important to wrap EditControl component into FeatureGroup component from react-leaflet.
+      // The elements you draw will be added to this FeatureGroup layer,
+      // when you hit edit button only items in this layer will be edited."
+      <FeatureGroup>
+        <EditControl
+          position="topright"
+          onCreated={this._onCreated}
+          onEdited={this._onEdited}
+          onEditStart={this._onEditDeleteStart}
+          onEditStop={this._onEditDeleteStop}
+          onDeleted={this._onDeleted}
+          onDeleteStart={this._onEditDeleteStart}
+          onDeleteStop={this._onEditDeleteStop}
+          draw={{
+            circle: {
+              repeatMode: false, // allows using the tool again after finishing the previous shape
+              shapeOptions: {
+                color: "#f9f10c",
+                opacity: 1 // affects the outline only. for some reason it wasn't at full opacity, so this is needed for more clarity
+              }
+            },
+            rectangle: {
+              repeatMode: false
+            },
+            polygon: {
+              repeatMode: true,
+              allowIntersection: false, // Restricts shapes to simple polygons
+              drawError: {
+                color: "#e1e100", // Color the shape will turn when intersects
+                message: "<strong>Oh snap!<strong> you can't draw that!" // Message that will show when intersect
+              },
+              shapeOptions: {
+                color: "#ed2572",
+                opacity: 1
+              }
+            },
+            polyline: {
+              repeatMode: true,
+              shapeOptions: {
+                color: "#ed2572",
+                opacity: 1
+              }
+            },
+            marker: {
+              repeatMode: false
+            },
+            circlemarker: false
+          }}
+        />
+
+        {/* iterate through every element fetched from back-end */}
+        {this.props.geoJSONLayer.features.map(feature => {
+          let id = feature.mapDrawingId;
+          let coords = feature.data.geometry.coordinates;
+          let type = feature.data.geometry.type;
+          let color = feature.data.properties.color;
+          let radius = feature.data.properties.radius;
+          let text = feature.data.properties.text;
+          let rectangle = feature.data.properties.rectangle;
+
+          if (type === "Point") {
+            // GeoJSON saves latitude first, not longitude like usual. swapping
+            let position = [coords[1], coords[0]];
+            if (radius) {
+              return (
+                // keys are required to be able to edit
+                <Circle
+                  key={Math.random()}
+                  center={position}
+                  id={id}
+                  radius={radius}
+                  color={color}
+                />
+              );
+            } else if (text) {
+              return (
+                <Marker
+                  key={Math.random()}
+                  position={position}
+                  id={id}
+                  color={color}
+                  icon={noIcon}
+                >
+                  <Tooltip
+                    direction="bottom"
+                    permanent
+                    className="editable"
+                    interactive={true}
+                  >
+                    <div class="editable">
+                      <div
+                        contenteditable="true"
+                        placeholder="Click out to save"
+                      >
+                        {text}
+                      </div>
+                    </div>
+                  </Tooltip>
+                </Marker>
+              );
+            } else {
+              // unknown if color changes anything. need to test
+              return (
+                <Marker
+                  key={Math.random()}
+                  position={position}
+                  id={id}
+                  color={color}
+                />
+              );
+            }
+          } else if (rectangle) {
+            // instead of an array of four coordinates, rectangles only have two corners
+            let bounds = coords[0].map(coord => {
+              return [coord[1], coord[0]];
+            });
+            return (
+              <Rectangle
+                key={Math.random()}
+                bounds={bounds}
+                id={id}
+                color={color}
+              />
+            );
+          } else if (type === "Polygon") {
+            // Polygon coordinates are wrapped under a one element array, for some reason
+            let positions = coords[0].map(coord => {
+              return [coord[1], coord[0]];
+            });
+            return (
+              <Polygon
+                key={Math.random()}
+                positions={positions}
+                id={id}
+                color={color}
+              />
+            );
+          } else if (type === "LineString") {
+            // Polyline coordinates are a normal array, unlike Polygon
+            let positions = coords.map(coord => {
+              return [coord[1], coord[0]];
+            });
+            return (
+              <Polyline
+                key={Math.random()}
+                positions={positions}
+                id={id}
+                color={color}
+              />
+            );
+          }
+        })}
+      </FeatureGroup>
+    );
   }
-  
-	_onCreated = (e) => {
-		let type = e.layerType; // from the example; isn't used right now, but may be relevant in the future
-		let layer = e.layer;
-    this.makeGeoJSON(e.layer);
-	}
-
-  // turn layer to GeoJSON data and add it to an array of all GeoJSON data of the current map
-	makeGeoJSON = (e) => {
-    let geoJSON = e.toGeoJSON();
-    let newGeoJSONAll = this.state.geoJSONAll;
-    newGeoJSONAll.push(geoJSON);
-    this.setState({geoJSONAll: newGeoJSONAll});
-    console.log(JSON.stringify(geoJSON, null, 4)); // printing GeoJSON data of the previous object create
-    console.log("newGeoJSONAll.length: " + newGeoJSONAll.length);
-	}
-	
-	render() {
-		return (
-			// "It's important to wrap EditControl component into FeatureGroup component from react-leaflet. The elements you draw will be added to this FeatureGroup layer, when you hit edit button only items in this layer will be edited."
-			<FeatureGroup> 
-				<EditControl
-					position='topright'
-					onCreated={this._onCreated}
-					draw={{
-						circle: {
-							repeatMode: true, // allows using the tool again after finishing the previous shape
-							shapeOptions: {
-								color: '#f9f10c',
-								opacity: 100
-							}
-						},
-						rectangle: {
-							repeatMode: true
-						},
-						polygon: {
-							repeatMode: true,
-							allowIntersection: false, // Restricts shapes to simple polygons
-							drawError: {
-								color: '#e1e100', // Color the shape will turn when intersects
-								message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
-							},
-							shapeOptions: {
-								color: '#ed2572',
-								opacity: 100
-							}
-						},
-						polyline: {
-							repeatMode: true,
-							shapeOptions: {
-								color: '#ed2572',
-								opacity: 100
-							}
-						},
-						marker: {
-							repeatMode: true
-						},
-						circlemarker: false
-					}}
-				/>
-			</FeatureGroup>
-		)
-	}
 }
 
-export default DrawTools;
\ No newline at end of file
+export default DrawTools;
diff --git a/src/components/EditGameForm.js b/src/components/EditGameForm.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbc37f8995faaaec41f56c51a6b1b6cdd6ba5d4b
--- /dev/null
+++ b/src/components/EditGameForm.js
@@ -0,0 +1,226 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { Map, TileLayer } from "react-leaflet";
+
+export class EditGameForm extends React.Component {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      gamename: "",
+      description: "",
+      startDate: "",
+      startTime: "",
+      endDate: "",
+      endTime: "",
+      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()
+    });
+  };
+
+  handleGameSave = e => {
+    let startDate =
+      this.state.startDate + "T" + this.state.startTime + ":00.000Z";
+    let endDate = this.state.endDate + "T" + this.state.endTime + ":00.000Z";
+
+    const gameObject = {
+      name: this.state.gamename,
+      desc: this.state.description,
+      map: "",
+      startdate: startDate,
+      enddate: endDate,
+      center: this.state.mapCenter
+    };
+
+    e.preventDefault();
+
+    let token = sessionStorage.getItem("token");
+
+    // Send Game info to the server
+    fetch(`${process.env.REACT_APP_API_URL}/game/edit/${this.props.gameId}`, {
+      method: "PUT",
+      headers: {
+        Authorization: "Bearer " + token,
+        Accept: "application/json",
+        "Content-Type": "application/json"
+      },
+      body: JSON.stringify(gameObject)
+    })
+      .then(res => res.json())
+      .then(result => {
+        alert(result.message);
+        this.handleView();
+      })
+      .catch(error => console.log("Error: ", error));
+  };
+
+  componentDidMount() {
+    document.addEventListener("keyup", this.handleEsc);
+    this.getGameInfo(this.props.gameId);
+  }
+
+  componentWillUnmount() {
+    document.removeEventListener("keyup", this.handleEsc);
+  }
+
+  getGameInfo(gameId) {
+    fetch(`${process.env.REACT_APP_API_URL}/game/${gameId}`)
+      .then(response => response.json())
+      .then(json => this.handleGameInfo(json))
+      .catch(error => console.log(error));
+  }
+
+  handleGameInfo(json) {
+    this.setState({
+      gamename: json.name,
+      description: json.desc,
+      startDate: json.startdate.substring(0, 10),
+      startTime: json.startdate.substring(11, 16),
+      endDate: json.enddate.substring(0, 10),
+      endTime: json.enddate.substring(11, 16),
+      zoom: 13,
+      mapCenter: {
+        lat: json.center.lat,
+        lng: json.center.lng
+      }
+    });
+  }
+
+  render() {
+    return ReactDOM.createPortal(
+      <div className="fade-main">
+        <div className="sticky">
+          <span
+            id="closeEditGameFormX"
+            className="close"
+            onClick={this.handleView}
+          >
+            ×
+          </span>
+        </div>
+        <div className="">
+          <form onSubmit={this.handleGameSave}>
+            <h1>Demo Game Creation</h1>
+            <br />
+            <input
+              placeholder="Game name"
+              name="gamename"
+              value={this.state.gamename}
+              onChange={this.handleChange}
+              id="editGameNameInput"
+            />
+            <br />
+            <input
+              placeholder="Description"
+              type="text"
+              name="description"
+              value={this.state.description}
+              onChange={this.handleChange}
+              id="editGameDescriptionInput"
+            />
+            <br />
+            <label className="">Start:</label>
+            <input
+              className="formDate"
+              type="date"
+              name="startDate"
+              value={this.state.startDate}
+              onChange={this.handleChange}
+              id="editGameDateStartInput"
+            />
+            <input
+              className="formTime"
+              type="time"
+              name="startTime"
+              value={this.state.startTime}
+              onChange={this.handleChange}
+              rid="editGameTimeStartInput"
+            />
+            <br />
+            <label className="">End:</label>
+            <input
+              className="formDate"
+              type="date"
+              name="endDate"
+              value={this.state.endDate}
+              onChange={this.handleChange}
+              min={this.state.startDate}
+              id="editGameDateEndInput"
+            />
+            <input
+              className="formTime"
+              type="time"
+              name="endTime"
+              value={this.state.endTime}
+              onChange={this.handleChange}
+              id="editGameTimeEndInput"
+            />
+            <br />
+            <label>Map things</label>
+            <br />
+            <Map
+              id="editGameCenterMap"
+              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 id="editGameSubmitButton" type="submit">
+              Save changes
+            </button>
+            <h2>{this.state.errorMsg}</h2>
+          </form>
+        </div>
+      </div>,
+      document.getElementById("form")
+    );
+  }
+}
+
+export default EditGameForm;
diff --git a/src/components/GameList.js b/src/components/GameList.js
new file mode 100644
index 0000000000000000000000000000000000000000..f3fc6d3c71a350b960302f428ed66df3271a8e87
--- /dev/null
+++ b/src/components/GameList.js
@@ -0,0 +1,99 @@
+import React, { Fragment } from "react";
+import EditGameForm from "./EditGameForm";
+
+class GameList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      games: [],
+      selectedGame: null,
+      editForm: false
+    };
+
+    this.toggleView = this.toggleView.bind(this);
+  }
+
+  componentDidMount() {
+    this.getGames();
+  }
+
+  getGames() {
+    fetch(`${process.env.REACT_APP_API_URL}/game/listgames`)
+      .then(response => response.json())
+      .then(games => {
+        this.setState({
+          games: games,
+          selectedGame: games !== undefined && games[0].id
+        });
+        // taking the initialized gameID to UserMap.js (GameList.js -> Header.js -> App.js -> UserMap.js)
+        this.props.handleGameChange(games[0].id);
+      })
+      .catch(error => {
+        console.log(error);
+      });
+  }
+
+  handleChange = e => {
+    this.setState(
+      {
+        selectedGame: e.target.value
+      },
+      () => {
+        // taking the changed gameID to UserMap.js (GameList.js -> Header.js -> App.js -> UserMap.js)
+        this.props.handleGameChange(this.state.selectedGame);
+      }
+    );
+  };
+
+  handleEditClick = e => {
+    if (this.state.selectedGame === null) {
+      alert("No game selected");
+    } else {
+      this.setState({
+        editForm: true
+      });
+    }
+  };
+
+  toggleView = e => {
+    this.setState({
+      editForm: !this.state.editForm
+    });
+    this.getGames();
+  };
+
+  render() {
+    let items = [];
+
+    for (let i = 0; i < this.state.games.length; i++) {
+      const element = this.state.games[i];
+      items.push(
+        <option key={element.id} value={element.id}>
+          {element.name}
+        </option>
+      );
+    }
+
+    return (
+      <Fragment>
+        <label>Game: </label>
+        <select id="changeActiveGameList" onChange={this.handleChange}>
+          {items}
+        </select>
+        {sessionStorage.getItem("token") && (
+          <button id="editGameButton" onClick={this.handleEditClick}>
+            Edit game
+          </button>
+        )}
+        {this.state.editForm && this.state.selectedGame !== null && (
+          <EditGameForm
+            gameId={this.state.selectedGame}
+            toggleView={this.toggleView}
+          />
+        )}
+      </Fragment>
+    );
+  }
+}
+
+export default GameList;
diff --git a/src/components/Header.js b/src/components/Header.js
index dfe41df38dfd877773b63aee334363518e12a6e8..13457f78a81c6381d8f0b630049491bb91102218 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -1,43 +1,46 @@
-import React from 'react';
+import React from "react";
 
-import LoginForm from './LoginForm';
-import RegisterForm from './RegisterForm';
+import LoginForm from "./LoginForm";
+import RegisterForm from "./RegisterForm";
+import GameList from "./GameList";
+import NewGameForm from "./NewGameForm";
 
 class Header extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+
   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
     });
   };
 
   handleState = data => {
-    sessionStorage.setItem('name', data.name);
-    sessionStorage.setItem('token', data.token);
+    sessionStorage.setItem("name", data.name);
+    sessionStorage.setItem("token", data.token);
     this.setState({ username: data.name, token: data.token });
   };
 
   handleLogout = () => {
     this.setState({ username: null, token: null });
-    sessionStorage.removeItem('token');
+    sessionStorage.removeItem("token");
   };
 
   // verifies the token (if it exists) on element mount with backend server
   componentDidMount() {
-    let token = sessionStorage.getItem('token');
+    let token = sessionStorage.getItem("token");
     if (token) {
-      fetch(`${process.env.REACT_APP_URL}/user/verify`, {
+      fetch(`${process.env.REACT_APP_API_URL}/user/verify`, {
         headers: {
-          Authorization: 'Bearer ' + token
+          Authorization: "Bearer " + token
         }
       })
         .then(res => res.json())
@@ -46,7 +49,7 @@ class Header extends React.Component {
             // if token is still valid, login user
             if (result === true) {
               this.setState({
-                username: sessionStorage.getItem('name'),
+                username: sessionStorage.getItem("name"),
                 token: token
               });
               // logout user if token has expired / is invalid
@@ -64,36 +67,60 @@ class Header extends React.Component {
   render() {
     return (
       <div>
-        <div className='header'>
+        <div className="header">
           {!this.state.username && (
-            <button id="registerButton" onClick={() => this.toggleView('register')}>
+            <button
+              id="registerButton"
+              onClick={() => this.toggleView("register")}
+            >
               register
             </button>
           )}
           {!this.state.username && (
-            <button id="loginButton" onClick={() => this.toggleView('login')}>login</button>
+            <button id="loginButton" onClick={() => this.toggleView("login")}>
+              login
+            </button>
           )}
           {this.state.username && (
-            <button id="logoutButton" onClick={this.handleLogout}>logout</button>
+            <button
+              id="newGameButton"
+              onClick={() => this.toggleView("newgame")}
+            >
+              New Game
+            </button>
+          )}
+          {this.state.username && (
+            <button id="logoutButton" onClick={this.handleLogout}>
+              logout
+            </button>
           )}
           {this.state.username && <button>{this.state.username}</button>}
-          <button id="changeLayerButton" onClick={this.props.handleLayerChange}>change layer</button>
+          <button id="changeLayerButton" onClick={this.props.handleLayerChange}>
+            change layer
+          </button>
+          <GameList handleGameChange={this.props.handleGameChange} />
         </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}
           />
         )}
-        
       </div>
     );
   }
diff --git a/src/components/LoginForm.js b/src/components/LoginForm.js
index dbf1c833d38183336d0d372c975699694ed5db65..61f3dec0a63cc4391c5f7a328303e9db9513d726 100644
--- a/src/components/LoginForm.js
+++ b/src/components/LoginForm.js
@@ -1,13 +1,13 @@
-import React from 'react';
+import React from "react";
 
 export class LoginForm extends React.Component {
   constructor(props) {
     super(props);
 
     this.state = {
-      errorMsg: '',
-      username: '',
-      password: ''
+      errorMsg: "",
+      username: "",
+      password: ""
     };
   }
 
@@ -39,10 +39,10 @@ export class LoginForm extends React.Component {
 
     // Send login info to the server
     fetch(`${process.env.REACT_APP_API_URL}/user/login`, {
-      method: 'POST',
+      method: "POST",
       headers: {
-        Accept: 'application/json',
-        'Content-Type': 'application/json'
+        Accept: "application/json",
+        "Content-Type": "application/json"
       },
       body: JSON.stringify({
         name: name,
@@ -69,47 +69,48 @@ export class LoginForm extends React.Component {
   };
 
   componentDidMount() {
-    document.addEventListener('keyup', this.handleEsc);
+    document.addEventListener("keyup", this.handleEsc);
   }
 
   componentWillUnmount() {
-    document.removeEventListener('keyup', this.handleEsc);
+    document.removeEventListener("keyup", this.handleEsc);
   }
 
   render() {
     return (
-      <div className='fade-main'>
-        <div className='sticky'>
+      <div className="fade-main">
+        <div className="sticky">
           <span
-            id='closeLoginFormX'
-            className='close'
+            id="closeLoginFormX"
+            className="close"
             onClick={this.handleView}
           >
             ×
           </span>
         </div>
-        <div className='login'>
+        <div className="login">
           <form onSubmit={this.handleLogin}>
             <h1>demo login</h1>
             <br />
             <input
-              placeholder='Enter Username'
-              name='username'
+              placeholder="Enter Username"
+              name="username"
               value={this.state.username}
               onChange={this.handleChange}
-              id='loginUsernameInput'
+              id="loginUsernameInput"
+              autofocus
             />
             <br />
             <input
-              placeholder='Enter password'
-              type='password'
-              name='password'
+              placeholder="Enter password"
+              type="password"
+              name="password"
               value={this.state.password}
               onChange={this.handleChange}
-              id='loginPasswordInput'
+              id="loginPasswordInput"
             />
             <br />
-            <button id='submitLoginButton' type='submit'>
+            <button id="submitLoginButton" type="submit">
               login
             </button>
             <h2>{this.state.errorMsg}</h2>
diff --git a/src/components/NewGameForm.js b/src/components/NewGameForm.js
new file mode 100644
index 0000000000000000000000000000000000000000..e84940d00c6619d3793d5b9cc5746ebf3269e36c
--- /dev/null
+++ b/src/components/NewGameForm.js
@@ -0,0 +1,199 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import { Map, TileLayer } from "react-leaflet";
+
+export class NewGameForm extends React.Component {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      gamename: "",
+      description: "",
+      startDate: "",
+      startTime: "",
+      endDate: "",
+      endTime: "",
+      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 =
+      this.state.startDate + "T" + this.state.startTime + ":00.000Z";
+    let endDate = this.state.endDate + "T" + this.state.endTime + ":00.000Z";
+
+    const gameObject = {
+      name: this.state.gamename,
+      desc: this.state.description,
+      map: "",
+      startdate: startDate,
+      enddate: endDate,
+      center: this.state.mapCenter
+    };
+
+    e.preventDefault();
+
+    let token = sessionStorage.getItem("token");
+
+    // Send Game info to the server
+    fetch(`${process.env.REACT_APP_API_URL}/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
+            id="closeNewGameFormX"
+            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}
+              id="newGameNameInput"
+            />
+            <br />
+            <input
+              placeholder="Description"
+              type="text"
+              name="description"
+              value={this.state.description}
+              onChange={this.handleChange}
+              id="newGameDescriptionInput"
+            />
+            <br />
+            <label className="">Start:</label>
+            <input
+              className="formDate"
+              type="date"
+              name="startDate"
+              value={this.state.startDate}
+              onChange={this.handleChange}
+              id="newGameDateStartInput"
+            />
+            <input
+              className="formTime"
+              type="time"
+              name="startTime"
+              onChange={this.handleChange}
+              id="newGameTimeStartInput"
+            />
+            <br />
+            <label className="">End:</label>
+            <input
+              className="formDate"
+              type="date"
+              name="endDate"
+              value={this.state.endDate}
+              onChange={this.handleChange}
+              min={this.state.startDate}
+              id="newGameDateEndInput"
+            />
+            <input
+              className="formTime"
+              type="time"
+              name="endTime"
+              onChange={this.handleChange}
+              id="newGameTimeEndInput"
+            />
+            <br />
+            <label>Map things</label>
+            <br />
+            <Map
+              id="newGameCenterMap"
+              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 id="newGameSubmitButton" type="submit">
+              Submit
+            </button>
+            <h2>{this.state.errorMsg}</h2>
+          </form>
+        </div>
+      </div>,
+      document.getElementById("form")
+    );
+  }
+}
+
+export default NewGameForm;
diff --git a/src/components/Player.js b/src/components/Player.js
new file mode 100644
index 0000000000000000000000000000000000000000..195cc40acbdc959c08b58da9b290bf44577f9e9f
--- /dev/null
+++ b/src/components/Player.js
@@ -0,0 +1,96 @@
+import React, { Component } from "react";
+import { Marker, Popup } from "react-leaflet";
+
+class Player extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      players: null
+    };
+  }
+
+  getPlayers() {
+    fetch(
+      `${process.env.REACT_APP_API_URL}/tracking/players/${
+        this.props.currentGameId
+      }`,
+      {
+        method: "GET",
+        headers: {
+          Authorization: "Bearer " + sessionStorage.getItem("token")
+        }
+      }
+    )
+      .then(res => res.json()) // no brackets over res.json() or it breaks (what)
+      .then(data => {
+        // don't do anything if data is not an array, as it breaks the map function at render
+        if (Array.isArray(data)) {
+          this.setState({
+            players: data
+          });
+        }
+      })
+      .catch(error => {
+        console.log(error);
+      });
+  }
+
+  componentDidMount() {
+    // update components every 10 seconds
+    this.interval = setInterval(() => this.setState(this.getPlayers()), 5000);
+  }
+
+  shouldComponentUpdate(nextProps, nextState) {
+    // do not update component until players have been fetched and game ID is available
+    if (this.state.players === null) {
+      this.getPlayers();
+      return false;
+    } else if (this.props.currentGameId === null) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  componentDidUpdate() {
+    // check if game ID has changed
+    if (this.state.currentGameId !== this.props.currentGameId) {
+      this.setState({
+        currentGameId: this.props.currentGameId
+      });
+    }
+  }
+
+  componentWillUnmount() {
+    clearInterval(this.interval);
+  }
+
+  render() {
+    return (
+      <div>
+        {this.state.players !== null &&
+          this.state.players.map(player => {
+            return (
+              <Marker
+                key={Math.random()}
+                position={[player.coordinates.lat, player.coordinates.lng]}
+                factionId={player.factionId}
+                gamepersonId={player.gamepersonId}
+                gamepersonRole={player.gamepersonRole}
+              >
+                <Popup>
+                  <b>factionId:</b> {player.factionId}
+                  <br />
+                  <b>gamepersonId:</b> {player.gamepersonId}
+                  <br />
+                  <b>gamepersonRole:</b> {player.gamepersonRole}
+                </Popup>
+              </Marker>
+            );
+          })}
+      </div>
+    );
+  }
+}
+
+export default Player;
diff --git a/src/components/RegisterForm.js b/src/components/RegisterForm.js
index 727fbde10465c456e9ea4452205bf3a75be1fc0a..3ef5ca7594ad2e8177d7a37037047b144000a68e 100644
--- a/src/components/RegisterForm.js
+++ b/src/components/RegisterForm.js
@@ -1,14 +1,14 @@
-import React from 'react';
+import React from "react";
 
 export class RegisterForm extends React.Component {
   constructor(props) {
     super(props);
 
     this.state = {
-      errorMsg: '',
-      username: '',
-      password: '',
-      password2: ''
+      errorMsg: "",
+      username: "",
+      password: "",
+      password2: ""
     };
   }
 
@@ -41,14 +41,14 @@ export class RegisterForm extends React.Component {
     e.preventDefault();
 
     if (this.state.password !== this.state.password2) {
-      this.handleError('Passwords do not match');
+      this.handleError("Passwords do not match");
     } else {
       // Send register info to the server
       fetch(`${process.env.REACT_APP_API_URL}/user/register`, {
-        method: 'POST',
+        method: "POST",
         headers: {
-          Accept: 'application/json',
-          'Content-Type': 'application/json'
+          Accept: "application/json",
+          "Content-Type": "application/json"
         },
         body: JSON.stringify({
           name: name,
@@ -76,56 +76,54 @@ export class RegisterForm extends React.Component {
   };
 
   componentDidMount() {
-    document.addEventListener('keyup', this.handleEsc);
+    document.addEventListener("keyup", this.handleEsc);
   }
 
   componentWillUnmount() {
-    document.removeEventListener('keyup', this.handleEsc);
+    document.removeEventListener("keyup", this.handleEsc);
   }
 
   render() {
     return (
-      <div className='fade-main'>
-        <div className='sticky'>
-          <span
-            id='closeRegisterFormX'
-            className='close'
-            onClick={this.handleView}
-          >
+      <div className="fade-main">
+        <div className="sticky">
+          <span className="close" onClick={this.handleView}>
             ×
           </span>
         </div>
-        <div className='login'>
+        <div className="login">
           <form onSubmit={this.handleRegister}>
             <h1>register new user</h1>
             <br />
             <input
-              placeholder='Enter Username'
-              name='username'
+              placeholder="Enter Username"
+              name="username"
               value={this.state.username}
               onChange={this.handleChange}
-              id='registerUsernameInput'
+              id="registerUsernameInput"
+              autoFocus
+              //required
             />
             <br />
             <input
-              placeholder='Enter password'
-              type='password'
-              name='password'
+              placeholder="Enter password"
+              type="password"
+              name="password"
               value={this.state.password}
               onChange={this.handleChange}
-              id='registerPasswordInput'
+              id="registerUsernameInput"
             />
             <br />
             <input
-              placeholder='Verify password'
-              type='password'
-              name='password2'
+              placeholder="Verify password"
+              type="password"
+              name="password2"
               value={this.state.password2}
               onChange={this.handleChange}
-              id='registerPasswordVerifyInput'
+              id="registerPasswordVerifyInput"
             />
             <br />
-            <button id='submitRegisterButton' type='submit'>
+            <button id="submitRegisterButton" type="submit">
               register
             </button>
             <h2>{this.state.errorMsg}</h2>
diff --git a/src/components/UserMap.js b/src/components/UserMap.js
index 52cce7ac28be2f1bbaa3a8aaeafd523e5b047cb3..d1e3f86927e264a3e337574b29597eaa0941b744 100644
--- a/src/components/UserMap.js
+++ b/src/components/UserMap.js
@@ -1,114 +1,205 @@
-import React, {Component} from 'react';
-import {
-	Map,
-	TileLayer,
-  ZoomControl,
-  Marker,
-  Popup
-} from 'react-leaflet'
-import DrawTools from './DrawTools.js'
+import React, { Component } from "react";
+import { Map, TileLayer, ZoomControl, Marker, Popup } from "react-leaflet";
+import DrawTools from "./DrawTools.js";
+import Player from "./Player.js";
 
 class UserMap extends Component {
-  constructor(props){
+  constructor(props) {
     super(props);
+
     this.state = {
       ownLat: null,
       ownLng: null,
-      mapUrl: 'https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg'
-    }
+      mapUrl: "https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg",
+      geoJSONLayer: {
+        type: "FeatureCollection",
+        features: []
+      },
+      currentGameId: null
+    };
 
+    this.sendGeoJSON = this.sendGeoJSON.bind(this);
+    this.setCurrentPosition = this.setCurrentPosition.bind(this);
     this.watchPositionId = null;
   }
 
-  componentDidMount(){
-    this.getCurrentPosition((position) => {
+  componentDidMount() {
+    this.getCurrentPosition(position => {
       this.setCurrentPosition(position);
     });
   }
 
-  componentWillUnmount(){
-    if(this.watchPositionId != null){
+  componentDidUpdate() {
+    // check if game ID has changed and fetch that game's drawings
+    if (this.state.currentGameId !== this.props.currentGameId) {
+      this.setState({
+        currentGameId: this.props.currentGameId
+      });
+      this.fetchGeoJSON();
+    }
+  }
+
+  // Sends the players drawings to the backend (and database)
+  sendGeoJSON(layerToDatabase, isDeleted) {
+    // isDeleted is used to determine the drawing's drawingIsActive status
+    // otherwise the fetch functions are the same in both if and else. any smarter way to do this?
+    if (isDeleted === true) {
+      fetch(
+        `${process.env.REACT_APP_API_URL}/draw/mapdrawing/${
+          this.props.currentGameId
+        }`,
+        {
+          method: "PUT",
+          headers: {
+            Authorization: "Bearer " + sessionStorage.getItem("token"),
+            Accept: "application/json",
+            "Content-Type": "application/json"
+          },
+          body: JSON.stringify({
+            type: "FeatureCollection",
+            drawingIsActive: false,
+            mapDrawingId: layerToDatabase.mapDrawingId,
+            data: layerToDatabase.data
+          })
+        }
+      );
+    } else {
+      fetch(
+        `${process.env.REACT_APP_API_URL}/draw/mapdrawing/${
+          this.props.currentGameId
+        }`,
+        {
+          method: "PUT",
+          headers: {
+            Authorization: "Bearer " + sessionStorage.getItem("token"),
+            Accept: "application/json",
+            "Content-Type": "application/json"
+          },
+          body: JSON.stringify({
+            type: "FeatureCollection",
+            drawingIsActive: true,
+            mapDrawingId: layerToDatabase.mapDrawingId,
+            data: layerToDatabase.data
+          })
+        }
+      );
+    }
+
+    // get the layers again to stop updating with old objects
+    this.fetchGeoJSON();
+  }
+
+  // Get the drawings from the backend and add them to the state, so they can be drawn
+  fetchGeoJSON() {
+    fetch(
+      `${process.env.REACT_APP_API_URL}/draw/map/${this.props.currentGameId}`,
+      {
+        method: "GET",
+        headers: {
+          Authorization: "Bearer " + sessionStorage.getItem("token"),
+          Accept: "application/json",
+          "Content-Type": "application/json"
+        }
+      }
+    )
+      .then(res => res.json())
+      .then(data => {
+        let newFeatures = [];
+        data.map(item => {
+          newFeatures.push(item);
+        });
+
+        this.setState({
+          geoJSONLayer: {
+            type: "FeatureCollection",
+            features: [...newFeatures]
+          }
+        });
+      })
+      .catch(error => {
+        console.log(error);
+      });
+  }
+
+  componentWillUnmount() {
+    if (this.watchPositionId != null) {
       navigator.geolocation.clearWatch(this.watchPositionId);
     }
   }
 
-  setCurrentPosition(position){
+  setCurrentPosition(position) {
     this.setState({
       ownLat: position.coords.latitude,
-      ownLng: position.coords.longitude,
+      ownLng: position.coords.longitude
     });
   }
 
-  getCurrentPosition(callback){
-    if(!navigator.geolocation){
+  getCurrentPosition(callback) {
+    if (!navigator.geolocation) {
       console.log("Can't get geolocation :/");
-    }
-    else{
+    } else {
       // Position tracking options
       const options = {
         enableHighAccuracy: true,
         timeout: 30000,
         maximumAge: 0
-      }
-
-      if(this.watchPositionId != null){navigator.geolocation.clearWatch(this.watchPositionId);}
-      
-      this.watchPositionId = navigator.geolocation.watchPosition((position) =>{
-        //success
-        if(position != null){
-          callback(position);
-        }
-      }, (error) =>{
-        console.log(error);
-        // disable tracking
-        if(this.watchPositionId != null){
-          navigator.geolocation.clearWatch(this.watchPositionId);
-        }
-      }, options);
-    }
-  }
+      };
 
-  positionToGeoJSON(position){
-    let geoJSON = {
-      type: "Feature",
-      properties: {},
-      geometry: {
-        type: "Point",
-        coordinates: [position.coords.longitude, position.coords.latitude]
+      if (this.watchPositionId != null) {
+        navigator.geolocation.clearWatch(this.watchPositionId);
       }
-    }
 
-    return JSON.stringify(geoJSON);
+      this.watchPositionId = navigator.geolocation.watchPosition(
+        position => {
+          //success
+          if (position != null) {
+            callback(position);
+          }
+        },
+        error => {
+          console.log(error);
+          // disable tracking
+          if (this.watchPositionId != null) {
+            navigator.geolocation.clearWatch(this.watchPositionId);
+          }
+        },
+        options
+      );
+    }
   }
 
   render() {
     return (
       <Map
-        className='map'
+        className="map"
         center={this.props.position}
         zoom={this.props.zoom}
-        minZoom='7'
-        maxZoom='17'
-        zoomControl={false}>
+        minZoom="7"
+        maxZoom="17"
+        zoomControl={false}
+      >
         <TileLayer
           attribution='&copy; <a href="https://www.maanmittauslaitos.fi/">Maanmittauslaitos</a>'
           url={this.props.mapUrl}
         />
-        <ZoomControl position='topright' />
-		    <DrawTools position={this.props.position} />
-        <Marker position={this.props.position}>
-          <Popup>
-            Se on perjantai, my dudes <br />
-          </Popup>
-        </Marker>
-        {this.state.ownLat !== null && <Marker position={[this.state.ownLat, this.state.ownLng]}>
-        <Popup>
-            User's real position.<br />
-          </Popup>
-        </Marker>}
+        <ZoomControl position="topright" />
+        <DrawTools
+          position={this.props.position}
+          sendGeoJSON={this.sendGeoJSON}
+          geoJSONLayer={this.state.geoJSONLayer}
+          currentGameId={this.props.currentGameId}
+        />
+        {this.state.ownLat !== null && (
+          <Marker position={[this.state.ownLat, this.state.ownLng]}>
+            <Popup>
+              User's real position.
+              <br />
+            </Popup>
+          </Marker>
+        )}
+        <Player currentGameId={this.state.currentGameId} />
       </Map>
     );
   }
 }
-
-export default UserMap;
\ No newline at end of file
+export default UserMap;
diff --git a/src/icons/button-textbox.png b/src/icons/button-textbox.png
new file mode 100644
index 0000000000000000000000000000000000000000..e36a2872bdf8f68df996d35159335a77211ead7a
Binary files /dev/null and b/src/icons/button-textbox.png differ
diff --git a/src/icons/color-icon.png b/src/icons/color-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..28e54479f3d7fbfecc52694f51a7c6d2dbec1a34
Binary files /dev/null and b/src/icons/color-icon.png differ
diff --git a/src/icons/nil.png b/src/icons/nil.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae058ee7bffad41634a20cd463fc94219f0de69b
Binary files /dev/null and b/src/icons/nil.png differ