diff --git a/core/tests/test_access_rights.py b/core/tests/test_access_rights.py
index 6e172626ff78f4374547336ebd2399e9c0461b09..9c22248b907e106d7a78448fb011655a04b5bb45 100644
--- a/core/tests/test_access_rights.py
+++ b/core/tests/test_access_rights.py
@@ -4,7 +4,7 @@ from rest_framework.test import (APIRequestFactory, APITestCase,
                                  force_authenticate)
 
 from core.views import (ExamApiViewSet, StudentReviewerApiViewSet,
-                        StudentSelfApiViewSet, TutorApiViewSet)
+                        StudentSelfApiView, TutorApiViewSet)
 from util.factories import GradyUserFactory
 
 
@@ -21,8 +21,8 @@ class AccessRightsOfStudentAPIViewTests(APITestCase):
         self.student = self.user_factory.make_student()
         self.tutor = self.user_factory.make_tutor()
         self.reviewer = self.user_factory.make_reviewer()
-        self.request = self.factory.get(reverse('student_page-list'))
-        self.view = StudentSelfApiViewSet.as_view({'get': 'retrieve'})
+        self.request = self.factory.get(reverse('student-page'))
+        self.view = StudentSelfApiView.as_view()
 
     def test_unauthenticated_access_denied(self):
         response = self.view(self.request)
diff --git a/core/tests/test_student_page.py b/core/tests/test_student_page.py
index 930163ad8c94ebb906210976e06f6de8253c3b14..099c54cd6d54d4bb4b910d4feee6180395274433 100644
--- a/core/tests/test_student_page.py
+++ b/core/tests/test_student_page.py
@@ -4,7 +4,7 @@ from rest_framework.test import (APIRequestFactory, APITestCase,
 
 from core.models import Reviewer, SubmissionType
 from core.tests import data_factories
-from core.views import StudentSelfApiViewSet
+from core.views import StudentSelfApiView
 
 
 class StudentPageTests(APITestCase):
@@ -19,8 +19,8 @@ class StudentPageTests(APITestCase):
         self.student = self.submission.student
         self.reviewer = Reviewer.objects.create(
             user=data_factories.make_user(username='reviewer'))
-        self.request = self.factory.get(reverse('student_page-list'))
-        self.view = StudentSelfApiViewSet.as_view({'get': 'retrieve'})
+        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)
diff --git a/core/urls.py b/core/urls.py
index 845578227821504d6eb67111ecf6ea7c33593140..7511c18649e358f4af225e18f74a4f1fa267faff 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -12,11 +12,15 @@ router.register(r'student', views.StudentReviewerApiViewSet)
 router.register(r'examtype', views.ExamApiViewSet)
 router.register(r'submissiontype', views.SubmissionTypeApiView)
 router.register(r'tutor', views.TutorApiViewSet)
