diff --git a/.env b/.env
new file mode 100644
index 0000000000000000000000000000000000000000..191b674a09d3c64e304abb26cfc22b19a8f660d4
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+REACT_APP_API_URL = "http://localhost:5000"
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c47346eb24c76e3ebdf37ae12b226e67b04488da..cf95bf2d9457edec5a21ba6b736ac979bd6135a1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -939,6 +939,11 @@
         "@hapi/hoek": "6.x.x"
       }
     },
+    "@icons/material": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
+      "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
+    },
     "@jest/console": {
       "version": "24.7.1",
       "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz",
@@ -7950,6 +7955,11 @@
         "object-visit": "^1.0.0"
       }
     },
+    "material-colors": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
+      "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
+    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -10078,6 +10088,19 @@
         "whatwg-fetch": "3.0.0"
       }
     },
+    "react-color": {
+      "version": "2.17.3",
+      "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz",
+      "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==",
+      "requires": {
+        "@icons/material": "^0.2.4",
+        "lodash": "^4.17.11",
+        "material-colors": "^1.2.1",
+        "prop-types": "^15.5.10",
+        "reactcss": "^1.2.0",
+        "tinycolor2": "^1.4.1"
+      }
+    },
     "react-cookie": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-4.0.0.tgz",
@@ -10311,6 +10334,14 @@
         "workbox-webpack-plugin": "4.2.0"
       }
     },
+    "reactcss": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
+      "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
+      "requires": {
+        "lodash": "^4.0.1"
+      }
+    },
     "read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -11757,6 +11788,11 @@
       "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
       "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
     },
+    "tinycolor2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+      "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+    },
     "tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
diff --git a/package.json b/package.json
index 6e710f05834f66edfcfe93fa11e6d53ad52e9239..cf145f8645b5f565e23c6d1bba0a60d1e6ff9062 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
     "leaflet": "^1.5.1",
     "leaflet-draw": "^1.0.4",
     "react": "^16.8.6",
+    "react-color": "^2.17.3",
     "react-cookie": "^4.0.0",
     "react-dom": "^16.8.6",
     "react-leaflet": "^2.3.0",
diff --git a/public/index.html b/public/index.html
index 8b2f9d1cb04b63987cab6a5b0645beb0aeafff57..421a898f120b5f1f39e1b60e6f6db3ef91e754f1 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="tasklist"></div>
     <div id="root"></div>
     <div id="form"></div>
     <!--
