diff --git a/core/permissions.py b/core/permissions.py
index bb478558c4f08d7f219bd683d7ab42eadea1d00b..211ed2fb337a792156257d30b2fc808ace7a9f7c 100644
--- a/core/permissions.py
+++ b/core/permissions.py
@@ -22,7 +22,7 @@ class IsUserGenericPermission(permissions.BasePermission):
         )
 
         user = request.user
-        is_authorized = user.is_authenticated() and any(isinstance(
+        is_authorized = user.is_authenticated and any(isinstance(
             user.get_associated_user(), models) for models in self.models)
 
         if not is_authorized:
diff --git a/core/serializers.py b/core/serializers.py
index 44b91717174fe9af54cddc52ce0e668564f31b28..74db00cfbd19e3cbe4cc08981ee15ad471859d05 100644
--- a/core/serializers.py
+++ b/core/serializers.py
@@ -4,7 +4,7 @@ from drf_dynamic_fields import DynamicFieldsMixin
 from rest_framework import serializers
 
 from core.models import (ExamType, Feedback, Student, Submission,
-                         SubmissionType, Tutor)
+                         SubmissionType, Test, Tutor)
 from util.factories import GradyUserFactory
 
 log = logging.getLogger(__name__)
@@ -13,7 +13,19 @@ user_factory = GradyUserFactory()
 
 class DynamicFieldsModelSerializer(DynamicFieldsMixin,
                                    serializers.ModelSerializer):
-    pass
+    def __init__(self, *args, **kwargs):
+        # Don't pass the 'fields' arg up to the superclass
+        fields = kwargs.pop('fields', None)
+
+        # Instantiate the superclass normally
+        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
+
+        if fields is not None:
+            # Drop any fields that are not specified in the `fields` argument.
+            allowed = set(fields)
+            existing = set(self.fields.keys())
+            for field_name in existing - allowed:
+                self.fields.pop(field_name)
 
 
 class ExamSerializer(DynamicFieldsModelSerializer):
@@ -31,35 +43,50 @@ class FeedbackSerializer(DynamicFieldsModelSerializer):
         fields = ('text', 'score')
 
 
+class TestSerializer(DynamicFieldsModelSerializer):
+
+    class Meta:
+        model = Test
+        fields = ('name', 'label', 'annotation')
+
+
 class SubmissionTypeSerializer(DynamicFieldsModelSerializer):
+    fullScore = serializers.IntegerField(source='full_score')
 
     class Meta:
         model = SubmissionType
-        fields = ('name', 'full_score', 'description', 'solution')
+        fields = ('id', 'name', 'fullScore', 'description', 'solution')
 
 
 class SubmissionSerializer(DynamicFieldsModelSerializer):
-    feedback = serializers.ReadOnlyField(source='feedback.text')
-    score = serializers.ReadOnlyField(source='feedback.score')
-    type_id = serializers.ReadOnlyField(source='type.id')
-    type_name = serializers.ReadOnlyField(source='type.name')
-    full_score = serializers.ReadOnlyField(source='type.full_score')
+    type = SubmissionTypeSerializer()
+    feedback = FeedbackSerializer()
+    tests = TestSerializer(many=True)
 
     class Meta:
         model = Submission
-        fields = ('type_id', 'type_name', 'text',
-                  'feedback', 'score', 'full_score')
+        fields = ('type', 'text', 'feedback', 'tests')
+
+
+class SubmissionListSerializer(DynamicFieldsModelSerializer):
+    type = SubmissionTypeSerializer(fields=('id', 'name', 'fullScore'))
+    # TODO change this according to new feedback model
+    feedback = FeedbackSerializer(fields=('score',))
+
+    class Meta:
+        model = Submission
+        fields = ('type', 'feedback')
 
 
 class StudentSerializer(DynamicFieldsModelSerializer):
     name = serializers.ReadOnlyField(source='user.fullname')
-    user = serializers.ReadOnlyField(source='user.username')
+    matrikel_no = serializers.ReadOnlyField(source='user.matrikel_no')
     exam = ExamSerializer()
-    submissions = SubmissionSerializer(many=True)
+    submissions = SubmissionListSerializer(many=True)
 
     class Meta:
         model = Student
-        fields = ('name', 'user', 'exam', 'submissions')
+        fields = ('name', 'user', 'matrikel_no', 'exam', 'submissions')
 
 
 class SubmissionNoTextFieldsSerializer(DynamicFieldsModelSerializer):
diff --git a/core/tests/test_student_page.py b/core/tests/test_student_page.py
index 8bd9f349564483dea02e3c4ffc927f4ec65c8e4c..2af05f2be40a884bb09934e1155265f3f2660a82 100644
--- a/core/tests/test_student_page.py
+++ b/core/tests/test_student_page.py
@@ -3,7 +3,7 @@ from rest_framework.test import (APIRequestFactory, APITestCase,
                                  force_authenticate)
 
 from core.models import SubmissionType
-from core.views import StudentSelfApiView
+from core.views import StudentSelfApiView, StudentSelfSubmissionsApiView
 from util.factories import make_test_data
 
 
@@ -57,7 +57,6 @@ class StudentPageTests(APITestCase):
 
         self.request = self.factory.get(reverse('student-page'))
         self.view = StudentSelfApiView.as_view()
-
         force_authenticate(self.request, user=self.student.user)
         self.response = self.view(self.request)
 
@@ -69,10 +68,6 @@ class StudentPageTests(APITestCase):
         self.assertEqual(
             self.response.data['name'], self.student.user.fullname)
 
-    def test_student_contains_associated_user(self):
-        self.assertEqual(
-            self.response.data['user'], self.student.user.username)
-
     def test_all_student_submissions_are_loded(self):
         self.assertEqual(len(self.submission_list),
                          SubmissionType.objects.count())
@@ -98,34 +93,116 @@ class StudentPageTests(APITestCase):
     # Tests concerning submission data
     def test_a_student_submissions_contains_type_name(self):
         self.assertEqual(
-            self.submission_list_first_entry['type_name'],
+            self.submission_list_first_entry['type']['name'],
             self.student.submissions.first().type.name)
 
     def test_a_student_submissions_contains_type_id(self):
         self.assertEqual(
-            self.submission_list_first_entry['type_id'],
+            self.submission_list_first_entry['type']['id'],
             self.student.submissions.first().type.id)
 
-    def test_submission_data_contains_text(self):
+    def test_submission_data_contains_full_score(self):
         self.assertEqual(
-            self.submission_list_first_entry['text'],
-            self.student.submissions.first().text)
+            self.submission_list_first_entry['type']['fullScore'],
+            self.student.submissions.first().type.full_score)
 
