diff --git a/.gitignore b/.gitignore
index 55debd42d1b4c4df14b7afa9d7a98620fe2f45e2..649f630549301946f0fd84b316eb8de4ac1f7552 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,6 @@ backend/secfit/*/__pycache__/
 backend/secfit/db.sqlite3
 
 .idea/
-venv/
\ No newline at end of file
+venv/
+.vscode/ 
+.DS_store
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 412d9ab99aa5cdccf5ca9522e3f0a52c1dd80aff..2a961e25a9befd9c9336e88c560ac5fd45a79ee2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,27 +1,31 @@
 variables:
-  HEROKU_APP_NAME: tdt4242-base
-  HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
+  HEROKU_APP_NAME_BACKEND: tdt4242-base
+  HEROKU_APP_NAME_FRONTEND: tdt4242-base-secfit
 
 stages:
-  - test
+#  - test
   - deploy
 
-test:
-  image: python:3
-  stage: test
-  script:
+#test:
+#  image: python:3
+#  stage: test
+#  script:
   # this configures Django application to use attached postgres database that is run on `postgres` host
-    - cd backend/secfit
-    - apt-get update -qy
-    - pip install -r requirements.txt
-    - python manage.py test
+#    - cd backend/secfit
+#    - apt-get update -qy
+#    - pip install -r requirements.txt
+#    - python manage.py test
 
 deploy:
+  image: ruby
   stage: deploy
-  variables:
-    HEROKU_APP_NAME: tdt4242-base
+  type: deploy
   script:
     - apt-get update -qy
-    - apt-get install -y ruby-dev
+    - apt-get install -y ruby ruby-dev
     - gem install dpl
-    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_AUTH_TOKEN
+    - dpl --provider=heroku --app=$HEROKU_APP_NAME_BACKEND --api-key=$HEROKU_AUTH_TOKEN
+    - dpl --provider=heroku --app=$HEROKU_APP_NAME_FRONTEND --api-key=$HEROKU_AUTH_TOKEN
+
+    
+
diff --git a/backend/secfit/Procfile b/backend/secfit/Procfile
new file mode 100644
index 0000000000000000000000000000000000000000..507db01c439e93dd7c81e0ec453289b04cf81497
--- /dev/null
+++ b/backend/secfit/Procfile
@@ -0,0 +1 @@
+web: gunicorn --pythonpath 'backend/secfit' secfit.wsgi --log-file -
diff --git a/backend/secfit/comments/migrations/0002_auto_20210304_2241.py b/backend/secfit/comments/migrations/0002_auto_20210304_2241.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c4fb6d46f3d27664651edc221a883f2e7a01888
--- /dev/null
+++ b/backend/secfit/comments/migrations/0002_auto_20210304_2241.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.1 on 2021-03-04 22:41
+
+from django.db import migrations, models
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('comments', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='comment',
+            name='timestamp',
+            field=models.DateTimeField(default=django.utils.timezone.now),
+        ),
+        migrations.AlterField(
+            model_name='like',
+            name='timestamp',
+            field=models.DateTimeField(default=django.utils.timezone.now),
+        ),
+    ]
diff --git a/backend/secfit/comments/models.py b/backend/secfit/comments/models.py
index e1bba07bce0d33e4325867917b71afea87651501..ac48dc2af65e65cd28ad46cefafec58bbaff399d 100644
--- a/backend/secfit/comments/models.py
+++ b/backend/secfit/comments/models.py
@@ -8,8 +8,10 @@ from django.urls import reverse
 from django.db import models
 from django.contrib.auth import get_user_model
 from workouts.models import Workout
-
+from django.utils import timezone
 # Create your models here.
+
+
 class Comment(models.Model):
     """Django model for a comment left on a workout.
 
@@ -26,7 +28,7 @@ class Comment(models.Model):
         Workout, on_delete=models.CASCADE, related_name="comments"
     )
     content = models.TextField()
-    timestamp = models.DateTimeField(auto_now_add=True)
+    timestamp = models.DateTimeField(default=timezone.now)
 
     class Meta:
         ordering = ["-timestamp"]
@@ -44,5 +46,6 @@ class Like(models.Model):
     owner = models.ForeignKey(
         get_user_model(), on_delete=models.CASCADE, related_name="likes"
     )
-    comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name="likes")
-    timestamp = models.DateTimeField(auto_now_add=True)
+    comment = models.ForeignKey(
+        Comment, on_delete=models.CASCADE, related_name="likes")
+    timestamp = models.DateTimeField(default=timezone.now)
diff --git a/backend/secfit/requirements.txt b/backend/secfit/requirements.txt
index 99bebaa8f4285653b160bd34a44af2eccc791ae5..0e475459526597a9968922641b5be594afb38ad3 100644
Binary files a/backend/secfit/requirements.txt and b/backend/secfit/requirements.txt differ
diff --git a/backend/secfit/secfit/django_heroku.py b/backend/secfit/secfit/django_heroku.py
new file mode 100644
index 0000000000000000000000000000000000000000..4735073c79f4f024d563a7a6a1b253c19e961e02
--- /dev/null
+++ b/backend/secfit/secfit/django_heroku.py
@@ -0,0 +1,118 @@
+# import logging
+import os
+
+import dj_database_url
+from django.test.runner import DiscoverRunner
+
+MAX_CONN_AGE = 600
+
+
+def settings(config, *, db_colors=False, databases=True, test_runner=True, staticfiles=True, allowed_hosts=True,
+             logging=True, secret_key=True):
+    # Database configuration.
+    # TODO: support other database (e.g. TEAL, AMBER, etc, automatically.)
+    if databases:
+        # Integrity check.
+        if 'DATABASES' not in config:
+            config['DATABASES'] = {'default': None}
+
+        conn_max_age = config.get('CONN_MAX_AGE', MAX_CONN_AGE)
+
+        if db_colors:
+            # Support all Heroku databases.
+            # TODO: This appears to break TestRunner.
+            for (env, url) in os.environ.items():
+                if env.startswith('HEROKU_POSTGRESQL'):
+                    db_color = env[len('HEROKU_POSTGRESQL_'):].split('_')[0]
+
+                    # logger.info('Adding ${} to DATABASES Django setting ({}).'.format(env, db_color))
+
+                    config['DATABASES'][db_color] = dj_database_url.parse(url, conn_max_age=conn_max_age,
+                                                                          ssl_require=True)
+
+        if 'DATABASE_URL' in os.environ:
+            # logger.info('Adding $DATABASE_URL to default DATABASE Django setting.')
+
+            # Configure Django for DATABASE_URL environment variable.
+            config['DATABASES']['default'] = dj_database_url.config(conn_max_age=conn_max_age, ssl_require=True)
+
+            # logger.info('Adding $DATABASE_URL to TEST default DATABASE Django setting.')
+
+            # Enable test database if found in CI environment.
+            if 'CI' in os.environ:
+                config['DATABASES']['default']['TEST'] = config['DATABASES']['default']
+
+        # else:
+        # logger.info('$DATABASE_URL not found, falling back to previous settings!')
+
+    if test_runner:
+        # Enable test runner if found in CI environment.
+        if 'CI' in os.environ:
+            config['TEST_RUNNER'] = 'django_heroku.HerokuDiscoverRunner'
+
+    # Staticfiles configuration.
+    if staticfiles:
+        # logger.info('Applying Heroku Staticfiles configuration to Django settings.')
+
+        config['STATIC_ROOT'] = os.path.join(config['BASE_DIR'], 'staticfiles')
+        config['STATIC_URL'] = '/static/'
+
+        # Ensure STATIC_ROOT exists.
+        os.makedirs(config['STATIC_ROOT'], exist_ok=True)
+
+        # Insert Whitenoise Middleware.
+        try:
+            config['MIDDLEWARE_CLASSES'] = tuple(
+                ['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE_CLASSES']))
+        except KeyError:
+            config['MIDDLEWARE'] = tuple(['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE']))
+
+        # Enable GZip.
+        config['STATICFILES_STORAGE'] = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
+
+    if allowed_hosts:
+        # logger.info('Applying Heroku ALLOWED_HOSTS configuration to Django settings.')
+        config['ALLOWED_HOSTS'] = ['*']
+    """
+    if logging:
+        logger.info('Applying Heroku logging configuration to Django settings.')
+
+        config['LOGGING'] = {
+            'version': 1,
+            'disable_existing_loggers': False,
+            'formatters': {
+                'verbose': {
+                    'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
+                               'pathname=%(pathname)s lineno=%(lineno)s ' +
+                               'funcname=%(funcName)s %(message)s'),
+                    'datefmt': '%Y-%m-%d %H:%M:%S'
+                },
+                'simple': {
+                    'format': '%(levelname)s %(message)s'
+                }
+            },
+            'handlers': {
+                'null': {
+                    'level': 'DEBUG',
+                    'class': 'logging.NullHandler',
+                },
+                'console': {
+                    'level': 'DEBUG',
+                    'class': 'logging.StreamHandler',
+                    'formatter': 'verbose'
+                }
+            },
+            'loggers': {
+                'testlogger': {
+                    'handlers': ['console'],
+                    'level': 'INFO',
+                }
+            }
+        }
+    """
+    # SECRET_KEY configuration.
+    if secret_key:
+        if 'SECRET_KEY' in os.environ:
+            # logger.info('Adding $SECRET_KEY to SECRET_KEY Django setting.')
+            # Set the Django setting from the environment variable.
+            config['SECRET_KEY'] = os.environ['SECRET_KEY']
\ No newline at end of file
diff --git a/backend/secfit/secfit/settings.py b/backend/secfit/secfit/settings.py
index 6f71ccf79bdf0bf29d89a1381795039cd5c480e0..b1f5c7c55ea91fa265dc39708850589d3d925c29 100644
--- a/backend/secfit/secfit/settings.py
+++ b/backend/secfit/secfit/settings.py
@@ -15,6 +15,8 @@ import os
 
 
 # Get the GROUPID variable to accept connections from the application server and NGINX
+from .django_heroku import settings
+
 groupid = os.environ.get("GROUPID", "0")
 
 # Email configuration
@@ -59,7 +61,9 @@ INSTALLED_APPS = [
     "workouts.apps.WorkoutsConfig",
     "users.apps.UsersConfig",
     "comments.apps.CommentsConfig",
+    "suggested_workouts.apps.SuggestedWorkoutsConfig",
     "corsheaders",
+
 ]
 
 MIDDLEWARE = [
@@ -139,9 +143,12 @@ REST_FRAMEWORK = {
     "PAGE_SIZE": 10,
     "DEFAULT_AUTHENTICATION_CLASSES": (
         "rest_framework_simplejwt.authentication.JWTAuthentication",
+        'rest_framework.authentication.SessionAuthentication',
     ),
 }
 
 AUTH_USER_MODEL = "users.User"
 
 DEBUG = True
+
+settings(locals())
diff --git a/backend/secfit/secfit/urls.py b/backend/secfit/secfit/urls.py
index 3146886ed88c67c7f8838c74cea38c7b7ee5555a..5bc17685ca2deb8ceb1642ae56bee320c1e47040 100644
--- a/backend/secfit/secfit/urls.py
+++ b/backend/secfit/secfit/urls.py
@@ -21,6 +21,7 @@ from django.conf.urls.static import static
 urlpatterns = [
     path("admin/", admin.site.urls),
     path("", include("workouts.urls")),
+    path("", include("suggested_workouts.urls")),
 ]
 
 urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/backend/secfit/suggested_workouts/__init__.py b/backend/secfit/suggested_workouts/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/backend/secfit/suggested_workouts/admin.py b/backend/secfit/suggested_workouts/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..65ffde0a2d8b0423ad3afb06a64562f4693152ac
--- /dev/null
+++ b/backend/secfit/suggested_workouts/admin.py
@@ -0,0 +1,9 @@
+"""Module for registering models from workouts app to admin page so that they appear
+"""
+from django.contrib import admin
+
+# Register your models here.
+from .models import SuggestedWorkout
+
+admin.site.register(SuggestedWorkout)
+
diff --git a/backend/secfit/suggested_workouts/apps.py b/backend/secfit/suggested_workouts/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..e4fea100302e8b54f212b0dbfacd6d10f4f411c5
--- /dev/null
+++ b/backend/secfit/suggested_workouts/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SuggestedWorkoutsConfig(AppConfig):
+    name = 'suggested_workouts'
diff --git a/backend/secfit/suggested_workouts/migrations/0001_initial.py b/backend/secfit/suggested_workouts/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d3c8a412ddc9ca6df96015173a93395d726eee5
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0001_initial.py
@@ -0,0 +1,38 @@
+# Generated by Django 3.1 on 2021-02-23 21:11
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='WorkoutRequest',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('is_active', models.BooleanField(blank=True, default=True)),
+                ('reciever', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reciever', to=settings.AUTH_USER_MODEL)),
+                ('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sender', to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SuggestedWorkout',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=100)),
+                ('date', models.DateTimeField(blank=True, null=True)),
+                ('notes', models.TextField()),
+                ('visibility', models.CharField(choices=[('PU', 'Public'), ('CO', 'Coach'), ('PR', 'Private')], default='CO', max_length=2)),
+                ('athlete', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='athlete', to=settings.AUTH_USER_MODEL)),
+                ('coach', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author', to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/0002_auto_20210304_2241.py b/backend/secfit/suggested_workouts/migrations/0002_auto_20210304_2241.py
new file mode 100644
index 0000000000000000000000000000000000000000..5da3bc244f4fbc5bcb4a4faf37c5cffcc8deed65
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0002_auto_20210304_2241.py
@@ -0,0 +1,30 @@
+# Generated by Django 3.1 on 2021-03-04 22:41
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('suggested_workouts', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='suggestedworkout',
+            name='visibility',
+        ),
+        migrations.AddField(
+            model_name='suggestedworkout',
+            name='status',
+            field=models.CharField(choices=[('a', 'Accepted'), ('p', 'Pending'), ('d', 'Declined')], default='p', max_length=8),
+        ),
+        migrations.AlterField(
+            model_name='suggestedworkout',
+            name='coach',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/0003_suggestedworkout_visibility.py b/backend/secfit/suggested_workouts/migrations/0003_suggestedworkout_visibility.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2910f0674211fb44aed07a9c21dbd28847a0250
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0003_suggestedworkout_visibility.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1 on 2021-03-04 22:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('suggested_workouts', '0002_auto_20210304_2241'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='suggestedworkout',
+            name='visibility',
+            field=models.CharField(default='PU', max_length=8),
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/0004_remove_suggestedworkout_visibility.py b/backend/secfit/suggested_workouts/migrations/0004_remove_suggestedworkout_visibility.py
new file mode 100644
index 0000000000000000000000000000000000000000..b954002b01399a9197dbd879f89bf3e0e250e09d
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0004_remove_suggestedworkout_visibility.py
@@ -0,0 +1,17 @@
+# Generated by Django 3.1 on 2021-03-04 23:00
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('suggested_workouts', '0003_suggestedworkout_visibility'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='suggestedworkout',
+            name='visibility',
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/0005_suggestedworkout_visibility.py b/backend/secfit/suggested_workouts/migrations/0005_suggestedworkout_visibility.py
new file mode 100644
index 0000000000000000000000000000000000000000..782a3ccc84eeb87085b6168e2b1101a7ae8a1e7b
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0005_suggestedworkout_visibility.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1 on 2021-03-04 23:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('suggested_workouts', '0004_remove_suggestedworkout_visibility'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='suggestedworkout',
+            name='visibility',
+            field=models.CharField(blank=True, default='', max_length=8, null=True),
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/0006_auto_20210305_0929.py b/backend/secfit/suggested_workouts/migrations/0006_auto_20210305_0929.py
new file mode 100644
index 0000000000000000000000000000000000000000..3daeb6a801389f183a47dffddb763e489c18c195
--- /dev/null
+++ b/backend/secfit/suggested_workouts/migrations/0006_auto_20210305_0929.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1 on 2021-03-05 09:29
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('suggested_workouts', '0005_suggestedworkout_visibility'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='suggestedworkout',
+            name='visibility',
+        ),
+        migrations.DeleteModel(
+            name='WorkoutRequest',
+        ),
+    ]
diff --git a/backend/secfit/suggested_workouts/migrations/__init__.py b/backend/secfit/suggested_workouts/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/backend/secfit/suggested_workouts/models.py b/backend/secfit/suggested_workouts/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..9b326867e03189dc8271da93ed5e0f9614da3c99
--- /dev/null
+++ b/backend/secfit/suggested_workouts/models.py
@@ -0,0 +1,30 @@
+from django.db import models
+from django.db import models
+from django.contrib.auth import get_user_model
+from django.utils import timezone
+
+
+class SuggestedWorkout(models.Model):
+    # Visibility levels
+    ACCEPTED = "a"
+    PENDING = "p"
+    DECLINED = "d"
+    STATUS_CHOICES = (
+        (ACCEPTED, "Accepted"),
+        (PENDING, "Pending"),
+        (DECLINED, "Declined"),
+    )
+    name = models.CharField(max_length=100)
+    date = models.DateTimeField(null=True, blank=True)
+    notes = models.TextField()
+    coach = models.ForeignKey(
+        get_user_model(), on_delete=models.CASCADE, related_name="owner")
+    athlete = models.ForeignKey(
+        get_user_model(), on_delete=models.CASCADE, related_name="athlete")
+
+    status = models.CharField(
+        max_length=8, choices=STATUS_CHOICES, default=PENDING)
+
+    def __str__(self):
+        return self.name
+ 
\ No newline at end of file
diff --git a/backend/secfit/suggested_workouts/serializer.py b/backend/secfit/suggested_workouts/serializer.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d214f20bf168c2d794589c98fae81479a43cae5
--- /dev/null
+++ b/backend/secfit/suggested_workouts/serializer.py
@@ -0,0 +1,128 @@
+from rest_framework import serializers
+from .models import SuggestedWorkout
+from users.models import User
+from workouts.serializers import WorkoutFileSerializer, ExerciseInstanceSerializer
+from workouts.models import ExerciseInstance, WorkoutFile
+
+
+class SuggestedWorkoutSerializer(serializers.ModelSerializer):
+    suggested_exercise_instances = ExerciseInstanceSerializer(
+        many=True, required=False)
+    suggested_workout_files = WorkoutFileSerializer(many=True, required=False)
+    coach_username = serializers.SerializerMethodField()
+
+    class Meta:
+        model = SuggestedWorkout
+        fields = ['id', 'athlete', 'coach_username', 'name', 'notes', 'date',
+                  'status', 'coach', 'suggested_exercise_instances', 'suggested_workout_files']
+        extra_kwargs = {"coach": {"read_only": True}}
+
+    def create(self, validated_data, coach):
+        """Custom logic for creating ExerciseInstances, WorkoutFiles, and a Workout.
+
+        This is needed to iterate over the files and exercise instances, since this serializer is
+        nested.
+
+        Args:
+            validated_data: Validated files and exercise_instances
+
+        Returns:
+            Workout: A newly created Workout
+        """
+        exercise_instances_data = validated_data.pop(
+            "suggested_exercise_instances")
+        files_data = []
+        if "suggested_workout_files" in validated_data:
+            files_data = validated_data.pop("suggested_workout_files")
+
+        suggested_workout = SuggestedWorkout.objects.create(
+            coach=coach, **validated_data)
+
+        for exercise_instance_data in exercise_instances_data:
+            ExerciseInstance.objects.create(
+                suggested_workout=suggested_workout, **exercise_instance_data)
+        for file_data in files_data:
+            WorkoutFile.objects.create(
+                suggested_workout=suggested_workout, owner=suggested_workout.coach, file=file_data.get(
+                    "file")
+            )
+
+        return suggested_workout
+
+    def update(self, instance, validated_data):
+        exercise_instances_data = validated_data.pop(
+            "suggested_exercise_instances")
+        exercise_instances = instance.suggested_exercise_instances
+
+        instance.name = validated_data.get("name", instance.name)
+        instance.notes = validated_data.get("notes", instance.notes)
+        instance.status = validated_data.get(
+            "status", instance.status)
+        instance.date = validated_data.get("date", instance.date)
+        instance.athlete = validated_data.get("athlete", instance.athlete)
+        instance.save()
+
+    # Handle ExerciseInstances
+
+    # This updates existing exercise instances without adding or deleting object.
+    # zip() will yield n 2-tuples, where n is
+    # min(len(exercise_instance), len(exercise_instance_data))
+        for exercise_instance, exercise_instance_data in zip(
+                exercise_instances.all(), exercise_instances_data):
+            exercise_instance.exercise = exercise_instance_data.get(
+                "exercise", exercise_instance.exercise)
+            exercise_instance.number = exercise_instance_data.get(
+                "number", exercise_instance.number
+            )
+            exercise_instance.sets = exercise_instance_data.get(
+                "sets", exercise_instance.sets
+            )
+            exercise_instance.save()
+
+        # If new exercise instances have been added to the workout, then create them
+        if len(exercise_instances_data) > len(exercise_instances.all()):
+            for i in range(len(exercise_instances.all()), len(exercise_instances_data)):
+                exercise_instance_data = exercise_instances_data[i]
+                ExerciseInstance.objects.create(
+                    suggested_workout=instance, **exercise_instance_data
+                )
+        # Else if exercise instances have been removed from the workout, then delete them
+        elif len(exercise_instances_data) < len(exercise_instances.all()):
+            for i in range(len(exercise_instances_data), len(exercise_instances.all())):
+                exercise_instances.all()[i].delete()
+
+        # Handle WorkoutFiles
+
+        if "suggested_workout_files" in validated_data:
+            files_data = validated_data.pop("suggested_workout_files")
+            files = instance.suggested_workout_files
+
+            for file, file_data in zip(files.all(), files_data):
+                file.file = file_data.get("file", file.file)
+                file.save()
+
+            # If new files have been added, creating new WorkoutFiles
+            if len(files_data) > len(files.all()):
+                for i in range(len(files.all()), len(files_data)):
+                    WorkoutFile.objects.create(
+                        suggested_workout=instance,
+                        owner=instance.coach,
+                        file=files_data[i].get("file"),
+                    )
+            # Else if files have been removed, delete WorkoutFiles
+            elif len(files_data) < len(files.all()):
+                for i in range(len(files_data), len(files.all())):
+                    files.all()[i].delete()
+
+        return instance
+
+    def get_coach_username(self, obj):
+        """Returns the owning user's username
+
+        Args:
+            obj (Workout): Current Workout
+
+        Returns:
+            str: Username of owner
+        """
+        return obj.coach.username
diff --git a/backend/secfit/suggested_workouts/tests.py b/backend/secfit/suggested_workouts/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/backend/secfit/suggested_workouts/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/backend/secfit/suggested_workouts/urls.py b/backend/secfit/suggested_workouts/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6a22224d2340cce1efa18137fbf96ca921964c9
--- /dev/null
+++ b/backend/secfit/suggested_workouts/urls.py
@@ -0,0 +1,16 @@
+from django.urls import path, include
+from suggested_workouts import views
+from rest_framework.urlpatterns import format_suffix_patterns
+
+urlpatterns = [
+    path("api/suggested-workouts/create/", views.createSuggestedWorkouts,
+         name="suggested_workouts"),
+    path("api/suggested-workouts/athlete-list/",
+         views.listAthleteSuggestedWorkouts, name="suggested_workouts_for_athlete"),
+    path("api/suggested-workouts/coach-list/",
+         views.listCoachSuggestedWorkouts, name="suggested_workouts_by_coach"),
+    path("api/suggested-workouts/", views.listAllSuggestedWorkouts,
+         name="list_all_suggested_workouts"),
+    path("api/suggested-workout/<int:pk>/",
+         views.detailedSuggestedWorkout, name="suggested-workout-detail")
+]
diff --git a/backend/secfit/suggested_workouts/views.py b/backend/secfit/suggested_workouts/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..85797a3e687bc83b60d0e7522b8986280bb932b7
--- /dev/null
+++ b/backend/secfit/suggested_workouts/views.py
@@ -0,0 +1,102 @@
+from rest_framework.decorators import api_view
+from suggested_workouts.models import SuggestedWorkout
+from .serializer import SuggestedWorkoutSerializer
+from users.models import User
+from rest_framework import status
+from rest_framework.response import Response
+from workouts.parsers import MultipartJsonParser
+from rest_framework.parsers import (
+    JSONParser
+)
+from rest_framework.decorators import parser_classes
+"""
+Handling post request of a new suggested workout instance. Handling update, delete and list exercises as well.
+"""
+
+
+@api_view(['POST'])
+@parser_classes([MultipartJsonParser,
+                 JSONParser])
+def createSuggestedWorkouts(request):
+    serializer = SuggestedWorkoutSerializer(data=request.data)
+    if serializer.is_valid():
+        chosen_athlete_id = request.data['athlete']
+        chosen_athlete = User.objects.get(id=chosen_athlete_id)
+        if(request.user != chosen_athlete.coach):
+            return Response({"message": "You can not assign the workout to someone who is not your athlete."}, status=status.HTTP_400_BAD_REQUEST)
+        # new_suggested_workout = SuggestedWorkout.objects.create(
+        #    coach=request.user, **serializer.validated_data)
+        serializer.create(
+            validated_data=serializer.validated_data, coach=request.user)
+        return Response({"message": "Suggested workout successfully created!"}, status=status.HTTP_201_CREATED)
+    return Response({"message": "Something went wrong.", "error": serializer.errors})
+
+
+@api_view(['GET'])
+def listAthleteSuggestedWorkouts(request):
+    # Henter ut riktige workouts gitt brukeren som sender requesten
+    suggested_workouts = SuggestedWorkout.objects.filter(athlete=request.user)
+    if not request.user:
+        return Response({"message": "You have to log in to see this information."}, status=status.HTTP_401_UNAUTHORIZED)
+    serializer = SuggestedWorkoutSerializer(
+        suggested_workouts, many=True, context={'request': request})
+    return Response(data=serializer.data, status=status.HTTP_200_OK)
+
+
+@api_view(['GET'])
+def listCoachSuggestedWorkouts(request):
+    # Gjør spørring på workouts der request.user er coach
+    if not request.user:
+        return Response({"message": "You have to log in to see this information."}, status=status.HTTP_401_UNAUTHORIZED)
+    suggested_workouts = SuggestedWorkout.objects.filter(coach=request.user)
+    serializer = SuggestedWorkoutSerializer(
+        suggested_workouts, many=True, context={'request': request})
+    return Response(data=serializer.data, status=status.HTTP_200_OK)
+
+
+@api_view(['GET'])
+def listAllSuggestedWorkouts(request):
+    # Lister alle workouts som er foreslått
+    suggested_workouts = SuggestedWorkout.objects.all()
+    serializer = SuggestedWorkoutSerializer(
+        suggested_workouts, many=True, context={'request': request})
+    if not request.user.id:
+        return Response({"message": "You have to log in to see this information."}, status=status.HTTP_401_UNAUTHORIZED)
+    # elif((request.user.id,) not in list(SuggestedWorkout.objects.values_list('coach')) or (request.user.id,) not in list(SuggestedWorkout.objects.values_list('athlete'))):
+    #     return Response({"message": "You must either be a coach or athlete of the suggested workouts to see this information."}, status=status.HTTP_401_UNAUTHORIZED)
+    return Response(data=serializer.data, status=status.HTTP_200_OK)
+
+
+"""
+View for both deleting,updating and retrieving a single workout.
+"""
+
+
+@api_view(['GET', 'DELETE', 'PUT'])
+@parser_classes([MultipartJsonParser,
+                 JSONParser])
+def detailedSuggestedWorkout(request, pk):
+    detailed_suggested_workout = SuggestedWorkout.objects.get(id=pk)
+    if not request.user.id:
+        return Response({"message": "Access denied."}, status=status.HTTP_401_UNAUTHORIZED)
+    elif request.method == 'GET':
+        serializer = SuggestedWorkoutSerializer(
+            detailed_suggested_workout, context={'request': request})
+        if(request.user.id != detailed_suggested_workout.coach.id and request.user.id != detailed_suggested_workout.athlete.id):
+            return Response({"messages": "You have to be a coach or athlete to see this information."}, status=status.HTTP_401_UNAUTHORIZED)
+        return Response(data=serializer.data, status=status.HTTP_200_OK)
+    elif request.method == 'DELETE':
+        if(request.user.id != detailed_suggested_workout.coach.id and request.user.id != detailed_suggested_workout.athlete.id):
+            return Response({"messages": "You have to be a coach or athlete to perform this action."}, status=status.HTTP_401_UNAUTHORIZED)
+        SuggestedWorkout.delete(detailed_suggested_workout)
+        return Response({"message": "Suggested workout successfully deleted."}, status=status.HTTP_204_NO_CONTENT)
+    elif request.method == 'PUT':
+        if(request.user.id != detailed_suggested_workout.coach.id and request.user.id != detailed_suggested_workout.athlete.id):
+            return Response({"messages": "You have to be a coach or athlete to perform this action."}, status=status.HTTP_401_UNAUTHORIZED)
+        serializer = SuggestedWorkoutSerializer(
+            detailed_suggested_workout, data=request.data)
+        if(serializer.is_valid()):
+            serializer.update(instance=SuggestedWorkout.objects.get(id=pk),
+                              validated_data=serializer.validated_data)
+            return Response({"message": "Successfully updated the suggested workout!"}, status=status.HTTP_200_OK)
+        return Response({"message": "Something went wrong.", "error": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
diff --git a/backend/secfit/users/admin.py b/backend/secfit/users/admin.py
index fc0af23c4473e29bcc06045aebfdd0d21989d22d..de6a0e93539eca3a56fc08eebce97d6fe05f68fd 100644
--- a/backend/secfit/users/admin.py
+++ b/backend/secfit/users/admin.py
@@ -11,9 +11,12 @@ class CustomUserAdmin(UserAdmin):
     add_form = CustomUserCreationForm
     form = CustomUserChangeForm
     model = get_user_model()
-    # list_display = UserAdmin.list_display + ('coach',)
+    list_display = UserAdmin.list_display + \
+        ('coach',) + ('phone_number',) + \
+        ('country',) + ('city',) + ('street_address',)
     fieldsets = UserAdmin.fieldsets + ((None, {"fields": ("coach",)}),)
-    add_fieldsets = UserAdmin.add_fieldsets + ((None, {"fields": ("coach",)}),)
+    add_fieldsets = UserAdmin.add_fieldsets + \
+        ((None, {"fields": ("coach", "phone_number")}),)
 
 
 admin.site.register(get_user_model(), CustomUserAdmin)
diff --git a/backend/secfit/users/migrations/0002_auto_20200907_1200.py b/backend/secfit/users/migrations/0002_auto_20200907_1200.py
deleted file mode 100644
index e1ffdfc85bbfa6746a249e02fb018710a3545c1a..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0002_auto_20200907_1200.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 3.1 on 2020-09-07 10:00
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0001_initial"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="offer",
-            name="stale",
-            field=models.BooleanField(default=False),
-        ),
-        migrations.AddField(
-            model_name="offer",
-            name="status",
-            field=models.CharField(
-                choices=[("a", "Accepted"), ("p", "Pending"), ("d", "Declined")],
-                default="p",
-                max_length=8,
-            ),
-        ),
-        migrations.DeleteModel(
-            name="OfferResponse",
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0002_auto_20210304_2241.py b/backend/secfit/users/migrations/0002_auto_20210304_2241.py
new file mode 100644
index 0000000000000000000000000000000000000000..007428eed8563af6bd93de6878709da7a3ea4ae7
--- /dev/null
+++ b/backend/secfit/users/migrations/0002_auto_20210304_2241.py
@@ -0,0 +1,82 @@
+# Generated by Django 3.1 on 2021-03-04 22:41
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+import users.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('users', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='AthleteFile',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('file', models.FileField(upload_to=users.models.athlete_directory_path)),
+            ],
+        ),
+        migrations.RemoveField(
+            model_name='offer',
+            name='offer_type',
+        ),
+        migrations.AddField(
+            model_name='offer',
+            name='status',
+            field=models.CharField(choices=[('a', 'Accepted'), ('p', 'Pending'), ('d', 'Declined')], default='p', max_length=8),
+        ),
+        migrations.AddField(
+            model_name='offer',
+            name='timestamp',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='city',
+            field=models.TextField(blank=True, max_length=50),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='country',
+            field=models.TextField(blank=True, max_length=50),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='phone_number',
+            field=models.TextField(blank=True, max_length=50),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='street_address',
+            field=models.TextField(blank=True, max_length=50),
+        ),
+        migrations.AlterField(
+            model_name='offer',
+            name='recipient',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='received_offers', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='user',
+            name='coach',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='athletes', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.DeleteModel(
+            name='OfferResponse',
+        ),
+        migrations.AddField(
+            model_name='athletefile',
+            name='athlete',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='coach_files', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='athletefile',
+            name='owner',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='athlete_files', to=settings.AUTH_USER_MODEL),
+        ),
+    ]
diff --git a/backend/secfit/users/migrations/0003_auto_20200907_1954.py b/backend/secfit/users/migrations/0003_auto_20200907_1954.py
deleted file mode 100644
index c7f18c817057b573e3275f36a69f00e13676e5f3..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0003_auto_20200907_1954.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 3.1 on 2020-09-07 17:54
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0002_auto_20200907_1200"),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name="offer",
-            name="recipient",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="received_offers",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0004_auto_20200907_2021.py b/backend/secfit/users/migrations/0004_auto_20200907_2021.py
deleted file mode 100644
index ff6be46f14e2bd0adc097f802b81ce758e4afcb1..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0004_auto_20200907_2021.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Generated by Django 3.1 on 2020-09-07 18:21
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0003_auto_20200907_1954"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="AthleteRequest",
-            fields=[
-                (
-                    "id",
-                    models.AutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                (
-                    "status",
-                    models.CharField(
-                        choices=[
-                            ("a", "Accepted"),
-                            ("p", "Pending"),
-                            ("d", "Declined"),
-                        ],
-                        default="p",
-                        max_length=8,
-                    ),
-                ),
-                ("stale", models.BooleanField(default=False)),
-                (
-                    "owner",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="sent_athlete_requests",
-                        to=settings.AUTH_USER_MODEL,
-                    ),
-                ),
-                (
-                    "recipient",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="received_athlete_requests",
-                        to=settings.AUTH_USER_MODEL,
-                    ),
-                ),
-            ],
-            options={
-                "abstract": False,
-            },
-        ),
-        migrations.CreateModel(
-            name="CoachRequest",
-            fields=[
-                (
-                    "id",
-                    models.AutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                (
-                    "status",
-                    models.CharField(
-                        choices=[
-                            ("a", "Accepted"),
-                            ("p", "Pending"),
-                            ("d", "Declined"),
-                        ],
-                        default="p",
-                        max_length=8,
-                    ),
-                ),
-                ("stale", models.BooleanField(default=False)),
-                (
-                    "owner",
-                    models.OneToOneField(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="sent_coach_request",
-                        to=settings.AUTH_USER_MODEL,
-                    ),
-                ),
-                (
-                    "recipient",
-                    models.ForeignKey(
-                        on_delete=django.db.models.deletion.CASCADE,
-                        related_name="received_coach_requests",
-                        to=settings.AUTH_USER_MODEL,
-                    ),
-                ),
-            ],
-            options={
-                "abstract": False,
-            },
-        ),
-        migrations.DeleteModel(
-            name="Offer",
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0005_auto_20200907_2039.py b/backend/secfit/users/migrations/0005_auto_20200907_2039.py
deleted file mode 100644
index 269e723bda3ff1b5b2207d1f7471b0f698682033..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0005_auto_20200907_2039.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Generated by Django 3.1 on 2020-09-07 18:39
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0004_auto_20200907_2021"),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name="athleterequest",
-            name="owner",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="sent_athleterequests",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AlterField(
-            model_name="athleterequest",
-            name="recipient",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="received_athleterequests",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AlterField(
-            model_name="coachrequest",
-            name="owner",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="sent_coachrequests",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AlterField(
-            model_name="coachrequest",
-            name="recipient",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="received_coachrequests",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0006_auto_20200907_2054.py b/backend/secfit/users/migrations/0006_auto_20200907_2054.py
deleted file mode 100644
index ed2ff761a8072336a82493831b79d1b99edb2b34..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0006_auto_20200907_2054.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generated by Django 3.1 on 2020-09-07 18:54
-
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0005_auto_20200907_2039"),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name="athleterequest",
-            name="timestamp",
-            field=models.DateTimeField(
-                auto_now_add=True, default=django.utils.timezone.now
-            ),
-            preserve_default=False,
-        ),
-        migrations.AddField(
-            model_name="coachrequest",
-            name="timestamp",
-            field=models.DateTimeField(
-                auto_now_add=True, default=django.utils.timezone.now
-            ),
-            preserve_default=False,
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0007_auto_20200910_0222.py b/backend/secfit/users/migrations/0007_auto_20200910_0222.py
deleted file mode 100644
index 48a081d1f9387a1eb0fcd66648ec53d0ec8c1410..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0007_auto_20200910_0222.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Generated by Django 3.1 on 2020-09-10 00:22
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import users.models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ("users", "0006_auto_20200907_2054"),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name="AthleteFile",
-            fields=[
-                (
-                    "id",
-                    models.AutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                (
-                    "file",
-                    models.FileField(upload_to=users.models.athlete_directory_path),
-                ),
-            ],
-        ),
-        migrations.CreateModel(
-            name="Offer",
-            fields=[
-                (
-                    "id",
-                    models.AutoField(
-                        auto_created=True,
-                        primary_key=True,
-                        serialize=False,
-                        verbose_name="ID",
-                    ),
-                ),
-                (
-                    "status",
-                    models.CharField(
-                        choices=[
-                            ("a", "Accepted"),
-                            ("p", "Pending"),
-                            ("d", "Declined"),
-                        ],
-                        default="p",
-                        max_length=8,
-                    ),
-                ),
-                (
-                    "offer_type",
-                    models.CharField(
-                        choices=[("a", "Athlete"), ("c", "Coach")],
-                        default="a",
-                        max_length=8,
-                    ),
-                ),
-                ("stale", models.BooleanField(default=False)),
-                ("timestamp", models.DateTimeField(auto_now_add=True)),
-            ],
-        ),
-        migrations.RemoveField(
-            model_name="coachrequest",
-            name="owner",
-        ),
-        migrations.RemoveField(
-            model_name="coachrequest",
-            name="recipient",
-        ),
-        migrations.AlterField(
-            model_name="user",
-            name="coach",
-            field=models.ForeignKey(
-                blank=True,
-                null=True,
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="athletes",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.DeleteModel(
-            name="AthleteRequest",
-        ),
-        migrations.DeleteModel(
-            name="CoachRequest",
-        ),
-        migrations.AddField(
-            model_name="offer",
-            name="owner",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="sent_offers",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AddField(
-            model_name="offer",
-            name="recipient",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="received_offers",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AddField(
-            model_name="athletefile",
-            name="athlete",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="coach_files",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-        migrations.AddField(
-            model_name="athletefile",
-            name="owner",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="athlete_files",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0008_auto_20201213_2228.py b/backend/secfit/users/migrations/0008_auto_20201213_2228.py
deleted file mode 100644
index b2a2d3bd1f048227365bd679b1a253855cd4b776..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0008_auto_20201213_2228.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Generated by Django 3.1 on 2020-12-13 21:28
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('users', '0007_auto_20200910_0222'),
-    ]
-
-    operations = [
-        migrations.RemoveField(
-            model_name='offer',
-            name='offer_type',
-        ),
-        migrations.RemoveField(
-            model_name='offer',
-            name='stale',
-        ),
-    ]
diff --git a/backend/secfit/users/migrations/0009_auto_20210204_1055.py b/backend/secfit/users/migrations/0009_auto_20210204_1055.py
deleted file mode 100644
index 90d76ebd4412716db60b8615e474bfa9bc0464b4..0000000000000000000000000000000000000000
--- a/backend/secfit/users/migrations/0009_auto_20210204_1055.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Generated by Django 3.1 on 2021-02-04 10:55
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('users', '0008_auto_20201213_2228'),
-    ]
-
-    operations = [
-        migrations.AddField(
-            model_name='user',
-            name='city',
-            field=models.TextField(blank=True, max_length=50),
-        ),
-        migrations.AddField(
-            model_name='user',
-            name='country',
-            field=models.TextField(blank=True, max_length=50),
-        ),
-        migrations.AddField(
-            model_name='user',
-            name='phone_number',
-            field=models.TextField(blank=True, max_length=50),
-        ),
-        migrations.AddField(
-            model_name='user',
-            name='street_address',
-            field=models.TextField(blank=True, max_length=50),
-        ),
-    ]
diff --git a/backend/secfit/workouts/migrations/0002_auto_20200910_0222.py b/backend/secfit/workouts/migrations/0002_auto_20200910_0222.py
deleted file mode 100644
index 2d592a4c8a3e975b99c89af0b1e395ed73c12823..0000000000000000000000000000000000000000
--- a/backend/secfit/workouts/migrations/0002_auto_20200910_0222.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 3.1 on 2020-09-10 00:22
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ("workouts", "0001_initial"),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name="workoutfile",
-            name="owner",
-            field=models.ForeignKey(
-                on_delete=django.db.models.deletion.CASCADE,
-                related_name="workout_files",
-                to=settings.AUTH_USER_MODEL,
-            ),
-        ),
-    ]
diff --git a/backend/secfit/workouts/migrations/0002_auto_20210304_2241.py b/backend/secfit/workouts/migrations/0002_auto_20210304_2241.py
new file mode 100644
index 0000000000000000000000000000000000000000..739d4979daf258fd940a9720d18555f0ece5b077
--- /dev/null
+++ b/backend/secfit/workouts/migrations/0002_auto_20210304_2241.py
@@ -0,0 +1,54 @@
+# Generated by Django 3.1 on 2021-03-04 22:41
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('suggested_workouts', '0002_auto_20210304_2241'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('workouts', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='RememberMe',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('remember_me', models.CharField(max_length=500)),
+            ],
+        ),
+        migrations.AddField(
+            model_name='exerciseinstance',
+            name='suggested_workout',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='suggested_exercise_instances', to='suggested_workouts.suggestedworkout'),
+        ),
+        migrations.AddField(
+            model_name='workout',
+            name='planned',
+            field=models.BooleanField(default=False),
+        ),
+        migrations.AddField(
+            model_name='workoutfile',
+            name='suggested_workout',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='suggested_workout_files', to='suggested_workouts.suggestedworkout'),
+        ),
+        migrations.AlterField(
+            model_name='exerciseinstance',
+            name='workout',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='exercise_instances', to='workouts.workout'),
+        ),
+        migrations.AlterField(
+            model_name='workoutfile',
+            name='owner',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='workout_files', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='workoutfile',
+            name='workout',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='files', to='workouts.workout'),
+        ),
+    ]
diff --git a/backend/secfit/workouts/migrations/0003_rememberme.py b/backend/secfit/workouts/migrations/0003_rememberme.py
deleted file mode 100644
index 0f1e9ac4743d0acd3134e412aed5916fdcc6b7b6..0000000000000000000000000000000000000000
--- a/backend/secfit/workouts/migrations/0003_rememberme.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 3.1 on 2021-02-04 10:55
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('workouts', '0002_auto_20200910_0222'),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='RememberMe',
-            fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('remember_me', models.CharField(max_length=500)),
-            ],
-        ),
-    ]
diff --git a/backend/secfit/workouts/migrations/0004_workout_planned.py b/backend/secfit/workouts/migrations/0004_workout_planned.py
deleted file mode 100644
index caccf27985e04eb3cfb1ef65cba921359a4c5c0f..0000000000000000000000000000000000000000
--- a/backend/secfit/workouts/migrations/0004_workout_planned.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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 108cb597a8a35ca00295e97116699c53ecabd364..5f9ab10100892d9ac1b6f50567447fe1e260167e 100644
--- a/backend/secfit/workouts/models.py
+++ b/backend/secfit/workouts/models.py
@@ -7,6 +7,7 @@ from django.db import models
 from django.core.files.storage import FileSystemStorage
 from django.conf import settings
 from django.contrib.auth import get_user_model
+from suggested_workouts.models import SuggestedWorkout
 
 
 class OverwriteStorage(FileSystemStorage):
@@ -95,6 +96,8 @@ class ExerciseInstance(models.Model):
     Kyle's workout on 15.06.2029 had one exercise instance: 3 (sets) reps (unit) of
     10 (number) pushups (exercise type)
 
+    Each suggested workouts shall also have a relation with one or more exercise instances just like a regular workout.
+
     Attributes:
         workout:    The workout associated with this exercise instance
         exercise:   The exercise type of this instance
@@ -103,8 +106,10 @@ class ExerciseInstance(models.Model):
     """
 
     workout = models.ForeignKey(
-        Workout, on_delete=models.CASCADE, related_name="exercise_instances"
+        Workout, on_delete=models.CASCADE, related_name="exercise_instances", null=True
     )
+    suggested_workout = models.ForeignKey(
+        SuggestedWorkout, on_delete=models.CASCADE, related_name="suggested_exercise_instances", null=True, blank=True)
     exercise = models.ForeignKey(
         Exercise, on_delete=models.CASCADE, related_name="instances"
     )
@@ -122,21 +127,29 @@ def workout_directory_path(instance, filename):
     Returns:
         str: Path where workout file is stored
     """
-    return f"workouts/{instance.workout.id}/{filename}"
+    if instance.workout != None:
+        return f"workouts/{instance.workout.id}/{filename}"
+    elif instance.suggested_workout != None:
+        return f"suggested_workouts/{instance.suggested_workout.id}/{filename}"
+    return f"images"
 
 
 class WorkoutFile(models.Model):
-    """Django model for file associated with a workout. Basically a wrapper.
+    """Django model for file associated with a workout or a suggested workout. Basically a wrapper.
 
     Attributes:
         workout: The workout for which this file has been uploaded
+        suggested_workout: The suggested workout for which the file has been uploaded
         owner:   The user who uploaded the file
         file:    The actual file that's being uploaded
     """
 
-    workout = models.ForeignKey(Workout, on_delete=models.CASCADE, related_name="files")
+    workout = models.ForeignKey(
+        Workout, on_delete=models.CASCADE, related_name="files", null=True, blank=True)
+    suggested_workout = models.ForeignKey(
+        SuggestedWorkout, on_delete=models.CASCADE, related_name="suggested_workout_files", null=True, blank=True)
     owner = models.ForeignKey(
-        get_user_model(), on_delete=models.CASCADE, related_name="workout_files"
+        get_user_model(), on_delete=models.CASCADE, related_name="workout_files", null=True, blank=True
     )
     file = models.FileField(upload_to=workout_directory_path)
 
diff --git a/backend/secfit/workouts/parsers.py b/backend/secfit/workouts/parsers.py
index 3255481ce8d327bdfa92f434bf1f03e04d158443..f1a4f70e303afc73272c462ee11ae5c4c709e65f 100644
--- a/backend/secfit/workouts/parsers.py
+++ b/backend/secfit/workouts/parsers.py
@@ -4,12 +4,48 @@ import json
 from rest_framework import parsers
 
 # Thanks to https://stackoverflow.com/a/50514630
+
+
 class MultipartJsonParser(parsers.MultiPartParser):
     """Parser for serializing multipart data containing both files and JSON.
 
     This is currently unused.
     """
 
+    def parse(self, stream, media_type=None, parser_context=None):
+        result = super().parse(
+            stream, media_type=media_type, parser_context=parser_context
+        )
+        data = {}
+        new_files = {"suggested_workout_files": []}
+
+        # for case1 with nested serializers
+        # parse each field with json
+        for key, value in result.data.items():
+            if not isinstance(value, str):
+                data[key] = value
+                continue
+            if "{" in value or "[" in value:
+                try:
+                    data[key] = json.loads(value)
+                except ValueError:
+                    data[key] = value
+            else:
+                data[key] = value
+
+        files = result.files.getlist("suggested_workout_files")
+        for file in files:
+            new_files["suggested_workout_files"].append({"file": file})
+
+        return parsers.DataAndFiles(data, new_files)
+
+
+class MultipartJsonParserWorkout(parsers.MultiPartParser):
+    """Parser for serializing multipart data containing both files and JSON.
+
+    This is currently unused.
+    """
+
     def parse(self, stream, media_type=None, parser_context=None):
         result = super().parse(
             stream, media_type=media_type, parser_context=parser_context
diff --git a/backend/secfit/workouts/serializers.py b/backend/secfit/workouts/serializers.py
index b36de6aefd2025a81fda2bfb1b32edf1544090a1..cda2d9d0acdf3faca081f57b9f2eaa05bbc316cc 100644
--- a/backend/secfit/workouts/serializers.py
+++ b/backend/secfit/workouts/serializers.py
@@ -5,6 +5,7 @@ from rest_framework.serializers import HyperlinkedRelatedField
 from workouts.models import Workout, Exercise, ExerciseInstance, WorkoutFile, RememberMe
 from datetime import datetime
 import pytz
+from suggested_workouts.models import SuggestedWorkout
 
 
 class ExerciseInstanceSerializer(serializers.HyperlinkedModelSerializer):
@@ -19,10 +20,13 @@ class ExerciseInstanceSerializer(serializers.HyperlinkedModelSerializer):
     workout = HyperlinkedRelatedField(
         queryset=Workout.objects.all(), view_name="workout-detail", required=False
     )
+    suggested_workout = HyperlinkedRelatedField(queryset=SuggestedWorkout.objects.all(
+    ), view_name="suggested-workout-detail", required=False)
 
     class Meta:
         model = ExerciseInstance
-        fields = ["url", "id", "exercise", "sets", "number", "workout"]
+        fields = ["url", "id", "exercise", "sets",
+                  "number", "workout", "suggested_workout"]
 
 
 class WorkoutFileSerializer(serializers.HyperlinkedModelSerializer):
@@ -39,10 +43,13 @@ class WorkoutFileSerializer(serializers.HyperlinkedModelSerializer):
     workout = HyperlinkedRelatedField(
         queryset=Workout.objects.all(), view_name="workout-detail", required=False
     )
+    suggested_workout = HyperlinkedRelatedField(
+        queryset=SuggestedWorkout.objects.all(), view_name="suggested-workout-detail", required=False
+    )
 
     class Meta:
         model = WorkoutFile
-        fields = ["url", "id", "owner", "file", "workout"]
+        fields = ["url", "id", "owner", "file", "workout", "suggested_workout"]
 
     def create(self, validated_data):
         return WorkoutFile.objects.create(**validated_data)
@@ -200,9 +207,10 @@ class WorkoutSerializer(serializers.HyperlinkedModelSerializer):
         if "files" in validated_data:
             files_data = validated_data.pop("files")
             files = instance.files
-
             for file, file_data in zip(files.all(), files_data):
+
                 file.file = file_data.get("file", file.file)
+                file.save()
 
             # If new files have been added, creating new WorkoutFiles
             if len(files_data) > len(files.all()):
diff --git a/backend/secfit/workouts/views.py b/backend/secfit/workouts/views.py
index 2026d46fb1f6a9638a4ed23d997ef10cfb26a7d5..26254774232a1baa7737a3f36a476dd0a083f4fc 100644
--- a/backend/secfit/workouts/views.py
+++ b/backend/secfit/workouts/views.py
@@ -11,7 +11,7 @@ from rest_framework.response import Response
 from rest_framework.reverse import reverse
 from django.db.models import Q
 from rest_framework import filters
-from workouts.parsers import MultipartJsonParser
+from workouts.parsers import MultipartJsonParserWorkout
 from workouts.permissions import (
     IsOwner,
     IsCoachAndVisibleToCoach,
@@ -118,7 +118,7 @@ class WorkoutList(
         permissions.IsAuthenticated
     ]  # User must be authenticated to create/view workouts
     parser_classes = [
-        MultipartJsonParser,
+        MultipartJsonParserWorkout,
         JSONParser,
     ]  # For parsing JSON and Multi-part requests
     filter_backends = [filters.OrderingFilter]
@@ -174,7 +174,7 @@ class WorkoutDetail(
         permissions.IsAuthenticated
         & (IsOwner | (IsReadOnly & (IsCoachAndVisibleToCoach | IsPublic)))
     ]
-    parser_classes = [MultipartJsonParser, JSONParser]
+    parser_classes = [MultipartJsonParserWorkout, JSONParser]
 
     def get(self, request, *args, **kwargs):
         return self.retrieve(request, *args, **kwargs)
@@ -241,7 +241,6 @@ class ExerciseInstanceList(
     generics.GenericAPIView,
 ):
     """Class defining the web response for the creation"""
-
     serializer_class = ExerciseInstanceSerializer
     permission_classes = [permissions.IsAuthenticated & IsOwnerOfWorkout]
 
@@ -259,7 +258,7 @@ class ExerciseInstanceList(
                 | (
                     (Q(workout__visibility="CO") | Q(workout__visibility="PU"))
                     & Q(workout__owner__coach=self.request.user)
-                )
+                ) | (Q(suggested_workout__coach=self.request.user) | Q(suggested_workout__athlete=self.request.user))
             ).distinct()
 
         return qs
@@ -271,14 +270,15 @@ class ExerciseInstanceDetail(
     mixins.DestroyModelMixin,
     generics.GenericAPIView,
 ):
+    queryset = ExerciseInstance.objects.all()
     serializer_class = ExerciseInstanceSerializer
-    permission_classes = [
-        permissions.IsAuthenticated
-        & (
-            IsOwnerOfWorkout
-            | (IsReadOnly & (IsCoachOfWorkoutAndVisibleToCoach | IsWorkoutPublic))
-        )
-    ]
+    # permission_classes = [
+    #    permissions.IsAuthenticated
+    #    & (
+    #       IsOwnerOfWorkout
+    # | (IsReadOnly & (IsCoachOfWorkoutAndVisibleToCoach | IsWorkoutPublic))
+    #    )
+   # ]
 
     def get(self, request, *args, **kwargs):
         return self.retrieve(request, *args, **kwargs)
@@ -303,7 +303,7 @@ class WorkoutFileList(
     queryset = WorkoutFile.objects.all()
     serializer_class = WorkoutFileSerializer
     permission_classes = [permissions.IsAuthenticated & IsOwnerOfWorkout]
-    parser_classes = [MultipartJsonParser, JSONParser]
+    parser_classes = [MultipartJsonParserWorkout, JSONParser]
 
     def get(self, request, *args, **kwargs):
         return self.list(request, *args, **kwargs)
diff --git a/frontend/Procfile b/frontend/Procfile
new file mode 100644
index 0000000000000000000000000000000000000000..c5d715421f1d1e0e364966d96ee675eacdc32d45
--- /dev/null
+++ b/frontend/Procfile
@@ -0,0 +1 @@
+web: cd frontend && cordova run browser --release --port=$PORT
diff --git a/frontend/www/scripts/scripts.js b/frontend/www/scripts/scripts.js
index 8c550009c43a70acc44ecd56c4434faa318c1c69..0a421de933dea21a0128fa7f5140a99e016c9d3a 100644
--- a/frontend/www/scripts/scripts.js
+++ b/frontend/www/scripts/scripts.js
@@ -117,6 +117,7 @@ function setReadOnly(readOnly, selector) {
 
     selector = `input[type="file"], select[name="${key}`;
     for (let input of form.querySelectorAll(selector)) {
+      console.log(input);
       if ((!readOnly && input.hasAttribute("disabled")))
       {
         input.disabled = false;
diff --git a/frontend/www/scripts/suggestedworkout.js b/frontend/www/scripts/suggestedworkout.js
new file mode 100644
index 0000000000000000000000000000000000000000..7d490eef3c2e02003643101f43a70fea2ea28885
--- /dev/null
+++ b/frontend/www/scripts/suggestedworkout.js
@@ -0,0 +1,443 @@
+let cancelWorkoutButton;
+let okWorkoutButton;
+let deleteWorkoutButton;
+let editWorkoutButton;
+let postCommentButton;
+let acceptWorkoutButton;
+let declineWorkoutButton;
+let athleteTitle;
+let coachTitle;
+
+async function retrieveWorkout(id, currentUser) {
+    let workoutData = null;
+    let response = await sendRequest("GET", `${HOST}/api/suggested-workout/${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);
+
+        if (currentUser.id == workoutData.coach) {
+            let suggestTypeSelect = await selectAthletesForSuggest(currentUser);
+            suggestTypeSelect.value = workoutData.athlete;
+
+        }
+
+
+        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 == "owner") {
+                input.value = workoutData.coach;
+            }
+
+            /*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 != "suggested_workout_files") {
+                input.value = newVal;
+            }
+        }
+
+        let input = form.querySelector("select:disabled");
+        // files
+        let filesDiv = document.querySelector("#uploaded-files");
+        console.log(workoutData.suggested_workout_files);
+        for (let file of workoutData.suggested_workout_files) {
+            console.log("Her skal jeg")
+            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.suggested_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.suggested_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.suggested_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.suggested_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");
+
+    let dateInput = document.querySelector("#inputDateTime");
+    dateInput.readOnly = !dateInput.readOnly;
+
+    document.querySelector("#inputOwner").readOnly = true;
+
+
+    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 deleteSuggestedWorkout(id) {
+    let response = await sendRequest("DELETE", `${HOST}/api/suggested-workout/${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 = generateSuggestWorkoutForm();
+
+    let response = await sendRequest("PUT", `${HOST}/api/suggested-workout/${id}/`, submitForm, "");
+    if (response.ok) {
+        location.reload();
+
+    } else {
+        let data = await response.json();
+        let alert = createAlert("Could not update workout!", data);
+        document.body.prepend(alert);
+    }
+}
+
+
+async function acceptWorkout(id) {
+    let submitForm = generateWorkoutForm();
+
+    let response = await sendRequest("POST", `${HOST}/api/workouts/`, submitForm, "");
+
+    if (response.ok) {
+        await deleteSuggestedWorkout(id);
+        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 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("owner", formData.get("coach_username"));
+    submitForm.delete("athlete");
+    submitForm.append("visibility", "PU");
+
+    // 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("suggested_workout_files", file);
+    }
+
+    submitForm.append("planned", true);
+    return submitForm;
+}
+
+function generateSuggestWorkoutForm() {
+    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("athlete", formData.get("athlete"));
+    submitForm.append("status", "p");
+
+
+    console.log(formData.get("athlete"));
+
+    // 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("suggested_exercise_instances", JSON.stringify(exerciseInstances));
+    // adding files
+    for (let file of formData.getAll("files")) {
+        if (file.name != "") {
+            submitForm.append("suggested_workout_files", file);
+        }
+    }
+
+
+    return submitForm;
+}
+
+async function createSuggestWorkout() {
+    let submitForm = generateSuggestWorkoutForm();
+
+
+    let response = await sendRequest("POST", `${HOST}/api/suggested-workouts/create/ `, 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 selectAthletesForSuggest(currentUser) {
+    console.log(currentUser)
+
+    let suggestTypes = [];
+    let suggestTemplate = document.querySelector("#template-suggest");
+    let divSuggestContainer = suggestTemplate.content.firstElementChild.cloneNode(true);
+    let suggestTypeSelect = divSuggestContainer.querySelector("select");
+    suggestTypeSelect.disabled = true;
+
+    for (let athleteUrl of currentUser.athletes) {
+        let response = await sendRequest("GET", athleteUrl);
+        let athlete = await response.json();
+
+        suggestTypes.push(athlete)
+    }
+
+
+    for (let i = 0; i < suggestTypes.length; i++) {
+        let option = document.createElement("option");
+        option.value = suggestTypes[i].id;
+        option.innerText = suggestTypes[i].username;
+        suggestTypeSelect.append(option);
+    }
+
+    let currentSuggestType = suggestTypes[0];
+    console.log(currentSuggestType);
+    suggestTypeSelect.value = currentSuggestType.id;
+
+    let divSuggestWorkout = document.querySelector("#div-suggest-workout");
+    divSuggestWorkout.appendChild(divSuggestContainer);
+    return suggestTypeSelect;
+}
+
+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();
+    }
+}
+
+
+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");
+    acceptWorkoutButton = document.querySelector("#btn-accept-workout");
+    declineWorkoutButton = document.querySelector("#btn-decline-workout");
+    coachTitle = document.querySelector("#coach-title");
+    athleteTitle = document.querySelector("#athlete-title");
+    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, currentUser);
+
+
+        if (workoutData["coach"] == currentUser.id) {
+            coachTitle.className = coachTitle.className.replace("hide", "");
+
+
+            editWorkoutButton.classList.remove("hide");
+            editWorkoutButton.addEventListener("click", handleEditWorkoutButtonClick);
+            deleteWorkoutButton.addEventListener("click", (async (id) => await deleteSuggestedWorkout(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", "");
+        }
+
+
+        if (workoutData["athlete"] == currentUser.id) {
+            athleteTitle.className = athleteTitle.className.replace("hide", "");
+            setReadOnly(false, "#form-workout");
+
+            document.querySelector("#inputOwner").readOnly = true;
+
+
+            declineWorkoutButton.classList.remove("hide");
+            acceptWorkoutButton.classList.remove("hide");
+
+            declineWorkoutButton.addEventListener("click", (async (id) => await deleteSuggestedWorkout(id)).bind(undefined, id));
+            acceptWorkoutButton.addEventListener("click", (async (id) => await acceptWorkout(id)).bind(undefined, id));
+            postCommentButton.addEventListener("click", (async (id) => await createComment(id)).bind(undefined, id));
+            divCommentRow.className = divCommentRow.className.replace(" hide", "");
+        }
+    } else {
+        await createBlankExercise();
+
+
+        if (currentUser.athletes.length > 0) {
+            await selectAthletesForSuggest(currentUser);
+        } else {
+            let alert = createAlert("Will no be able to suggest workout due to not having any athltes", undefined);
+            document.body.prepend(alert);
+        }
+
+        setReadOnly(false, "#form-workout");
+        let ownerInput = document.querySelector("#inputOwner");
+        ownerInput.value = currentUser.username;
+        ownerInput.readOnly = !ownerInput.readOnly;
+
+        let dateInput = document.querySelector("#inputDateTime");
+        dateInput.readOnly = !dateInput.readOnly;
+
+
+        coachTitle.className = coachTitle.className.replace("hide", "");
+
+        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 (currentUser) => await createSuggestWorkout(currentUser)).bind(undefined, currentUser));
+        cancelWorkoutButton.addEventListener("click", handleCancelDuringWorkoutCreate);
+        divCommentRow.className += " hide";
+    }
+
+});
\ No newline at end of file
diff --git a/frontend/www/scripts/workouts.js b/frontend/www/scripts/workouts.js
index d18ba4e2608917456bc088d8e46c578ab2fd792f..f01af08fa0a57055abc0434fd27be6e9cc49c74a 100644
--- a/frontend/www/scripts/workouts.js
+++ b/frontend/www/scripts/workouts.js
@@ -41,18 +41,64 @@ async function fetchWorkouts(ordering) {
   }
 }
 
+async function fetchSuggestedWorkouts() {
+    let responseSuggestAthlete = await sendRequest("GET", `${HOST}/api/suggested-workouts/athlete-list/`);
+    let responseSuggestCoach = await sendRequest("GET", `${HOST}/api/suggested-workouts/coach-list/`);
+
+    if (!responseSuggestCoach || !responseSuggestAthlete) {
+        throw new Error(`HTTP error! status: ${responseSuggestAthlete.status || responseSuggestCoach.status}`);
+    } else {
+        let suggestWorkoutAthlete = await responseSuggestAthlete.json();
+        let suggestWorkoutCoach = await responseSuggestCoach.json();
+
+        let suggestedWorkouts = suggestWorkoutAthlete.concat(suggestWorkoutCoach);
+        let container = document.getElementById('div-content');
+
+        suggestedWorkouts.forEach(workout => {
+            let templateWorkout = document.querySelector("#template-suggested-workout");
+            let cloneWorkout = templateWorkout.content.cloneNode(true);
+
+            let aWorkout = cloneWorkout.querySelector("a");
+            aWorkout.href = `suggestworkout.html?id=${workout.id}`;
+
+            let h5 = aWorkout.querySelector("h5");
+            h5.textContent = workout.name;
+
+            //let localDate = new Date(workout.date);
+
+            let table = aWorkout.querySelector("table");
+            let rows = table.querySelectorAll("tr");
+            rows[0].querySelectorAll("td")[1].textContent = workout.coach_username; //Owner
+            rows[1].querySelectorAll("td")[1].textContent = workout.suggested_exercise_instances.length; // Exercises
+            rows[2].querySelectorAll("td")[1].textContent = workout.status === "p" ? "Pending" : "Accept"; // Exercises
+
+
+            container.appendChild(aWorkout);
+        });
+
+        return [suggestWorkoutAthlete, suggestWorkoutCoach];
+    }
+
+}
+
+
 function createWorkout() {
   window.location.replace("workout.html");
 }
 
+function suggestWorkout() {
+    window.location.replace("suggestworkout.html");
+}
+
 function planWorkout() {
   window.location.replace("plannedWorkout.html");
 }
 
 window.addEventListener("DOMContentLoaded", async () => {
   let createButton = document.querySelector("#btn-create-workout");
-  createButton.addEventListener("click", createWorkout);
-
+  let suggestButton = document.querySelector("#btn-suggest-workout");
+    suggestButton.addEventListener("click", suggestWorkout);
+    createButton.addEventListener("click", createWorkout);
   let planButton = document.querySelector("#btn-plan-workout");
   planButton.addEventListener("click", planWorkout);
   let ordering = "-date";
@@ -61,11 +107,11 @@ window.addEventListener("DOMContentLoaded", async () => {
   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}`;
+        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 =
@@ -79,17 +125,20 @@ window.addEventListener("DOMContentLoaded", async () => {
     ordering += "__username";
   }
   let workouts = await fetchWorkouts(ordering);
+let [athleteWorkout, coachWorkout] = await fetchSuggestedWorkouts();
+
+    let allWorkouts = workouts.concat(athleteWorkout, coachWorkout);
 
-  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 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++) {
+      for (let j = 0; j < allWorkouts.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 workout = allWorkouts[j];
         let workoutAnchor = workoutAnchors[j];
 
         switch (event.currentTarget.id) {
@@ -136,8 +185,33 @@ window.addEventListener("DOMContentLoaded", async () => {
               workoutAnchor.classList.add("hide");
             }
             break;
-          default:
-            workoutAnchor.classList.remove("hide");
+          case "list-suggested-coach-workouts-list":
+                        if (currentUser.coach) {
+                            let coachID = currentUser?.coach?.split('/');
+                            if (coachID[coachID.length - 2] == workout.coach) {
+                                workoutAnchor.classList.remove('hide');
+
+                            }
+                        } else {
+                            workoutAnchor.classList.add('hide');
+                        }
+                        break;
+                    case "list-suggested-athlete-workouts-list":
+                        let athletes = currentUser?.athletes?.map((athlete) => {
+                            let athleteIdSplit = athlete.split('/');
+                            return Number(athleteIdSplit[athleteIdSplit.length - 2]);
+
+                        })
+                        if (athletes.includes(workout.athlete)) {
+                            console.log("hei")
+                            workoutAnchor.classList.remove('hide');
+                        } else {
+                            workoutAnchor.classList.add('hide');
+                        }
+                        break;
+
+                    default :
+                        workoutAnchor.classList.remove("hide");
             break;
         }
       }
diff --git a/frontend/www/suggestworkout.html b/frontend/www/suggestworkout.html
new file mode 100644
index 0000000000000000000000000000000000000000..6201d5fd7577dfadc577ffb77397481a9821c3dd
--- /dev/null
+++ b/frontend/www/suggestworkout.html
@@ -0,0 +1,191 @@
+<!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 hide" id="coach-title">Suggest Workout to Athlete</h3>
+          <h3 class="mt-3 hide" id="athlete-title">
+            Suggested Workout from Coach
+          </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="coach_username"
+            readonly
+          />
+        </div>
+        <div class="col-lg-6"></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" id="div-suggest-workout"></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-accept-workout"
+            value="  Accept  "
+          />
+
+          <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"
+          />
+          <input
+            type="button"
+            class="btn btn-danger float-end hide"
+            id="btn-decline-workout"
+            value="Decline"
+          />
+        </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>
+
+    <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>
+
+    <template id="template-suggest">
+      <div>
+        <label class="form-label suggest-athlete">Athlete </label>
+        <select class="form-select" name="athlete"></select>
+      </div>
+    </template>
+
+    <script src="scripts/defaults.js"></script>
+    <script src="scripts/scripts.js"></script>
+    <script src="scripts/suggestedworkout.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>
diff --git a/frontend/www/workouts.html b/frontend/www/workouts.html
index 07a5c42f91513e7822acc9a93d14f88bcceea913..195c27a60658fed654aa8588f132c9a42952f72c 100644
--- a/frontend/www/workouts.html
+++ b/frontend/www/workouts.html
@@ -1,65 +1,148 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta charset="UTF-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
     <title>Workouts</title>
-    <link rel="stylesheet" href="styles/style.css">
-    <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">
+    <link rel="stylesheet" href="styles/style.css"/>
+    <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>
+    <script
+            src="https://kit.fontawesome.com/0ce6c392ca.js"
+            crossorigin="anonymous"
+    ></script>
     <script src="scripts/navbar.js" type="text/javascript" defer></script>
 </head>
 <body>
-    <navbar-el></navbar-el>
+<navbar-el></navbar-el>
 
-    <div class="container">
-        <div class="row">
-            <div class="col-lg text-center">
-                <h3 class="mt-5">View Workouts</h3>
-                <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-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>
-                <div class="mt-1">Sort by: <a href="?ordering=date">Date</a> <a href="?ordering=owner">Owner</a> <a href="?ordering=name">Name</a>
-                    <br>Currently sorting by: <span id="current-sort"></span>
-                </div>
-                <div class="list-group mt-1" id="div-content"></div>
-              </div>
+<div class="container">
+    <div class="row">
+        <div class="col-lg text-center">
+            <h3 class="mt-5">View Workouts</h3>
+            <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">
+            <input
+                    type="button"
+                    class="btn btn-success"
+                    id="btn-suggest-workout"
+                    value="Suggest workout for athlete"
+            />
         </div>
-
     </div>
-
-    <template id="template-workout">
-        <a class="list-group-item list-group-item-action flex-column align-items-start my-1 workout">
-            <div class="d-flex w-100 justify-content-between align-items-center">
-                <h5 class="mb-1"></h5>
+    <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-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>
+                <a
+                        class="list-group-item list-group-item-action"
+                        id="list-suggested-coach-workouts-list"
+                        data-bs-toggle="list"
+                        href="#list-suggested-coach-workouts"
+                        role="tab"
+                        aria-controls="public"
+                >Suggested Workouts From Coach</a
+                >
+                <a
+                        class="list-group-item list-group-item-action"
+                        id="list-suggested-athlete-workouts-list"
+                        data-bs-toggle="list"
+                        href="#list-suggested-athlete-workouts"
+                        role="tab"
+                        aria-controls="public"
+                >Suggested Workouts To Athletes</a
+                >
             </div>
-            <div class="d-flex">
-                <table class="mb-1 text-start">
-                    <tr><td>Date:</td><td></td></tr>
-                    <tr><td>Time:</td><td></td></tr>
-                    <tr><td>Owner:</td><td></td></tr>
-                    <tr><td>Exercises:</td><td></td></tr>
-                </table>       
+            <div class="mt-1">Sort by: <a href="?ordering=date">Date</a> <a href="?ordering=owner">Owner</a> <a
+                    href="?ordering=name">Name</a>
+                <br>Currently sorting by: <span id="current-sort"></span>
             </div>
-        </a>
+            <div class="list-group mt-1" id="div-content"></div>
+        </div>
+    </div>
+
+</div>
+
+<template id="template-workout">
+      <a
+        class="list-group-item list-group-item-action flex-column align-items-start my-1 workout"
+      >
+        <div class="d-flex w-100 justify-content-between align-items-center">
+          <h5 class="mb-1"></h5>
+        </div>
+        <div class="d-flex">
+          <table class="mb-1 text-start">
+            <tr>
+              <td>Date:</td>
+              <td></td>
+            </tr>
+            <tr>
+              <td>Time:</td>
+              <td></td>
+            </tr>
+            <tr>
+              <td>Owner:</td>
+              <td></td>
+            </tr>
+            <tr>
+              <td>Exercises:</td>
+              <td></td>
+            </tr>
+          </table>
+        </div>
+      </a>
+</template>
+
+    <template id="template-suggested-workout">
+      <a
+        class="list-group-item list-group-item-action flex-column align-items-start my-1 workout"
+      >
+        <div class="d-flex w-100 justify-content-between align-items-center">
+          <h5 class="mb-1"></h5>
+        </div>
+        <div class="d-flex">
+          <table class="mb-1 text-start">
+            <tr>
+              <td>Owner:</td>
+              <td></td>
+            </tr>
+            <tr>
+              <td>Exercises:</td>
+              <td></td>
+            </tr>
+            <tr>
+              <td>Status:</td>
+              <td></td>
+            </tr>
+          </table>
+        </div>
+      </a>
     </template>
 
-    <script src="scripts/defaults.js"></script>
-    <script src="scripts/scripts.js"></script>
-    <script src="scripts/workouts.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
+<script src="scripts/defaults.js"></script>
+<script src="scripts/scripts.js"></script>
+<script src="scripts/workouts.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>
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..3f61d7ab32f94f72962298f2f8dfb40446719625
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+  "name": "secfit",
+  "description": "Secure Fitness",
+  "version": "0.0.1",
+  "engines": {
+    "node": "12.x"
+  },
+  "dependencies": {
+      "cordova": "10.0.0",
+      "cordova-browser": "6.0.0",
+      "cordova-plugin-whitelist": "^1.3.4"
+  }
+}
diff --git a/release.sh b/release.sh
deleted file mode 100644
index 19ebb5a890dd92982ee6f3826240dcb7e380630c..0000000000000000000000000000000000000000
--- a/release.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-
-IMAGE_ID=$(docker inspect ${HEROKU_REGISTRY_IMAGE} --format={{.Id}})
-PAYLOAD='{"updates": [{"type": "web", "docker_image": "'"$IMAGE_ID"'"}]}'
-
-curl -n -X PATCH https://api.heroku.com/apps/$HEROKU_APP_NAME/formation \
-  -d "${PAYLOAD}" \
-  -H "Content-Type: application/json" \
-  -H "Accept: application/vnd.heroku+json; version=3.docker-releases" \
-  -H "Authorization: Bearer ${HEROKU_AUTH_TOKEN}"
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..149fa0ca2a0c640f8fca7579069137b598b2f329
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,32 @@
+asgiref==3.2.10
+astroid==2.4.2
+certifi==2020.6.20
+chardet==3.0.4
+colorama==0.4.3
+dj-database-url==0.5.0
+Django==3.1
+django-cleanup==5.0.0
+django-cors-headers==3.4.0
+djangorestframework==3.11.1
+djangorestframework-simplejwt==4.6.0
+gunicorn==20.0.4
+httpie==2.2.0
+idna==2.10
+isort==4.3.21
+lazy-object-proxy==1.4.3
+mccabe==0.6.1
+psycopg2-binary
+Pygments==2.6.1
+PyJWT==1.7.1
+pylint==2.5.3
+pylint-django==2.3.0
+pylint-plugin-utils==0.6
+pytz==2020.1
+requests==2.24.0
+rope==0.17.0
+six==1.15.0
+sqlparse==0.3.1
+toml==0.10.1
+urllib3==1.25.10
+whitenoise==5.2.0
+wrapt==1.12.1