-router.register(r'student-page', views.StudentSelfApiViewSet,
-                base_name='student_page')
+
+# regular views that are not viewsets
+regular_views_urlpatterns = [
+    url(r'student-page', views.StudentSelfApiView.as_view(), name='student-page')
+]
 
 urlpatterns = [
     url(r'^api/', include(router.urls)),
+    url(r'^api/', include(regular_views_urlpatterns)),
     url(r'^api-token-auth/', obtain_jwt_token),
     url(r'^api-token-refresh', refresh_jwt_token),
     url(r'^$', TemplateView.as_view(template_name='index.html')),
diff --git a/core/views.py b/core/views.py
index 563331875203a5312d98bbc74e4e5e5afa15ee40..ed932990555d678923b716a80c204fde4ebaf4ce 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,7 +1,7 @@
 """ All API views that are used to retrieve data from the database. They
 can be categorized by the permissions they require. All views require a
 user to be authenticated and most are only accessible by one user group """
-from rest_framework import mixins, viewsets
+from rest_framework import mixins, viewsets, generics
 
 from core.models import ExamType, Student, SubmissionType, Tutor
 from core.permissions import IsReviewer, IsStudent
@@ -10,10 +10,9 @@ from core.serializers import (ExamSerializer, StudentSerializer,
                               SubmissionTypeSerializer, TutorSerializer)
 
 
-class StudentSelfApiViewSet(viewsets.ReadOnlyModelViewSet):
+class StudentSelfApiView(generics.RetrieveAPIView):
     """ Gets all data that belongs to one student """
     permission_classes = (IsStudent,)
-    queryset = Student.objects.all()
     serializer_class = StudentSerializer
 
     def get_object(self) -> Student:
diff --git a/frontend/package.json b/frontend/package.json
index 9a8b2be5838dca92a043717b4fb8e678d35a8756..df857580b0d73ecbe6c26b4116cac54a204a78b6 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,6 +14,7 @@
   },
   "dependencies": {
     "axios": "^0.17.0",
+    "material-design-icons": "^3.0.1",
     "vue": "^2.5.2",
     "vue-router": "^3.0.1",
     "vuetify": "^0.17.3",
diff --git a/frontend/src/assets/logo.png b/frontend/src/assets/logo.png
deleted file mode 100644
index f3d2503fc2a44b5053b0837ebea6e87a2d339a43..0000000000000000000000000000000000000000
Binary files a/frontend/src/assets/logo.png and /dev/null differ
diff --git a/frontend/src/components/Login.vue b/frontend/src/components/Login.vue
index fddc17eecc103aa5bac87342fbd1e78fb165eca7..92e3a906c3de047889f2560f8a810089dd0d161a 100644
--- a/frontend/src/components/Login.vue
+++ b/frontend/src/components/Login.vue
@@ -49,7 +49,7 @@
     methods: {
       submit () {
         this.$store.dispatch('getJWTToken', this.credentials).then(response => {
-          this.$router.push('/reviewer/')
+          this.$router.push('/student/')
         }).catch(_ => {
           this.error = this.$store.state.error
         })
diff --git a/frontend/src/components/base/BaseLayout.vue b/frontend/src/components/base/BaseLayout.vue
new file mode 100644
index 0000000000000000000000000000000000000000..26d45fe79899e68ffbed62e44b68447a2a0205ff
--- /dev/null
+++ b/frontend/src/components/base/BaseLayout.vue
@@ -0,0 +1,87 @@
+<template>
+  <div>
+    <v-navigation-drawer
+      fixed
+      clipped
+      app
+      v-model="drawer"
+    >
+      <v-toolbar flat>
+        <v-list>
+          <v-list-tile>
+            <v-list-tile-title class="title">
+              {{ examInstance }}
+            </v-list-tile-title>
+          </v-list-tile>
+        </v-list>
+      </v-toolbar>
+      <v-list dense>
+        <v-list-tile v-for="(item, i) in navItems" :key="i" :to="item.route">
+          {{ item.name }}
+        </v-list-tile>
+      </v-list>
+    </v-navigation-drawer>
+    <v-toolbar
+      app
+      clipped-left
+      fixed
+      dark
+      color="indigo darken-4"
+      class="grady-toolbar"
+    >
+      <v-toolbar-title>
+        <v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
+        <v-avatar>
+          <img src="../../assets/brand.png">
+        </v-avatar>
+      </v-toolbar-title>
+      <span class="pl-2 grady-speak">{{ gradySpeak }}</span>
+      <div class="toolbar-content">
+        <span>{{ userRole }} | {{ username }}</span>
+      </div>
+      <v-btn color="blue darken-1" to="/" @click.native="logout">Logout</v-btn>
+    </v-toolbar>
+    <v-content>
+      <slot></slot>
+    </v-content>
+  </div>
+</template>
+
+<script>
+  import { mapActions, mapGetters, mapState } from 'vuex'
+  export default {
+    name: 'base-layout',
+    data () {
+      return {
+        drawer: true
+      }
+    },
+    props: ['navItems'],
+    computed: {
+      ...mapGetters([
+        'gradySpeak'
+      ]),
+      ...mapState([
+        'examInstance',
+        'username',
+        'userRole'
+      ])
+    },
+    methods: {
+      ...mapActions([
+        'logout'
+      ])
+    }
+  }
+</script>
+
+<style scoped>
+  .toolbar-content {
+    margin-left: auto;
+  }
+
+  .grady-toolbar {
+    font-weight: bold;
+  }
+
+</style>
diff --git a/frontend/src/components/student/StudentLayout.vue b/frontend/src/components/student/StudentLayout.vue
new file mode 100644
index 0000000000000000000000000000000000000000..105f55c30fcc3e4fedb75b4c262c1ca9cf54ecef
--- /dev/null
+++ b/frontend/src/components/student/StudentLayout.vue
@@ -0,0 +1,25 @@
+<template>
+  <base-layout
+    :navItems="navItems"
+  >
+    <slot></slot>
+  </base-layout>
+</template>
+
+<script>
+  import BaseLayout from '../base/BaseLayout'
+  export default {
+    components: {BaseLayout},
+    name: 'student-layout',
+    data () {
+      return {
+        navItems: [
+          {
+            name: 'Login',
+            route: '/'
+          }
+        ]
+      }
+    }
+  }
+</script>
diff --git a/frontend/src/components/student/StudentNav.vue b/frontend/src/components/student/StudentNav.vue
deleted file mode 100644
index 3b2484e9d207c8f3e87b8ff9d67eaaec93a1e4d9..0000000000000000000000000000000000000000
--- a/frontend/src/components/student/StudentNav.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-<template>
-  <v-navbar toggleable="md" type="light" variant="light">
-    <v-navbar-toggle target="nav_collapse"></v-navbar-toggle>
-
-    <v-navbar-brand>
-      <img src="../../assets/brand.png" width="30" class="d-inline-block align-top">
-      Grady
-    </v-navbar-brand>
-
-    <v-collapse is-nav id="nav_collapse">
-
-      <v-navbar-nav id="nav-left">
-        <v-nav-item class="active" href="#">Results</v-nav-item>
-        <v-nav-item href="#">Statistics</v-nav-item>
-      </v-navbar-nav>
-
-      <!-- Right aligned nav items -->
-      <v-navbar-nav class="ml-auto">
-        <v-nav-item>{{ this.$store.state.username }}</v-nav-item>
-        <router-link to="/">
-          <v-button class="btn-dark" @click="logout()" >Signout</v-button>
-        </router-link>
-      </v-navbar-nav>
-    </v-collapse>
-  </v-navbar>
-</template>
-
-
-<script>
-  export default {
-    name: 'grady-nav',
-    methods: {
-      logout () {
-        this.$store.dispatch('logout')
-      }
-    }
-  }
-</script>
diff --git a/frontend/src/components/student/StudentPage.vue b/frontend/src/components/student/StudentPage.vue
index b1e9249692fde918bbbfb6f48106301ed3fb62ef..686550e29f57f3f254c265fc81631b434c394ff5 100644
--- a/frontend/src/components/student/StudentPage.vue
+++ b/frontend/src/components/student/StudentPage.vue
@@ -1,25 +1,24 @@
 <template>
-  <div>
-    <grady-nav></grady-nav>
-    <div class="container-fluid">
-      <div class="row justify-content-center my-3">
-        <div class="col-md-3">
-          <h2 class="my-5">Exam Overview</h2>
+  <student-layout>
+    <v-container fluid>
+      <v-layout justify center>
+        <v-flex md3>
+          <h2>Exam Overview</h2>
           <exam-information v-if="doneLoading" :exam="exam"></exam-information>
-        </div>
-        <div class="col-md-6 offset-md-1" v-if="doneLoading">
-          <h2 class="my-5">Submissions of {{ this.studentData.name }}</h2>
+        </v-flex>
+        <v-flex md7 offset-md1 v-if="doneLoading">
+          <h2>Submissions of {{ this.studentData.name }}</h2>
           <submission-list :submissions="submissions"></submission-list>
-        </div>
-      </div>
-    </div>
-  </div>
+        </v-flex>
+      </v-layout>
+    </v-container>
+  </student-layout>
 </template>
 
 
 <script>
   import ax from '@/store/api'
-  import GradyNav from './StudentNav.vue'
+  import StudentLayout from './StudentLayout.vue'
   import SubmissionList from './SubmissionList.vue'
   import ExamInformation from './ExamInformation.vue'
 
@@ -27,7 +26,7 @@
     components: {
       ExamInformation,
       SubmissionList,
-      GradyNav},
+      StudentLayout},
     name: 'student-page',
     data () {
       return {
@@ -37,7 +36,7 @@
     },
     created: function () {
       this.doneLoading = false
-      ax.get('api/student/').then(response => {
+      ax.get('api/student-page/').then(response => {
         this.studentData = response.data
         this.doneLoading = true
       })
diff --git a/frontend/src/components/student/SubmissionDetail.vue b/frontend/src/components/student/SubmissionDetail.vue
new file mode 100644
index 0000000000000000000000000000000000000000..56f6dc744d9169b5681c63b9091a1b673c2c5852
--- /dev/null
+++ b/frontend/src/components/student/SubmissionDetail.vue
@@ -0,0 +1,10 @@
+<template>
+  <p>Test</p>
+</template>
+
+
+<script>
+  export default {
+    name: 'submission-detail'
+  }
+</script>
diff --git a/frontend/src/components/student/SubmissionList.vue b/frontend/src/components/student/SubmissionList.vue
index c39e745fc152cca06a50428cc0f9fe595b858230..6d0238b118813d39a12f97f97266b7485323839d 100644
--- a/frontend/src/components/student/SubmissionList.vue
+++ b/frontend/src/components/student/SubmissionList.vue
@@ -1,9 +1,19 @@
 <template>
   <div class="row my-2 justify-content-center">
-    <b-table hover :items="submissions" :fields="fields"></b-table>
-    <div class="alert alert-info">
-      You reached <b>{{ sumScore }}</b> of <b>{{ sumFullScore }}</b> possible points( {{ pointRatio }}% ).
-    </div>
+    <v-data-table
+      hide-actions
+      :headers="headers"
+      :items="submissions"
+    >
+      <template slot="items" slot-scope="props">
+        <td>{{ props.item.type }}</td>
+        <td class="text-xs-right">{{ props.item.score }}</td>
+        <td class="text-xs-right">{{ props.item.full_score }}</td>
+      </template>
+    </v-data-table>
+    <v-alert color="info" value="true">
+      You reached <b>{{ sumScore }}</b> of <b>{{ sumFullScore }}</b> possible points ( {{ pointRatio }}% ).
+    </v-alert>
   </div>
 </template>
 
@@ -13,6 +23,22 @@
     name: 'submission-list',
     data () {
       return {
+        headers: [
+          {
+            text: 'Task',
+            align: 'left',
+            value: 'type'
+          },
+          {
+            text: 'Score',
+            value: 'score'
+          },
+          {
+            text: 'Maximum Score',
+            value: 'full_score'
+          }
+        ],
+
         fields: [
           { key: 'type', sortable: true },
           { key: 'score', label: 'Score', sortable: true },
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 997422b82770d3b595a39127ea98f36215f9c98c..9a43b0eea0680622375f3caf543207d03cbc4a1e 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -7,6 +7,7 @@ import store from './store/store'
 import Vuetify from 'vuetify'
 
 import 'vuetify/dist/vuetify.min.css'
+import 'material-design-icons/iconfont/material-icons.css'
 
 Vue.use(Vuetify)
 
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index efb8236906d71e2dc99b1f2f5453851413f6988a..3e5f67cc59bb4ecb70ffb8ba3a9a94e3c2e4862b 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -2,8 +2,10 @@ import Vue from 'vue'
 import Router from 'vue-router'
 import Login from '@/components/Login'
 import StudentPage from '@/components/student/StudentPage'
+import SubmissionDetail from '@/components/student/SubmissionDetail'
 import ReviewerPage from '@/components/reviewer/ReviewerPage'
 import StudentListOverview from '@/components/reviewer/StudentListOverview'
+import BaseLayout from '@/components/base/BaseLayout'
 
 Vue.use(Router)
 
@@ -17,7 +19,14 @@ export default new Router({
     {
       path: '/student/',
       name: 'student-page',
-      component: StudentPage
+      component: StudentPage,
+      children: [
+        {
+          path: 'submission:id/',
+          component: SubmissionDetail
+        }
+      ]
+
     },
     {
       path: '/reviewer/',
@@ -28,6 +37,11 @@ export default new Router({
       path: 'reviewer/student-overview/',
       name: 'student-overview',
       component: StudentListOverview
+    },
+    {
+      path: '/base/',
+      name: 'base-layout',
+      component: BaseLayout
     }
   ]
 })
diff --git a/frontend/src/store/grady_speak.js b/frontend/src/store/grady_speak.js
new file mode 100644
index 0000000000000000000000000000000000000000..6ae7abba064d4c3f07922ad004073bea8baacbfc
--- /dev/null
+++ b/frontend/src/store/grady_speak.js
@@ -0,0 +1,25 @@
+const gradySays = [
+  'Now let\'s see if we can improve this with a little water, sir.',
+  'Won\'t keep you a moment, sir.',
+  'Grady, sir. Delbert Grady.',
+  'Yes, sir.',
+  'That\'s right, sir.',
+  'Why no, sir. I don\'t believe so.',
+  'Ah ha, it\'s coming off now, sir.',
+  'Why no, sir. I don\'t believe so.',
+  'Yes, sir.  I have a wife and two daughters, sir.',
+  'Oh, they\'re somewhere around.  I\'m not quite sure at the moment, sir.',
+  'That\'s strange, sir.  I don\'t have any recollection of that at all.',
+  'I\'m sorry to differ with you, sir, but you are the caretaker.',
+  'You have always been the caretaker, I should know, sir.',
+  'I\'ve always been here.',
+  'Indeed, he is, Mr. Torrance. A very willful boy. ',
+  'A rather naughty boy, if I may be so bold, sir.',
+  'Perhaps they need a good talking to, if you don\'t mind my saying so. Perhaps a bit more.',
+  'My girls, sir, they didn\'t care for the Overlook at first.',
+  'One of them actually stole a packet of matches and tried to burn it down.',
+  'But I corrected them, sir.',
+  'And when my wife tried to prevent me from doing my duty... I corrected her.'
+]
+
+export default gradySays
diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js
index 3eb032bf8effaf4fb5e4e2e69237d1c74fb588b7..9766bf89d1f78a8004278f201912618921eba887 100644
--- a/frontend/src/store/store.js
+++ b/frontend/src/store/store.js
@@ -2,26 +2,37 @@ import Vuex from 'vuex'
 import Vue from 'vue'
 import ax from './api'
 
+import gradySays from './grady_speak'
+
 Vue.use(Vuex)
 
 const store = new Vuex.Store({
   state: {
     token: '',
     loggedIn: false,
-    username: '',
-    error: ''
+    username: 'username',
+    userRole: 'Student',
+    error: '',
+    examInstance: 'B.Inf 1301 Kohorte 2'
+  },
+  getters: {
+    gradySpeak: state => {
+      return gradySays[Math.floor(Math.random() * gradySays.length)]
+    }
   },
   mutations: {
     'API_FAIL': function (state, error) {
       state.error = error
     },
-    'LOGIN': function (state, creds) {
-      state.token = creds.token
+    'SET_JWT_TOKEN': function (state, token) {
+      state.token = token
+      ax.defaults.headers.common['Authorization'] = 'JWT ' + token
+    },
+    'LOGIN': function (state, username) {
       state.loggedIn = true
-      state.username = creds.username
+      state.username = username
     },
     'LOGOUT': function (state) {
-      state.token = ''
       state.loggedIn = false
     }
   },
@@ -29,10 +40,8 @@ const store = new Vuex.Store({
     async getJWTToken (context, credentials) {
       try {
         const response = await ax.post('api-token-auth/', credentials)
-        context.commit('LOGIN', {
-          token: response.data.token,
-          username: credentials.username
-        })
+        context.commit('LOGIN', credentials.username)
+        context.commit('SET_JWT_TOKEN', response.data.token)
       } catch (error) {
         if (error.response) {
           const errorMsg = 'Unable to log in with provided credentials.'
@@ -47,6 +56,7 @@ const store = new Vuex.Store({
     },
     logout (store) {
       store.commit('LOGOUT')
+      store.commit('SET_JWT_TOKEN', '')
     }
   }
 })
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 7fac4471d3aef38b2a829c2ace79c724663298f8..e4ccbb2e378208009ccbf7e2e92e305fef76116a 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -3704,6 +3704,10 @@ map-obj@^1.0.0, map-obj@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
 
+material-design-icons@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/material-design-icons/-/material-design-icons-3.0.1.tgz#9a71c48747218ebca51e51a66da682038cdcb7bf"
+
 math-expression-evaluator@^1.2.14:
   version "1.2.17"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"