-    def test_submission_data_contains_feedback(self):
+    def test_submission_data_contains_feedback_score(self):
         self.assertEqual(
-            self.submission_list_first_entry['feedback'],
-            self.student.submissions.first().feedback.text)
+            self.submission_list_first_entry['feedback']['score'],
+            self.student.submissions.first().feedback.score)
+
+    # We don't want a matriculation number here
+    def test_matriculation_number_is_not_send(self):
+        self.assertNotIn('matrikel_no', self.submission_list_first_entry)
+
+
+class StudentSelfSubmissionsTests(APITestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        cls.factory = APIRequestFactory()
+
+    def setUp(self):
+        self.test_data = make_test_data(data_dict={
+            'submission_types': [{
+                'name': 'problem01',
+                'full_score': 10,
+                'description': 'Very hard',
+                'solution': 'Impossible!'
+            }],
+            'students': [{
+                'username': 'user01',
+            }],
+            'tutors': [{
+                'username': 'tutor01'
+            }],
+            'submissions': [{
+                'user': 'user01',
+                'type': 'problem01',
+                'text': 'Too hard for me ;-(',
+                'feedback': {
+                    'of_tutor': 'tutor01',
+                    'text': 'Very bad!',
+                    'score': 3
+                }
+            }]
+        })
+
+        self.student = self.test_data['students'][0]
+        self.tutor = self.test_data['tutors'][0]
+        self.submission = self.test_data['submissions'][0]
+        self.feedback = self.submission.feedback
+
+        self.request = self.factory.get(reverse('student-submissions'))
+        self.view = StudentSelfSubmissionsApiView.as_view()
+
+        force_authenticate(self.request, user=self.student.user)
+        self.response = self.view(self.request)
 
-    def test_submission_data_contains_score(self):
+        self.submission_list = self.response.data
+        self.submission_list_first_entry = self.submission_list[0]
+
+    # Tests concerning submission data
+    def test_a_student_submissions_contains_type_name(self):
         self.assertEqual(
-            self.submission_list_first_entry['score'],
-            self.student.submissions.first().feedback.score)
+            self.submission_list_first_entry['type']['name'],
+            self.student.submissions.first().type.name)
+
+    def test_a_student_submissions_contains_type_id(self):
+        self.assertEqual(
+            self.submission_list_first_entry['type']['id'],
+            self.student.submissions.first().type.id)
 
     def test_submission_data_contains_full_score(self):
         self.assertEqual(
-            self.submission_list_first_entry['full_score'],
+            self.submission_list_first_entry['type']['fullScore'],
             self.student.submissions.first().type.full_score)
 
+    def test_submission_data_contains_description(self):
+        self.assertEqual(
+            self.submission_list_first_entry['type']['description'],
+            self.student.submissions.first().type.description)
+
+    def test_submission_data_contains_solution(self):
+        self.assertEqual(
+            self.submission_list_first_entry['type']['solution'],
+            self.student.submissions.first().type.solution)
+
+    def test_submission_data_contains_text(self):
+        self.assertEqual(
+            self.submission_list_first_entry['text'],
+            self.student.submissions.first().text)
+
+    def test_submission_data_contains_feedback_score(self):
+        self.assertEqual(
+            self.submission_list_first_entry['feedback']['score'],
+            self.student.submissions.first().feedback.score)
+
+    def test_submission_data_contains_feedback_text(self):
+        self.assertEqual(
+            self.submission_list_first_entry['feedback']['text'],
+            self.student.submissions.first().feedback.text)
+
     # We don't want a matriculation number here
     def test_matriculation_number_is_not_send(self):
         self.assertNotIn('matrikel_no', self.submission_list_first_entry)
diff --git a/core/tests/test_submissiontypeview.py b/core/tests/test_submissiontypeview.py
index c1c7f4b096e2bebee299d89abefb04fbd254816f..0bd370da38fb30272d295784593848663ac09314 100644
--- a/core/tests/test_submissiontypeview.py
+++ b/core/tests/test_submissiontypeview.py
@@ -10,7 +10,7 @@ from core.views import SubmissionTypeApiView
 from util.factories import GradyUserFactory
 
 
-class SubmissionTypeViewTest(APITestCase):
+class SubmissionTypeViewTestList(APITestCase):
 
     @classmethod
     def setUpTestData(cls):
@@ -37,10 +37,41 @@ class SubmissionTypeViewTest(APITestCase):
         self.assertEqual('Hard question', self.response.data[0]['name'])
 
     def test_get_full_score(self):
-        self.assertEqual(20, self.response.data[0]['full_score'])
+        self.assertEqual(20, self.response.data[0]['fullScore'])
+
+
+class SubmissionTypeViewTestRetrieve(APITestCase):
+
+    @classmethod
+    def setUpTestData(cls):
+        cls.factory = APIRequestFactory()
+        cls.user_factory = GradyUserFactory()
+
+    def setUp(self):
+        self.request = self.factory.get('/api/submissiontype/')
+        SubmissionType.objects.create(name='Hard question',
+                                      full_score=20,
+                                      description='Whatever')
+        self.pk = SubmissionType.objects.first().pk
+        force_authenticate(self.request,
+                           self.user_factory.make_reviewer().user)
+        self.view = SubmissionTypeApiView.as_view({'get': 'retrieve'})
+        self.response = self.view(self.request, pk=self.pk)
+
+    def test_can_access_when_authenticated(self):
+        self.assertEqual(self.response.status_code, status.HTTP_200_OK)
+
+    def test_get_id(self):
+        self.assertEqual(self.pk, self.response.data['id'])
+
+    def test_get_sumbission_type_name(self):
+        self.assertEqual('Hard question', self.response.data['name'])
+
+    def test_get_full_score(self):
+        self.assertEqual(20, self.response.data['fullScore'])
 
     def test_get_descritpion(self):
