diff --git a/backend/secfit/groups/admin.py b/backend/secfit/groups/admin.py
index bab8ce01038620fa2be80370e192f0288b212d28..4a5b0e737fcd0959191df2fc95335440d88e8e27 100644
--- a/backend/secfit/groups/admin.py
+++ b/backend/secfit/groups/admin.py
@@ -1,7 +1,10 @@
 from django.contrib import admin
 
 # Register your models here.
-from .models import Group, Membership
+from .models import Group, Membership, Content, Comment, Like
 
 admin.site.register(Group)
 admin.site.register(Membership)
+admin.site.register(Content)
+admin.site.register(Comment)
+admin.site.register(Like)
diff --git a/backend/secfit/groups/migrations/0002_auto_20220314_1123.py b/backend/secfit/groups/migrations/0002_auto_20220314_1123.py
new file mode 100644
index 0000000000000000000000000000000000000000..b03eedd76a1b34ffe23f43bc124d207f4438bbb1
--- /dev/null
+++ b/backend/secfit/groups/migrations/0002_auto_20220314_1123.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1 on 2022-03-14 10:23
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('groups', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='membership',
+            name='group',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='memberOf', to='groups.group'),
+        ),
+    ]
diff --git a/backend/secfit/groups/migrations/0003_content.py b/backend/secfit/groups/migrations/0003_content.py
new file mode 100644
index 0000000000000000000000000000000000000000..76bf596aabf1bf41f1a4bdcc8aabb768ab6d2498
--- /dev/null
+++ b/backend/secfit/groups/migrations/0003_content.py
@@ -0,0 +1,27 @@
+# Generated by Django 3.1 on 2022-03-14 10:48
+
+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),
+        ('groups', '0002_auto_20220314_1123'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Content',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('title', models.TextField(max_length=100)),
+                ('description', models.TextField()),
+                ('image', models.ImageField(blank=True, upload_to='media')),
+                ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creator', to=settings.AUTH_USER_MODEL)),
+                ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ownedByGroup', to='groups.group')),
+            ],
+        ),
+    ]
diff --git a/backend/secfit/groups/migrations/0004_comment.py b/backend/secfit/groups/migrations/0004_comment.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e9d2ee50f580934501750d410100d321d063182
--- /dev/null
+++ b/backend/secfit/groups/migrations/0004_comment.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1 on 2022-03-14 18:17
+
+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),
+        ('groups', '0003_content'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Comment',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('message', models.TextField()),
+                ('content', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='relatedContent', to='groups.content')),
+                ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='commentOwner', to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]
diff --git a/backend/secfit/groups/migrations/0005_like.py b/backend/secfit/groups/migrations/0005_like.py
new file mode 100644
index 0000000000000000000000000000000000000000..0f9b6869181a63f3c2dd1472b7a4011ba29bbcf5
--- /dev/null
+++ b/backend/secfit/groups/migrations/0005_like.py
@@ -0,0 +1,27 @@
+# Generated by Django 3.1 on 2022-03-14 20:12
+
+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),
+        ('groups', '0004_comment'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Like',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('content', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='likedContent', to='groups.content')),
+                ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='likeOwner', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'unique_together': {('owner', 'content')},
+            },
+        ),
+    ]
diff --git a/backend/secfit/groups/models.py b/backend/secfit/groups/models.py
index f07b6141a38ee0a99e5800fb17c9a22d94ee021d..2488cf8783f4d4e9607a5f4d241e226fd1c8eb77 100644
--- a/backend/secfit/groups/models.py
+++ b/backend/secfit/groups/models.py
@@ -41,3 +41,53 @@ class Membership(models.Model):
     class Meta:
         # restriction so that no user is a member two times in a group.
         unique_together = ('member', 'group')
