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 7d7f9508468c0da993d1991880bbf8fde6c93677..61ee8dc196700804d4f532ea9d6751894a57cd97 100644
--- a/src/App.css
+++ b/src/App.css
@@ -197,3 +197,18 @@ div.login button:hover {
   text-shadow: none;
   font-weight: normal;
 }
+.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/Header.js b/src/components/Header.js
index 0663cc382019e1aa00f9757a98b4fe5fb1a5508f..422e9be78a823b7c2f778898b0c00a64381cb04a 100644
--- a/src/components/Header.js
+++ b/src/components/Header.js
@@ -1,9 +1,10 @@
-import React from 'react';
+import React from "react";
 
-import LoginForm from './LoginForm';
-import RegisterForm from './RegisterForm';
-import GameList from './GameList';
-import NewGameForm from './NewGameForm';
+import LoginForm from "./LoginForm";
+import RegisterForm from "./RegisterForm";
+import GameList from "./GameList";
+import NewGameForm from "./NewGameForm";
+import TaskListButton from "./TaskListButton";
 
 class Header extends React.Component {
   constructor(props) {
@@ -11,7 +12,7 @@ class Header extends React.Component {
   }
 
   state = {
-    form: '', // Popup form (login, register etc.)
+    form: "", // Popup form (login, register etc.)
     username: null,
     token: null
   };
@@ -24,23 +25,23 @@ class Header extends React.Component {
   };
 
   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_API_URL}/user/verify`, {
         headers: {
-          Authorization: 'Bearer ' + token
+          Authorization: "Bearer " + token
         }
       })
         .then(res => res.json())
@@ -49,7 +50,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
@@ -67,56 +68,57 @@ class Header extends React.Component {
   render() {
     return (
       <div>
-        <div className='header'>
+        <div className="header">
           {!this.state.username && (
             <button
-              id='registerButton'
-              onClick={() => this.toggleView('register')}
+              id="registerButton"
+              onClick={() => this.toggleView("register")}
             >
               register
             </button>
           )}
           {!this.state.username && (
-            <button id='loginButton' onClick={() => this.toggleView('login')}>
+            <button id="loginButton" onClick={() => this.toggleView("login")}>
               login
             </button>
           )}
           {this.state.username && (
             <button
-              id='newGameButton'
-              onClick={() => this.toggleView('newgame')}
+              id="newGameButton"
+              onClick={() => this.toggleView("newgame")}
             >
               New Game
             </button>
           )}
           {this.state.username && (
-            <button id='logoutButton' onClick={this.handleLogout}>
+            <button id="logoutButton" onClick={this.handleLogout}>
               logout
             </button>
           )}
           {this.state.username && <button>{this.state.username}</button>}
-          <button id='changeLayerButton' onClick={this.props.handleLayerChange}>
+          <button id="changeLayerButton" onClick={this.props.handleLayerChange}>
             change layer
           </button>
           <GameList handleGameChange={this.props.handleGameChange} />
+          {this.state.username && <TaskListButton />}
         </div>
-        {this.state.form === 'register' && (
+        {this.state.form === "register" && (
           <RegisterForm
-            view=''
+            view=""
             handleState={this.handleState}
             toggleView={this.toggleView}
           />
         )}
-        {this.state.form === 'login' && (
+        {this.state.form === "login" && (
           <LoginForm
-            view=''
+            view=""
             handleState={this.handleState}
             toggleView={this.toggleView}
           />
         )}
-        {this.state.form === 'newgame' && (
+        {this.state.form === "newgame" && (
           <NewGameForm
-            view=''
+            view=""
             handleState={this.handleState}
             toggleView={this.toggleView}
           />
diff --git a/src/components/TaskItem.js b/src/components/TaskItem.js
new file mode 100644
index 0000000000000000000000000000000000000000..7b53d079ca501eef11a9a1bcc57e5f096cf10a36
--- /dev/null
+++ b/src/components/TaskItem.js
@@ -0,0 +1,119 @@
+import React, { Fragment } 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;