-        self.assertEqual('Whatever', self.response.data[0]['description'])
+        self.assertEqual('Whatever', self.response.data['description'])
 
     def test_there_is_no_solution_to_nothing(self):
-        self.assertEqual('', self.response.data[0]['solution'])
+        self.assertEqual('', self.response.data['solution'])
diff --git a/core/urls.py b/core/urls.py
index cb66e7d2222fa0fd4a9706a00c8bac8339c93646..2f2e47e682c450f8efe0bdd2a892b3424a7e5f01 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -17,6 +17,8 @@ router.register(r'tutor', views.TutorApiViewSet)
 regular_views_urlpatterns = [
     url(r'student-page', views.StudentSelfApiView.as_view(),
         name='student-page'),
+    url(r'student-submissions', views.StudentSelfSubmissionsApiView.as_view(),
+        name='student-submissions'),
     url(r'user-role', views.get_user_role, name='user-role'),
     url(r'jwt-time-delta', views.get_jwt_expiration_delta,
         name='jwt-time-delta')
diff --git a/core/views.py b/core/views.py
index 6d5a9595d19d6c8451c84da2f92c6f2a674c0dcc..2b87315b923a92222eb84cffa8b04734c20245a1 100644
--- a/core/views.py
+++ b/core/views.py
@@ -10,7 +10,8 @@ from core.models import ExamType, Student, SubmissionType, Tutor
 from core.permissions import IsReviewer, IsStudent
 from core.serializers import (ExamSerializer, StudentSerializer,
                               StudentSerializerForListView,
-                              SubmissionTypeSerializer, TutorSerializer)
+                              SubmissionSerializer, SubmissionTypeSerializer,
+                              TutorSerializer)
 
 
 @api_view()
@@ -35,6 +36,14 @@ class StudentSelfApiView(generics.RetrieveAPIView):
         return self.request.user.student
 
 
+class StudentSelfSubmissionsApiView(generics.ListAPIView):
+    permission_classes = (IsStudent, )
+    serializer_class = SubmissionSerializer
+
+    def get_queryset(self):
+        return self.request.user.student.submissions
+
+
 class ExamApiViewSet(viewsets.ReadOnlyModelViewSet):
     """ Gets a list of an individual exam by Id if provided """
     permission_classes = (IsReviewer,)
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 47893229c88166fe70838840516122f9687ae87a..0e0910b3cbff0ccb4a7884cf6d4abd3832648c76 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -15,4 +15,7 @@
 </script>
 
 <style>
+  #app {
+    font-family: Roboto, sans-serif;
+  }
 </style>
diff --git a/frontend/src/components/base/BaseLayout.vue b/frontend/src/components/BaseLayout.vue
similarity index 88%
rename from frontend/src/components/base/BaseLayout.vue
rename to frontend/src/components/BaseLayout.vue
index 5daac11f8551b3b9a797f77b59aacd987f8a9026..3f18a9866469951978cbc9420c4b34edfd9c3184 100644
--- a/frontend/src/components/base/BaseLayout.vue
+++ b/frontend/src/components/BaseLayout.vue
@@ -5,7 +5,7 @@
       clipped
       app
       permanent
-      :mini-variant.sync="mini"
+      :mini-variant="mini"
     >
       <v-toolbar flat>
         <v-list>
@@ -26,7 +26,7 @@
           </v-list-tile>
         </v-list>
       </v-toolbar>
-        <slot name="navigation"></slot>
+        <slot name="sidebar-content"></slot>
     </v-navigation-drawer>
     <v-toolbar
       app
@@ -38,7 +38,7 @@
     >
       <v-toolbar-title>
         <v-avatar>
-          <img src="../../assets/brand.png">
+          <img src="../assets/brand.png">
         </v-avatar>
       </v-toolbar-title>
       <span class="pl-2 grady-speak">{{ gradySpeak }}</span>
@@ -48,7 +48,7 @@
       <v-btn color="blue darken-1" to="/" @click.native="logout">Logout</v-btn>
     </v-toolbar>
     <v-content>
-      <slot></slot>
+      <router-view></router-view>
     </v-content>
   </div>
 </template>
@@ -67,7 +67,6 @@
         'gradySpeak'
       ]),
       ...mapState([
-        'examInstance',
         'username',
         'userRole'
       ])
@@ -76,6 +75,11 @@
       ...mapActions([
         'logout'
       ])
+    },
+    watch: {
+      mini: function () {
+        this.$emit('sidebarMini', this.mini)
+      }
     }
   }
 </script>
diff --git a/frontend/src/components/SubmissionType.vue b/frontend/src/components/SubmissionType.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5827cbb6836d6bc58373ac3b32bbc09b21eb6cab
--- /dev/null
+++ b/frontend/src/components/SubmissionType.vue
@@ -0,0 +1,54 @@
+<template>
+  <v-container>
+    <h2 class="mb-2">{{ name }} - Full score: {{ fullScore }}</h2>
+    <v-expansion-panel expand>
+      <v-expansion-panel-content
+      v-for="(item, key, i) in {Description: description, Solution:solution}" 
+      :key="i"
+      :value="expandedByDefault[key]">
+      <div slot="header">{{ key }}</div>
+        <v-card color="grey lighten-4">
+          <v-card-text>
+            {{ item }}
+          </v-card-text>
+        </v-card>
+      </v-expansion-panel-content>
+    </v-expansion-panel>
+  </v-container>
+</template>
+
+
+<script>
+  export default {
+    name: 'submission-type',
+    props: {
+      name: {
+        type: String,
+        required: true
+      },
+      description: {
+        type: String,
+        required: true
+      },
+      solution: {
+        type: String,
+        required: true
+      },
+      fullScore: {
+        type: Number,
+        required: true
+      },
+      expandedByDefault: {
+        type: Object,
+        default: function () {
+          return {
+            Description: true,
+            Solution: true
+          }
+        },
+        required: false
+      }
+    }
+  }
+</script>
+
diff --git a/frontend/src/components/student/ExamInformation.vue b/frontend/src/components/student/ExamInformation.vue
index 817cd58c1e42da874890066be1d87409c4d5e4cd..21795f0503e1eb9d97590fe94ac943eda1243318 100644
--- a/frontend/src/components/student/ExamInformation.vue
+++ b/frontend/src/components/student/ExamInformation.vue
@@ -5,12 +5,12 @@
         <th>Modul</th>
         <td>{{ exam.module_reference }}</td>
       </tr>