+
+
+class Content(models.Model):
+    creator = models.ForeignKey(
+        get_user_model(), on_delete=models.CASCADE, related_name="creator"
+    )
+    group = models.ForeignKey(
+        Group, on_delete=models.CASCADE, related_name="ownedByGroup"
+    )
+    title = models.TextField(max_length=100)
+    description = models.TextField()
+    image = models.ImageField(upload_to='media', blank=True)
+
+
+class Comment(models.Model):
+    """Django model for a comment left on a workout.
+
+    Attributes:
+        owner:       Who posted the comment
+        workout:     The workout this comment was left on.
+        content:     The content of the comment.
+        timestamp:   When the comment was created.
+    """
+    owner = models.ForeignKey(
+        get_user_model(), on_delete=models.CASCADE, related_name="commentOwner"
+    )
+    content = models.ForeignKey(
+        Content, on_delete=models.CASCADE, related_name="relatedContent"
+    )
+    message = models.TextField()
+
+
+class Like(models.Model):
+    """Django model for a comment left on a workout.
+
+    Attributes:
+        owner:       Who posted the comment
+        workout:     The workout this comment was left on.
+        content:     The content of the comment.
+        timestamp:   When the comment was created.
+    """
+    owner = models.ForeignKey(
+        get_user_model(), on_delete=models.CASCADE, related_name="likeOwner"
+    )
+    content = models.ForeignKey(
+        Content, on_delete=models.CASCADE, related_name="likedContent"
+    )
+
+    class Meta:
+        unique_together = ('owner', 'content')
diff --git a/backend/secfit/groups/serializers.py b/backend/secfit/groups/serializers.py
index aa602f2e82a91bc0087988e52fc50d8c19e6bfcc..d4be6d03029eb662c0e5214b15edcfda4e6f3a5e 100644
--- a/backend/secfit/groups/serializers.py
+++ b/backend/secfit/groups/serializers.py
@@ -1,6 +1,6 @@
 from rest_framework import serializers
 from rest_framework.serializers import HyperlinkedRelatedField
-from .models import Group, Membership
+from .models import Group, Membership, Content, Comment, Like
 
 
 class GroupSerializer(serializers.HyperlinkedModelSerializer):
@@ -26,3 +26,41 @@ class MembershipSerializer(serializers.ModelSerializer):
     class Meta:
         model = Membership
         fields = ["id", "member", "group"]
+
+
+class ContentSerializer(serializers.ModelSerializer):
+    """Serializer for an Exercise. Hyperlinks are used for relationships by default.
+
+    Serialized fields: url, id, name, description, duration, calories, muscle group, unit, instances
+
+    Attributes:
+        instances:  Associated exercise instances with this Exercise type. Hyperlinks.
+    """
+
+    class Meta:
+        model = Content
+        fields = ["id", "group", "title", "description", "image"]
+        creator = serializers.ReadOnlyField(source='creator.id')
+        image = serializers.Field(required=False)
+
+
+class CommentSerializer(serializers.ModelSerializer):
+    """Serializer for a membership instance
+
+    Serialized fields: id, member, group
+    """
+    class Meta:
+        model = Comment
+        fields = ["id", "content", "message"]
+        owner = serializers.ReadOnlyField(source="owner.username")
+
+
+class LikeSerializer(serializers.ModelSerializer):
+    """Serializer for a membership instance
+
+    Serialized fields: id, member, group
+    """
+    class Meta:
+        model = Like
+        fields = ["id", "content"]
+        owner = serializers.ReadOnlyField(source="owner.username")
diff --git a/backend/secfit/groups/urls.py b/backend/secfit/groups/urls.py
index 32d8282ff3fc2c084290855c61f61facc1bd1eae..a1ba51a81e0c22a218f03c0f315e5f199ece5895 100644
--- a/backend/secfit/groups/urls.py
+++ b/backend/secfit/groups/urls.py
@@ -1,9 +1,14 @@
 from django.urls import path
-from .views import GroupView, MembershipView, getGroup
+from .views import GroupView, MembershipView, getGroup, ContentList, PostContent, PostComment, CommentList, PostLike
 
 
 urlpatterns = [
     path("api/groups/", GroupView.as_view(), name="group-view"),
     path("api/members/", MembershipView.as_view(), name="membership-view"),
     path("api/groups/<int:pk>/", getGroup.as_view(), name="updateGroup-view"),
+    path("api/content/", PostContent.as_view(), name="postContent-view"),
+    path("api/content/<int:pk>/", ContentList.as_view(), name="contentList-view"),
+    path("api/comment/", PostComment.as_view(), name="postComment-view"),
+    path("api/comment/<int:pk>/", CommentList.as_view(), name="CommentList-view"),
+    path("api/like/", PostLike.as_view(), name="postLike-view"),
 ]
diff --git a/backend/secfit/groups/views.py b/backend/secfit/groups/views.py
index aa110a772833a7aa35219d1f30cf7203ac94abcb..5081bfa06e96b5a45fda519184cf4c1308c8acc3 100644
--- a/backend/secfit/groups/views.py
+++ b/backend/secfit/groups/views.py
@@ -1,8 +1,8 @@
 from django.shortcuts import render
 from rest_framework import generics, mixins
