Add list of user-generated closed-ended questions
This commit is contained in:
68
components/ClosedEndedQuestionsList.vue
Normal file
68
components/ClosedEndedQuestionsList.vue
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<v-data-table
|
||||||
|
:headers="headers"
|
||||||
|
:items="questions"
|
||||||
|
:items-per-page.sync="itemsPerPage"
|
||||||
|
:sort-by="sortBy"
|
||||||
|
:sort-desc="sortDesc"
|
||||||
|
no-data-text="Keine Daten vorhanden"
|
||||||
|
no-results-text="Keine passenden Ergebnisse gefunden"
|
||||||
|
locale="de-DE"
|
||||||
|
:footer-props="{ itemsPerPageOptions: itemsPerPageArray, itemsPerPageText: 'Fragen pro Seite'}"
|
||||||
|
>
|
||||||
|
<!-- eslint-disable-next-line vue/valid-v-slot -->
|
||||||
|
<template #item.created="{ item }">
|
||||||
|
{{ new Date(item.created * 1000).toLocaleDateString('de-DE') }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- eslint-disable-next-line vue/valid-v-slot -->
|
||||||
|
<template #item.status="{ item }">
|
||||||
|
<v-icon :color="getStatusIcon(item.status).color">{{ getStatusIcon(item.status).icon }}</v-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- eslint-disable-next-line -->
|
||||||
|
<template #footer.page-text="{ pageStart, pageStop, itemsLength }">
|
||||||
|
<span>{{ pageStart }}-{{ pageStop }} von {{ itemsLength }}</span>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { states } from '~/plugins/closed-ended-question'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'OpenEndedQuestionsList',
|
||||||
|
props: {
|
||||||
|
questions: {
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
headers: [
|
||||||
|
{ text: 'Hinzugefügt', value: 'created', width: 1, class: 'text-no-wrap' },
|
||||||
|
{ text: 'Status', value: 'status', width: 1, class: 'text-no-wrap' },
|
||||||
|
{
|
||||||
|
text: 'Frage',
|
||||||
|
sortable: false,
|
||||||
|
value: 'question',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
itemsPerPageArray: [10, 25, 50],
|
||||||
|
itemsPerPage: 10,
|
||||||
|
sortBy: 'created',
|
||||||
|
sortDesc: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getStatusIcon (status) {
|
||||||
|
switch(status) {
|
||||||
|
case states.approved: return { icon: 'mdi-check', color: 'success' }
|
||||||
|
case states.declined: return { icon: 'mdi-close', color: 'error' }
|
||||||
|
default: return { icon: 'mdi-timer-sand', color: '' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -71,7 +71,18 @@
|
|||||||
Neue Quizfrage einreichen
|
Neue Quizfrage einreichen
|
||||||
</v-expansion-panel-header>
|
</v-expansion-panel-header>
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<AddClosedEndedQuestion />
|
<v-tabs v-model="tab" color="primary">
|
||||||
|
<v-tab>Neue Frage</v-tab>
|
||||||
|
<v-tab>Meine Fragen</v-tab>
|
||||||
|
</v-tabs>
|
||||||
|
<v-tabs-items v-model="tab" style="background-color: transparent !important;">
|
||||||
|
<v-tab-item>
|
||||||
|
<AddClosedEndedQuestion />
|
||||||
|
</v-tab-item>
|
||||||
|
<v-tab-item>
|
||||||
|
<ClosedEndedQuestionsList :questions="userQuestions" />
|
||||||
|
</v-tab-item>
|
||||||
|
</v-tabs-items>
|
||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</v-expansion-panels>
|
</v-expansion-panels>
|
||||||
@@ -81,23 +92,23 @@
|
|||||||
<script>
|
<script>
|
||||||
import { collection, query, where, orderBy, limit, getDocs } from 'firebase/firestore'
|
import { collection, query, where, orderBy, limit, getDocs } from 'firebase/firestore'
|
||||||
import { GameConverter } from '~/plugins/game'
|
import { GameConverter } from '~/plugins/game'
|
||||||
|
import { ClosedEndedQuestionConverter } from '~/plugins/closed-ended-question'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'QuizComponent',
|
name: 'QuizComponent',
|
||||||
props: {
|
|
||||||
courseId: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
openGames: [],
|
openGames: [],
|
||||||
completedGames: [],
|
completedGames: [],
|
||||||
expPanel: 0
|
userQuestions: [],
|
||||||
|
expPanel: 0,
|
||||||
|
tab: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
courseId () {
|
||||||
|
return this.$store.state.selectedCourse
|
||||||
|
},
|
||||||
games () {
|
games () {
|
||||||
return this.$store.state.user.games[this.courseId]
|
return this.$store.state.user.games[this.courseId]
|
||||||
},
|
},
|
||||||
@@ -114,6 +125,15 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
tab (val) {
|
||||||
|
// Get the user's own questions from the db the
|
||||||
|
// first time they switch to the "My Questions" tab.
|
||||||
|
if (val === 1/* && this.userQuestions.length === 0 */) {
|
||||||
|
this.getUserQuestions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
// Get list of unfinished games from db
|
// Get list of unfinished games from db
|
||||||
this.getOpenGames()
|
this.getOpenGames()
|
||||||
@@ -158,8 +178,25 @@ export default {
|
|||||||
this.$toast({ content: error, color: 'error' })
|
this.$toast({ content: error, color: 'error' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getUserQuestions () {
|
||||||
|
const q = query(
|
||||||
|
collection(this.$db, `kurse/${this.courseId}/fragenGeschlossen`).withConverter(ClosedEndedQuestionConverter),
|
||||||
|
where('ersteller', '==', this.$auth.currentUser.uid)
|
||||||
|
)
|
||||||
|
|
||||||
|
getDocs(q).then((querySnapshot) => {
|
||||||
|
const questions = []
|
||||||
|
querySnapshot.forEach((doc) => {
|
||||||
|
// doc.data() is never undefined for query doc snapshots
|
||||||
|
questions.push(doc.data())
|
||||||
|
})
|
||||||
|
this.userQuestions = questions
|
||||||
|
}).catch((error) => {
|
||||||
|
// Query failed; display error message
|
||||||
|
this.$toast({ content: error, color: 'error' })
|
||||||
|
})
|
||||||
|
},
|
||||||
playVersus () {
|
playVersus () {
|
||||||
// TODO
|
|
||||||
this.$router.push(`${this.$route.path}/play`)
|
this.$router.push(`${this.$route.path}/play`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user