-      <tr v-if="!exam.pass_only">
+      <tr>
         <th>Pass score</th>
         <td>{{ exam.pass_score }}</td>
       </tr>
-      <tr v-else>
-        <th>Pass only!</th>
+      <tr v-if="exam.passOnly">
+        <th>Pass only exam!</th>
       </tr>
       <tr>
         <th>Total score</th>
diff --git a/frontend/src/components/student/SubmissionDetail.vue b/frontend/src/components/student/SubmissionDetail.vue
deleted file mode 100644
index 1a757b4618bb608c0cd31ae509646ca2840eb670..0000000000000000000000000000000000000000
--- a/frontend/src/components/student/SubmissionDetail.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-<template>
-  <v-layout>
-
-    <annotated-submission class="ma-3" :editable="false"></annotated-submission>
-  </v-layout>
-</template>
-
-
-<script>
-  import AnnotatedSubmission from '../submission_notes/AnnotatedSubmission'
-  export default {
-    components: {
-      AnnotatedSubmission
-    },
-    name: 'submission-detail'
-  }
-</script>
diff --git a/frontend/src/components/student/SubmissionList.vue b/frontend/src/components/student/SubmissionList.vue
index 3954d89985f97702e2512e127963ecf6334747ea..7ef34f95222b4308396b03585ca8feda408c84db 100644
--- a/frontend/src/components/student/SubmissionList.vue
+++ b/frontend/src/components/student/SubmissionList.vue
@@ -7,10 +7,10 @@
       item-key="type"
     >
       <template slot="items" slot-scope="props">
-        <td>{{ props.item.type_name }}</td>
-        <td class="text-xs-right">{{ props.item.score }}</td>
-        <td class="text-xs-right">{{ props.item.full_score }}</td>
-        <td class="text-xs-right"><v-btn :to="`submission/${props.item.type_id}`" color="orange lighten-2">View</v-btn></td>
+        <td>{{ props.item.type.name }}</td>
+        <td class="text-xs-right">{{ props.item.feedback.score }}</td>
+        <td class="text-xs-right">{{ props.item.type.fullScore }}</td>
+        <td class="text-xs-right"><v-btn :to="`submission/${props.item.type.id}`" color="orange lighten-2"><v-icon>chevron_right</v-icon></v-btn></td>
       </template>
     </v-data-table>
     <v-alert color="info" value="true">
@@ -29,22 +29,17 @@
           {
             text: 'Task',
             align: 'left',
-            value: 'type'
+            value: 'type',
+            sortable: false
           },
           {
             text: 'Score',
-            value: 'score'
+            value: 'feedback.score'
           },
           {
             text: 'Maximum Score',
-            value: 'full_score'
+            value: 'type.fullScore'
           }
-        ],
-
-        fields: [
-          { key: 'type', sortable: true },
-          { key: 'score', label: 'Score', sortable: true },
-          { key: 'full_score', sortable: true }
         ]
       }
     },
@@ -56,11 +51,10 @@
     },
     computed: {
       sumScore () {
-        console.log(this.submissions)
-        return this.submissions.map(a => a.score).reduce((a, b) => a + b)
+        return this.submissions.map(a => a.feedback.score).reduce((a, b) => a + b)
       },
       sumFullScore () {
-        return this.submissions.map(a => a.full_score).reduce((a, b) => a + b)
+        return this.submissions.map(a => a.type.fullScore).reduce((a, b) => a + b)
       },
       pointRatio () {
         return ((this.sumScore / this.sumFullScore) * 100).toFixed(2)
diff --git a/frontend/src/components/submission_notes/AnnotatedSubmission.vue b/frontend/src/components/submission_notes/AnnotatedSubmission.vue
index 774d55a825b5a8756522067fd27f6faec25cb2b1..d5c24b1bc2ed03e7ed30ac554e0bf9ee9cc7a564 100644
--- a/frontend/src/components/submission_notes/AnnotatedSubmission.vue
+++ b/frontend/src/components/submission_notes/AnnotatedSubmission.vue
@@ -1,11 +1,8 @@
 <template>
-  <table>
+  <table class="elevation-1">
     <tr v-for="(code, index) in submission" :key="index">
       <td class="line-number-cell">
-        <!--<v-tooltip left close-delay="20" color="transparent" content-class="comment-icon">-->
-          <v-btn block class="line-number-btn" slot="activator" @click="toggleEditorOnLine(index)">{{ index }}</v-btn>
-          <!--<v-icon small color="indigo accent-3" class="comment-icon">comment</v-icon>-->
-        <!--</v-tooltip>-->
+        <v-btn block class="line-number-btn" @click="toggleEditorOnLine(index)">{{ index }}</v-btn>
       </td>
       <td>
         <pre class="prettyprint"><code class="lang-c"> {{ code }}</code></pre>
@@ -26,7 +23,6 @@
 
 
 <script>
-  import {mapGetters, mapState} from 'vuex'
   import CommentForm from '@/components/submission_notes/FeedbackForm.vue'
   import FeedbackComment from '@/components/submission_notes/FeedbackComment.vue'
 
@@ -36,24 +32,34 @@
       CommentForm},
     name: 'annotated-submission',
     props: {
+      rawSubmission: {
+        type: String,
+        required: true
+      },
+      score: {
+        type: Number,
+        required: true
+      },
+      feedback: {
+        type: Object,
+        required: true
+      },
       editable: {
         type: Boolean,
         default: false
       }
     },
-    beforeCreate () {
-      this.$store.dispatch('getFeedback', 0)
-      this.$store.dispatch('getSubmission', 0)
-    },
-    computed: {
-      ...mapState({
-        feedback: state => state.submissionNotes.feedback
-      }),
-      ...mapGetters(['submission'])
-    },
     data: function () {
       return {
-        showEditorOnLine: { }
+        showEditorOnLine: {}
+      }
+    },
+    computed: {
+      submission () {
+        return this.rawSubmission.split('\n').reduce((acc, cur, index) => {
+          acc[index + 1] = cur
+          return acc
+        }, {})
       }
     },
     methods: {
@@ -75,13 +81,8 @@
     border-collapse: collapse;
   }
 
-  td {
-    /*white-space: nowrap;*/
-    /*border: 1px solid green;*/
-  }
 
   .line-number-cell {
-    /*padding-left: 50px;*/
     vertical-align: top;
   }
 
@@ -101,9 +102,4 @@
     min-width: fit-content;
     margin: 0;
   }
