Refactor: layout

This commit is contained in:
2022-11-03 15:32:22 +01:00
parent fe7d3d98b0
commit dba0ab3e23
8 changed files with 100 additions and 62 deletions

View File

@@ -52,7 +52,7 @@ import { collection, doc, addDoc, writeBatch } from 'firebase/firestore'
// https://vee-validate.logaretm.com/v3/guide/basics.html // https://vee-validate.logaretm.com/v3/guide/basics.html
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate' import { ValidationProvider, ValidationObserver, extend } from 'vee-validate'
import { required } from 'vee-validate/dist/rules' import { required } from 'vee-validate/dist/rules'
import { ClosedEndedQuestion, ClosedEndedQuestionConverter } from '~/plugins/closed-ended-question' import { ClosedEndedQuestion, ClosedEndedQuestionConverter, states } from '~/plugins/closed-ended-question'
// Override the default error message of required fields // Override the default error message of required fields
extend('required', { extend('required', {
@@ -75,6 +75,11 @@ export default {
} }
}, },
methods: { methods: {
isAuthorized () {
const isTutor = this.$auth.currentUser.email.endsWith('@iu.org')
const isAdmin = this.$store.getters.isAdmin
return isTutor || isAdmin
},
submit () { submit () {
this.loading = true this.loading = true
@@ -86,14 +91,17 @@ export default {
this.$auth.currentUser.uid, // Ref: https://firebase.google.com/docs/reference/js/v8/firebase.User this.$auth.currentUser.uid, // Ref: https://firebase.google.com/docs/reference/js/v8/firebase.User
Date.now() / 1000, // Current UNIX timestamp in seconds Date.now() / 1000, // Current UNIX timestamp in seconds
this.comment ? [this.comment] : [], this.comment ? [this.comment] : [],
'neu' this.isAuthorized() ? states.approved : states.new
) )
// Add a new document with a generated id // Add a new document with a generated id
addDoc(collection(this.$db, `kurse/${this.$store.state.selectedCourse}/fragenGeschlossen`).withConverter(ClosedEndedQuestionConverter), q) addDoc(collection(this.$db, `kurse/${this.$store.state.selectedCourse}/fragenGeschlossen`).withConverter(ClosedEndedQuestionConverter), q)
.then((docRef) => { .then((docRef) => {
// Successfully added new question to database // Successfully added new question to database
this.$toast({ content: 'Deine Frage wurde eingereicht!', color: 'success' }) const content = this.isAuthorized()
? 'Die Frage wurde hinzugefügt!'
: 'Deine Frage wurde eingereicht und wartet auf Bestätigung durch den Tutor!'
this.$toast({ content, color: 'success' })
}) })
.catch((error) => { .catch((error) => {
// Failed to add question to database; display error message // Failed to add question to database; display error message
@@ -131,7 +139,7 @@ export default {
this.$auth.currentUser.uid, // Ref: https://firebase.google.com/docs/reference/js/v8/firebase.User this.$auth.currentUser.uid, // Ref: https://firebase.google.com/docs/reference/js/v8/firebase.User
Date.now() / 1000, // Current UNIX timestamp in seconds Date.now() / 1000, // Current UNIX timestamp in seconds
[], [],
'genehmigt' states.approved
) )
const questionRef = doc(collection(this.$db, `kurse/${this.$store.state.selectedCourse}/fragenGeschlossen`).withConverter(ClosedEndedQuestionConverter)) const questionRef = doc(collection(this.$db, `kurse/${this.$store.state.selectedCourse}/fragenGeschlossen`).withConverter(ClosedEndedQuestionConverter))

35
components/Challenge.vue Normal file
View File

@@ -0,0 +1,35 @@
<template>
<v-container fluid>
<v-subheader class="text-h5 text--primary">Challenge</v-subheader>
<v-divider></v-divider>
<v-btn depressed color="success" class="my-3" @click="playVersus">
<v-icon left>mdi-play</v-icon>
Quiz Spielen
</v-btn>
<AddClosedEndedQuestion />
</v-container>
</template>
<script>
export default {
name: 'ChallengeComponent',
props: {
courseId: {
type: String,
required: true
}
},
data () {
return {
}
},
created () {
},
methods: {
playVersus () {
// TODO
this.$router.push(`${this.$route.path}/play`)
}
}
}
</script>

View File

@@ -1,5 +1,8 @@
<template> <template>
<v-expansion-panels> <v-container fluid>
<v-subheader class="text-h5 text--primary">Offene Fragen</v-subheader>
<v-divider></v-divider>
<v-expansion-panels focusable class="my-3">
<v-expansion-panel <v-expansion-panel
v-for="(item, i) in questions" v-for="(item, i) in questions"
:key="i" :key="i"
@@ -12,6 +15,8 @@
</v-expansion-panel-content> </v-expansion-panel-content>
</v-expansion-panel> </v-expansion-panel>
</v-expansion-panels> </v-expansion-panels>
<AddOpenEndedQuestion />
</v-container>
</template> </template>
<script> <script>
@@ -21,7 +26,7 @@ import { OpenEndedQuestionConverter } from '~/plugins/open-ended-question'
export default { export default {
name: 'CoopComponent', name: 'CoopComponent',
props: { props: {
courseID: { courseId: {
type: String, type: String,
required: true required: true
} }
@@ -37,7 +42,7 @@ export default {
methods: { methods: {
getQuestions () { getQuestions () {
// Create a reference to the open-ended questions collection of the currently selected course // Create a reference to the open-ended questions collection of the currently selected course
const questionsRef = collection(this.$db, `kurse/${this.courseID}/fragenOffen`).withConverter(OpenEndedQuestionConverter) const questionsRef = collection(this.$db, `kurse/${this.courseId}/fragenOffen`).withConverter(OpenEndedQuestionConverter)
// Execute the query // Execute the query
getDocs(questionsRef).then((querySnapshot) => { getDocs(questionsRef).then((querySnapshot) => {

View File

@@ -3,9 +3,9 @@
<template> <template>
<v-dialog v-model="show" width="500"> <v-dialog v-model="show" width="500">
<template #activator="{ on, attrs }"> <template #activator="{ on, attrs }">
<v-btn fixed top left dark color="red lighten-2" v-bind="attrs" v-on="on"> <v-btn fixed top dark color="red lighten-2" :style="{left: '50%', transform:'translateX(-50%)'}" v-bind="attrs" v-on="on">
<v-icon left>mdi-alert-circle-outline</v-icon> <v-icon left>mdi-alert-circle-outline</v-icon>
Demo-Account Info Mit Demo-Account Anmelden
</v-btn> </v-btn>
</template> </template>
<v-card elevation="12" class="mx-auto"> <v-card elevation="12" class="mx-auto">
@@ -44,7 +44,6 @@
<script> <script>
import { signInWithEmailAndPassword } from 'firebase/auth' import { signInWithEmailAndPassword } from 'firebase/auth'
export const demoAccounts = ['max.muster.test@iubh-fernstudium.de', 'tutor.test@iu.org', 'admin.test@iu.org']
export default { export default {
data () { data () {

View File

@@ -1,10 +1,5 @@
<template> <template>
<v-container fluid fill-height> <v-container fluid fill-height>
<v-row>
<v-col cols="12">
<span class="text-h4">{{ title }}</span>
</v-col>
</v-row>
<NuxtChild /> <NuxtChild />
</v-container> </v-container>
</template> </template>
@@ -16,20 +11,8 @@ export default {
courseID: undefined courseID: undefined
} }
}, },
computed: {
title () {
const courseName = this.$store.getters.getCourseByID(this.courseID).name
return `${this.courseID.toUpperCase()} - ${courseName}`
}
},
created () { created () {
this.courseID = this.$route.params.course this.courseID = this.$route.params.course
} }
} }
</script> </script>
<style>
.tete {
flex: 1 1 auto;
}
</style>

View File

@@ -1,20 +1,23 @@
<template> <template>
<v-container fluid class="pa-0">
<v-sheet class="rounded-lg pa-2">
<span class="text-h4 text--secondary">{{ courseID.toUpperCase() }}</span>
<span class="text-h4">{{ $store.getters.getCourseByID(courseID).name }}</span>
</v-sheet>
<v-container> <v-container>
<v-row> <v-row>
<v-col cols="auto"> <v-col v-if="isAuthorized" cols="12">
<v-btn depressed color="primary" @click="playVersus">Challenge Mode</v-btn> <TutorPanel :course-id="courseID" />
</v-col> </v-col>
<v-col cols="12"> <v-col cols="12">
<Coop :courseID="courseID" /> <Challenge :course-id="courseID" />
</v-col> </v-col>
<v-col cols="12"> <v-col cols="12">
<AddClosedEndedQuestion /> <Coop :course-id="courseID" />
</v-col>
<v-col cols="12">
<AddOpenEndedQuestion />
</v-col> </v-col>
</v-row> </v-row>
</v-container> </v-container>
</v-container>
</template> </template>
<script> <script>
@@ -26,15 +29,14 @@ export default {
} }
}, },
computed: { computed: {
isAuthorized () {
const isTutor = this.$auth.currentUser.email.endsWith('@iu.org')
const isAdmin = this.$store.getters.isAdmin
return isTutor || isAdmin
}
}, },
created () { created () {
this.courseID = this.$route.params.course this.courseID = this.$route.params.course
},
methods: {
playVersus () {
// TODO
this.$router.push(`${this.$route.path}/play`)
}
} }
} }
</script> </script>

View File

@@ -41,7 +41,7 @@ import {
import _sampleSize from 'lodash-es/sampleSize' import _sampleSize from 'lodash-es/sampleSize'
import _shuffle from 'lodash-es/shuffle' import _shuffle from 'lodash-es/shuffle'
import _capitalize from 'lodash-es/capitalize' import _capitalize from 'lodash-es/capitalize'
import { ClosedEndedQuestionConverter } from '~/plugins/closed-ended-question' import { ClosedEndedQuestionConverter, states } from '~/plugins/closed-ended-question'
import { Game, GameConverter } from '~/plugins/game' import { Game, GameConverter } from '~/plugins/game'
export default { export default {
@@ -101,7 +101,7 @@ export default {
// Create a query against the collection. // Create a query against the collection.
// Only questions with the status "approved" (=genehmigt) should be fetched from the database // Only questions with the status "approved" (=genehmigt) should be fetched from the database
const q = query(questionsRef, where('status', '==', 'genehmigt')) const q = query(questionsRef, where('status', '==', states.approved))
// Execute the query // Execute the query
return getDocs(q).then((querySnapshot) => { return getDocs(q).then((querySnapshot) => {

View File

@@ -11,6 +11,12 @@ export class ClosedEndedQuestion {
} }
} }
export const states = {
new: 'neu',
approved: 'genehmigt',
declined: 'abgelehnt'
}
// Firestore data converter // Firestore data converter
export const ClosedEndedQuestionConverter = { export const ClosedEndedQuestionConverter = {
toFirestore: (closedEndedQuestion) => { toFirestore: (closedEndedQuestion) => {