-from .models import Group, Membership
+from .models import Group, Membership, Content, Comment, Like
 from rest_framework import permissions
-from .serializers import GroupSerializer, MembershipSerializer
+from .serializers import GroupSerializer, MembershipSerializer, ContentSerializer, CommentSerializer, LikeSerializer
 from rest_framework.filters import OrderingFilter
 
 
@@ -69,3 +69,104 @@ class MembershipView(
 
     def post(self, request, *args, **kwargs):
         return self.create(request, *args, **kwargs)
+
+
+class ContentList(
+    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+):
+    """Class defining the web response for the creation of content, or
+    a list of content.
+
+    HTTP methods: GET, POST
+    """
+
+    queryset = Content.objects.all()
+    serializer_class = ContentSerializer
+
+    def get(self, request, *args, **kwargs):
+        return self.list(request, *args, **kwargs)
+
+    def get_queryset(self):
+        qs = Content.objects.all()
+        pk = self.kwargs['pk']
+        qs = Content.objects.filter(group=pk)
+        return qs
+
+
+class PostContent(
+    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+):
+    """Class defining the web response for the creation of content, or
+    a list of content.
+
+    HTTP methods: GET, POST
+    """
+
+    queryset = Content.objects.all()
+    serializer_class = ContentSerializer
+
+    def post(self, request, *args, **kwargs):
+        return self.create(request, *args, **kwargs)
+
+    def perform_create(self, serializer):
+        serializer.save(creator=self.request.user)
+
+
+class PostComment(
+    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+):
+    """Class defining the web response for the creation of content, or
+    a list of content.
+
+    HTTP methods: GET, POST
+    """
+
+    queryset = Comment.objects.all()
+    serializer_class = CommentSerializer
+
+    def post(self, request, *args, **kwargs):
+        return self.create(request, *args, **kwargs)
+
+    def perform_create(self, serializer):
+        serializer.save(owner=self.request.user)
+
+
+class CommentList(
+    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+):
+    """Class defining the web response for the creation of content, or
+    a list of content.
+
+    HTTP methods: GET, POST
+    """
+
+    queryset = Comment.objects.all()
+    serializer_class = CommentSerializer
+
+    def get(self, request, *args, **kwargs):
+        return self.list(request, *args, **kwargs)
+
+    def get_queryset(self):
+        qs = Comment.objects.all()
+        pk = self.kwargs['pk']
+        qs = Comment.objects.filter(content=pk)
+        return qs
+
+
+class PostLike(
+    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+):
+    """Class defining the web response for the creation of content, or
+    a list of content.
+
+    HTTP methods: GET, POST
+    """
+
+    queryset = Like.objects.all()
+    serializer_class = LikeSerializer
+
+    def post(self, request, *args, **kwargs):
+        return self.create(request, *args, **kwargs)
+
+    def perform_create(self, serializer):
+        serializer.save(owner=self.request.user)
diff --git a/backend/secfit/requirements.txt b/backend/secfit/requirements.txt
index 9feb375bde1e8fb7befe6c102dd29beeee7c6940..88fa935213723454c324824ac92816923797c869 100644
Binary files a/backend/secfit/requirements.txt and b/backend/secfit/requirements.txt differ
diff --git a/backend/secfit/users/migrations/0010_auto_20220314_1123.py b/backend/secfit/users/migrations/0010_auto_20220314_1123.py
new file mode 100644
index 0000000000000000000000000000000000000000..0ee7eccf975fd6d2278d975380c18886be9c755a
--- /dev/null
+++ b/backend/secfit/users/migrations/0010_auto_20220314_1123.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.1 on 2022-03-14 10:23
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('users', '0009_auto_20210204_1055'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='user',
+            name='age',
+            field=models.PositiveIntegerField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='bio',
+            field=models.TextField(blank=True, max_length=200, null=True),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='expirience',
+            field=models.PositiveIntegerField(blank=True, null=True),
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='favorite_dicipline',
+            field=models.TextField(blank=True, max_length=50, null=True),
+        ),
+    ]
diff --git a/frontend/www/addcontent.html b/frontend/www/addcontent.html
new file mode 100644
index 0000000000000000000000000000000000000000..bf6fa17430ae909902ef5ecfc197f14bfd191d50
--- /dev/null
+++ b/frontend/www/addcontent.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>addcontent</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">Share your workout with the group!</h3>
+                </div>
+            </div>
+        <form class="row g-3" id="form-content">
+            <div class="col-lg-6 ">
+                <label for="inputTitle" class="form-label">Title</label>
+                <input type="text" class="form-control" id="inputTitle" name="title">
+            </div>
+            <div class="col-lg-6"></div>
+            <div class="col-lg-6">
+                <label for="inputDescription" class="form-label">Description</label>
+                <textarea class="form-control" id="inputDescription" name="description"></textarea>
+            </div>
+            <div class="col-lg-6">
+                <div class="col-lg-6">
+                    <label for="files">Select a file:</label>
+                    <input type="file" class="form-control" id="customFile" name="files" multiple>
+                </div>
+            </div>
+            <div class="col-lg-6"></div>
+            <div class="col-lg-6">
+                <input type="button" class="btn btn-primary" id="btn-ok-addcontent" value="  OK  ">
+                <input type="button" class="btn btn-secondary" id="btn-cancel-addcontent" value="Cancel">
+            </div>
+            <div class="col-lg-6">
+
+            </div>
+        </form>
+        </div>
+        <script src="scripts/defaults.js"></script>
+        <script src="scripts/scripts.js"></script>
+        <script src="scripts/addcontent.js"></script>
+        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/frontend/www/contentcomments.html b/frontend/www/contentcomments.html
new file mode 100644
index 0000000000000000000000000000000000000000..6871cbe0dcdb443a113c88c688379324f87d66c2
--- /dev/null
+++ b/frontend/www/contentcomments.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Comments</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 text-center">
+                <h3 class="mt-5" id="groupName">View comments!</h3>
+                <p>Here you can post comments and like.</p>
+        </div>
+        <div class="col-lg-6">
+            <input type="button" class="btn btn-success" id="btn-like" value="Like">
+        </div>
+        <div class="col-lg-6">
+
+        </div>
+        <div class="row">
+            <div class="col-lg text-center">
+                <div class="list-group mt-1" id="div-comment"></div>
+            </div>
+        </div>
+        
+    </div>
+
+    <template id="template-comment">
+        <a class="list-group-item list-group-item-action flex-column align-items-start my-1 exercise" href="">
+            <div class="d-flex w-100 justify-content-between align-items-center">
+                <h5 class="mb-1"></h5>
+            </div>
+            <div class="d-flex">
+                <p class="mb-1">
+                </p>
+            </div>
+        </a>
+    </template>
+
+    <div class="container">
+        <form class="row g-3" id="form-comment">
+            <div class="col-lg-6">
+                <label for="inputComment" class="form-label">Comment</label>
+                <textarea class="form-control" id="inputComment" name="comment"></textarea>
+            </div>
+            <div class="col-lg-6"></div>
+            <div class="col-lg-6">
+                <input type="button" class="btn btn-primary" id="btn-add-comment" value="Post comment">
+            </div>
+            <div class="col-lg-6">
+
+            </div>
+        </form>
+    </div>
+
+    <script src="scripts/defaults.js"></script>
+    <script src="scripts/scripts.js"></script>
+    <script src="scripts/contentcomments.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/frontend/www/groupContent.html b/frontend/www/groupContent.html
new file mode 100644
index 0000000000000000000000000000000000000000..5ce93401ff7669eecd37afe1876992b9a1bcde06
--- /dev/null
+++ b/frontend/www/groupContent.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Groups</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 text-center">
+                <h3 class="mt-5" id="groupName">View content!</h3>
+                <p>Here you can view, create, and edit content.</p>
+                <input type="button" class="btn btn-primary" id="btn-add-content" value="new Post">
+                <input type="button" class="btn btn-link" id="btn-edit-group" value="Edit group details">
+        </div>
+        <div class="row">
+            <div class="col-lg text-center">
+                <div class="list-group mt-1" id="div-content"></div>
+            </div>
+        </div>
+    </div>
+
+    <template id="template-content">
+        <a class="list-group-item list-group-item-action flex-column align-items-start my-1 exercise" href="">
+            <div class="d-flex w-100 justify-content-between align-items-center">
+                <h5 class="mb-1"></h5>
+            </div>
+            <div class="d-flex">
+                <p class="mb-1">
+                </p>
+            </div>
+        </a>
+    </template>
+
+    <script src="scripts/defaults.js"></script>
+    <script src="scripts/scripts.js"></script>
+    <script src="scripts/groupContent.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/frontend/www/scripts/addcontent.js b/frontend/www/scripts/addcontent.js
new file mode 100644
index 0000000000000000000000000000000000000000..e1e79ab69b37b6f3283df1a99a121b97de14a6cb
--- /dev/null
+++ b/frontend/www/scripts/addcontent.js
@@ -0,0 +1,48 @@
+let cancelButton;
+let okButton;
+
+function handleCancelButtonDuringCreate() {
+    window.location.replace("groups.html");
+}
+
+/**
+ * This api request is fired when the user clicks the button to add content to a group
+ * It sends a POST request with the form data, and relocates to groupsContent page or
+ * sends an error message in respons. 
+ */
+async function addContent() {
+    let form = document.querySelector("#form-content");
+    let formData = new FormData(form);
+    const urlParams = new URLSearchParams(window.location.search);
+    if (urlParams.has('id')) {
+        const groupId = urlParams.get('id');
+        const input = document.querySelector('input[type="file"]');
+        let body = {"group": groupId,
+                    "title": formData.get("title"),
+                    "description": formData.get("description"),
+                    };
+
+        let response = await sendRequest("POST", `${HOST}/api/content/`, body);
+
+        if (response.ok) {
+            window.location.replace(`groupContent.html?id=${groupId}`);
+        } else {
+            let data = await response.json();
+            let alert = createAlert("Could not create new group!", data);
+            document.body.prepend(alert);
+        }
+    }
+}
+
+/**
+ * When a user enters the group.html this decides whether it
+ * is entered in view/edit mode or in create mode. If the html contains
+ * a url parameter with an id it is entered in view/edit mode.
+ */
+
+window.addEventListener("DOMContentLoaded", async () => {
+    cancelButton = document.querySelector("#btn-cancel-addcontent");
+    okButton = document.querySelector("#btn-ok-addcontent");
+    okButton.addEventListener("click", async () => await addContent());
+    cancelButton.addEventListener("click", handleCancelButtonDuringCreate);
+});
\ No newline at end of file
diff --git a/frontend/www/scripts/contentcomments.js b/frontend/www/scripts/contentcomments.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbb45b83475b0b04e43145fc08683bbdd9968f67
--- /dev/null
+++ b/frontend/www/scripts/contentcomments.js
@@ -0,0 +1,97 @@
+/**
+ * Sendes a get request to the API to retrieve a list of all the groups
+ * If the response is ok then each group instance is placed in html code
+ * to make a list of all the groups.
+ */
+ async function fetchComments(id) {
+    let response = await sendRequest("GET", `${HOST}/api/comment/${id}`);
+
+    if (response.ok) {
+        let data = await response.json();
+
+        let comments = data.results;
+        let container = document.getElementById('div-comment');
+        let commentTemplate = document.querySelector("#template-comment");
+        comments.forEach(comment => {
+            const commentAnchor = commentTemplate.content.firstElementChild.cloneNode(true);
+            //contentAnchor.href = `group.html?id=${content.id}`;
+
+            const h5 = commentAnchor.querySelector("h5");
+            h5.textContent = comment.owner;
+
+            const p = commentAnchor.querySelector("p");
+            p.textContent = comment.message;   
+
+            container.appendChild(commentAnchor);
+        });
+    }
+
+    return response;
+}
+
+async function addComment() {
+    let form = document.querySelector("#form-comment");
+    let formData = new FormData(form);
+    const urlParams = new URLSearchParams(window.location.search);
+    if (urlParams.has('id')) {
+        const contentId = urlParams.get('id');
+        let body = {"content": contentId,
+                    "message": formData.get("comment"),
+                    };
+
+        let response = await sendRequest("POST", `${HOST}/api/comment/`, body);
+
+        if (response.ok) {
+            window.location.replace(`contentcomments.html?id=${contentId}`);
+        } else {
+            let data = await response.json();
+            let alert = createAlert("Could not create new group!", data);
+            document.body.prepend(alert);
+        }
+    }
+
+}
+
+async function like() {
+    const urlParams = new URLSearchParams(window.location.search);
+    if (urlParams.has('id')) {
+        const contentId = urlParams.get('id');
+        let body = {"content": contentId};
+
+        let response = await sendRequest("POST", `${HOST}/api/like/`, body);
+
+        if (response.ok) {
+            window.location.replace(`contentcomments.html?id=${contentId}`);
+        } else {
+            let data = await response.json();
+            let alert = createAlert("Could not create new group!", data);
+            document.body.prepend(alert);
+        }
+    }
+
+}
+
+/**
+ * When a user enters groups.html then the groups are fetched.
+ */
+window.addEventListener("DOMContentLoaded", async () => {
+    let addButton = document.querySelector("#btn-add-comment");
+    addButton.addEventListener("click", async () => await addComment());
+    let likeButton = document.querySelector("#btn-like");
+    likeButton.addEventListener("click", async () => await like());
+    
+
+    const urlParams = new URLSearchParams(window.location.search);
+
+    if (urlParams.has('id')) {
+        const contentId = urlParams.get('id');
+        await fetchComments(contentId);
+
+        if (!response.ok) {
+            let data = await response.json();
+            let alert = createAlert("Could not retrieve groups!", data);
+            document.body.prepend(alert);
+        }
+    }    
+
+});
diff --git a/frontend/www/scripts/groupContent.js b/frontend/www/scripts/groupContent.js
new file mode 100644
index 0000000000000000000000000000000000000000..08e1c04a6e6c8cc9add3a1be59ffc56b478a6b72
--- /dev/null
+++ b/frontend/www/scripts/groupContent.js
@@ -0,0 +1,74 @@
+/**
+ * Sendes a get request to the API to retrieve a list of all the groups
+ * If the response is ok then each group instance is placed in html code
+ * to make a list of all the groups.
+ */
+ async function fetchContent(id) {
+    let response = await sendRequest("GET", `${HOST}/api/content/${id}`);
+
+    if (response.ok) {
+        let data = await response.json();
+
+        let contents = data.results;
+        let container = document.getElementById('div-content');
+        let contentTemplate = document.querySelector("#template-content");
+        contents.forEach(content => {
+            const contentAnchor = contentTemplate.content.firstElementChild.cloneNode(true);
+            contentAnchor.href = `contentcomments.html?id=${content.id}`;
+
+            const h5 = contentAnchor.querySelector("h5");
+            h5.textContent = content.title;
+
+            const p = contentAnchor.querySelector("p");
+            p.textContent = content.description;   
+
+            container.appendChild(contentAnchor);
+        });
+    }
+
+    return response;
+}
+
+function addContent() {
+    const urlParams = new URLSearchParams(window.location.search);
+    if (urlParams.has('id')) {
+        const groupId = urlParams.get('id');
+        window.location.replace(`addcontent.html?id=${groupId}`);
+    }
+
+}
+
+function editGroup() {
+    const urlParams = new URLSearchParams(window.location.search);
+    if (urlParams.has('id')) {
+        const groupId = urlParams.get('id');
+        window.location.replace(`group.html?id=${groupId}`);
+    }
+}
+
+/**
+ * When a user enters groups.html then the groups are fetched.
+ */
+window.addEventListener("DOMContentLoaded", async () => {
+    let addButton = document.querySelector("#btn-add-content");
+    addButton.addEventListener("click", addContent);
+    let editButton = document.querySelector("#btn-edit-group");
+    editButton.addEventListener("click", editGroup);
+    
+
+    const urlParams = new URLSearchParams(window.location.search);
+
+    if (urlParams.has('id')) {
+        const groupId = urlParams.get('id');
+        await fetchContent(groupId);
+
+        if (!response.ok) {
+            let data = await response.json();
+            let alert = createAlert("Could not retrieve groups!", data);
+            document.body.prepend(alert);
+        }
+    } 
+
+    
+
+});
diff --git a/frontend/www/scripts/groups.js b/frontend/www/scripts/groups.js
index e690c1d0770b235cacd53dffdf333c1bf67a87c9..d3daab52b4676a044a9823840ec5a7c6f7ee3650 100644
--- a/frontend/www/scripts/groups.js
+++ b/frontend/www/scripts/groups.js
@@ -14,7 +14,7 @@ async function fetchGroups(request) {
         let groupTemplate = document.querySelector("#template-group");
         groups.forEach(group => {
             const groupAnchor = groupTemplate.content.firstElementChild.cloneNode(true);
-            groupAnchor.href = `group.html?id=${group.id}`;
+            groupAnchor.href = `groupContent.html?id=${group.id}`;
 
             const h5 = groupAnchor.querySelector("h5");
             h5.textContent = group.name;