Skip to content
Snippets Groups Projects
Commit 54474602 authored by robinwilliam.hundt's avatar robinwilliam.hundt
Browse files

More experimental work on layout

Added BaseLayout component that will serve as bas for the layout of the app. It is modeled after https://next.vuetifyjs.com/examples/layouts/google-contacts . The gradySpeak has been moved to the front-end.
parent 5195b842
No related branches found
No related tags found
2 merge requests!23Resolve "Logout of tutors after inactivity",!22WIP: Started work on navigation and layout
Pipeline #
frontend/src/assets/logo.png

6.69 KiB

<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>
......@@ -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
})
......
<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>
<template>
<base-layout
></base-layout>
</template>
<script>
import BaseLayout from '../base/BaseLayout'
export default {
components: {BaseLayout},
name: 'student-layout',
data () {
return {
navItems: [
{
route: '/'
}
]
}
}
}
</script>
<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>
<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
})
......
<template>
<p>Test</p>
</template>
<script>
export default {
name: 'submission-detail'
}
</script>
......@@ -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/',
......
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
......@@ -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', '')
}
}
})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment