diff --git a/backend/secfit/requirements.txt b/backend/secfit/requirements.txt
index bb4d37fd1a49afc92c9df6f535c4956fdebb805b..99bebaa8f4285653b160bd34a44af2eccc791ae5 100644
Binary files a/backend/secfit/requirements.txt and b/backend/secfit/requirements.txt differ
diff --git a/backend/secfit/workouts/admin.py b/backend/secfit/workouts/admin.py
index cb43794b85492adcb933dc4e46f875029dc411cf..777980c0f343933b46363a7fb467c960ea514d25 100644
--- a/backend/secfit/workouts/admin.py
+++ b/backend/secfit/workouts/admin.py
@@ -9,3 +9,4 @@ admin.site.register(Exercise)
 admin.site.register(ExerciseInstance)
 admin.site.register(Workout)
 admin.site.register(WorkoutFile)
+
diff --git a/backend/secfit/workouts/migrations/0004_workout_planned.py b/backend/secfit/workouts/migrations/0004_workout_planned.py
new file mode 100644
index 0000000000000000000000000000000000000000..caccf27985e04eb3cfb1ef65cba921359a4c5c0f
--- /dev/null
+++ b/backend/secfit/workouts/migrations/0004_workout_planned.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1 on 2021-02-27 12:48
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('workouts', '0003_rememberme'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='workout',
+            name='planned',
+            field=models.BooleanField(default=False),
+        ),
+    ]
diff --git a/backend/secfit/workouts/models.py b/backend/secfit/workouts/models.py
index 5e3c6d1614d54992b42491bee8207a65410c5961..108cb597a8a35ca00295e97116699c53ecabd364 100644
--- a/backend/secfit/workouts/models.py
+++ b/backend/secfit/workouts/models.py
@@ -38,6 +38,7 @@ class Workout(models.Model):
         notes:       Notes about the workout
         owner:       User that logged the workout
         visibility:  The visibility level of the workout: Public, Coach, or Private
+        planned:     Indicates if it is a planned workout
     """
 
     name = models.CharField(max_length=100)
@@ -46,6 +47,7 @@ class Workout(models.Model):
     owner = models.ForeignKey(
         get_user_model(), on_delete=models.CASCADE, related_name="workouts"
     )
+    planned = models.BooleanField(default=False)
 
     # Visibility levels
     PUBLIC = "PU"  # Visible to all authenticated users
@@ -67,7 +69,6 @@ class Workout(models.Model):
     def __str__(self):
         return self.name
 
-
 class Exercise(models.Model):
     """Django model for an exercise type that users can create.
 
diff --git a/backend/secfit/workouts/serializers.py b/backend/secfit/workouts/serializers.py
index a966ed3d752dcf54767a10f2b4b53d416e095a33..b36de6aefd2025a81fda2bfb1b32edf1544090a1 100644
--- a/backend/secfit/workouts/serializers.py
+++ b/backend/secfit/workouts/serializers.py
@@ -3,6 +3,8 @@
 from rest_framework import serializers
 from rest_framework.serializers import HyperlinkedRelatedField
 from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile, RememberMe
+from datetime import datetime
+import pytz
 
 
 class ExerciseInstanceSerializer(serializers.HyperlinkedModelSerializer):
@@ -52,7 +54,7 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
     This serializer specifies nested serialization since a workout consists of WorkoutFiles
     and ExerciseInstances.
 
-    Serialized fields: url, id, name, date, notes, owner, owner_username, visiblity,
+    Serialized fields: url, id, name, date, notes, owner, planned, owner_username, visiblity,
                        exercise_instances, files
 
     Attributes:
@@ -74,6 +76,7 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
             "date",
             "notes",
             "owner",
+            "planned",
             "owner_username",
             "visibility",
             "exercise_instances",
@@ -93,6 +96,19 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
         Returns:
             Workout: A newly created Workout
         """
+        # Check if date is valid
+        timeNow = datetime.now()
+        timeNowAdjusted = pytz.utc.localize(timeNow)
+
+        if validated_data["planned"]:
+            if timeNowAdjusted >= validated_data["date"]:
+                raise serializers.ValidationError(
+                    {"date": ["Date must be a future date"]})
+        else:
+            if timeNowAdjusted <= validated_data["date"]:
+                raise serializers.ValidationError(
+                    {"date": ["Date must be an old date"]})
+
         exercise_instances_data = validated_data.pop("exercise_instances")
         files_data = []
         if "files" in validated_data:
@@ -101,10 +117,12 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
         workout = Workout.objects.create(**validated_data)
 
         for exercise_instance_data in exercise_instances_data:
-            ExerciseInstance.objects.create(workout=workout, **exercise_instance_data)
+            ExerciseInstance.objects.create(
+                workout=workout, **exercise_instance_data)
         for file_data in files_data:
             WorkoutFile.objects.create(
-                workout=workout, owner=workout.owner, file=file_data.get("file")
+                workout=workout, owner=workout.owner, file=file_data.get(
+                    "file")
             )
 
         return workout
@@ -122,12 +140,27 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
         Returns:
             Workout: Updated Workout instance
         """
+        # Add date and planned check
+        # Check if date is valid
+        timeNow = datetime.now()
+        timeNowAdjusted = pytz.utc.localize(timeNow)
+
+        if validated_data["planned"]:
+            if timeNowAdjusted >= validated_data["date"]:
+                raise serializers.ValidationError(
+                    {"date": ["Date must be a future date"]})
+        else:
+            if timeNowAdjusted <= validated_data["date"]:
+                raise serializers.ValidationError(
+                    {"date": ["Date must be an old date"]})
+
         exercise_instances_data = validated_data.pop("exercise_instances")
         exercise_instances = instance.exercise_instances
 
         instance.name = validated_data.get("name", instance.name)
         instance.notes = validated_data.get("notes", instance.notes)
-        instance.visibility = validated_data.get("visibility", instance.visibility)
+        instance.visibility = validated_data.get(
+            "visibility", instance.visibility)
         instance.date = validated_data.get("date", instance.date)
         instance.save()
 
diff --git a/backend/secfit/workouts/views.py b/backend/secfit/workouts/views.py
index efddf40454376b23d233f9fe2cecaf9da43fddb8..2026d46fb1f6a9638a4ed23d997ef10cfb26a7d5 100644
--- a/backend/secfit/workouts/views.py
+++ b/backend/secfit/workouts/views.py
@@ -31,8 +31,11 @@ from rest_framework_simplejwt.tokens import RefreshToken
 from rest_framework.response import Response
 import json
 from collections import namedtuple
-import base64, pickle
+import base64
+import pickle
 from django.core.signing import Signer
+from datetime import datetime
+import pytz
 
 
 @api_view(["GET"])
@@ -141,6 +144,16 @@ class WorkoutList(
                 Q(visibility="PU")
                 | (Q(visibility="CO") & Q(owner__coach=self.request.user))
             ).distinct()
+            # Check if the planned workout has happened
+            if len(qs) > 0:
+                timeNow = datetime.now()
+                timeNowAdjusted = pytz.utc.localize(timeNow)
+                for i in range(0, len(qs)):
+                    if qs[i].planned:
+                        if timeNowAdjusted > qs[i].date:
+                            # Update: set planned to false
+                            qs[i].planned = False
+                            qs[i].save()
 
         return qs
 