diff --git a/src/App.css b/src/App.css
index d09ddd38e9af220ac7f8af30cf562952e241034e..8cf31418c5cc17db9852182200e9fc8dce43451c 100644
--- a/src/App.css
+++ b/src/App.css
@@ -59,6 +59,8 @@ div.fade-main {
   margin: auto;
   text-align: center;
   background-color: rgba(0, 0, 0, 0.85);
+  color: white;
+  overflow: scroll;
 }
 
 div.sticky {
@@ -214,3 +216,19 @@ div.login button:hover {
   max-width: 500px;
   padding: 10px;
 }
+
+.tasklist {
+  position: absolute;
+  margin-top: 50px;
+  z-index: 2020;
+  background-color: #ffffff80;
+}
+
+.tasklist-item {
+  margin: 20px;
+}
+
+.task-form {
+  display: flex;
+  flex-direction: column;
+}
diff --git a/src/components/EditGameForm.js b/src/components/EditGameForm.js
index fbc37f8995faaaec41f56c51a6b1b6cdd6ba5d4b..55247e638269ca8cb9d888d972cc9ec75aa08857 100644
--- a/src/components/EditGameForm.js
+++ b/src/components/EditGameForm.js
@@ -1,23 +1,36 @@
-import React from "react";
+import React, { Fragment } from "react";
 import ReactDOM from "react-dom";
 import { Map, TileLayer } from "react-leaflet";
+import { SketchPicker } from "react-color";
+import reactCSS from "reactcss";
 
 export class EditGameForm extends React.Component {
   constructor(props) {
     super(props);
 
     this.state = {
+      zoom: 13,
       gamename: "",
       description: "",
       startDate: "",
       startTime: "",
       endDate: "",
       endTime: "",
-      zoom: 13,
+      map: "",
       mapCenter: {
         lat: 62.2416479,
         lng: 25.7597186
-      }
+      },
+      factionNameInput: "", // >= 2 chars
+      factionPasswordInput: "", // >= 3 chars
+      factionColorInput: "#852222",
+      factions: [],
+      objectivePointDescriptionInput: "", // >= 7
+      objectivePointMultiplierInput: "", // number
+      objectivePoints: [],
+      capture_time: 300,
+      confirmation_time: 60,
+      displayColorPicker: false
     };
 
     this.handleMapDrag = this.handleMapDrag.bind(this);
@@ -32,6 +45,143 @@ export class EditGameForm extends React.Component {
     this.setState({ [name]: value });
   };
 
+  handleFactionAdd = e => {
+    e.preventDefault();
+
+    if (
+      this.state.factionNameInput === "" ||
+      this.state.factionPasswordInput === ""
+    ) {
+      return alert("Faction needs a name and password");
+    }
+
+    if (
+      this.state.factions.findIndex(
+        faction => faction.factionName === this.state.factionNameInput
+      ) !== -1
+    ) {
+      return alert(
+        "Faction " + this.state.factionNameInput + " already exists"
+      );
+    }
+
+    this.setState(state => {
+      let factions = state.factions;
+      factions.push({
+        factionName: this.state.factionNameInput,
+        factionPassword: this.state.factionPasswordInput,
+        colour: this.state.factionColorInput,
+        multiplier: 1
+      });
+      return {
+        factions: factions,
+        factionNameInput: "",
+        factionPasswordInput: ""
+      };
+    });
+  };
+
+  removeFaction(factionName) {
+    this.setState(state => {
+      let factions = state.factions;
+      const index = factions.findIndex(
+        faction => faction.factionName === factionName
+      );
+
+      if (index !== -1) {
+        factions.splice(index, 1);
+      } else {
+        console.log("Faction is not in the faction list");
+      }
+
+      return factions;
+    });
+  }
+
+  handleObjectivePointAdd = e => {
+    e.preventDefault();
+
+    if (
+      this.state.objectivePointDescriptionInput === "" ||
+      this.state.objectivePointMultiplierInput === ""
+    ) {
+      return alert("Capture point needs an ID and multiplier");
+    }
+
+    if (
+      this.state.objectivePoints.findIndex(
+        point =>
+          point.objectivePointDescription ===
+          this.state.objectivePointDescriptionInput
+      ) !== -1
+    ) {
+      return alert(
+        "Capture point " +
+          this.state.objectivePointDescriptionInput +
+          " already exists"
+      );
+    }
+
+    this.setState(state => {
+      let objectivePoints = state.objectivePoints;
+      objectivePoints.push({
+        objectivePointDescription: this.state.objectivePointDescriptionInput,
+        objectivePointMultiplier: parseFloat(
+          this.state.objectivePointMultiplierInput
+        )
+      });
+
+      return {
+        objectivePoints: objectivePoints,
+        objectivePointDescriptionInput: "",
+        objectivePointMultiplierInput: ""
+      };
+    });
+  };
+
+  removeObjectivePoint(objectivePointId) {
+    this.setState(state => {
+      let objectivePoints = state.objectivePoints;
+      const index = objectivePoints.findIndex(
+        point => point.objectivePointDescription === objectivePointId
+      );
+
+      if (index !== -1) {
+        objectivePoints.splice(index, 1);
+      } else {
+        console.log("Objective point is not in the point list");
+      }
+
+      return objectivePoints;
+    });
+  }
+
+  handleGameDeletion = e => {
+    e.preventDefault();
+
+    let token = sessionStorage.getItem("token");
+
+    if (window.confirm("Are you sure you want to delete this game")) {
+      alert("Game deleted");
+
+      fetch(
+        `${process.env.REACT_APP_API_URL}/game/delete/${this.props.gameId}`,
+        {
+          method: "DELETE",
+          headers: {
+            Authorization: "Bearer " + token
+          }
+        }
+      )
+        .then(result => result.json())
+        .then(result => {
+          console.log(result);
+          this.handleView();
+        })
+        .catch(error => console.log(error));
+    }
+  };
+
   // show/hide this form
   handleView = e => {
     this.props.toggleView(this.props.view);
@@ -57,20 +207,44 @@ export class EditGameForm extends React.Component {
   };
 
   handleGameSave = e => {
+    e.preventDefault();
+
     let startDate =
       this.state.startDate + "T" + this.state.startTime + ":00.000Z";
     let endDate = this.state.endDate + "T" + this.state.endTime + ":00.000Z";
 
-    const gameObject = {
+    let objectivePoints = this.state.objectivePoints;
+
+    // objective points are not allowed if the game has no factions
+    if (this.state.factions.length === 0) {
+      objectivePoints = [];
+    }
+
+    // Object the form sends to server
+    let gameObject = {
       name: this.state.gamename,
       desc: this.state.description,
       map: "",
       startdate: startDate,
       enddate: endDate,
-      center: this.state.mapCenter
+      center: this.state.mapCenter,
+      factions: this.state.factions,
+      objective_points: objectivePoints
     };
 
-    e.preventDefault();
+    // Add node settings to the game if the game has objective points
+    if (objectivePoints.length > 0) {
+      gameObject.nodesettings = {
+        node_settings: {
+          capture_time: this.state.capture_time,
+          confirmation_time: this.state.confirmation_time,
+          owner: 0,
+          capture: 0,
+          buttons_available: 16,
+          heartbeat_interval: 60
+        }
+      };
+    }
 
     let token = sessionStorage.getItem("token");
 
@@ -84,7 +258,13 @@ export class EditGameForm extends React.Component {
       },
       body: JSON.stringify(gameObject)
     })
-      .then(res => res.json())
+      .then(res => {
+        if (!res.ok) {
+          throw Error(res.statusMessage);
+        } else {
+          return res.json();
+        }
+      })
       .then(result => {
         alert(result.message);
         this.handleView();
@@ -104,27 +284,144 @@ export class EditGameForm extends React.Component {
   getGameInfo(gameId) {
     fetch(`${process.env.REACT_APP_API_URL}/game/${gameId}`)
       .then(response => response.json())
-      .then(json => this.handleGameInfo(json))
+      .then(json => this.setGameInfoToState(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
+  setGameInfoToState(json) {
+    let token = sessionStorage.getItem("token");
+
+    // Get factions and passwordds
+    fetch(
+      `${process.env.REACT_APP_API_URL}/game/get-factions/${this.props.gameId}`,
+      {
+        method: "GET",
+        headers: {
+          Authorization: "Bearer " + token
+        }
       }
-    });
+    )
+      .then(result => result.json())
+      .then(result => {
+        let factions = result.map(faction => {
+          return {
+            factionName: faction.factionName,
+            factionPassword: faction.factionPassword,
+            multiplier: 1,
+            colour: faction.colour
+          };
+        });
+
+        // Remove objective point's id from the object
+        let objectivePoints = json.objective_points.map(point => {
+          return {
+            objectivePointDescription: point.objectivePointDescription,
+            objectivePointMultiplier: point.objectivePointMultiplier
+          };
+        });
+
+        // get node settings if the settings exists in the game
+        let nodesettings =
+          json.nodesettings !== null &&
+          json.nodesettings.node_settings !== undefined
+            ? json.nodesettings.node_settings
+            : undefined;
+
+        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),
+          mapCenter: {
+            lat: json.center.lat,
+            lng: json.center.lng
+          },
+          factions: factions,
+          objectivePoints: objectivePoints,
+          capture_time:
+            nodesettings !== undefined
+              ? json.nodesettings.node_settings.capture_time
+              : this.state.capture_time,
+          confirmation_time:
+            nodesettings !== undefined
+              ? json.nodesettings.node_settings.confirmation_time
+              : this.state.confirmation_time
+        });
+      })
+      .catch(error => console.log(error));
   }
 
   render() {
+    let factions = [];
+    for (let i = 0; i < this.state.factions.length; i++) {
+      const faction = this.state.factions[i];
+      factions.push(
+        <li key={faction.factionName}>
+          <div style={{ color: faction.colour }}>
+            {faction.factionName} : {faction.factionPassword}
+          </div>
+          <button
+            type="button"
+            onClick={() => this.removeFaction(faction.factionName)}
+          >
+            Remove
+          </button>
+        </li>
+      );
+    }
+
+    let objectivePoints = [];
+    for (let i = 0; i < this.state.objectivePoints.length; i++) {
+      const point = this.state.objectivePoints[i];
+      objectivePoints.push(
+        <li key={point.objectivePointDescription}>
+          <div>
+            {point.objectivePointDescription} : {point.objectivePointMultiplier}
+          </div>
+          <button
+            type="button"
+            onClick={() =>
+              this.removeObjectivePoint(point.objectivePointDescription)
+            }
+          >
+            Remove
+          </button>
+        </li>
+      );
+    }
+
+    const styles = reactCSS({
+      default: {
+        color: {
+          width: "36px",
+          height: "14px",
+          borderRadius: "2px",
+          background: `${this.state.factionColorInput}`
+        },
+        swatch: {
+          padding: "5px",
+          background: "#fff",
+          borderRadius: "1px",
+          boxShadow: "0 0 0 1px rgba(0,0,0,.1)",
+          display: "inline-block",
+          cursor: "pointer"
+        },
+        popover: {
+          position: "absolute",
+          zIndex: "2"
+        },
+        cover: {
+          position: "fixed",
+          top: "0px",
+          right: "0px",
+          bottom: "0px",
+          left: "0px"
+        }
+      }
+    });
+
     return ReactDOM.createPortal(
       <div className="fade-main">
         <div className="sticky">
@@ -137,85 +434,208 @@ export class EditGameForm extends React.Component {
           </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}
+          <form id="gameEditForm" onSubmit={this.handleGameSave} />
+          <form id="factionAddFrom" onSubmit={this.handleFactionAdd} />
+          <form id="gameDeletionForm" onSubmit={this.handleGameDeletion} />
+          <form
+            id="objectivePointAddFrom"
+            onSubmit={this.handleObjectivePointAdd}
+          />
+
+          <h1>Demo Game Editor</h1>
+          <br />
+          <input
+            placeholder="Game name"
+            name="gamename"
+            value={this.state.gamename}
+            onChange={this.handleChange}
+            id="editGameNameInput"
+            form="gameEditForm"
+            required
+          />
+          <br />
+          <input
+            placeholder="Description"
+            type="text"
+            name="description"
+            value={this.state.description}
+            onChange={this.handleChange}
+            id="editGameDescriptionInput"
+            form="gameEditForm"
+            required
+          />
+          <br />
+          <label className="">Start:</label>
+          <input
+            className="formDate"
+            type="date"
+            name="startDate"
+            value={this.state.startDate}
+            onChange={this.handleChange}
+            id="editGameDateStartInput"
+            form="gameEditForm"
+            required
+          />
+          <input
+            className="formTime"
+            type="time"
+            name="startTime"
+            value={this.state.startTime}
+            onChange={this.handleChange}
+            sid="editGameTimeStartInput"
+            form="gameEditForm"
+            required
+          />
+          <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"
+            form="gameEditForm"
+            required
+          />
+          <input
+            className="formTime"
+            type="time"
+            name="endTime"
+            value={this.state.endTime}
+            onChange={this.handleChange}
+            id="editGameTimeEndInput"
+            form="gameEditForm"
+            required
+          />
+          <br />
+          <br />
+
+          <label>Factions</label>
+          <br />
+          <input
+            name="factionNameInput"
+            value={this.state.factionNameInput}
+            minLength="2"
+            onChange={this.handleChange}
+            placeholder="Add new faction"
+            form="factionAddFrom"
+          />
+          <input
+            name="factionPasswordInput"
+            value={this.state.factionPasswordInput}
+            minLength="3"
+            onChange={this.handleChange}
+            placeholder="Faction password"
+            form="factionAddFrom"
+          />
+          <div
+            style={styles.swatch}
+            onClick={() =>
+              this.setState({
+                displayColorPicker: !this.state.displayColorPicker
+              })
+            }
+          >
+            <div style={styles.color} />
+          </div>
+          {this.state.displayColorPicker && (
+            <div
+              style={styles.cover}
+              onClick={() => this.setState({ displayColorPicker: false })}
             >
-              <TileLayer
-                attribution="Maanmittauslaitoksen kartta"
-                url=" https://tiles.kartat.kapsi.fi/taustakartta/{z}/{x}/{y}.jpg"
+              <SketchPicker
+                color={this.state.factionColorInput}
+                onChangeComplete={color =>
+                  this.setState({ factionColorInput: color.hex })
+                }
               />
-            </Map>
-            <br />
-            <button id="editGameSubmitButton" type="submit">
-              Save changes
-            </button>
-            <h2>{this.state.errorMsg}</h2>
-          </form>
+            </div>
+          )}
+          <button type="submit" form="factionAddFrom">
+            Add
+          </button>
+          <ul>{factions}</ul>
+          <br />
+          <br />
+          <label>Objective points</label>
+          <br />
+          <input
+            name="objectivePointDescriptionInput"
+            type="number"
+            value={this.state.objectivePointDescriptionInput}
+            onChange={this.handleChange}
+            placeholder="Objective point id"
+            min="1000000"
+            form="objectivePointAddFrom"
+          />
+          <input
+            name="objectivePointMultiplierInput"
+            type="number"
+            value={this.state.objectivePointMultiplierInput}
+            onChange={this.handleChange}
+            placeholder="Objective point multiplier"
+            form="objectivePointAddFrom"
+          />
+          <button type="submit" form="objectivePointAddFrom">
+            Add
+          </button>
+          <ul>{objectivePoints}</ul>
+          <br />
+          <br />
+          <label>Node things (set if objective points are in the game)</label>
+          <br />
+          <br />
+          <label className="" form="gameEditForm">
+            Capture time:
+          </label>
+          <input
+            name="capture_time"
+            type="number"
+            value={this.state.capture_time}
+            form="gameEditForm"
+            onChange={this.handleChange}
+          />
+          <label className="">Confimation time:</label>
+          <input
+            name="confirmation_time"
+            type="number"
+            value={this.state.confirmation_time}
+            form="gameEditForm"
+            onChange={this.handleChange}
+          />
+          <br />
+          <br />
+          <label>Map things</label>
+          <br />
+          <Map
+            id="editGameCenterMap"
+            className=""
+            center={[this.state.mapCenter.lat, this.state.mapCenter.lng]}
+            zoom={this.state.zoom}
+            maxZoom="13"
+            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
+            style={{ backgroundColor: "red" }}
+            type="submit"
+            form="gameDeletionForm"
+          >
+            Delete
+          </button>
+          <button id="editGameSubmitButton" type="submit" form="gameEditForm">
+            Save changes
+          </button>
+          <h2>{this.state.errorMsg}</h2>
         </div>
       </div>,
       document.getElementById("form")
diff --git a/src/components/GameSidebar.js b/src/components/GameSidebar.js
new file mode 100644
index 0000000000000000000000000000000000000000..0511cdc3e9762a1e027a7f180ff8112289e5d311
--- /dev/null
+++ b/src/components/GameSidebar.js
@@ -0,0 +1,31 @@
+import React from "react";
+import NewGameForm from "./NewGameForm";
+import GameList from "./GameList";
+
+export default class GameSidebar extends React.Component {
+  state = {
+    form: ""
+  };
+
+  toggleView = view => {
+    this.setState({
+      form: view
+    });
+  };
+
+  render() {
+    return (
+      <div className="game-sidebar">
+        <GameList />
+        {this.props.loggedIn && (
+          <button id="newGameButton" onClick={() => this.toggleView("newgame")}>
+            New Game
+          </button>
+        )}
+        {this.state.form === "newgame" && (
+          <NewGameForm view="" toggleView={() => this.toggleView("")} />
+        )}
+      </div>
+    );
+  }
+}
diff --git a/src/components/Header.js b/src/components/Header.js
index f941d3d6fc83ce7c1cead32a09a5ebead50670da..066b5c08879590f34410982b70174b0906def37b 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -1,11 +1,15 @@
 import React from "react";
-import GameList from "./GameList";
+import LoginForm from "./LoginForm";
+import RegisterForm from "./RegisterForm";
+import TaskListButton from "./TaskListButton";
+import GameSidebar from "./GameSidebar";
 
 class Header extends React.Component {
   state = {
     form: "", // Popup form (login, register etc.)
     username: null,
-    token: null
+    token: null,
+    sidebar: false
   };
 
   // toggles the login/register view
@@ -73,6 +77,7 @@ class Header extends React.Component {
               login
             </button>
           )}
+
           {this.state.username && (
             <button id="logoutButton" onClick={this.handleLogout}>
               logout
@@ -82,8 +87,31 @@ class Header extends React.Component {
           <button id="changeLayerButton" onClick={this.props.handleLayerChange}>
             change layer
           </button>
-          <GameList handleGameChange={this.props.handleGameChange} />
+          {this.state.username && <TaskListButton />}
+          <button
+            id="sidebarButton"
+            onClick={() => this.setState({ sidebar: !this.state.sidebar })}
+          >
+            Tools
+          </button>
+          {this.state.sidebar && (
+            <GameSidebar loggedIn={this.state.username ? true : false} />
+          )}
         </div>
+        {this.state.form === "register" && (
+          <RegisterForm
+            view=""
+            handleState={this.handleState}
+            toggleView={this.toggleView}
+          />
+        )}
+        {this.state.form === "login" && (
+          <LoginForm
+            view=""
+            handleState={this.handleState}
+            toggleView={this.toggleView}
+          />
+        )}
       </div>
     );
   }
diff --git a/src/components/JoinGameForm.js b/src/components/JoinGameForm.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ea0aaf958683a807ee73ed23abe19882f591fe7
--- /dev/null
+++ b/src/components/JoinGameForm.js
@@ -0,0 +1,41 @@
+import React from "react";
+
+export default class JoinGameForm extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      gameJSON: undefined
+    };
+  }
+
+  componentDidMount() {
+    if (this.props.gameId === undefined) {
+      alert("game not selected");
+    } else {
+      fetch(`${process.env.REACT_APP_API_URL}/game/${this.props.gameId}`)
+        .then(result => result.json())
+        .then(json => {
+          this.setState({
+            gameJSON: json
+          });
+        })
+        .catch(error => console.log(error));
+    }
+  }
+
+  render() {
+    if (this.state.gameJSON === undefined) {
+      return false;
+    }
+
+    return (
+      <div>
+        <form>
+          <label>Join game: {this.state.gameJSON.name}</label>
+          <div>{this.state.gameJSON.desc}</div>
+          <button onClick={() => console.log("clicked")}>Submit</button>
+        </form>
+      </div>
+    );
+  }
+}
diff --git a/src/components/NewGameForm.js b/src/components/NewGameForm.js
index e84940d00c6619d3793d5b9cc5746ebf3269e36c..778373289f9a0980b688469baa3e05f409d4c59e 100644
--- a/src/components/NewGameForm.js
+++ b/src/components/NewGameForm.js
@@ -86,7 +86,12 @@ export class NewGameForm extends React.Component {
     })
       .then(res => res.json())
       .then(result => {
-        this.handleView();
+        if (result.code) {
+          alert(result.message);
+        } else {
+          alert(`Game ${this.state.gamename} added`);
+          this.handleView();
+        }
       })
       .catch(error => console.log("Error: ", error));
   };
@@ -112,83 +117,98 @@ export class NewGameForm extends React.Component {
           </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"
+          <form id="gameCreationForm" onSubmit={this.handleGameCreation} />
+          <h1>Demo Game Creation</h1>
+          <br />
+          <input
+            placeholder="Game name"
+            name="gamename"
+            value={this.state.gamename}
+            onChange={this.handleChange}
+            id="newGameNameInput"
+            form="gameCreationForm"
+            required
+          />
+          <br />
+          <input
+            placeholder="Description"
+            type="text"
+            name="description"
+            value={this.state.description}
+            onChange={this.handleChange}
+            id="newGameDescriptionInput"
+            form="gameCreationForm"
+            required
+          />
+          <br />
+          <label className="">Start:</label>
+          <input
+            className="formDate"
+            type="date"
+            name="startDate"
+            value={this.state.startDate}
+            onChange={this.handleChange}
+            id="newGameDateStartInput"
+            form="gameCreationForm"
+            required
+          />
+          <input
+            className="formTime"
+            type="time"
+            name="startTime"
+            onChange={this.handleChange}
+            id="newGameTimeStartInput"
+            form="gameCreationForm"
+            required
+          />
+          <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"
+            form="gameCreationForm"
+            required
+          />
+          <input
+            className="formTime"
+            type="time"
+            name="endTime"
+            onChange={this.handleChange}
+            id="newGameTimeEndInput"
+            form="gameCreationForm"
+            required
+          />
+          <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"
             />
-            <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>
+          </Map>
+          <br />
+          <button
+            id="newGameSubmitButton"
+            type="submit"
+            form="gameCreationForm"
+          >
+            Submit
+          </button>
+          <h2>{this.state.errorMsg}</h2>
         </div>
       </div>,
       document.getElementById("form")
diff --git a/src/components/RegisterForm.js b/src/components/RegisterForm.js
index b1357b7c9a45a74653e643ee45368a5df4305c64..832de85fafaa6a87f06247142d87554e17b697b7 100644
--- a/src/components/RegisterForm.js
+++ b/src/components/RegisterForm.js
@@ -63,7 +63,7 @@ export class RegisterForm extends React.Component {
               this.props.handleState(result);
               this.handleView();
             } else {
-              this.handleError(result.errorResponse.message);
+              this.handleError(result.message);
             }
           },
           // Note: it's important to handle errors here
@@ -83,7 +83,7 @@ export class RegisterForm extends React.Component {
   componentWillUnmount() {
     document.removeEventListener("keyup", this.handleEsc);
   }
-
+  // UNCOMMENT "REQUIRED" FOR PRODUCTION
   render() {
     return (
       <div className="fade-main">
diff --git a/src/components/TaskItem.js b/src/components/TaskItem.js
new file mode 100644
index 0000000000000000000000000000000000000000..620ba85b27a310ef6a284cfd563e88695d5cfa0a
--- /dev/null
+++ b/src/components/TaskItem.js
@@ -0,0 +1,119 @@
+import React from "react";
+
+class TaskItem extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      edit: false,
+      selectedFactionId: "",
+      factions: []
+    };
+  }
+
+  componentDidMount() {
+    this.getFactionlist(this.props.gameId);
+  }
+
+  onEditClick = e => {
+    this.setState({
+      edit: !this.state.edit
+    });
+  };
+
+  getFactionlist(gameId) {
+    fetch(`${process.env.REACT_APP_URL}/game/${gameId}`, {
+      method: "GET"
+    })
+      .then(result => {
+        if (!result.ok) {
+          throw Error(result.responseText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        this.setState({
+          factions: result.factions,
+          selectedFactionId: result.factions[0].factionId
+        });
+      })
+      .catch(error => console.log(error));
+  }
+
+  onSaveSubmit = e => {
+    e.preventDefault();
+    this.props.onSave(this.props.task, this.state.selectedFactionId);
+    this.setState({
+      edit: false
+    });
+  };
+
+  handleFactionChange = e => {
+    this.setState({
+      selectedFactionId: e.target.value
+    });
+  };
+
+  onTaskDelete = e => {
+    e.preventDefault();
+    this.props.onDelete(this.props.task.taskId);
+    this.setState({
+      edit: false
+    });
+  };
+
+  render() {
+    let factionlistItems = [];
+    for (let i = 0; i < this.state.factions.length; i++) {
+      const faction = this.state.factions[i];
+      factionlistItems.push(
+        <option key={faction.factionId} value={faction.factionId}>
+          {faction.factionName}
+        </option>
+      );
+    }
+
+    return (
+      <div className="tasklist-item">
+        <div>
+          <label>{this.props.task.taskName}</label>
+        </div>
+        <div>
+          <label>{this.props.task.taskDescription}</label>
+          <br />
+          <label>
+            Faction:{" "}
+            {this.props.task.faction !== null
+              ? this.props.task.faction.factionName
+              : "Every faction"}
+          </label>
+          <br />
+          {this.props.task.taskWinner !== null && (
+            <label>Winner: {this.props.task.taskWinner.factionName}</label>
+          )}
+        </div>
+        {this.props.task.taskIsActive && (
+          <button onClick={this.onEditClick}>Edit</button>
+        )}
+        {this.state.edit && (
+          <form onSubmit={this.onSaveSubmit}>
+            <select
+              value={this.state.selectedFactionId}
+              onChange={e =>
+                this.setState({ selectedFactionId: e.target.value })
+              }
+            >
+              {factionlistItems}
+            </select>
+            <button type="submit">Save</button>
+          </form>
+        )}
+        <button onClick={this.onTaskDelete} style={{ backgroundColor: "red" }}>
+          Delete
+        </button>
+      </div>
+    );
+  }
+}
+
+export default TaskItem;
diff --git a/src/components/TaskList.js b/src/components/TaskList.js
new file mode 100644
index 0000000000000000000000000000000000000000..fedbc03ae0dbac449f8aa4c7518dcca03597b897
--- /dev/null
+++ b/src/components/TaskList.js
@@ -0,0 +1,255 @@
+import ReactDOM from "react-dom";
+import React from "react";
+import TaskItem from "./TaskItem";
+
+class TaskList extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      taskNameInput: "", // >= 3
+      taskDescriptionInput: "", // no limits
+      tasks: [],
+      factionlist: [],
+      selectedFactionId: ""
+    };
+  }
+
+  componentDidMount() {
+    this.getTasks(this.props.gameId);
+    this.getFactionlist(this.props.gameId); // TODO: remove if the user is not admin?
+  }
+
+  getTasks(gameId) {
+    let token = sessionStorage.getItem("token");
+    fetch(`${process.env.REACT_APP_URL}/task/get-tasks/${gameId}`, {
+      method: "GET",
+      headers: {
+        Authorization: "Bearer " + token
+      }
+    })
+      .then(result => {
+        if (!result.ok) {
+          throw Error(result.responseText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        this.setState({
+          tasks: result
+        });
+      })
+      .catch(error => console.log(error));
+  }
+
+  getFactionlist(gameId) {
+    fetch(`${process.env.REACT_APP_URL}/game/${gameId}`, {
+      method: "GET"
+    })
+      .then(result => {
+        if (!result.ok) {
+          throw Error(result.responseText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        this.setState({
+          factionlist: result.factions
+        });
+      })
+      .catch(error => console.log(error));
+  }
+
+  handleTaskCreation = e => {
+    e.preventDefault();
+    if (this.state.taskNameInput === "") {
+      return alert("Task needs a name");
+    }
+
+    let token = sessionStorage.getItem("token");
+    fetch(`${process.env.REACT_APP_URL}/task/new-task/${this.props.gameId}`, {
+      method: "POST",
+      headers: {
+        Authorization: "Bearer " + token,
+        "Content-Type": "application/json"
+      },
+      body: JSON.stringify({
+        taskName: this.state.taskNameInput,
+        taskDescription: this.state.taskDescriptionInput,
+        taskIsActive: true,
+        faction:
+          this.state.selectedFactionId === ""
+            ? null
+            : this.state.selectedFactionId,
+        taskWinner: null,
+        taskGame: this.props.gameId
+      })
+    })
+      .then(result => {
+        if (!result.ok) {
+          throw Error(Response.statusText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        alert(result.message);
+        this.setState({
+          taskDescriptionInput: "",
+          taskNameInput: ""
+        });
+        this.getTasks(this.props.gameId);
+      })
+      .catch(error => console.log(error));
+  };
+
+  handleFactionChange = e => {
+    this.setState({
+      selectedFactionId: e.target.value
+    });
+  };
+
+  onTaskEditSave = (task, winnerFactionId) => {
+    let token = sessionStorage.getItem("token");
+    fetch(`${process.env.REACT_APP_URL}/task/edit-task/${this.props.gameId}`, {
+      method: "POST",
+      headers: {
+        Authorization: "Bearer " + token,
+        "Content-Type": "application/json"
+      },
+      body: JSON.stringify({
+        taskId: task.taskId,
+        taskWinner: winnerFactionId,
+        taskGame: this.props.gameId
+      })
+    })
+      .then(result => {
+        if (!result.ok) {
+          throw Error(result.responseText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        alert(result.message);
+        this.getTasks(this.props.gameId);
+      })
+      .catch(error => console.log(error));
+  };
+
+  onTaskDeletion = taskId => {
+    if (taskId === (undefined || null)) {
+      return;
+    }
+    let token = sessionStorage.getItem("token");
+    fetch(
+      `${process.env.REACT_APP_URL}/task/delete-task/${this.props.gameId}`,
+      {
+        method: "DELETE",
+        headers: {
+          Authorization: "Bearer " + token,
+          "Content-Type": "application/json"
+        },
+        body: JSON.stringify({
+          taskId: taskId
+        })
+      }
+    )
+      .then(result => {
+        if (!result.ok) {
+          throw Error(result.responseText);
+        } else {
+          return result.json();
+        }
+      })
+      .then(result => {
+        alert(result.message);
+        this.getTasks(this.props.gameId);
+      })
+      .catch(error => console.log(error));
+  };
+
+  render() {
+    let incompleteTasks = [];
+    let completedTasks = [];
+    for (let i = 0; i < this.state.tasks.length; i++) {
+      const task = this.state.tasks[i];
+      if (task.taskWinner !== null) {
+        completedTasks.push(
+          <TaskItem
+            key={task.taskId}
+            task={task}
+            gameId={this.props.gameId}
+            onSave={this.onTaskEditSave}
+            onDelete={this.onTaskDeletion}
+          />
+        );
+      } else {
+        incompleteTasks.push(
+          <TaskItem
+            key={task.taskId}
+            task={task}
+            gameId={this.props.gameId}
+            onSave={this.onTaskEditSave}
+            onDelete={this.onTaskDeletion}
+          />
+        );
+      }
+    }
+
+    let factionlistItems = this.state.factionlist.map(item => {
+      return (
+        <option key={item.factionId} value={item.factionId}>
+          {item.factionName}
+        </option>
+      );
+    });
+
+    // add all factions option to the faction list
+    factionlistItems.unshift(
+      <option key="all" value="">
+        Every faction
+      </option>
+    );
+
+    return ReactDOM.createPortal(
+      <div className="tasklist">
+        <h1>Tasklist</h1>
+        <form className="task-form" onSubmit={this.handleTaskCreation}>
+          <label>New task</label>
+          <input
+            id="taskNameInput"
+            type="text"
+            placeholder="Task name"
+            minLength="3"
+            value={this.state.taskNameInput}
+            onChange={e => this.setState({ taskNameInput: e.target.value })}
+          />
+          <textarea
+            id="taskDescriptionInput"
+            placeholder="Task description"
+            value={this.state.taskDescriptionInput}
+            onChange={e =>
+              this.setState({ taskDescriptionInput: e.target.value })
+            }
+          />
+          <select id="taskFactionSelect" onChange={this.handleFactionChange}>
+            {factionlistItems}
+          </select>
+          <button id="newTaskSubmitButton" type="submit">
+            Add new task
+          </button>
+        </form>
+        {incompleteTasks}
+        <br />
+        <label>Completed tasks</label>
+        {completedTasks}
+        <br />
+      </div>,
+      document.getElementById("tasklist")
+    );
+  }
+}
+
+export default TaskList;
diff --git a/src/components/TaskListButton.js b/src/components/TaskListButton.js
new file mode 100644
index 0000000000000000000000000000000000000000..988beab9c3b21520190f5fde33774e76ac74ba35
--- /dev/null
+++ b/src/components/TaskListButton.js
@@ -0,0 +1,53 @@
+import React, { Fragment } from "react";
+import TaskList from "./TaskList";
+
+class TaskListButton extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      open: false,
+      newTasks: 0
+    };
+
+    this.handleClick = this.handleClick.bind(this);
+  }
+
+  componentDidMount() {
+    this.getNewTask();
+  }
+
+  getNewTask() {
+    this.setState({
+      newTasks: this.state.open ? 0 : this.state.newTasks + 1
+    });
+  }
+
+  handleClick = e => {
+    this.setState(
+      {
+        open: !this.state.open
+      },
+      () => {
+        // Set new task cout to zero when the tasklist opens
+        if (this.state.open) {
+          this.setState({ newTasks: 0 });
+        }
+      }
+    );
+  };
+
+  render() {
+    return (
+      <Fragment>
+        <button id="tasklistButton" onClick={this.handleClick}>
+          Tasks ({this.state.newTasks})
+        </button>
+        {this.state.open && (
+          <TaskList gameId="2c097e6a-591c-4a27-b7cb-38eb44e1f31c" />
+        )}
+      </Fragment>
+    );
+  }
+}
+
+export default TaskListButton;