-
-  .comment-icon {
-    border: 0;
-  }
-
 </style>
diff --git a/frontend/src/components/submission_notes/FeedbackComment.vue b/frontend/src/components/submission_notes/FeedbackComment.vue
index a63b4de6a32267608763b9f999f5088adf462e71..637fce73cc1aba84136cc7b87ded37f22d423db9 100644
--- a/frontend/src/components/submission_notes/FeedbackComment.vue
+++ b/frontend/src/components/submission_notes/FeedbackComment.vue
@@ -40,12 +40,11 @@
     margin: 20px 10px 10px 10px;
     padding: 5px;
     background-color: #F3F3F3;
-    border-radius: 5px;
-    border: 5px solid #3D8FC1;
+    border-radius: 0px;
+    border: 2px solid #3D8FC1;
   }
 
   .body .message {
-    font-family: Roboto, sans-serif;
     min-height: 30px;
     border-radius: 3px;
     font-size: 14px;
diff --git a/frontend/src/components/Login.vue b/frontend/src/pages/Login.vue
similarity index 100%
rename from frontend/src/components/Login.vue
rename to frontend/src/pages/Login.vue
diff --git a/frontend/src/components/reviewer/ReviewerPage.vue b/frontend/src/pages/reviewer/ReviewerPage.vue
similarity index 100%
rename from frontend/src/components/reviewer/ReviewerPage.vue
rename to frontend/src/pages/reviewer/ReviewerPage.vue
diff --git a/frontend/src/components/reviewer/ReviewerToolbar.vue b/frontend/src/pages/reviewer/ReviewerToolbar.vue
similarity index 100%
rename from frontend/src/components/reviewer/ReviewerToolbar.vue
rename to frontend/src/pages/reviewer/ReviewerToolbar.vue
diff --git a/frontend/src/components/reviewer/StudentListOverview.vue b/frontend/src/pages/reviewer/StudentListOverview.vue
similarity index 100%
rename from frontend/src/components/reviewer/StudentListOverview.vue
rename to frontend/src/pages/reviewer/StudentListOverview.vue
diff --git a/frontend/src/components/student/StudentLayout.vue b/frontend/src/pages/student/StudentLayout.vue
similarity index 50%
rename from frontend/src/components/student/StudentLayout.vue
rename to frontend/src/pages/student/StudentLayout.vue
index e7f12d7e18c370097fce830654470f1f224d499f..28bcabe7d01421d6df21290284122123787418a0 100644
--- a/frontend/src/components/student/StudentLayout.vue
+++ b/frontend/src/pages/student/StudentLayout.vue
@@ -1,9 +1,12 @@
 <template>
-  <base-layout>
+  <base-layout @sidebarMini="mini = $event">
+
     <template  slot="header">
       {{ module_reference }}
     </template>
-    <v-list dense slot="navigation">
+
+    <v-list dense slot="sidebar-content">
+
       <v-list-tile exact v-for="(item, i) in generalNavItems" :key="i" :to="item.route">
         <v-list-tile-action>
           <v-icon>{{ item.icon }}</v-icon>
@@ -14,30 +17,38 @@
           </v-list-tile-title>
         </v-list-tile-content>
       </v-list-tile>
+
       <v-divider></v-divider>
-    <v-list-tile exact v-for="(item, i) in submissionNavItems" :key="i" :to="item.route">
-      <v-list-tile-action>
-        <v-icon>assignment</v-icon>
-      </v-list-tile-action>
-      <v-list-tile-content>
-        <v-list-tile-title>
-          {{ item.name }}
-        </v-list-tile-title>
-      </v-list-tile-content>
-    </v-list-tile>
+        <v-card color="grey lighten-2" v-if="!mini">
+          <v-card-title primary-title>
+            <exam-information :exam="exam"></exam-information>
+          </v-card-title>
+        </v-card>
+      <v-list-tile exact v-for="(item, i) in submissionNavItems" :key="i" :to="item.route">
+        <v-list-tile-action>
+          <v-icon v-if="!visited[item.id]">assignment</v-icon>
+          <v-icon v-else>check</v-icon>
+        </v-list-tile-action>
+        <v-list-tile-content>
+          <v-list-tile-title>
+            {{ item.name }}
+          </v-list-tile-title>
+        </v-list-tile-content>
+      </v-list-tile>
     </v-list>
-    <router-view></router-view>
   </base-layout>
 </template>
 
 <script>
   import { mapState } from 'vuex'
-  import BaseLayout from '../base/BaseLayout'
+  import BaseLayout from '@/components/BaseLayout'
+  import ExamInformation from '@/components/student/ExamInformation'
   export default {
-    components: {BaseLayout},
+    components: {BaseLayout, ExamInformation},
     name: 'student-layout',
     data () {
       return {
+        mini: false,
         generalNavItems: [
           {
             name: 'Overview',
@@ -55,13 +66,16 @@
     computed: {
       ...mapState({
         module_reference: state => state.studentPage.exam.module_reference,
-        submissions: state => state.studentPage.submissions
+        submissions: state => state.studentPage.submissionsForList,
+        exam: state => state.studentPage.exam,
+        visited: state => state.studentPage.visited
       }),
       submissionNavItems: function () {
         return this.submissions.map((sub, index) => {
           return {
-            name: sub.type_name,
-            route: `/student/submission/${sub.type_id}`
+            name: sub.type.name,
+            id: sub.type.id,
+            route: `/student/submission/${sub.type.id}`
           }
         })
       }
diff --git a/frontend/src/components/student/StudentPage.vue b/frontend/src/pages/student/StudentPage.vue
similarity index 59%
rename from frontend/src/components/student/StudentPage.vue
rename to frontend/src/pages/student/StudentPage.vue
index 1bcb1fc7dd9111067b9f0110a879b862f3751925..f42887fafa50ebe7338e25107e5f28aba38be1cd 100644
--- a/frontend/src/components/student/StudentPage.vue
+++ b/frontend/src/pages/student/StudentPage.vue
@@ -1,12 +1,8 @@
 <template>
     <v-container fluid>
       <v-layout justify center>
-        <v-flex md3>
-          <h2>Exam Overview</h2>
-          <exam-information v-if="!loading" :exam="exam"></exam-information>
-        </v-flex>
-        <template v-if="!loading">
-          <v-flex md7 offset-md1>
+        <template v-if="loaded">
+          <v-flex md10 mt-5 offset-xs1>
             <h2>Submissions of {{ studentName }}</h2>
             <submission-list :submissions="submissions"></submission-list>
           </v-flex>
@@ -19,8 +15,8 @@
 <script>
   import {mapState} from 'vuex'
   import StudentLayout from './StudentLayout.vue'
-  import SubmissionList from './SubmissionList.vue'
-  import ExamInformation from './ExamInformation.vue'
+  import SubmissionList from '@/components/student/SubmissionList.vue'
+  import ExamInformation from '@/components/student/ExamInformation.vue'
 
   export default {
     components: {
@@ -29,14 +25,18 @@
       StudentLayout},
     name: 'student-page',
     created: function () {
-      this.$store.dispatch('getStudentData')
+      if (!this.loaded) {
+        this.$store.dispatch('getStudentData').then(() => {
+          this.$store.dispatch('getStudentSubmissions')
+        })
+      }
     },
     computed: {
       ...mapState({
         studentName: state => state.studentPage.studentName,
         exam: state => state.studentPage.exam,
-        submissions: state => state.studentPage.submissions,
-        loading: state => state.studentPage.loading
+        submissions: state => state.studentPage.submissionsForList,
+        loaded: state => state.studentPage.loaded
       })
     }
   }
diff --git a/frontend/src/pages/student/StudentSubmissionPage.vue b/frontend/src/pages/student/StudentSubmissionPage.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1d13fc4ccad88fb4198b5e72e052678827878f75
--- /dev/null
+++ b/frontend/src/pages/student/StudentSubmissionPage.vue
@@ -0,0 +1,48 @@
+<template>
+  <v-container flex>
+    <v-layout>
+      <v-flex xs-12 sm-6 md-6 ma-5>
+        <annotated-submission 
+        :rawSubmission="rawSubmission"
+        :score="score"
+        :feedback="{}">
+        </annotated-submission>
+      </v-flex>
+      <v-flex xs-12 sm-6 md-6>
+        <submission-type
+        v-bind="submissionType">
+        </submission-type>
+      </v-flex>
+    </v-layout>
+  </v-container>
+</template>
+
+
+<script>
+  import { mapState } from 'vuex'
+  import AnnotatedSubmission from '@/components/submission_notes/AnnotatedSubmission'
+  import SubmissionType from '@/components/SubmissionType'
+  export default {
+    name: 'student-submission-page',
+    components: {AnnotatedSubmission, SubmissionType},
+    computed: {
+      id: function () {
+        return this.$route.params.id
+      },
+      ...mapState({
+        rawSubmission: function (state) { return state.studentPage.submissionData[this.id].text },
+        score: function (state) { return state.studentPage.submissionData[this.id].feedback.score },
+        submissionType: function (state) { return state.studentPage.submissionData[this.id].type }
+        // feedback: function (state) { return state.studentPage.submissionData[this.$route.params.id].feedback.text }
+      })
+    },
+    mounted: function () {
+      this.$store.commit('SET_VISITED', { index: this.id, visited: true })
+    },
+    updated: function () {
+      if (this.id) {
+        this.$store.commit('SET_VISITED', { index: this.id, visited: true })
+      }
+    }
+  }
+</script>
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index 849fbf66c4d47a38992f6ea97e5dcf25776d7966..9ff1b8396d577be2140bdcd7f47140c012d2ae05 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -1,14 +1,12 @@
 import Vue from 'vue'
 import Router from 'vue-router'
 import store from '../store/store'
-import Login from '@/components/Login'
-import StudentPage from '@/components/student/StudentPage'
-import StudentLayout from '@/components/student/StudentLayout'
-import SubmissionDetail from '@/components/student/SubmissionDetail'
-import ReviewerPage from '@/components/reviewer/ReviewerPage'
-import StudentListOverview from '@/components/reviewer/StudentListOverview'
-import BaseLayout from '@/components/base/BaseLayout'
-import AnnotatedSubmission from '@/components/submission_notes/AnnotatedSubmission'
+import Login from '@/pages/Login'
+import StudentPage from '@/pages/student/StudentPage'
+import StudentSubmissionPage from '@/pages/student/StudentSubmissionPage'
+import StudentLayout from '@/pages/student/StudentLayout'
+import ReviewerPage from '@/pages/reviewer/ReviewerPage'
+import StudentListOverview from '@/pages/reviewer/StudentListOverview'
 
 Vue.use(Router)
 
@@ -29,7 +27,7 @@ const router = new Router({
         },
         {
           path: 'submission/:id',
-          component: SubmissionDetail
+          component: StudentSubmissionPage
         }
       ]
 
@@ -43,28 +41,16 @@ const router = new Router({
       path: 'reviewer/student-overview/',
       name: 'student-overview',
       component: StudentListOverview
-    },
-    {
-      path: '/base/',
-      name: 'base-layout',
-      component: BaseLayout
-    },
-    {
-      path: '/notes/',
-      name: 'annotated-submission',
-      component: AnnotatedSubmission
     }
   ]
 })
 
 router.beforeEach((to, from, next) => {
-  if (to.path === '/') {
+  if (to.path === '/' || from.path === '/') {
     next()
   } else {
-    const now = new Date()
+    const now = Date.now()
     if (now - store.state.logInTime > store.state.jwtTimeDelta * 1000) {
-      console.log(now)
-      console.log(store.state.logInTime)
       store.dispatch('logout').then(() => {
         store.commit('API_FAIL', 'You\'ve been logged out due to inactivity')
         next('/')
diff --git a/frontend/src/store/modules/student-page.js b/frontend/src/store/modules/student-page.js
index ce6cc28b92de50247aea85562782e5b4924b8968..45a5b34f3d678182a596e039f83d48aaf83d98bd 100644
--- a/frontend/src/store/modules/student-page.js
+++ b/frontend/src/store/modules/student-page.js
@@ -4,9 +4,10 @@ const studentPage = {
   state: {
     studentName: '',
     exam: {},
-    submissionTypes: [],
-    submissions: [],
-    loading: true
+    submissionsForList: [],
+    submissionData: {},
+    visited: {},
+    loaded: false
   },
   mutations: {
     'SET_STUDENT_NAME': function (state, name) {
@@ -18,26 +19,81 @@ const studentPage = {
     'SET_SUBMISSION_TYPES': function (state, submissionTypes) {
       state.submissionTypes = submissionTypes
     },
-    'SET_SUBMISSIONS': function (state, submissions) {
-      state.submissions = submissions
+    'SET_SUBMISSIONS_FOR_LIST': function (state, submissions) {
+      state.submissionsForList = submissions
     },
-    'SET_LOADING': function (state, loading) {
-      state.loading = loading
+    /**
+     * Reduces the array submissionData returned by the /api/student-submissions
+     * into an object where the keys are the SubmissionType id's and the values
+     * the former array elements. This is done to have direct access to the data
+     * via the SubmissionType id.
+     */
+    'SET_FULL_SUBMISSION_DATA': function (state, submissionData) {
+      state.submissionData = submissionData.reduce((acc, cur, index) => {
+        acc[cur.type.id] = cur
+        return acc
+      }, {})
+    },
+    'SET_VISITED': function (state, visited) {
+      state.visited = { ...state.visited, [visited.index]: visited.visited }
+    },
+    'SET_LOADED': function (state, loaded) {
+      state.loaded = loaded
     }
   },
   actions: {
 
     getStudentData (context) {
-      context.commit('SET_LOADING', true)
+      context.commit('SET_LOADED', false)
       ax.get('api/student-page/').then(response => {
         const data = response.data
         context.commit('SET_STUDENT_NAME', data.name)
         context.commit('SET_EXAM', data.exam)
-        context.commit('SET_SUBMISSIONS', data.submissions)
-        context.commit('SET_LOADING', false)
+        context.commit('SET_SUBMISSIONS_FOR_LIST', data.submissions)
+        context.commit('SET_LOADED', true)
       })
+    },
+
+    async getStudentSubmissions (context) {
+      const response = await ax.get('/api/student-submissions')
+      context.commit('SET_FULL_SUBMISSION_DATA', response.data)
     }
   }
 }
 
+// const mockSubmission = '//Procedural Programming technique shows creation of Pascal\'s Triangl\n' +
+//   '#include <iostream>\n' +
+//   '#include <iomanip>\n' +
+//   '\n' +
+//   'using namespace std;\n' +
+//   '\n' +
+//   '\n' +
+//   'int** comb(int** a , int row , int col)\n' +
+//   '{\n' +
+//   '   int mid = col/2;\n' +
+//   '        //clear matrix\n' +
+//   '         for( int i = 0 ; i < row ; i++)\n' +
+//   '         for( int j = 0 ; j < col ; j++)\n' +
+//   '                a[i][j] = 0;\n' +
+//   '                a[0][mid] = 1; //put 1 in the middle of first row\n' +
+//   '    //build up Pascal\'s Triangle matrix\n' +
+//   '     for( int i = 1 ; i < row ; i++)\n' +
+//   '        {\n' +
+//   '          for( int j = 1 ; j < col - 1 ; j++)\n' +
+//   '               a[i][j] = a[i-1][j-1] + a[i-1][j+1];\n' +
+//   '        }\n' +
+//   '   return a;\n' +
+//   '}\n' +
+//   'void disp(int** ptr, int row, int col)\n' +
+//   '{\n' +
+//   '  cout << endl << endl;\n' +
+//   '    for ( int i = 0 ; i < row ; i++)\n' +
+//   '        {\n' +
+//   '        for ( int j = 0 ; j < col ; j++)\n'
+
+// const mockFeedback = {
+//   '1': 'Youre STUPID',
+//   '4': 'Very much so'
+// }
+
 export default studentPage
diff --git a/frontend/src/store/modules/submission-notes.js b/frontend/src/store/modules/submission-notes.js
index cde09fa0c39e2f4a38869dc8746aee0c3be86628..10a47e24d2471d5d27e39900a0d8002c228f8007 100644
--- a/frontend/src/store/modules/submission-notes.js
+++ b/frontend/src/store/modules/submission-notes.js
@@ -1,76 +1,44 @@
-import Vue from 'vue'
+// import Vue from 'vue'
 
-const mockSubmission = '//Procedural Programming technique shows creation of Pascal\'s Triangl\n' +
-  '#include <iostream>\n' +
-  '#include <iomanip>\n' +
-  'using namespace std;\n' +
-  'int** comb(int** a , int row , int col)\n' +
-  '{\n' +
-  '   int mid = col/2;\n' +
-  '        //clear matrix\n' +
-  '         for( int i = 0 ; i < row ; i++)\n' +
-  '         for( int j = 0 ; j < col ; j++)\n' +
-  '                a[i][j] = 0;\n' +
-  '                a[0][mid] = 1; //put 1 in the middle of first row\n' +
-  '    //build up Pascal\'s Triangle matrix\n' +
-  '     for( int i = 1 ; i < row ; i++)\n' +
-  '        {\n' +
-  '          for( int j = 1 ; j < col - 1 ; j++)\n' +
-  '               a[i][j] = a[i-1][j-1] + a[i-1][j+1];\n' +
-  '        }\n' +
-  '   return a;\n' +
-  '}\n' +
-  'void disp(int** ptr, int row, int col)\n' +
-  '{\n' +
-  '  cout << endl << endl;\n' +
-  '    for ( int i = 0 ; i < row ; i++)\n' +
-  '        {\n' +
-  '        for ( int j = 0 ; j < col ; j++)\n'
+// const submissionNotes = {
+//   state: {
+//     rawSubmission: '',
+//     feedback: {}
+//   },
+//   getters: {
+//     // reduce the string rawSubmission into an object where the keys are the
+//     // line indexes starting at one and the values the corresponding submission line
+//     // this makes iterating over the submission much more pleasant
+//     submission: state => {
+//       return state.rawSubmission.split('\n').reduce((acc, cur, index) => {
+//         acc[index + 1] = cur
+//         return acc
+//       }, {})
+//     }
+//   },
+//   mutations: {
+//     'SET_RAW_SUBMISSION': function (state, submission) {
+//       state.rawSubmission = mockSubmission
+//     },
+//     'SET_FEEDBACK': function (state, feedback) {
+//       state.feedback = feedback
+//     },
+//     'UPDATE_FEEDBACK': function (state, feedback) {
+//       Vue.set(state.feedback, feedback.lineIndex, feedback.content)
+//     }
+//   },
+//   actions: {
+//     // TODO remove mock data
+//     getSubmission (context, submissionId) {
+//       context.commit('SET_RAW_SUBMISSION', mockSubmission)
+//     },
+//     getFeedback (context, feedbackId) {
+//       context.commit('SET_FEEDBACK', mockFeedback)
+//     },
+//     updateFeedback (context, lineIndex, feedbackContent) {
+//       context.commit('UPDATE_FEEDBACK', lineIndex, feedbackContent)
+//     }
+//   }
+// }
 
-const mockFeedback = {
-  '1': 'Youre STUPID',
-  '4': 'Very much so'
-}
-
-const submissionNotes = {
-  state: {
-    rawSubmission: '',
-    feedback: {}
-  },
-  getters: {
-    // reduce the string rawSubmission into an object where the keys are the
-    // line indexes starting at one and the values the corresponding submission line
-    // this makes iterating over the submission much more pleasant
-    submission: state => {
-      return state.rawSubmission.split('\n').reduce((acc, cur, index) => {
-        acc[index + 1] = cur
-        return acc
-      }, {})
-    }
-  },
-  mutations: {
-    'SET_RAW_SUBMISSION': function (state, submission) {
-      state.rawSubmission = mockSubmission
-    },
-    'SET_FEEDBACK': function (state, feedback) {
-      state.feedback = feedback
-    },
-    'UPDATE_FEEDBACK': function (state, feedback) {
-      Vue.set(state.feedback, feedback.lineIndex, feedback.content)
-    }
-  },
-  actions: {
-    // TODO remove mock data
-    getSubmission (context, submissionId) {
-      context.commit('SET_RAW_SUBMISSION', mockSubmission)
-    },
-    getFeedback (context, feedbackId) {
-      context.commit('SET_FEEDBACK', mockFeedback)
-    },
-    updateFeedback (context, lineIndex, feedbackContent) {
-      context.commit('UPDATE_FEEDBACK', lineIndex, feedbackContent)
-    }
-  }
-}
-
-export default submissionNotes
+// export default submissionNotes
diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js
index e9c4797677a92abc9ea439689f159bad28cbf567..0eb0f5fbfdc57213ffbe3d1967864ceb73f3a184 100644
--- a/frontend/src/store/store.js
+++ b/frontend/src/store/store.js
@@ -3,22 +3,20 @@ import Vue from 'vue'
 import ax from './api'
 
 import gradySays from './grady_speak'
-import submissionNotes from './modules/submission-notes'
 import studentPage from './modules/student-page'
 
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
   modules: {
-    submissionNotes,
     studentPage
   },
   state: {
     token: sessionStorage.getItem('jwtToken'),
     loggedIn: !!sessionStorage.getItem('jwtToken'),
-    logInTime: sessionStorage.getItem('logInTime'),
+    logInTime: Number(sessionStorage.getItem('logInTime')),
     username: sessionStorage.getItem('username'),
-    jwtTimeDelta: sessionStorage.getItem('jwtTimeDelta'),
+    jwtTimeDelta: Number(sessionStorage.getItem('jwtTimeDelta')),
     userRole: sessionStorage.getItem('userRole'),
     error: ''
   },
@@ -36,7 +34,7 @@ const store = new Vuex.Store({
       state.logInTime = Date.now()
       ax.defaults.headers['Authorization'] = 'JWT ' + token
       sessionStorage.setItem('jwtToken', token)
-      sessionStorage.setItem('logInTime', state.logInTime)
+      sessionStorage.setItem('logInTime', String(state.logInTime))
     },
     'SET_JWT_TIME_DELTA': function (state, timeDelta) {
       state.jwtTimeDelta = timeDelta
diff --git a/frontend/test/unit/specs/SubmissionList.spec.js b/frontend/test/unit/specs/SubmissionList.spec.js
index 8e855486029934dc781d0058d6bc7e11c7d2ac03..59542a0f8b2fa47dc6c9755a78071f42dc551b9a 100644
--- a/frontend/test/unit/specs/SubmissionList.spec.js
+++ b/frontend/test/unit/specs/SubmissionList.spec.js
@@ -4,18 +4,24 @@ import SubmissionList from '@/components/student/SubmissionList'
 describe('SubmissionList.vue', () => {
   it('tests the SubmissionList for students', () => {
     const data = [{
-      'type': 'Aufgabe 01',
-      'text': 'I dont know the answer.',
-      'feedback': 'I am very disappointed.',
-      'score': 5,
-      'full_score': 14
+      type: {
+        name: 'Aufgabe 01',
+        fullScore: 14
+      },
+      feedback: {
+        text: 'I am very disappointed.',
+        score: 5
+      }
     },
     {
-      'type': 'Aufgabe 01',
-      'text': 'A very good solution, indeed',
-      'feedback': 'I am still very disappointed.',
-      'score': 7,
-      'full_score': 10
+      type: {
+        name: 'Aufgabe 02',
+        fullScore: 10
+      },
+      feedback: {
+        text: 'I am still very disappointed.',
+        score: 7
+      }
     }]
 
     const Constructor = Vue.extend(SubmissionList)
diff --git a/util/factories.py b/util/factories.py
index 63da6ecf45e9311f49225f1e29f29344b293431e..f90e649c35bca6d74429aa48707ff27f0fdc922c 100644
--- a/util/factories.py
+++ b/util/factories.py
@@ -134,7 +134,8 @@ def make_submission_types(submission_types=[], **kwargs):
 def make_students(students=[], **kwargs):
     return [GradyUserFactory().make_student(
         username=student['username'],
-        exam=ExamType.objects.get(module_reference=student['exam']),
+        exam=ExamType.objects.get(module_reference=student['exam']) if
+        'exam' in student else None,
         password=student.get('password', None)
     ) for student in students]