@@ -155,7 +168,6 @@ class WorkoutDetail(
 
     HTTP methods: GET, PUT, DELETE
     """
-
     queryset = Workout.objects.all()
     serializer_class = WorkoutSerializer
     permission_classes = [
diff --git a/frontend/www/plannedWorkout.html b/frontend/www/plannedWorkout.html
new file mode 100644
index 0000000000000000000000000000000000000000..f66b88c6b0e77fb44ff64a7465336dc7042fafa6
--- /dev/null
+++ b/frontend/www/plannedWorkout.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Workout</title>
+
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
+
+    <script src="https://kit.fontawesome.com/0ce6c392ca.js" crossorigin="anonymous"></script>
+    <link rel="stylesheet" href="styles/style.css">
+    <script src="scripts/navbar.js" type="text/javascript" defer></script>
+</head>
+<body>
+  <navbar-el></navbar-el>
+
+    <div class="container">
+        <div class="row">
+            <div class="col-lg">
+                <h3 class="mt-3">View/Edit Planned Workout</h3>
+            </div>
+          </div>
+        <div class="row">
+          <div class="col-lg">
+            <p class="mt-4">A planned workout is a future workout that will be autologged</h3>
+          </div>
+        </div>       
+    <form class="row g-3 mb-4" id="form-workout">
+        <div class="col-lg-6 ">
+          <label for="inputName" class="form-label">Name</label>
+          <input type="text" class="form-control" id="inputName" name="name" readonly>
+        </div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-6">
+          <label for="inputDateTime" class="form-label">Date/Time</label>
+          <input type="datetime-local" class="form-control" id="inputDateTime" name="date" readonly>
+        </div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-6">
+            <label for="inputOwner" class="form-label">Owner</label>
+            <input type="text" class="form-control" id="inputOwner" name="owner_username" readonly>
+        </div>
+        <div class="col-lg-6">
+          <label for="inputVisibility" class="form-label">Visibility</label>
+          <select id="inputVisibility" class="form-select" name="visibility" disabled>
+            <option value="PU">Public</option>
+            <option value="CO">Coach</option>
+            <option value="PR">Private</option>
+          </select>
+        </div>
+        <div class="col-lg-6">
+          <label for="inputNotes" class="form-label">Notes</label>
+          <textarea class="form-control" id="inputNotes" name="notes" readonly></textarea>
+        </div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-6">
+          <div class="input-group">
+              <input type="file" class="form-control" id="customFile" name="files" multiple disabled>
+          </div>
+          <div id="uploaded-files" class="ms-1 mt-2">            
+          </div>
+        </div>
+        <div class="col-lg-6">
+        </div>
+        <div class="col-lg-6">
+          <input type="button" class="btn btn-primary hide" id="btn-ok-workout" value="  OK  ">
+          <input type="button" class="btn btn-primary hide" id="btn-edit-workout" value=" Edit ">
+          <input type="button" class="btn btn-secondary hide" id="btn-cancel-workout" value="Cancel">
+          <input type="button" class="btn btn-danger float-end hide" id="btn-delete-workout" value="Delete">
+        </div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-12">
+            <h3 class="mt-3">Exercises</h3>
+        </div>
+        <div id="div-exercises" class="col-lg-12">
+        </div>
+        <div class="col-lg-6">
+          <input type="button" class="btn btn-primary hide" id="btn-add-exercise" value="Add exercise">
+          <input type="button" class="btn btn-danger hide" id="btn-remove-exercise" value="Remove exercise">
+        </div>
+        <div class="col-lg-6"></div>
+
+      </form>
+      <div class="row bootstrap snippets bootdeys" id="div-comment-row">
+              <div class="col-md-8 col-sm-12">
+                  <div class="comment-wrapper">
+                      <div class="card">
+                          <div class="card-header bg-primary text-light">
+                              Comment panel
+                          </div>
+                          <div class="card-body">
+                              <textarea class="form-control" id="comment-area" placeholder="write a comment..." rows="3"></textarea>
+                              <br>
+                              <button type="button" id="post-comment" class="btn btn-info pull-right">Post</button>
+                              <div class="clearfix"></div>
+                              <hr>
+                              <ul id="comment-list" class="list-unstyled">
+                              </ul>
+                          </div>
+                      </div>
+                  </div>
+          
+              </div>
+          </div>
+          </div> 
+
+    <template id="template-exercise">
+      <div class="row div-exercise-container g-3 mb-3">
+        <div class="col-lg-6"><h5>Exercise</h5></div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-6">
+          <label class="form-label exercise-type">Type</label>
+          <select class="form-select" name="type">
+          </select>
+        </div>
+        <div class="col-lg-6"></div>
+        <div class="col-lg-3">
+          <label class="form-label exercise-sets">Sets</label>
+          <input type="number" class="form-control" name="sets">
+        </div>
+        <div class="col-lg-3">
+          <label class="form-label exercise-number">Number</label>
+          <input type="number" class="form-control" name="number">
+        </div>
+        <div class="col-lg-6"></div>
+      </div>
+    </template>
+    
+    <script src="scripts/defaults.js"></script>
+    <script src="scripts/scripts.js"></script>
+    <script src="scripts/plannedWorkout.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
+  </body>
+</html>
\ No newline at end of file
diff --git a/frontend/www/scripts/plannedWorkout.js b/frontend/www/scripts/plannedWorkout.js
new file mode 100644
index 0000000000000000000000000000000000000000..da55ea239787a25d9591b7f1e7e3465238d560f3
--- /dev/null
+++ b/frontend/www/scripts/plannedWorkout.js
@@ -0,0 +1,426 @@
+let cancelWorkoutButton;
+let okWorkoutButton;
+let deleteWorkoutButton;
+let editWorkoutButton;
+let postCommentButton;
+
+async function retrieveWorkout(id) {
+  let workoutData = null;
+  let response = await sendRequest("GET", `${HOST}/api/workouts/${id}/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not retrieve workout data!", data);
+    document.body.prepend(alert);
+  } else {
+    workoutData = await response.json();
+    let form = document.querySelector("#form-workout");
+    let formData = new FormData(form);
+
+    for (let key of formData.keys()) {
+      let selector = `input[name="${key}"], textarea[name="${key}"]`;
+      let input = form.querySelector(selector);
+      let newVal = workoutData[key];
+      if (key == "date") {
+        // Creating a valid datetime-local string with the correct local time
+        let date = new Date(newVal);
+        date = new Date(
+          date.getTime() - date.getTimezoneOffset() * 60 * 1000
+        ).toISOString(); // get ISO format for local time
+        newVal = date.substring(0, newVal.length - 1); // remove Z (since this is a local time, not UTC)
+      }
+      if (key != "files") {
+        input.value = newVal;
+      }
+    }
+
+    let input = form.querySelector("select:disabled");
+    input.value = workoutData["visibility"];
+    // files
+    let filesDiv = document.querySelector("#uploaded-files");
+    for (let file of workoutData.files) {
+      let a = document.createElement("a");
+      a.href = file.file;
+      let pathArray = file.file.split("/");
+      a.text = pathArray[pathArray.length - 1];
+      a.className = "me-2";
+      filesDiv.appendChild(a);
+    }
+
+    // create exercises
+
+    // fetch exercise types
+    let exerciseTypeResponse = await sendRequest(
+      "GET",
+      `${HOST}/api/exercises/`
+    );
+    let exerciseTypes = await exerciseTypeResponse.json();
+
+    //TODO: This should be in its own method.
+    for (let i = 0; i < workoutData.exercise_instances.length; i++) {
+      let templateExercise = document.querySelector("#template-exercise");
+      let divExerciseContainer = templateExercise.content.firstElementChild.cloneNode(
+        true
+      );
+
+      let exerciseTypeLabel = divExerciseContainer.querySelector(
+        ".exercise-type"
+      );
+      exerciseTypeLabel.for = `inputExerciseType${i}`;
+
+      let exerciseTypeSelect = divExerciseContainer.querySelector("select");
+      exerciseTypeSelect.id = `inputExerciseType${i}`;
+      exerciseTypeSelect.disabled = true;
+
+      let splitUrl = workoutData.exercise_instances[i].exercise.split("/");
+      let currentExerciseTypeId = splitUrl[splitUrl.length - 2];
+      let currentExerciseType = "";
+
+      for (let j = 0; j < exerciseTypes.count; j++) {
+        let option = document.createElement("option");
+        option.value = exerciseTypes.results[j].id;
+        if (currentExerciseTypeId == exerciseTypes.results[j].id) {
+          currentExerciseType = exerciseTypes.results[j];
+        }
+        option.innerText = exerciseTypes.results[j].name;
+        exerciseTypeSelect.append(option);
+      }
+
+      exerciseTypeSelect.value = currentExerciseType.id;
+
+      let exerciseSetLabel = divExerciseContainer.querySelector(
+        ".exercise-sets"
+      );
+      exerciseSetLabel.for = `inputSets${i}`;
+
+      let exerciseSetInput = divExerciseContainer.querySelector(
+        "input[name='sets']"
+      );
+      exerciseSetInput.id = `inputSets${i}`;
+      exerciseSetInput.value = workoutData.exercise_instances[i].sets;
+      exerciseSetInput.readOnly = true;
+
+      let exerciseNumberLabel = divExerciseContainer.querySelector(
+        ".exercise-number"
+      );
+      (exerciseNumberLabel.for = "for"), `inputNumber${i}`;
+      exerciseNumberLabel.innerText = currentExerciseType.unit;
+
+      let exerciseNumberInput = divExerciseContainer.querySelector(
+        "input[name='number']"
+      );
+      exerciseNumberInput.id = `inputNumber${i}`;
+      exerciseNumberInput.value = workoutData.exercise_instances[i].number;
+      exerciseNumberInput.readOnly = true;
+
+      let exercisesDiv = document.querySelector("#div-exercises");
+      exercisesDiv.appendChild(divExerciseContainer);
+    }
+  }
+  return workoutData;
+}
+
+function handleCancelDuringWorkoutEdit() {
+  location.reload();
+}
+
+function handleEditWorkoutButtonClick() {
+  let addExerciseButton = document.querySelector("#btn-add-exercise");
+  let removeExerciseButton = document.querySelector("#btn-remove-exercise");
+
+  setReadOnly(false, "#form-workout");
+  document.querySelector("#inputOwner").readOnly = true; // owner field should still be readonly
+
+  editWorkoutButton.className += " hide";
+  okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
+  cancelWorkoutButton.className = cancelWorkoutButton.className.replace(
+    " hide",
+    ""
+  );
+  deleteWorkoutButton.className = deleteWorkoutButton.className.replace(
+    " hide",
+    ""
+  );
+  addExerciseButton.className = addExerciseButton.className.replace(
+    " hide",
+    ""
+  );
+  removeExerciseButton.className = removeExerciseButton.className.replace(
+    " hide",
+    ""
+  );
+
+  cancelWorkoutButton.addEventListener("click", handleCancelDuringWorkoutEdit);
+}
+
+async function deleteWorkout(id) {
+  let response = await sendRequest("DELETE", `${HOST}/api/workouts/${id}/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert(`Could not delete workout ${id}!`, data);
+    document.body.prepend(alert);
+  } else {
+    window.location.replace("workouts.html");
+  }
+}
+
+async function updateWorkout(id) {
+  let submitForm = generateWorkoutForm();
+
+  let response = await sendRequest(
+    "PUT",
+    `${HOST}/api/workouts/${id}/`,
+    submitForm,
+    ""
+  );
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not update workout!", data);
+    document.body.prepend(alert);
+  } else {
+    location.reload();
+  }
+}
+
+function generateWorkoutForm() {
+  // TODO: Add check for future date
+  var today = new Date().toISOString();
+
+  document.querySelector("#inputDateTime").min = today;
+
+  let form = document.querySelector("#form-workout");
+
+  let formData = new FormData(form);
+  let submitForm = new FormData();
+
+  submitForm.append("name", formData.get("name"));
+  let date = new Date(formData.get("date")).toISOString();
+  submitForm.append("date", date);
+  submitForm.append("notes", formData.get("notes"));
+  submitForm.append("visibility", formData.get("visibility"));
+  submitForm.append("planned", true);
+
+  // adding exercise instances
+  let exerciseInstances = [];
+  let exerciseInstancesTypes = formData.getAll("type");
+  let exerciseInstancesSets = formData.getAll("sets");
+  let exerciseInstancesNumbers = formData.getAll("number");
+  for (let i = 0; i < exerciseInstancesTypes.length; i++) {
+    exerciseInstances.push({
+      exercise: `${HOST}/api/exercises/${exerciseInstancesTypes[i]}/`,
+      number: exerciseInstancesNumbers[i],
+      sets: exerciseInstancesSets[i],
+    });
+  }
+
+  submitForm.append("exercise_instances", JSON.stringify(exerciseInstances));
+  // adding files
+  for (let file of formData.getAll("files")) {
+    submitForm.append("files", file);
+  }
+  return submitForm;
+}
+
+async function createWorkout() {
+  let submitForm = generateWorkoutForm();
+
+  let response = await sendRequest(
+    "POST",
+    `${HOST}/api/workouts/`,
+    submitForm,
+    ""
+  );
+
+  if (response.ok) {
+    window.location.replace("workouts.html");
+  } else {
+    let data = await response.json();
+    let alert = createAlert("Could not create new workout!", data);
+    document.body.prepend(alert);
+  }
+}
+
+function handleCancelDuringWorkoutCreate() {
+  window.location.replace("workouts.html");
+}
+
+async function createBlankExercise() {
+  let form = document.querySelector("#form-workout");
+
+  let exerciseTypeResponse = await sendRequest("GET", `${HOST}/api/exercises/`);
+  let exerciseTypes = await exerciseTypeResponse.json();
+
+  let exerciseTemplate = document.querySelector("#template-exercise");
+  let divExerciseContainer = exerciseTemplate.content.firstElementChild.cloneNode(
+    true
+  );
+  let exerciseTypeSelect = divExerciseContainer.querySelector("select");
+
+  for (let i = 0; i < exerciseTypes.count; i++) {
+    let option = document.createElement("option");
+    option.value = exerciseTypes.results[i].id;
+    option.innerText = exerciseTypes.results[i].name;
+    exerciseTypeSelect.append(option);
+  }
+
+  let currentExerciseType = exerciseTypes.results[0];
+  exerciseTypeSelect.value = currentExerciseType.name;
+
+  let divExercises = document.querySelector("#div-exercises");
+  divExercises.appendChild(divExerciseContainer);
+}
+
+function removeExercise(event) {
+  let divExerciseContainers = document.querySelectorAll(
+    ".div-exercise-container"
+  );
+  if (divExerciseContainers && divExerciseContainers.length > 0) {
+    divExerciseContainers[divExerciseContainers.length - 1].remove();
+  }
+}
+
+function addComment(author, text, date, append) {
+  /* Taken from https://www.bootdey.com/snippets/view/Simple-Comment-panel#css*/
+  let commentList = document.querySelector("#comment-list");
+  let listElement = document.createElement("li");
+  listElement.className = "media";
+  let commentBody = document.createElement("div");
+  commentBody.className = "media-body";
+  let dateSpan = document.createElement("span");
+  dateSpan.className = "text-muted pull-right me-1";
+  let smallText = document.createElement("small");
+  smallText.className = "text-muted";
+
+  if (date != "Now") {
+    let localDate = new Date(date);
+    smallText.innerText = localDate.toLocaleString();
+  } else {
+    smallText.innerText = date;
+  }
+
+  dateSpan.appendChild(smallText);
+  commentBody.appendChild(dateSpan);
+
+  let strong = document.createElement("strong");
+  strong.className = "text-success";
+  strong.innerText = author;
+  commentBody.appendChild(strong);
+  let p = document.createElement("p");
+  p.innerHTML = text;
+
+  commentBody.appendChild(strong);
+  commentBody.appendChild(p);
+  listElement.appendChild(commentBody);
+
+  if (append) {
+    commentList.append(listElement);
+  } else {
+    commentList.prepend(listElement);
+  }
+}
+
+async function createComment(workoutid) {
+  let commentArea = document.querySelector("#comment-area");
+  let content = commentArea.value;
+  let body = {
+    workout: `${HOST}/api/workouts/${workoutid}/`,
+    content: content,
+  };
+
+  let response = await sendRequest("POST", `${HOST}/api/comments/`, body);
+  if (response.ok) {
+    addComment(sessionStorage.getItem("username"), content, "Now", false);
+  } else {
+    let data = await response.json();
+    let alert = createAlert("Failed to create comment!", data);
+    document.body.prepend(alert);
+  }
+}
+
+async function retrieveComments(workoutid) {
+  let response = await sendRequest("GET", `${HOST}/api/comments/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not retrieve comments!", data);
+    document.body.prepend(alert);
+  } else {
+    let data = await response.json();
+    let comments = data.results;
+    for (let comment of comments) {
+      let splitArray = comment.workout.split("/");
+      if (splitArray[splitArray.length - 2] == workoutid) {
+        addComment(comment.owner, comment.content, comment.timestamp, true);
+      }
+    }
+  }
+}
+
+window.addEventListener("DOMContentLoaded", async () => {
+  cancelWorkoutButton = document.querySelector("#btn-cancel-workout");
+  okWorkoutButton = document.querySelector("#btn-ok-workout");
+  deleteWorkoutButton = document.querySelector("#btn-delete-workout");
+  editWorkoutButton = document.querySelector("#btn-edit-workout");
+  let postCommentButton = document.querySelector("#post-comment");
+  let divCommentRow = document.querySelector("#div-comment-row");
+  let buttonAddExercise = document.querySelector("#btn-add-exercise");
+  let buttonRemoveExercise = document.querySelector("#btn-remove-exercise");
+
+  buttonAddExercise.addEventListener("click", createBlankExercise);
+  buttonRemoveExercise.addEventListener("click", removeExercise);
+
+  const urlParams = new URLSearchParams(window.location.search);
+  let currentUser = await getCurrentUser();
+
+  if (urlParams.has("id")) {
+    const id = urlParams.get("id");
+    let workoutData = await retrieveWorkout(id);
+    await retrieveComments(id);
+
+    if (workoutData["owner"] == currentUser.url) {
+      editWorkoutButton.classList.remove("hide");
+      editWorkoutButton.addEventListener("click", handleEditWorkoutButtonClick);
+      deleteWorkoutButton.addEventListener(
+        "click",
+        (async (id) => await deleteWorkout(id)).bind(undefined, id)
+      );
+      okWorkoutButton.addEventListener(
+        "click",
+        (async (id) => await updateWorkout(id)).bind(undefined, id)
+      );
+      postCommentButton.addEventListener(
+        "click",
+        (async (id) => await createComment(id)).bind(undefined, id)
+      );
+      divCommentRow.className = divCommentRow.className.replace(" hide", "");
+    }
+  } else {
+    await createBlankExercise();
+    let ownerInput = document.querySelector("#inputOwner");
+    ownerInput.value = currentUser.username;
+    setReadOnly(false, "#form-workout");
+    ownerInput.readOnly = !ownerInput.readOnly;
+
+    okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
+    cancelWorkoutButton.className = cancelWorkoutButton.className.replace(
+      " hide",
+      ""
+    );
+    buttonAddExercise.className = buttonAddExercise.className.replace(
+      " hide",
+      ""
+    );
+    buttonRemoveExercise.className = buttonRemoveExercise.className.replace(
+      " hide",
+      ""
+    );
+
+    okWorkoutButton.addEventListener(
+      "click",
+      async () => await createWorkout()
+    );
+    cancelWorkoutButton.addEventListener(
+      "click",
+      handleCancelDuringWorkoutCreate
+    );
+    divCommentRow.className += " hide";
+  }
+});
diff --git a/frontend/www/scripts/workout.js b/frontend/www/scripts/workout.js
index 9cb67115417e25a1117118edab54121d86f7aed0..8123d50937a9ec5a92d90bdec8426681a0409502 100644
--- a/frontend/www/scripts/workout.js
+++ b/frontend/www/scripts/workout.js
@@ -4,440 +4,519 @@ let deleteWorkoutButton;
 let editWorkoutButton;
 let exportWorkoutButton;
 let postCommentButton;
+let planned = false;
 
 async function retrieveWorkout(id) {
-    let workoutData = null;
-    let response = await sendRequest("GET", `${HOST}/api/workouts/${id}/`);
-    if (!response.ok) {
-        let data = await response.json();
-        let alert = createAlert("Could not retrieve workout data!", data);
-        document.body.prepend(alert);
-    } else {
-        workoutData = await response.json();
-        let form = document.querySelector("#form-workout");
-        let formData = new FormData(form);
-
-        for (let key of formData.keys()) {
-            let selector = `input[name="${key}"], textarea[name="${key}"]`;
-            let input = form.querySelector(selector);
-            let newVal = workoutData[key];
-            if (key == "date") {
-                // Creating a valid datetime-local string with the correct local time
-                let date = new Date(newVal);
-                date = new Date(date.getTime() - (date.getTimezoneOffset() * 60 * 1000)).toISOString(); // get ISO format for local time
-                newVal = date.substring(0, newVal.length - 1);    // remove Z (since this is a local time, not UTC)
-            }
-            if (key != "files") {
-                input.value = newVal;
-            }
-        }
-
-        let input = form.querySelector("select:disabled");
-        input.value = workoutData["visibility"];
-        // files
-        let filesDiv = document.querySelector("#uploaded-files");
-        for (let file of workoutData.files) {
-            let a = document.createElement("a");
-            a.href = file.file;
-            let pathArray = file.file.split("/");
-            a.text = pathArray[pathArray.length - 1];
-            a.className = "me-2";
-            filesDiv.appendChild(a);
-        }
-
-        // create exercises
-
-        // fetch exercise types
-        let exerciseTypeResponse = await sendRequest("GET", `${HOST}/api/exercises/`);
-        let exerciseTypes = await exerciseTypeResponse.json();
-
-        //TODO: This should be in its own method.
-        for (let i = 0; i < workoutData.exercise_instances.length; i++) {
-            let templateExercise = document.querySelector("#template-exercise");
-            let divExerciseContainer = templateExercise.content.firstElementChild.cloneNode(true);
-
-            let exerciseTypeLabel = divExerciseContainer.querySelector('.exercise-type');
-            exerciseTypeLabel.for = `inputExerciseType${i}`;
-
-            let exerciseTypeSelect = divExerciseContainer.querySelector("select");
-            exerciseTypeSelect.id = `inputExerciseType${i}`;
-            exerciseTypeSelect.disabled = true;
+  let workoutData = null;
+  let response = await sendRequest("GET", `${HOST}/api/workouts/${id}/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not retrieve workout data!", data);
+    document.body.prepend(alert);
+  } else {
+    workoutData = await response.json();
+    let form = document.querySelector("#form-workout");
+    let formData = new FormData(form);
+    planned = workoutData.planned;
+    for (let key of formData.keys()) {
+      let selector = `input[name="${key}"], textarea[name="${key}"]`;
+      let input = form.querySelector(selector);
+      let newVal = workoutData[key];
+      if (key == "date") {
+        // Creating a valid datetime-local string with the correct local time
+        let date = new Date(newVal);
+        date = new Date(
+          date.getTime() - date.getTimezoneOffset() * 60 * 1000
+        ).toISOString(); // get ISO format for local time
+        newVal = date.substring(0, newVal.length - 1); // remove Z (since this is a local time, not UTC)
+      }
+      if (key != "files") {
+        input.value = newVal;
+      }
+    }
 
-            let splitUrl = workoutData.exercise_instances[i].exercise.split("/");
-            let currentExerciseTypeId = splitUrl[splitUrl.length - 2];
-            let currentExerciseType = "";
+    let input = form.querySelector("select:disabled");
+    input.value = workoutData["visibility"];
+    // files
+    let filesDiv = document.querySelector("#uploaded-files");
+    for (let file of workoutData.files) {
+      let a = document.createElement("a");
+      a.href = file.file;
+      let pathArray = file.file.split("/");
+      a.text = pathArray[pathArray.length - 1];
+      a.className = "me-2";
+      filesDiv.appendChild(a);
+    }
 
-            for (let j = 0; j < exerciseTypes.count; j++) {
-                let option = document.createElement("option");
-                option.value = exerciseTypes.results[j].id;
-                if (currentExerciseTypeId == exerciseTypes.results[j].id) {
-                    currentExerciseType = exerciseTypes.results[j];
-                }
-                option.innerText = exerciseTypes.results[j].name;
-                exerciseTypeSelect.append(option);
-            }
+    // create exercises
 
-            exerciseTypeSelect.value = currentExerciseType.id;
+    // fetch exercise types
+    let exerciseTypeResponse = await sendRequest(
+      "GET",
+      `${HOST}/api/exercises/`
+    );
+    let exerciseTypes = await exerciseTypeResponse.json();
 
-            let exerciseSetLabel = divExerciseContainer.querySelector('.exercise-sets');
-            exerciseSetLabel.for = `inputSets${i}`;
+    //TODO: This should be in its own method.
+    for (let i = 0; i < workoutData.exercise_instances.length; i++) {
+      let templateExercise = document.querySelector("#template-exercise");
+      let divExerciseContainer = templateExercise.content.firstElementChild.cloneNode(
+        true
+      );
 
-            let exerciseSetInput = divExerciseContainer.querySelector("input[name='sets']");
-            exerciseSetInput.id = `inputSets${i}`;
-            exerciseSetInput.value = workoutData.exercise_instances[i].sets;
-            exerciseSetInput.readOnly = true;
+      let exerciseTypeLabel = divExerciseContainer.querySelector(
+        ".exercise-type"
+      );
+      exerciseTypeLabel.for = `inputExerciseType${i}`;
 
-            let exerciseNumberLabel = divExerciseContainer.querySelector('.exercise-number');
-            exerciseNumberLabel.for = "for", `inputNumber${i}`;
-            exerciseNumberLabel.innerText = currentExerciseType.unit;
+      let exerciseTypeSelect = divExerciseContainer.querySelector("select");
+      exerciseTypeSelect.id = `inputExerciseType${i}`;
+      exerciseTypeSelect.disabled = true;
 
-            let exerciseNumberInput = divExerciseContainer.querySelector("input[name='number']");
-            exerciseNumberInput.id = `inputNumber${i}`;
-            exerciseNumberInput.value = workoutData.exercise_instances[i].number;
-            exerciseNumberInput.readOnly = true;
+      let splitUrl = workoutData.exercise_instances[i].exercise.split("/");
+      let currentExerciseTypeId = splitUrl[splitUrl.length - 2];
+      let currentExerciseType = "";
 
-            let exercisesDiv = document.querySelector("#div-exercises");
-            exercisesDiv.appendChild(divExerciseContainer);
+      for (let j = 0; j < exerciseTypes.count; j++) {
+        let option = document.createElement("option");
+        option.value = exerciseTypes.results[j].id;
+        if (currentExerciseTypeId == exerciseTypes.results[j].id) {
+          currentExerciseType = exerciseTypes.results[j];
         }
+        option.innerText = exerciseTypes.results[j].name;
+        exerciseTypeSelect.append(option);
+      }
+
+      exerciseTypeSelect.value = currentExerciseType.id;
+
+      let exerciseSetLabel = divExerciseContainer.querySelector(
+        ".exercise-sets"
+      );
+      exerciseSetLabel.for = `inputSets${i}`;
+
+      let exerciseSetInput = divExerciseContainer.querySelector(
+        "input[name='sets']"
+      );
+      exerciseSetInput.id = `inputSets${i}`;
+      exerciseSetInput.value = workoutData.exercise_instances[i].sets;
+      exerciseSetInput.readOnly = true;
+
+      let exerciseNumberLabel = divExerciseContainer.querySelector(
+        ".exercise-number"
+      );
+      (exerciseNumberLabel.for = "for"), `inputNumber${i}`;
+      exerciseNumberLabel.innerText = currentExerciseType.unit;
+
+      let exerciseNumberInput = divExerciseContainer.querySelector(
+        "input[name='number']"
+      );
+      exerciseNumberInput.id = `inputNumber${i}`;
+      exerciseNumberInput.value = workoutData.exercise_instances[i].number;
+      exerciseNumberInput.readOnly = true;
+
+      let exercisesDiv = document.querySelector("#div-exercises");
+      exercisesDiv.appendChild(divExerciseContainer);
     }
-    return workoutData;
+  }
+  return workoutData;
 }
 
 function handleCancelDuringWorkoutEdit() {
-    location.reload();
+  location.reload();
 }
 
 function handleEditWorkoutButtonClick() {
-    let addExerciseButton = document.querySelector("#btn-add-exercise");
-    let removeExerciseButton = document.querySelector("#btn-remove-exercise");
-
-    setReadOnly(false, "#form-workout");
-    document.querySelector("#inputOwner").readOnly = true;  // owner field should still be readonly 
-
-    editWorkoutButton.className += " hide";
-    exportWorkoutButton.className += " hide";
-    okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
-    cancelWorkoutButton.className = cancelWorkoutButton.className.replace(" hide", "");
-    deleteWorkoutButton.className = deleteWorkoutButton.className.replace(" hide", "");
-    addExerciseButton.className = addExerciseButton.className.replace(" hide", "");
-    removeExerciseButton.className = removeExerciseButton.className.replace(" hide", "");
-
-    cancelWorkoutButton.addEventListener("click", handleCancelDuringWorkoutEdit);
-
+  let addExerciseButton = document.querySelector("#btn-add-exercise");
+  let removeExerciseButton = document.querySelector("#btn-remove-exercise");
+
+  setReadOnly(false, "#form-workout");
+  document.querySelector("#inputOwner").readOnly = true; // owner field should still be readonly
+
+  editWorkoutButton.className += " hide";
+  exportWorkoutButton.className += " hide";
+  okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
+  cancelWorkoutButton.className = cancelWorkoutButton.className.replace(
+    " hide",
+    ""
+  );
+  deleteWorkoutButton.className = deleteWorkoutButton.className.replace(
+    " hide",
+    ""
+  );
+  addExerciseButton.className = addExerciseButton.className.replace(
+    " hide",
+    ""
+  );
+  removeExerciseButton.className = removeExerciseButton.className.replace(
+    " hide",
+    ""
+  );
+
+  cancelWorkoutButton.addEventListener("click", handleCancelDuringWorkoutEdit);
 }
 
 //Taken from github: https://gist.github.com/dannypule/48418b4cd8223104c6c92e3016fc0f61
 function handleExportToCalendarClick(workoutData) {
-
-    const headers = {
-        subject: "Subject",
-        startDate: "Start date",
-        startTime: "Start time",
-        description: "Description"
-    }
-
-    const dataFormatted = []
-
-    const startTime = new Date(workoutData.date).toLocaleTimeString("en-us")
-    const startDate = new Date(workoutData.date).toLocaleString('en-us', {
-        year: 'numeric',
-        month: '2-digit',
-        day: '2-digit'
-    }).replace(/(\d+)\/(\d+)\/(\d+)/, '$1/$2/$3')
-
-
-    dataFormatted.push({
-        subject: workoutData.name,
-        startDate: startDate,
-        startTime: startTime,
-        description: workoutData.notes
+  const headers = {
+    subject: "Subject",
+    startDate: "Start date",
+    startTime: "Start time",
+    description: "Description",
+  };
+
+  const dataFormatted = [];
+
+  const startTime = new Date(workoutData.date).toLocaleTimeString("en-us");
+  const startDate = new Date(workoutData.date)
+    .toLocaleString("en-us", {
+      year: "numeric",
+      month: "2-digit",
+      day: "2-digit",
     })
+    .replace(/(\d+)\/(\d+)\/(\d+)/, "$1/$2/$3");
 
+  dataFormatted.push({
+    subject: workoutData.name,
+    startDate: startDate,
+    startTime: startTime,
+    description: workoutData.notes,
+  });
 
-    console.log(dataFormatted)
+  console.log(dataFormatted);
 
-    exportCSVFile(headers, dataFormatted, "event")
+  exportCSVFile(headers, dataFormatted, "event");
 }
 
 //Taken from github: https://gist.github.com/dannypule/48418b4cd8223104c6c92e3016fc0f61
 function convertToCSV(objArray) {
-    var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
-    var str = '';
-
-    for (var i = 0; i < array.length; i++) {
-        var line = '';
-        for (var index in array[i]) {
-            if (line != '') line += ','
+  var array = typeof objArray != "object" ? JSON.parse(objArray) : objArray;
+  var str = "";
 
-            line += array[i][index];
-        }
+  for (var i = 0; i < array.length; i++) {
+    var line = "";
+    for (var index in array[i]) {
+      if (line != "") line += ",";
 
-        str += line + '\r\n';
+      line += array[i][index];
     }
 
-    return str;
+    str += line + "\r\n";
+  }
+
+  return str;
 }
 
 //Taken from github: https://gist.github.com/dannypule/48418b4cd8223104c6c92e3016fc0f61
 function exportCSVFile(headers, items, fileTitle) {
-
-    console.log(items, headers)
-    if (headers) {
-        items.unshift(headers);
-    }
-
-    // Convert Object to JSON
-    var jsonObject = JSON.stringify(items);
-
-    var csv = this.convertToCSV(jsonObject);
-
-    var exportedFilenmae = fileTitle + '.csv' || 'export.csv';
-
-    var blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
-    if (navigator.msSaveBlob) { // IE 10+
-        navigator.msSaveBlob(blob, exportedFilenmae);
-    } else {
-        var link = document.createElement("a");
-        if (link.download !== undefined) { // feature detection
-            // Browsers that support HTML5 download attribute
-            var url = URL.createObjectURL(blob);
-            link.setAttribute("href", url);
-            link.setAttribute("download", exportedFilenmae);
-            link.style.visibility = 'hidden';
-            document.body.appendChild(link);
-            link.click();
-            document.body.removeChild(link);
-        }
+  console.log(items, headers);
+  if (headers) {
+    items.unshift(headers);
+  }
+
+  // Convert Object to JSON
+  var jsonObject = JSON.stringify(items);
+
+  var csv = this.convertToCSV(jsonObject);
+
+  var exportedFilenmae = fileTitle + ".csv" || "export.csv";
+
+  var blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
+  if (navigator.msSaveBlob) {
+    // IE 10+
+    navigator.msSaveBlob(blob, exportedFilenmae);
+  } else {
+    var link = document.createElement("a");
+    if (link.download !== undefined) {
+      // feature detection
+      // Browsers that support HTML5 download attribute
+      var url = URL.createObjectURL(blob);
+      link.setAttribute("href", url);
+      link.setAttribute("download", exportedFilenmae);
+      link.style.visibility = "hidden";
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
     }
+  }
 }
 
 async function deleteWorkout(id) {
-    let response = await sendRequest("DELETE", `${HOST}/api/workouts/${id}/`);
-    if (!response.ok) {
-        let data = await response.json();
-        let alert = createAlert(`Could not delete workout ${id}!`, data);
-        document.body.prepend(alert);
-    } else {
-        window.location.replace("workouts.html");
-    }
+  let response = await sendRequest("DELETE", `${HOST}/api/workouts/${id}/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert(`Could not delete workout ${id}!`, data);
+    document.body.prepend(alert);
+  } else {
+    window.location.replace("workouts.html");
+  }
 }
 
 async function updateWorkout(id) {
-    let submitForm = generateWorkoutForm();
-
-    let response = await sendRequest("PUT", `${HOST}/api/workouts/${id}/`, submitForm, "");
-    if (!response.ok) {
-        let data = await response.json();
-        let alert = createAlert("Could not update workout!", data);
-        document.body.prepend(alert);
-    } else {
-        location.reload();
-    }
+  let submitForm = generateWorkoutForm();
+  let response = await sendRequest(
+    "PUT",
+    `${HOST}/api/workouts/${id}/`,
+    submitForm,
+    ""
+  );
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not update workout!", data);
+    document.body.prepend(alert);
+  } else {
+    location.reload();
+  }
 }
 
 function generateWorkoutForm() {
-    let form = document.querySelector("#form-workout");
-
-    let formData = new FormData(form);
-    let submitForm = new FormData();
-
-    submitForm.append("name", formData.get('name'));
-    let date = new Date(formData.get('date')).toISOString();
-    submitForm.append("date", date);
-    submitForm.append("notes", formData.get("notes"));
-    submitForm.append("visibility", formData.get("visibility"));
-
-    // adding exercise instances
-    let exerciseInstances = [];
-    let exerciseInstancesTypes = formData.getAll("type");
-    let exerciseInstancesSets = formData.getAll("sets");
-    let exerciseInstancesNumbers = formData.getAll("number");
-    for (let i = 0; i < exerciseInstancesTypes.length; i++) {
-        exerciseInstances.push({
-            exercise: `${HOST}/api/exercises/${exerciseInstancesTypes[i]}/`,
-            number: exerciseInstancesNumbers[i],
-            sets: exerciseInstancesSets[i]
-        });
-    }
-
-    submitForm.append("exercise_instances", JSON.stringify(exerciseInstances));
-    // adding files
-    for (let file of formData.getAll("files")) {
-        submitForm.append("files", file);
-    }
-    return submitForm;
+  var today = new Date().toISOString();
+
+  document.querySelector("#inputDateTime").min = today;
+
+  let form = document.querySelector("#form-workout");
+
+  let formData = new FormData(form);
+  let submitForm = new FormData();
+
+  submitForm.append("name", formData.get("name"));
+  let date = new Date(formData.get("date")).toISOString();
+  submitForm.append("date", date);
+  submitForm.append("notes", formData.get("notes"));
+  submitForm.append("visibility", formData.get("visibility"));
+
+  submitForm.append("planned", planned);
+
+  // adding exercise instances
+  let exerciseInstances = [];
+  let exerciseInstancesTypes = formData.getAll("type");
+  let exerciseInstancesSets = formData.getAll("sets");
+  let exerciseInstancesNumbers = formData.getAll("number");
+  for (let i = 0; i < exerciseInstancesTypes.length; i++) {
+    exerciseInstances.push({
+      exercise: `${HOST}/api/exercises/${exerciseInstancesTypes[i]}/`,
+      number: exerciseInstancesNumbers[i],
+      sets: exerciseInstancesSets[i],
+    });
+  }
+
+  submitForm.append("exercise_instances", JSON.stringify(exerciseInstances));
+  // adding files
+  for (let file of formData.getAll("files")) {
+    submitForm.append("files", file);
+  }
+  return submitForm;
 }
 
 async function createWorkout() {
-    let submitForm = generateWorkoutForm();
+  let submitForm = generateWorkoutForm();
 
-    let response = await sendRequest("POST", `${HOST}/api/workouts/`, submitForm, "");
+  let response = await sendRequest(
+    "POST",
+    `${HOST}/api/workouts/`,
+    submitForm,
+    ""
+  );
 
-    if (response.ok) {
-        window.location.replace("workouts.html");
-    } else {
-        let data = await response.json();
-        let alert = createAlert("Could not create new workout!", data);
-        document.body.prepend(alert);
-    }
+  if (response.ok) {
+    window.location.replace("workouts.html");
+  } else {
+    let data = await response.json();
+    let alert = createAlert("Could not create new workout!", data);
+    document.body.prepend(alert);
+  }
 }
 
 function handleCancelDuringWorkoutCreate() {
-    window.location.replace("workouts.html");
+  window.location.replace("workouts.html");
 }
 
 async function createBlankExercise() {
-    let form = document.querySelector("#form-workout");
+  let form = document.querySelector("#form-workout");
 
-    let exerciseTypeResponse = await sendRequest("GET", `${HOST}/api/exercises/`);
-    let exerciseTypes = await exerciseTypeResponse.json();
+  let exerciseTypeResponse = await sendRequest("GET", `${HOST}/api/exercises/`);
+  let exerciseTypes = await exerciseTypeResponse.json();
 
-    let exerciseTemplate = document.querySelector("#template-exercise");
-    let divExerciseContainer = exerciseTemplate.content.firstElementChild.cloneNode(true);
-    let exerciseTypeSelect = divExerciseContainer.querySelector("select");
+  let exerciseTemplate = document.querySelector("#template-exercise");
+  let divExerciseContainer = exerciseTemplate.content.firstElementChild.cloneNode(
+    true
+  );
+  let exerciseTypeSelect = divExerciseContainer.querySelector("select");
 
-    for (let i = 0; i < exerciseTypes.count; i++) {
-        let option = document.createElement("option");
-        option.value = exerciseTypes.results[i].id;
-        option.innerText = exerciseTypes.results[i].name;
-        exerciseTypeSelect.append(option);
-    }
+  for (let i = 0; i < exerciseTypes.count; i++) {
+    let option = document.createElement("option");
+    option.value = exerciseTypes.results[i].id;
+    option.innerText = exerciseTypes.results[i].name;
+    exerciseTypeSelect.append(option);
+  }
 
-    let currentExerciseType = exerciseTypes.results[0];
-    exerciseTypeSelect.value = currentExerciseType.name;
+  let currentExerciseType = exerciseTypes.results[0];
+  exerciseTypeSelect.value = currentExerciseType.name;
 
-    let divExercises = document.querySelector("#div-exercises");
-    divExercises.appendChild(divExerciseContainer);
+  let divExercises = document.querySelector("#div-exercises");
+  divExercises.appendChild(divExerciseContainer);
 }
 
 function removeExercise(event) {
-    let divExerciseContainers = document.querySelectorAll(".div-exercise-container");
-    if (divExerciseContainers && divExerciseContainers.length > 0) {
-        divExerciseContainers[divExerciseContainers.length - 1].remove();
-    }
+  let divExerciseContainers = document.querySelectorAll(
+    ".div-exercise-container"
+  );
+  if (divExerciseContainers && divExerciseContainers.length > 0) {
+    divExerciseContainers[divExerciseContainers.length - 1].remove();
+  }
 }
 
 function addComment(author, text, date, append) {
-    /* Taken from https://www.bootdey.com/snippets/view/Simple-Comment-panel#css*/
-    let commentList = document.querySelector("#comment-list");
-    let listElement = document.createElement("li");
-    listElement.className = "media";
-    let commentBody = document.createElement("div");
-    commentBody.className = "media-body";
-    let dateSpan = document.createElement("span");
-    dateSpan.className = "text-muted pull-right me-1";
-    let smallText = document.createElement("small");
-    smallText.className = "text-muted";
-
-    if (date != "Now") {
-        let localDate = new Date(date);
-        smallText.innerText = localDate.toLocaleString();
-    } else {
-        smallText.innerText = date;
-    }
-
-    dateSpan.appendChild(smallText);
-    commentBody.appendChild(dateSpan);
-
-    let strong = document.createElement("strong");
-    strong.className = "text-success";
-    strong.innerText = author;
-    commentBody.appendChild(strong);
-    let p = document.createElement("p");
-    p.innerHTML = text;
-
-    commentBody.appendChild(strong);
-    commentBody.appendChild(p);
-    listElement.appendChild(commentBody);
-
-    if (append) {
-        commentList.append(listElement);
-    } else {
-        commentList.prepend(listElement);
-    }
-
+  /* Taken from https://www.bootdey.com/snippets/view/Simple-Comment-panel#css*/
+  let commentList = document.querySelector("#comment-list");
+  let listElement = document.createElement("li");
+  listElement.className = "media";
+  let commentBody = document.createElement("div");
+  commentBody.className = "media-body";
+  let dateSpan = document.createElement("span");
+  dateSpan.className = "text-muted pull-right me-1";
+  let smallText = document.createElement("small");
+  smallText.className = "text-muted";
+
+  if (date != "Now") {
+    let localDate = new Date(date);
+    smallText.innerText = localDate.toLocaleString();
+  } else {
+    smallText.innerText = date;
+  }
+
+  dateSpan.appendChild(smallText);
+  commentBody.appendChild(dateSpan);
+
+  let strong = document.createElement("strong");
+  strong.className = "text-success";
+  strong.innerText = author;
+  commentBody.appendChild(strong);
+  let p = document.createElement("p");
+  p.innerHTML = text;
+
+  commentBody.appendChild(strong);
+  commentBody.appendChild(p);
+  listElement.appendChild(commentBody);
+
+  if (append) {
+    commentList.append(listElement);
+  } else {
+    commentList.prepend(listElement);
+  }
 }
 
 async function createComment(workoutid) {
-    let commentArea = document.querySelector("#comment-area");
-    let content = commentArea.value;
-    let body = {workout: `${HOST}/api/workouts/${workoutid}/`, content: content};
-
-    let response = await sendRequest("POST", `${HOST}/api/comments/`, body);
-    if (response.ok) {
-        addComment(sessionStorage.getItem("username"), content, "Now", false);
-    } else {
-        let data = await response.json();
-        let alert = createAlert("Failed to create comment!", data);
-        document.body.prepend(alert);
-    }
+  let commentArea = document.querySelector("#comment-area");
+  let content = commentArea.value;
+  let body = {
+    workout: `${HOST}/api/workouts/${workoutid}/`,
+    content: content,
+  };
+
+  let response = await sendRequest("POST", `${HOST}/api/comments/`, body);
+  if (response.ok) {
+    addComment(sessionStorage.getItem("username"), content, "Now", false);
+  } else {
+    let data = await response.json();
+    let alert = createAlert("Failed to create comment!", data);
+    document.body.prepend(alert);
+  }
 }
 
 async function retrieveComments(workoutid) {
-    let response = await sendRequest("GET", `${HOST}/api/comments/`);
-    if (!response.ok) {
-        let data = await response.json();
-        let alert = createAlert("Could not retrieve comments!", data);
-        document.body.prepend(alert);
-    } else {
-        let data = await response.json();
-        let comments = data.results;
-        for (let comment of comments) {
-            let splitArray = comment.workout.split("/");
-            if (splitArray[splitArray.length - 2] == workoutid) {
-                addComment(comment.owner, comment.content, comment.timestamp, true);
-            }
-        }
+  let response = await sendRequest("GET", `${HOST}/api/comments/`);
+  if (!response.ok) {
+    let data = await response.json();
+    let alert = createAlert("Could not retrieve comments!", data);
+    document.body.prepend(alert);
+  } else {
+    let data = await response.json();
+    let comments = data.results;
+    for (let comment of comments) {
+      let splitArray = comment.workout.split("/");
+      if (splitArray[splitArray.length - 2] == workoutid) {
+        addComment(comment.owner, comment.content, comment.timestamp, true);
+      }
     }
+  }
 }
 
 window.addEventListener("DOMContentLoaded", async () => {
-    cancelWorkoutButton = document.querySelector("#btn-cancel-workout");
-    okWorkoutButton = document.querySelector("#btn-ok-workout");
-    deleteWorkoutButton = document.querySelector("#btn-delete-workout");
-    editWorkoutButton = document.querySelector("#btn-edit-workout");
-    exportWorkoutButton = document.querySelector("#btn-export-workout");
-    let postCommentButton = document.querySelector("#post-comment");
-    let divCommentRow = document.querySelector("#div-comment-row");
-    let buttonAddExercise = document.querySelector("#btn-add-exercise");
-    let buttonRemoveExercise = document.querySelector("#btn-remove-exercise");
-
-    buttonAddExercise.addEventListener("click", createBlankExercise);
-    buttonRemoveExercise.addEventListener("click", removeExercise);
-
-    const urlParams = new URLSearchParams(window.location.search);
-    let currentUser = await getCurrentUser();
-
-    if (urlParams.has('id')) {
-        const id = urlParams.get('id');
-        let workoutData = await retrieveWorkout(id);
-        await retrieveComments(id);
-
-        if (workoutData["owner"] == currentUser.url) {
-            editWorkoutButton.classList.remove("hide");
-            exportWorkoutButton.classList.remove("hide");
-            editWorkoutButton.addEventListener("click", handleEditWorkoutButtonClick);
-            exportWorkoutButton.addEventListener("click", ((workoutData) => handleExportToCalendarClick(workoutData)).bind(undefined, workoutData));
-            deleteWorkoutButton.addEventListener("click", (async (id) => await deleteWorkout(id)).bind(undefined, id));
-            okWorkoutButton.addEventListener("click", (async (id) => await updateWorkout(id)).bind(undefined, id));
-            postCommentButton.addEventListener("click", (async (id) => await createComment(id)).bind(undefined, id));
-            divCommentRow.className = divCommentRow.className.replace(" hide", "");
-        }
-    } else {
-        await createBlankExercise();
-        let ownerInput = document.querySelector("#inputOwner");
-        ownerInput.value = currentUser.username;
-        setReadOnly(false, "#form-workout");
-        ownerInput.readOnly = !ownerInput.readOnly;
-
-        okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
-        cancelWorkoutButton.className = cancelWorkoutButton.className.replace(" hide", "");
-        buttonAddExercise.className = buttonAddExercise.className.replace(" hide", "");
-        buttonRemoveExercise.className = buttonRemoveExercise.className.replace(" hide", "");
-
-        okWorkoutButton.addEventListener("click", async () => await createWorkout());
-        cancelWorkoutButton.addEventListener("click", handleCancelDuringWorkoutCreate);
-        divCommentRow.className += " hide";
+  cancelWorkoutButton = document.querySelector("#btn-cancel-workout");
+  okWorkoutButton = document.querySelector("#btn-ok-workout");
+  deleteWorkoutButton = document.querySelector("#btn-delete-workout");
+  editWorkoutButton = document.querySelector("#btn-edit-workout");
+  exportWorkoutButton = document.querySelector("#btn-export-workout");
+  let postCommentButton = document.querySelector("#post-comment");
+  let divCommentRow = document.querySelector("#div-comment-row");
+  let buttonAddExercise = document.querySelector("#btn-add-exercise");
+  let buttonRemoveExercise = document.querySelector("#btn-remove-exercise");
+
+  buttonAddExercise.addEventListener("click", createBlankExercise);
+  buttonRemoveExercise.addEventListener("click", removeExercise);
+
+  const urlParams = new URLSearchParams(window.location.search);
+  let currentUser = await getCurrentUser();
+
+  if (urlParams.has("id")) {
+    const id = urlParams.get("id");
+    let workoutData = await retrieveWorkout(id);
+    await retrieveComments(id);
+
+    if (workoutData["owner"] == currentUser.url) {
+      editWorkoutButton.classList.remove("hide");
+      exportWorkoutButton.classList.remove("hide");
+      editWorkoutButton.addEventListener("click", handleEditWorkoutButtonClick);
+      exportWorkoutButton.addEventListener(
+        "click",
+        ((workoutData) => handleExportToCalendarClick(workoutData)).bind(
+          undefined,
+          workoutData
+        )
+      );
+      deleteWorkoutButton.addEventListener(
+        "click",
+        (async (id) => await deleteWorkout(id)).bind(undefined, id)
+      );
+      okWorkoutButton.addEventListener(
+        "click",
+        (async (id) => await updateWorkout(id)).bind(undefined, id)
+      );
+      postCommentButton.addEventListener(
+        "click",
+        (async (id) => await createComment(id)).bind(undefined, id)
+      );
+      divCommentRow.className = divCommentRow.className.replace(" hide", "");
     }
+  } else {
+    await createBlankExercise();
+    let ownerInput = document.querySelector("#inputOwner");
+    ownerInput.value = currentUser.username;
+    setReadOnly(false, "#form-workout");
+    ownerInput.readOnly = !ownerInput.readOnly;
 
-});
\ No newline at end of file
+    okWorkoutButton.className = okWorkoutButton.className.replace(" hide", "");
+    cancelWorkoutButton.className = cancelWorkoutButton.className.replace(
+      " hide",
+      ""
+    );
+    buttonAddExercise.className = buttonAddExercise.className.replace(
+      " hide",
+      ""
+    );
+    buttonRemoveExercise.className = buttonRemoveExercise.className.replace(
+      " hide",
+      ""
+    );
+
+    okWorkoutButton.addEventListener(
+      "click",
+      async () => await createWorkout()
+    );
+    cancelWorkoutButton.addEventListener(
+      "click",
+      handleCancelDuringWorkoutCreate
+    );
+    divCommentRow.className += " hide";
+  }
+});
diff --git a/frontend/www/scripts/workouts.js b/frontend/www/scripts/workouts.js
index 772be1ea070499ad9574d787d990c1ca17097bdf..d18ba4e2608917456bc088d8e46c578ab2fd792f 100644
--- a/frontend/www/scripts/workouts.js
+++ b/frontend/www/scripts/workouts.js
@@ -1,106 +1,146 @@
 async function fetchWorkouts(ordering) {
-    let response = await sendRequest("GET", `${HOST}/api/workouts/?ordering=${ordering}`);
+  let response = await sendRequest(
+    "GET",
+    `${HOST}/api/workouts/?ordering=${ordering}`
+  );
 
-    if (!response.ok) {
-        throw new Error(`HTTP error! status: ${response.status}`);
-    } else {
-        let data = await response.json();
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    let data = await response.json();
 
-        let workouts = data.results;
-        let container = document.getElementById('div-content');
-        workouts.forEach(workout => {
-            let templateWorkout = document.querySelector("#template-workout");
-            let cloneWorkout = templateWorkout.content.cloneNode(true);
+    let workouts = data.results;
+    let container = document.getElementById("div-content");
+    workouts.forEach((workout) => {
+      let templateWorkout = document.querySelector("#template-workout");
+      let cloneWorkout = templateWorkout.content.cloneNode(true);
 
-            let aWorkout = cloneWorkout.querySelector("a");
-            aWorkout.href = `workout.html?id=${workout.id}`;
+      let aWorkout = cloneWorkout.querySelector("a");
+      aWorkout.href = `workout.html?id=${workout.id}`;
 
-            let h5 = aWorkout.querySelector("h5");
-            h5.textContent = workout.name;
+      let h5 = aWorkout.querySelector("h5");
+      h5.textContent = workout.name;
 
-            let localDate = new Date(workout.date);
+      let localDate = new Date(workout.date);
 
-            let table = aWorkout.querySelector("table");
-            let rows = table.querySelectorAll("tr");
-            rows[0].querySelectorAll("td")[1].textContent = localDate.toLocaleDateString(); // Date
-            rows[1].querySelectorAll("td")[1].textContent = localDate.toLocaleTimeString(); // Time
-            rows[2].querySelectorAll("td")[1].textContent = workout.owner_username; //Owner
-            rows[3].querySelectorAll("td")[1].textContent = workout.exercise_instances.length; // Exercises
+      let table = aWorkout.querySelector("table");
+      let rows = table.querySelectorAll("tr");
+      rows[0].querySelectorAll(
+        "td"
+      )[1].textContent = localDate.toLocaleDateString(); // Date
+      rows[1].querySelectorAll(
+        "td"
+      )[1].textContent = localDate.toLocaleTimeString(); // Time
+      rows[2].querySelectorAll("td")[1].textContent = workout.owner_username; //Owner
+      rows[3].querySelectorAll("td")[1].textContent =
+        workout.exercise_instances.length; // Exercises
 
-            container.appendChild(aWorkout);
-        });
-        return workouts;
-    }
+      container.appendChild(aWorkout);
+    });
+    return workouts;
+  }
 }
 
 function createWorkout() {
-    window.location.replace("workout.html");
+  window.location.replace("workout.html");
+}
+
+function planWorkout() {
+  window.location.replace("plannedWorkout.html");
 }
 
 window.addEventListener("DOMContentLoaded", async () => {
-    let createButton = document.querySelector("#btn-create-workout");
-    createButton.addEventListener("click", createWorkout);
-    let ordering = "-date";
-
-    const urlParams = new URLSearchParams(window.location.search);
-    if (urlParams.has('ordering')) {
-        let aSort = null;
-        ordering = urlParams.get('ordering');
-        if (ordering == "name" || ordering == "owner" || ordering == "date") {
-                let aSort = document.querySelector(`a[href="?ordering=${ordering}"`);
-                aSort.href = `?ordering=-${ordering}`;
-        } 
-    } 
-
-    let currentSort = document.querySelector("#current-sort");
-    currentSort.innerHTML = (ordering.startsWith("-") ? "Descending" : "Ascending") + " " + ordering.replace("-", "");
-
-    let currentUser = await getCurrentUser();
-    // grab username
-    if (ordering.includes("owner")) {
-        ordering += "__username";
+  let createButton = document.querySelector("#btn-create-workout");
+  createButton.addEventListener("click", createWorkout);
+
+  let planButton = document.querySelector("#btn-plan-workout");
+  planButton.addEventListener("click", planWorkout);
+  let ordering = "-date";
+
+  const urlParams = new URLSearchParams(window.location.search);
+  if (urlParams.has("ordering")) {
+    let aSort = null;
+    ordering = urlParams.get("ordering");
+    if (ordering == "name" || ordering == "owner" || ordering == "date") {
+      let aSort = document.querySelector(`a[href="?ordering=${ordering}"`);
+      aSort.href = `?ordering=-${ordering}`;
     }
-    let workouts = await fetchWorkouts(ordering);
-    
-    let tabEls = document.querySelectorAll('a[data-bs-toggle="list"]');
-    for (let i = 0; i < tabEls.length; i++) {
-        let tabEl = tabEls[i];
-        tabEl.addEventListener('show.bs.tab', function (event) {
-            let workoutAnchors = document.querySelectorAll('.workout');
-            for (let j = 0; j < workouts.length; j++) {
-                // I'm assuming that the order of workout objects matches
-                // the other of the workout anchor elements. They should, given
-                // that I just created them.
-                let workout = workouts[j];
-                let workoutAnchor = workoutAnchors[j];
-
-                switch (event.currentTarget.id) {
-                    case "list-my-workouts-list":
-                        if (workout.owner == currentUser.url) {
-                            workoutAnchor.classList.remove('hide');
-                        } else {
-                            workoutAnchor.classList.add('hide');
-                        }
-                        break;
-                    case "list-athlete-workouts-list":
-                        if (currentUser.athletes && currentUser.athletes.includes(workout.owner)) {
-                            workoutAnchor.classList.remove('hide');
-                        } else {
-                            workoutAnchor.classList.add('hide');
-                        }
-                        break;
-                    case "list-public-workouts-list":
-                        if (workout.visibility == "PU") {
-                            workoutAnchor.classList.remove('hide');
-                        } else {
-                            workoutAnchor.classList.add('hide');
-                        }
-                        break;
-                    default :
-                        workoutAnchor.classList.remove('hide');
-                        break;
-                }
+  }
+
+  let currentSort = document.querySelector("#current-sort");
+  currentSort.innerHTML =
+    (ordering.startsWith("-") ? "Descending" : "Ascending") +
+    " " +
+    ordering.replace("-", "");
+
+  let currentUser = await getCurrentUser();
+  // grab username
+  if (ordering.includes("owner")) {
+    ordering += "__username";
+  }
+  let workouts = await fetchWorkouts(ordering);
+
+  let tabEls = document.querySelectorAll('a[data-bs-toggle="list"]');
+  for (let i = 0; i < tabEls.length; i++) {
+    let tabEl = tabEls[i];
+    tabEl.addEventListener("show.bs.tab", function (event) {
+      let workoutAnchors = document.querySelectorAll(".workout");
+      for (let j = 0; j < workouts.length; j++) {
+        // I'm assuming that the order of workout objects matches
+        // the other of the workout anchor elements. They should, given
+        // that I just created them.
+        let workout = workouts[j];
+        let workoutAnchor = workoutAnchors[j];
+
+        switch (event.currentTarget.id) {
+          case "list-my-logged-workouts-list":
+            if (workout.owner == currentUser.url) {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
             }
-        });
-    }
-});
\ No newline at end of file
+
+            if (!workout.planned) {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
+            }
+            break;
+          case "list-my-planned-workouts-list":
+            if (workout.owner == currentUser.url) {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
+            }
+
+            if (workout.planned) {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
+            }
+            break;
+          case "list-athlete-workouts-list":
+            if (
+              currentUser.athletes &&
+              currentUser.athletes.includes(workout.owner)
+            ) {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
+            }
+            break;
+          case "list-public-workouts-list":
+            if (workout.visibility == "PU") {
+              workoutAnchor.classList.remove("hide");
+            } else {
+              workoutAnchor.classList.add("hide");
+            }
+            break;
+          default:
+            workoutAnchor.classList.remove("hide");
+            break;
+        }
+      }
+    });
+  }
+});
diff --git a/frontend/www/workout.html b/frontend/www/workout.html
index 2e5d881a2103c5117d061618f44465d4486f7e7f..849b3fa093ad8ac03b08fe95801728260af00a84 100644
--- a/frontend/www/workout.html
+++ b/frontend/www/workout.html
@@ -17,9 +17,14 @@
     <div class="container">
         <div class="row">
             <div class="col-lg">
-                <h3 class="mt-3">View/Edit Workout</h3>
+                <h3 class="mt-3">View/Edit Logged Workout</h3>
             </div>
-        </div>
+          </div>
+          <div class="row">
+            <div class="col-lg">
+              <p class="mt-4">A logged workout is a workout you have completed</p>
+            </div>
+          </div>        
     <form class="row g-3 mb-4" id="form-workout">
         <div class="col-lg-6 ">
           <label for="inputName" class="form-label">Name</label>
diff --git a/frontend/www/workouts.html b/frontend/www/workouts.html
index b34439d55031d7f029647d8a425669b795d8fde0..07a5c42f91513e7822acc9a93d14f88bcceea913 100644
--- a/frontend/www/workouts.html
+++ b/frontend/www/workouts.html
@@ -20,13 +20,15 @@
                 <p>Here you can view workouts completed by you, your athletes, 
                     or the public. Click on a workout to view its details.</p>
                 <input type="button" class="btn btn-success" id="btn-create-workout" value="Log new workout">
+                <input type="button" class="btn btn-success" id="btn-plan-workout" value="Plan new workout">
             </div>
         </div>
         <div class="row">
             <div class="col-lg text-center">
                 <div class="list-group list-group-horizontal d-inline-flex mt-2" id="list-tab" role="tablist">
                   <a class="list-group-item list-group-item-action active" id="list-all-workouts-list" data-bs-toggle="list" href="#list-all-workouts" role="tab" aria-controls="all">All Workouts</a>
-                  <a class="list-group-item list-group-item-action" id="list-my-workouts-list" data-bs-toggle="list" href="#list-my-workouts" role="tab" aria-controls="my">My Workouts</a>
+                  <a class="list-group-item list-group-item-action" id="list-my-logged-workouts-list" data-bs-toggle="list" href="#list-my-workouts" role="tab" aria-controls="my">My logged Workouts</a>
+                  <a class="list-group-item list-group-item-action" id="list-my-planned-workouts-list" data-bs-toggle="list" href="#list-my-planned-workouts" role="tab" aria-controls="my">My Planned workouts</a>
                   <a class="list-group-item list-group-item-action" id="list-athlete-workouts-list" data-bs-toggle="list" href="#list-athlete-workouts" role="tab" aria-controls="athlete">Athlete Workouts</a>
                   <a class="list-group-item list-group-item-action" id="list-public-workouts-list" data-bs-toggle="list" href="#list-public-workouts" role="tab" aria-controls="public">Public Workouts</a>
                 </div>