Skip to content
Snippets Groups Projects
Commit 6d1acdde authored by Kristiane Skogvang Kolshus's avatar Kristiane Skogvang Kolshus
Browse files

Merge branch 'frontend-quiz-api-req' into 'main'

Frontend quiz api req

See merge request !23
parents 22829f0c 37e04a20
No related branches found
No related tags found
1 merge request!23Frontend quiz api req
Pipeline #268846 passed
Showing
with 954 additions and 119 deletions
//methods for constructing Quiz and Question-objects. Maybe instead do this in api service?
//JSON to quiz-object(s)
//JSON to question-object(s)
//quiz-object to JSON
//question-object to JSON
//quiz questions: gets questionIds, send this to questionCards?
//Later: splitting into packages
/**
QuizDTO:
Integer id;
String title;
List<Integer> questionIds;
Integer creatorId;
QuizCategory category;
QuizDifficulty difficulty;
*/
<script>
import { RouterLink, RouterView } from 'vue-router';
import router from "@/router/index.js";
import { useRouter } from 'vue-router';
export default {
props: {
answerId: {
type: Number,
required: true,
},
answer: {
type: String,
required: true,
},
correct: {
type: Boolean,
required: false
}
},
methods: {
deleteAnswer() {
}
}
}
</script>
<template>
<div class="question-wrapper">
<h3>{{answer}}</h3>
<div class="quiz-footer">
<button @click="deleteAnswer" class="delete-btn">Delete</button>
</div>
</div>
</template>
<style>
.overViewQuestion-page{
padding: 50px;
}
.quiz-header{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.quiz-body{
margin-bottom: 40px;
}
.question-wrapper {
display: flex;
width: 80%;
justify-content: space-between;
}
.quiz-footer{
display: flex;
justify-content: space-evenly;
align-items: center;
padding-left: 25px;
padding-right: 25px;
}
</style>
\ No newline at end of file
<script>
/*
<script setup>
const props = defineProps({
show: Boolean
})*/
export default {
props: {
questionId: {
type: Number,
required: true
}
},
mounted() {
//APi req
},
data() {
return {
questionText: '',
correctIndex: 0,
answers: [
{answerId: 0, answer: 'first answer', correct: true},
{answerId: 1, answer: 'second answer', correct: false},
{answerId: 2, answer: 'third answer', correct: false}
]
}
},
methods: {
closeModal() {
this.$emit('close');
},
newAnswer() {
//default: not correct!
},
}
};
</script>
<template>
<div class="modal-overlay" @click="closeModal">
<div @click.stop class="modal-mask">
<div class="modal-container">
<div class="question-title">
<h3>Question: </h3>
<input v-model="questionText" placeholder="Type your question here">
</div>
<div class="modal-body">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Answer</th>
<th scope="col">Correct ?</th>
</tr>
</thead>
<tbody>
<tr v-for="answer in answers">
<th scope="row">{{answer.answer}}</th>
<td>
<input type="text" v-model="answer.answer" id="questionInput">
</td>
<td>
<input :checked="answer.correct_answer === 1" class="form-check-input" :value="answer.id" @change="handleRadioToggle(answer.id)" type="radio">
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
default footer
<button
class="modal-default-button"
@click="$emit('close')">
OK
</button>
</div>
</div>
</div>
</div>
<!--
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default header</slot>
</div>
<div class="modal-body">
<slot name="body">default body</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button
class="modal-default-button"
@click="$emit('close')"
>OK</button>
</slot>
</div>
</div>
</div>
</Transition>
-->
</template>
<style>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}
.modal-container {
width: 500px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}
.question-title {
display: flex;
justify-content: space-between;
}
.modal-header h5 {
margin-top: 0;
color: #363636;
}
.modal-body {
margin: 20px 0;
}
.modal-default-button {
float: right;
}
.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>
\ No newline at end of file
<script setup>
const props = defineProps({
show: Boolean
<script>
import {apiClient} from "@/api.js";
export default {
props: {
quizId: {
type: Number,
required: true
}
},
data() {
return {
questionText: '',
answers: [{ text: '', correct: false }],
correctAnswerIndex: 0,
type: 'MC',
score: 0,
correctAnswer: null,
errorMsg: ''
}
},
methods: {
//TODO: error prevention/handling
async handleSubmit() {
try {
this.findCorrectAnswer();
await apiClient.post('/questions', {
quizId: this.quizId,
questionText: this.questionText,
type: this.type,
answer: this.correctAnswer,
options: this.answers.map(answer => answer.text), //just the strings!
score: this.score
//add questionId to questions in editQuiz!
})
} catch (error) {
this.errorMsg = 'Error signing up';
}
},
closeModal() {
this.$emit('close');
},
newAnswer() {
this.answers.push({ text: '', correct: false });
},
findCorrectAnswer(){
if (this.correctAnswerIndex !== null && this.answers[this.correctAnswerIndex]) {
this.correctAnswer = this.answers[this.correctAnswerIndex].text;
}
}
}
};
</script>
<template>
<div class="modal-overlay" @click="closeModal">
<div @click.stop class="modal-mask">
<div class="modal-container">
<form @submit.prevent="handleSubmit">
<div class="question-title">
<h3>Question:</h3>
<input v-model="questionText" placeholder="Type your question here">
<label>Score:</label>
<input type="number" id="scoreInput" v-model="score">
</div>
<div class="modal-body">
<!--
<AnswerCard answer-id="answerCard" v-for="answer in answers"
:key="answer.id" :answerId="answer.id" :answer="answer.answer" :correct="answer.correct"/>
-->
<table class="table">
<thead>
<tr>
<th scope="col">Answer</th>
<th scope="col">Correct ?</th>
</tr>
</thead>
<tbody>
<tr v-for="(answer, index) in answers">
<td><input type="text" v-model="answer.text"></td>
<td>
<input type="radio" :id="'correctAnswer_' + index" :value="index" v-model="correctAnswerIndex">
<label :for="'correctAnswer_' + index">Correct</label>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button class="edit-btn" @click="newAnswer">Add answer</button>
<button class="modal-default-button" @click="$emit('close')">SUBMIT</button>
</div>
</form>
</div>
</div>
</div>
<!--
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
......@@ -28,6 +121,7 @@ const props = defineProps({
</div>
</div>
</Transition>
-->
</template>
<style>
......@@ -53,6 +147,14 @@ const props = defineProps({
transition: all 0.3s ease;
}
.question-title {
display: flex;
justify-content: space-between;
}
.modal-header h5 {
margin-top: 0;
color: #363636;
......
<script>
import { RouterLink, RouterView } from 'vue-router';
import router from "@/router/index.js";
import { useRouter } from 'vue-router';
import EditQuestionModel from "@/components/shared/EditQuestionModel.vue";
export default {
components: {EditQuestionModel},
props: {
questionId: {
type: Number,
required: true,
}
},
mounted() {
//API req, get question from id
},
data() {
return {
showEditQuestion: false,
questionNum: 0,
question: 'question text'
}
},
methods: {
deleteQuestion() {
//API req, delete question
},
editQuestion() {
this.showEditQuestion = true;
console.log(this.showEditQuestion);
},
hideEditQuestion() {
this.showEditQuestion = false;
//TODO: update answers, +answer count
}
}
}
</script>
<template>
<div class="question-wrapper">
<h4>{{questionId}}</h4>
<h3>{{question}}</h3>
<div class="quiz-footer">
<button @click="editQuestion" class="edit-btn">Edit</button>
<button @click="deleteQuestion" class="delete-btn">Delete</button>
</div>
<EditQuestionModel :question-id=questionId v-if="this.showEditQuestion" @close="hideEditQuestion"/>
</div>
</template>
<style>
.overViewQuestion-page{
padding: 50px;
}
.quiz-header{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.quiz-body{
margin-bottom: 40px;
}
.question-wrapper {
display: flex;
width: 80%;
justify-content: space-between;
}
.quiz-footer{
display: flex;
justify-content: space-evenly;
align-items: center;
padding-left: 25px;
padding-right: 25px;
}
</style>
\ No newline at end of file
<script>
import router from "@/router/index.js";
import {apiClient} from "@/api.js";
export default {
props: {
quizId: {
type: Number,
required: true,
}
},
data() {
return {
quizTitle: null,
quizDifficulty: null,
quizCategory: null
}
},
mounted() {
this.getQuiz();
},
methods: {
async getQuiz() {
console.log('Fetching data for quiz: ', this.quizId);
try {
await apiClient.get('/quiz/quiz/' + this.quizId).then(response => {
this.quizTitle = JSON.parse(response.data.title);
this.category = JSON.parse(response.data.category);
this.difficulty = JSON.parse(response.data.difficulty);
});
} catch (error) {
//TODO: proper error handling
this.errorMsg = 'Error retrieving quizzes';
}
},
//link to pages, play quiz, edit, delete, with quizId
playQuiz() {
//create new router-method to playQuiz, using quizId
router.push({name: 'playQuiz', params: {quizId: this.quizId}});
},
editQuiz() {
//create new router-method to editQuiz, using quizId
router.push({name: 'editQuiz', params: {quizId: this.quizId}});
},
}
}
</script>
<template>
<div class="course-col">
<div class="quiz-header">
<h3>{{ quizTitle }}</h3>
<!--
<Svg :name="selectedIcon" />
-->
</div>
<div class="quiz-body">
<p>{{ quizDifficulty }}</p>
<p>{{ quizCategory }}</p>
</div>
<div class="quiz-footer">
<button @click="playQuiz" class="play-btn">Play</button>
<button @click="editQuiz" class="edit-btn">Edit</button>
</div>
</div>
</template>
<style>
.overViewQuestion-page{
padding: 50px;
}
.quiz-header{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.quiz-body{
margin-bottom: 40px;
}
.quiz-footer{
display: flex;
justify-content: space-evenly;
align-items: center;
padding-left: 25px;
padding-right: 25px;
}
</style>
\ No newline at end of file
export const categoryEnums = [
'BUSINESS',
'ART',
'COMPUTER_SCIENCE',
'CULTURE_AND_TRADITIONS',
'FINANCE',
'GENERAL_KNOWLEDGE',
'GEOGRAPHY',
'HISTORY',
'LANGUAGES',
'LAW',
'MATH',
'MUSIC',
'SCIENCE',
'SEASONAL',
'SOCIAL_EMOTIONAL_LEARNING',
'SOCIAL_STUDIES',
'TRIVIA'
];
\ No newline at end of file
export const difficultyEnums = [
'EASY',
'MEDIUM',
'HARD'
]
\ No newline at end of file
export default class Question {
constructor(questionId, quizId, score, questionText, answers) {
this.questionId = questionId;
this.quizId = quizId;
this.score = score;
this.questionText = questionText;
this.answers = answers;
}
}
//method for parsing JSON to question-objects, and opposite? Perhaps better to delegate to a JSON parsing class
\ No newline at end of file
export default class Quiz {
constructor(quizId, title, creatorId, questions, category, difficulty) {
this.quizId = quizId;
this.title = title;
this.creatorId = creatorId;
this.questions = questions;
this.category = category;
this.difficulty = difficulty;
}
}
/**
QuizDTO:
Integer id;
String title;
List<Integer> questionIds;
Integer creatorId;
QuizCategory category;
QuizDifficulty difficulty;
*/
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import EditQuizView from "@/views/EditQuizView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
......@@ -37,7 +38,7 @@ const router = createRouter({
{
path: '/createQuiz',
name: 'create Quiz',
component: () => import('../views/EditQuizView.vue')
component: () => import('../views/NewQuizView.vue')
},
{
path: '/overviewQuiz',
......@@ -45,9 +46,16 @@ const router = createRouter({
component: () => import('../views/OverviewQuizView.vue')
},
{
path: '/play-quiz',
path: '/play-quiz/:quizId',
name: 'playQuiz',
component: () => import('../views/PlayQuizView.vue')
component: () => import('../views/PlayQuizView.vue'),
params: true
},
{
path: '/edit-quiz/:quizId',
name: 'editQuiz',
component: EditQuizView,
params: true
},
]
})
......
import {apiClient} from "@/api.js";
export const getToken = () => {
return localStorage.getItem('token');
}
......@@ -9,3 +11,8 @@ export const setToken = (token) => {
export const removeToken = () => {
localStorage.removeItem('token');
}
export const getIdByToken= () => {
//TODO: set up encryption and getID
return apiClient.get('/user/getId/' + getToken());
}
\ No newline at end of file
<script setup>
<script>
import NewQuestionModel from "@/components/shared/NewQuestionModel.vue";
import {ref} from "vue";
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import router from "@/router/index.js";
import {apiClient} from "@/api.js";
import QuestionCard from "@/components/shared/QuestionCard.vue";
/**
const quizId = ref(null); //TODO: set quiz id when routing here
const createdQuestion = ref(null);
const newAnswers = ref([]);
const showNewQuestionModal = ref(false);
let showNewQuestionModal = ref(false);
const selectedAnswer = ref(null);
const existingQuestions = ref([]);
let answerId = 1;
const errorMsg = ''; //TODO: display error to user
const quizName = ref('');
const errorMsg = ''; //TODO: display error to user*/
//send list of question-ids?
export default {
components: {NewQuestionModel, QuestionCard},
data() {
return {
showNewQuestion: false,
creatorId: null,
quizId: null,
quizTitle: '',
questions: [], //question list is just a list of q-ids!!
category: '',
difficulty: '',
errorMsg: ''
//TODO: make quiz object
};
},
mounted() {
this.quizId = this.$route.params.quizId;
this.getQuiz(this.quizId);
},
methods: {
getQuiz(quizId) {
console.log('Fetching data for quiz: ', quizId);
try {
apiClient.get('/quiz/quiz/' + this.quizId).then(response => {
this.quizTitle = JSON.parse(response.data.title);
this.questions = JSON.parse(JSON.stringify(response.data.questions));
this.creatorId = JSON.parse(response.data.creatorId);
this.category = JSON.parse(response.data.category);
this.difficulty = JSON.parse(response.data.difficulty);
});
} catch (error) {
//TODO: proper error handling
this.errorMsg = 'Error retrieving quizzes';
}
},
newQuestion() {
this.showNewQuestion = true;
console.log(this.showNewQuestion);
},
hideNewQuestion() {
this.showNewQuestion = false;
//TODO: questions answers, +question count
},
deleteQuiz() {
//API req, quizId
}
},
};
/**
function createQuestion() {
showNewQuestionModal.value = true;
}
function destroyModal() {
showNewQuestionModal.value = false;
}
function addNewAnswers() {
const newAnswer = {
id: answerId++,
......@@ -38,8 +93,9 @@ function handleRadioToggle(Id) {
answer.correct_answer = 0
}
})
}
}*/
/**
function validateAnswers() {
for(const answer of newAnswers.value) {
if(answer.answer.trim()==='') {
......@@ -55,7 +111,7 @@ function answerCount() {
return true
}
}
/*
async function getExistingQuestions() {
try {
const response = await apiClient.get(`/quizzes/${quizId.value}/questions`); // Fetch questions for a specific quiz
......@@ -66,7 +122,9 @@ async function getExistingQuestions() {
alert('An error occurred while fetching existing questions');
}
}
*/
/**
async function submitQuestion() {
//TODO: proper error handling
if(!createdQuestion.value){
......@@ -90,15 +148,21 @@ async function submitQuestion() {
this.errorMsg = 'Error logging in';
}
}
*/
</script>
<template>
<body>
<div class="createQuestion-page">
<div class="newQuizDiv">
<router-link to="/overviewQuiz"> <- </router-link>
<h1>Create a question to your quiz</h1>
<h1>Edit quiz {{quizId}}</h1>
<div class="question-div">
<QuestionCard v-for="question in questions" :question-id=question.id
:key="question.id"/>
</div>
<NewQuestionModel v-if="showNewQuestion" @close="hideNewQuestion" quiz-id="this.quizId"/>
<!--
<div class="question-table">
<table class="table">
<thead>
......@@ -121,6 +185,9 @@ async function submitQuestion() {
</tbody>
</table>
-->
<!--
<Teleport to="body">
<NewQuestionModel :show="showNewQuestionModal" @close="destroyModal">
......@@ -166,11 +233,11 @@ async function submitQuestion() {
</NewQuestionModel>
</Teleport>
</div>
<div>
<button @click="createQuestion" class="add-Btn"> Add Question </button> <br>
-->
<div class="footer">
<button @click="newQuestion" class="add-Btn"> Add Question </button>
<button class="delete-btn"> DELETE QUIZ </button>
<button class="save-Btn"> SAVE QUIZ </button>
</div>
</div>
......@@ -179,7 +246,7 @@ async function submitQuestion() {
</template>
<style>
.createQuestion-page{
.newQuizDiv{
padding: 20px;
}
......
<script>
import NewQuestionModel from "@/components/shared/NewQuestionModel.vue";
import { ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import router from "@/router/index.js";
import {apiClient} from "@/api.js";
import {getIdByToken} from "@/tokenController.js";
import {categoryEnums} from "@/data/categories.js"
import {difficultyEnums} from "@/data/difficulties.js";
//like editquiz, but w/o questions, redirect to edit when quiz is constructed
export default {
data() {
return {
showNewQuestion: false,
creatorId: null,
quiz: null,
quizId: null,
quizTitle: '',
questions: [],
category: '',
difficulty: '',
errorMsg: '',
selectedCategory: null,
categories: categoryEnums,
selectedDifficulty: null,
difficulties: difficultyEnums,
//TODO: make quiz object
};
},
mounted() {
this.getUser();
},
methods: {
async constructQuiz() {
try {
await apiClient.post('quiz/create', {
title: this.quizTitle,
questionIds: this.questions,
creatorId: this.creatorId,
category: this.selectedCategory,
difficulty: this.selectedDifficulty
}).then(response => {
this.quizId = JSON.parse(response.data.id);
router.push({name: 'editQuiz', params: {quizId: this.quizId}});
})
} catch(error){
this.errorMsg = 'Cannot construct quiz';
}
},
getUser() {
this.creatorId = getIdByToken();
}
},
}
</script>
<template>
<body>
<form @submit.prevent="constructQuiz">
<div class="newQuizDiv">
<router-link to="/overviewQuiz"> <- </router-link>
<h1>New quiz</h1>
<div>
<h2>Title</h2>
<input>
</div>
<div>
<h2>Category</h2>
<form>
<select v-model="selectedCategory">
<option v-for="category in categories" :key="category.id" :value="category.id">{{category.category}}</option>
</select>
</form>
</div>
<div>
<h2>Difficulty</h2>
<form>
<select v-model="selectedDifficulty">
<option v-for="difficulty in difficulties" :key="difficulty.id" :value="difficulty.id">{{difficulty.difficulty}}</option>
</select>
</form>
</div>
<!--
<div class="question-table">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Question</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>What is Vue?</td>
<td>
<button class="play-btn">View</button>
<button class="edit-btn">Edit</button>
<button class="delete-btn"> Delete</button>
</td>
</tr>
</tbody>
</table>
-->
<!--
<Teleport to="body">
<NewQuestionModel :show="showNewQuestionModal" @close="destroyModal">
<template #header>
<h5> Add New Question</h5>
</template>
<template #body>
<form>
<div class="mb-3">
<label for="question" class="form-label">Question</label> <br>
<input type="text" v-model="createdQuestion" class="form-control" id="questionInput">
</div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Answer</th>
<th scope="col">Correct ?</th>
</tr>
</thead>
<tbody>
<tr v-for="(answer, index) in newAnswers">
<th scope="row">{{answer.id}}</th>
<td>
<input type="text" v-model="answer.answer" id="questionInput">
</td>
<td>
<input :checked="answer.correct_answer === 1" class="form-check-input" :value="answer.id" @change="handleRadioToggle(answer.id)" type="radio">
</td>
</tr>
</tbody>
</table>
</form>
</template>
<template #footer>
<button @click="addNewAnswers" class="add-Btn" v-if="newAnswers.length<4" >+</button>
<button @click="destroyModal" class="close-btn"> Close</button>
<button v-if="newAnswers.length>=2" @click="submitQuestion" class="submit-btn">Submit</button>
</template>
</NewQuestionModel>
</Teleport>
</div>
-->
<div class="footer">
<router-link to="/overviewQuiz"> Cancel </router-link>
<div class="submit-section">
<input id="submit" type="submit"/>
</div>
</div>
</div>
</form>
</body>
</template>
<style>
.newQuizDiv{
padding: 20px;
}
input{
height: 25px;
width: 100%;
}
.submit-section {
display: flex;
justify-content: center;
align-items: center;
}
#submit {
min-width: 150px;
min-height: 60px;
font-size: 24px;
border-radius: 6px;
background-color: #242F40;
color: white;
border: none;
cursor: pointer;
margin-top: 20px;
}
</style>
\ No newline at end of file
<template>
<body>
<div class="overViewQuestion-page">
<div class="headerDiv">
<div>
<router-link to="/dashboard"> <- </router-link>
<h1>Your quizzes</h1>
<p>Select a quiz for your creation to either play, edit or delete</p>
<div class="row">
<div class="course-col">
<div class="quiz-header">
<h3>Quiz 1</h3>
<Svg :name="selectedIcon" />
</div>
<div class="quiz-body">
<p>Info about quiz...</p>
<p>Category:</p>
<div id="form-box">
<form>
<select id="quiz-category-1" @change="changeCategory">
<option value="Animal">Animals</option>
<option value="Athletic">Athletic/Sport</option>
<option value="Computer" selected="selected">Computer Science</option>
<option value="Drama">Drama/Movie</option>
<option value="Music">Music</option>
<option value="Religion">Religion</option>
<option value="Science">Science</option>
<option value="Society">Society</option>
<option value="Other">Other</option>
</select>
</form>
<div>
<button class="add-Btn">Create Quiz</button>
<router-link to="/createQuiz"> New quiz </router-link>
</div>
</div>
<div class="quiz-footer">
<router-link to="/play-quiz" class="play-btn">Play</router-link>
<router-link to="/createQuiz" class="edit-btn">Edit</router-link>
<button class="delete-btn">Delete</button>
</div>
</div>
<div>
<button class="add-Btn">Create Quiz</button>
<div class="row">
<div class="quiz-div">
<QuizCard id="quizCard" v-for= "quiz in quizList" :key="quiz.id" :quiz-id="quiz.id" />
</div>
</div>
</div>
</body>
</template>
<script>
import { defineComponent } from "vue";
import Svg from "@/assets/Svg.vue";
import QuizCard from "@/components/shared/QuizCard.vue";
import {getIdByToken} from "@/tokenController.js";
import {apiClient} from "@/api.js";
import {ref} from "vue";
getQuizzes();
const quizzes = ref([]);
async function getQuizzes() {
//TODO: try/catch
const response = await apiClient.get('/quizzes/${quizId.value}');
quizzes.value = response.data; //TODO: create parsing method
}
export default defineComponent({
components: { Svg },
export default {
components: {
QuizCard,
},
data() {
return {
selectedCategory: 'Computer',
categoryIcons: {
'Animal': 'animal-category',
'Athletic': 'athletic-category',
'Computer': 'computer-category',
'Drama': 'drama-category',
'Music': 'music-category',
'Religion': 'religion-category',
'Science': 'science-category',
'Society': 'society-category',
'Other': 'other-category'
}
userId: null,
quizNo: 0,
quizList: [],
};
},
computed: {
selectedIcon() {
return this.categoryIcons[this.selectedCategory];
}
mounted() {
this.setUserId();
this.populateQuizzes();
},
methods: {
changeCategory(event) {
this.selectedCategory = event.target.value;
async populateQuizzes() {
try {
await apiClient.get('/quiz/creator/' + this.userId).then(response => {
this.quizList = JSON.parse(JSON.stringify(response.data));
//TODO: set max amt.
this.quizNo = this.quizList.length;
});
} catch (error) {
//TODO: proper error handling
this.errorMsg = 'Error retrieving quizzes';
}
},/*
populateQuizzes() {
this.quizNo = this.quizList.length;
},*/
setUserId() {
this.userId = getIdByToken();
}
},
created() {
this.setUserId();
this.populateQuizzes();
}
}
});
</script>
<style>
......@@ -100,26 +76,22 @@ export default defineComponent({
padding: 50px;
}
.quiz-header{
.quiz-div {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.quiz-body{
margin-bottom: 40px;
float: left;
box-sizing: border-box;
}
#quiz-category{
padding: 1px;
background-color: #FFF;
border-radius: 5px;
font-family: monospace;
}
.quiz-footer{
.headerDiv {
display: flex;
justify-content: space-evenly;
align-items: center;
padding-left: 25px;
padding-right: 25px;
width: 100%;
justify-content: space-between;
}
#quizCard {
width: calc(50% - 10px);
}
</style>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment