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/BaseLayout.vue b/frontend/src/components/BaseLayout.vue deleted file mode 100644 index 494bed866deee6680978fa15dc3b642642d8dd57..0000000000000000000000000000000000000000 --- a/frontend/src/components/BaseLayout.vue +++ /dev/null @@ -1,34 +0,0 @@ -<template> - <v-navigation-drawer - fixed - clipped - app - v-model="drawer" - > - <v-list dense v-for="(item, i) in items"> - <v-list-tile> - <router-link to="item.path" :key="i"></router-link> - </v-list-tile> - </v-list> - </v-navigation-drawer> -</template> - - -<script> - export default { - name: 'base-layout', - data () { - return { - drawer: true, - items: [ - { - path: 'grady-login' - } - ] - } - } - } -</script> - -<style> -</style> 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..e29bbc50aa024b5cb7b5d328afd8f1584b417399 --- /dev/null +++ b/frontend/src/components/base/BaseLayout.vue @@ -0,0 +1,68 @@ +<template> + <div> + <v-navigation-drawer + fixed + clipped + app + v-model="drawer" + > + <v-list dense> + <v-list-tile v-for="(item, i) in navItems" :key="i" :to="item.path"> + {{ item.name }} + </v-list-tile> + </v-list> + </v-navigation-drawer> + <v-toolbar + app + clipped-left + fixed + color="deep-orange darken-4" + class="grady-toolbar" + > + <v-toolbar-title> + <!--<v-toolbar-side-icon v-icon="fa-bars"></v-toolbar-side-icon>--> + <span @click.stop="drawer = !drawer">Icon</span> + <v-avatar> + <img src="../../assets/brand.png"> + </v-avatar> + </v-toolbar-title> + <span class="pl-2 grady-speak">{{ gradySpeak }}</span> + <h2 class="pl-5">{{ $store.state.examInstance }}</h2> + <div class="toolbar-content"> + <span>Logged in as {{ $store.state.username }}</span> + </div> + </v-toolbar> + <v-content> + <slot></slot> + </v-content> + </div> +</template> + +<script> + import { mapGetters } from 'vuex' + export default { + name: 'base-layout', + data () { + return { + drawer: true, + props: ['navItems'] + } + }, + computed: { + ...mapGetters([ + 'gradySpeak' + ]) + } + } +</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..e6704128720bf61956ba29d150ecc26109ba4609 --- /dev/null +++ b/frontend/src/components/student/StudentLayout.vue @@ -0,0 +1,22 @@ +<template> + <base-layout + + ></base-layout> +</template> + +<script> + import BaseLayout from '../base/BaseLayout' + export default { + components: {BaseLayout}, + name: 'student-layout', + data () { + return { + navItems: [ + { + 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..5a9e9a83bb648088213a7664db82d4103c639b07 100644 --- a/frontend/src/components/student/StudentPage.vue +++ b/frontend/src/components/student/StudentPage.vue @@ -1,25 +1,22 @@ <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> + <v-container fluid> + <v-layout justify center> + <v-flex md5> + <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> + <div md6 offset-md1 v-if="doneLoading"> + <h2>Submissions of {{ this.studentData.name }}</h2> <submission-list :submissions="submissions"></submission-list> </div> - </div> - </div> - </div> + </v-layout> + </v-container> </template> <script> import ax from '@/store/api' - import GradyNav from './StudentNav.vue' + import GradyNav from './StudentLayout.vue' import SubmissionList from './SubmissionList.vue' import ExamInformation from './ExamInformation.vue' @@ -37,7 +34,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/router/index.js b/frontend/src/router/index.js index 133fb7fc2cf2c79b320fe9e20a884f1612262eb9..3e5f67cc59bb4ecb70ffb8ba3a9a94e3c2e4862b 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -2,9 +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/BaseLayout' +import BaseLayout from '@/components/base/BaseLayout' Vue.use(Router) @@ -18,7 +19,14 @@ export default new Router({ { path: '/student/', name: 'student-page', - component: StudentPage + component: StudentPage, + children: [ + { + path: 'submission:id/', + component: SubmissionDetail + } + ] + }, { path: '/reviewer/', diff --git a/frontend/src/store/grady_speak.js b/frontend/src/store/grady_speak.js new file mode 100644 index 0000000000000000000000000000000000000000..9c8e1952ddc1910770a617a7060a20d5668e3bda --- /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. Avery 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..fe3e31c4d2218d08221ff07c1bac87e9a6feec2e 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -2,6 +2,8 @@ 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({ @@ -9,19 +11,27 @@ const store = new Vuex.Store({ token: '', loggedIn: false, username: '', - error: '' + 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 +39,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 +55,7 @@ const store = new Vuex.Store({ }, logout (store) { store.commit('LOGOUT') + store.commit('SET_JWT_TOKEN', '') } } })