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

Preliminary first draft of backend requests for quiz creation and editing

parent 96ba7009
Branches master
No related tags found
1 merge request!23Frontend quiz api req
Pipeline #268843 passed
Showing
with 478 additions and 110 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;
*/
...@@ -4,27 +4,36 @@ ...@@ -4,27 +4,36 @@
const props = defineProps({ const props = defineProps({
show: Boolean show: Boolean
})*/ })*/
import AnswerCard from "@/components/shared/AnswerCard.vue";
export default { export default {
components: {AnswerCard}, props: {
questionId: {
type: Number,
required: true
}
},
mounted() {
//APi req
},
data() { data() {
return { return {
questionText: '', questionText: '',
correctIndex: 0,
answers: [ answers: [
{answerId: 0, answer: 'first answer', correct: true}, {answerId: 0, answer: 'first answer', correct: true},
{answerId: 1, answer: 'second answer', correct: false}, {answerId: 1, answer: 'second answer', correct: false},
{answerId: 2, answer: 'third answer', correct: false}, {answerId: 2, answer: 'third answer', correct: false}
], ]
correctIndex: 0
} }
}, },
methods: { methods: {
closeModal() { closeModal() {
this.$emit('close'); this.$emit('close');
}, },
newAnswer() { newAnswer() {
//default: not correct! //default: not correct!
} },
} }
}; };
...@@ -39,8 +48,26 @@ export default { ...@@ -39,8 +48,26 @@ export default {
<input v-model="questionText" placeholder="Type your question here"> <input v-model="questionText" placeholder="Type your question here">
</div> </div>
<div class="modal-body"> <div class="modal-body">
<AnswerCard answer-id="answerCard" v-for="answer in answers" <table class="table">
:key="answer.id" :answerId="answer.id" :answer="answer.answer" :correct="answer.correct"/> <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>
<div class="modal-footer"> <div class="modal-footer">
default footer default footer
......
<script> <script>
/* import {apiClient} from "@/api.js";
<script setup>
const props = defineProps({
show: Boolean
})*/
import AnswerCard from "@/components/shared/AnswerCard.vue";
export default { export default {
components: {AnswerCard}, props: {
quizId: {
type: Number,
required: true
}
},
data() { data() {
return { return {
questionText: '', questionText: '',
answers: [ answers: [{ text: '', correct: false }],
{answerId: 0, answer: 'first answer', correct: true}, correctAnswerIndex: 0,
{answerId: 1, answer: 'second answer', correct: false}, type: 'MC',
{answerId: 2, answer: 'third answer', correct: false}, score: 0,
], correctAnswer: null,
correctIndex: 0 errorMsg: ''
} }
}, },
methods: { 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() { closeModal() {
this.$emit('close'); this.$emit('close');
}, },
newAnswer() { newAnswer() {
//default: not correct! this.answers.push({ text: '', correct: false });
},
findCorrectAnswer(){
if (this.correctAnswerIndex !== null && this.answers[this.correctAnswerIndex]) {
this.correctAnswer = this.answers[this.correctAnswerIndex].text;
}
} }
} }
...@@ -34,22 +57,42 @@ export default { ...@@ -34,22 +57,42 @@ export default {
<div class="modal-overlay" @click="closeModal"> <div class="modal-overlay" @click="closeModal">
<div @click.stop class="modal-mask"> <div @click.stop class="modal-mask">
<div class="modal-container"> <div class="modal-container">
<form @submit.prevent="handleSubmit">
<div class="question-title"> <div class="question-title">
<h3>Question:</h3> <h3>Question:</h3>
<input v-model="questionText" placeholder="Type your question here"> <input v-model="questionText" placeholder="Type your question here">
<label>Score:</label>
<input type="number" id="scoreInput" v-model="score">
</div> </div>
<div class="modal-body"> <div class="modal-body">
<!--
<AnswerCard answer-id="answerCard" v-for="answer in answers" <AnswerCard answer-id="answerCard" v-for="answer in answers"
:key="answer.id" :answerId="answer.id" :answer="answer.answer" :correct="answer.correct"/> :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>
<div class="modal-footer"> <div class="modal-footer">
default footer <button class="edit-btn" @click="newAnswer">Add answer</button>
<button <button class="modal-default-button" @click="$emit('close')">SUBMIT</button>
class="modal-default-button"
@click="$emit('close')">
OK
</button>
</div> </div>
</form>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -2,33 +2,36 @@ ...@@ -2,33 +2,36 @@
import { RouterLink, RouterView } from 'vue-router'; import { RouterLink, RouterView } from 'vue-router';
import router from "@/router/index.js"; import router from "@/router/index.js";
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import EditQuestionModel from "@/components/shared/EditQuestionModel.vue";
export default { export default {
components: {EditQuestionModel},
props: { props: {
questionId: { questionId: {
type: Number, type: Number,
required: true, required: true,
}
}, },
questionNum: { mounted() {
type: Number, //API req, get question from id
required: false,
},
question: {
type: String,
required: false,
}, },
data() {
return {
showEditQuestion: false,
questionNum: 0,
question: 'question text'
}
}, },
methods: { methods: {
//link to pages, play quiz, edit, delete, with quizId deleteQuestion() {
viewQuestion() { //API req, delete question
//create new router-method to playQuiz, using quizId
//router.push({name: 'playQuiz', params: {questionId: this.questionId}});
}, },
editQuestion() { editQuestion() {
//create new router-method to editQuiz, using quizId this.showEditQuestion = true;
//this.$router.push({name: 'editQuiz', params: {questionId: this.questionId}}); console.log(this.showEditQuestion);
}, },
deleteQuestion() { hideEditQuestion() {
this.showEditQuestion = false;
//TODO: update answers, +answer count
} }
} }
} }
...@@ -36,13 +39,13 @@ export default { ...@@ -36,13 +39,13 @@ export default {
<template> <template>
<div class="question-wrapper"> <div class="question-wrapper">
<h4>{{questionNum}}</h4> <h4>{{questionId}}</h4>
<h3>{{question}}</h3> <h3>{{question}}</h3>
<div class="quiz-footer"> <div class="quiz-footer">
<button @click="viewQuestion" class="play-btn">Play</button>
<button @click="editQuestion" class="edit-btn">Edit</button> <button @click="editQuestion" class="edit-btn">Edit</button>
<button @click="deleteQuestion" class="delete-btn">Edit</button> <button @click="deleteQuestion" class="delete-btn">Delete</button>
</div> </div>
<EditQuestionModel :question-id=questionId v-if="this.showEditQuestion" @close="hideEditQuestion"/>
</div> </div>
</template> </template>
......
<script> <script>
import { RouterLink, RouterView } from 'vue-router';
import router from "@/router/index.js"; import router from "@/router/index.js";
import { useRouter } from 'vue-router'; import {apiClient} from "@/api.js";
export default { export default {
props: { props: {
quizId: { quizId: {
type: Number, type: Number,
required: true, required: true,
}
}, },
quizName: { data() {
type: String, return {
required: true, quizTitle: null,
}, quizDifficulty: null,
quizDescription: { quizCategory: null
type: String,
required: true,
} }
},
mounted() {
this.getQuiz();
}, },
methods: { 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 //link to pages, play quiz, edit, delete, with quizId
playQuiz() { playQuiz() {
//create new router-method to playQuiz, using quizId //create new router-method to playQuiz, using quizId
...@@ -25,7 +42,7 @@ export default { ...@@ -25,7 +42,7 @@ export default {
}, },
editQuiz() { editQuiz() {
//create new router-method to editQuiz, using quizId //create new router-method to editQuiz, using quizId
this.$router.push({name: 'editQuiz', params: {quizId: this.quizId}}); router.push({name: 'editQuiz', params: {quizId: this.quizId}});
}, },
} }
} }
...@@ -34,13 +51,14 @@ export default { ...@@ -34,13 +51,14 @@ export default {
<template> <template>
<div class="course-col"> <div class="course-col">
<div class="quiz-header"> <div class="quiz-header">
<h3>{{ quizName }}</h3> <h3>{{ quizTitle }}</h3>
<!-- <!--
<Svg :name="selectedIcon" /> <Svg :name="selectedIcon" />
--> -->
</div> </div>
<div class="quiz-body"> <div class="quiz-body">
<p>{{ quizDescription }}</p> <p>{{ quizDifficulty }}</p>
<p>{{ quizCategory }}</p>
</div> </div>
<div class="quiz-footer"> <div class="quiz-footer">
<button @click="playQuiz" class="play-btn">Play</button> <button @click="playQuiz" class="play-btn">Play</button>
......
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;
*/
...@@ -38,7 +38,7 @@ const router = createRouter({ ...@@ -38,7 +38,7 @@ const router = createRouter({
{ {
path: '/createQuiz', path: '/createQuiz',
name: 'create Quiz', name: 'create Quiz',
component: () => import('../views/EditQuizView.vue') component: () => import('../views/NewQuizView.vue')
}, },
{ {
path: '/overviewQuiz', path: '/overviewQuiz',
......
...@@ -13,7 +13,6 @@ export const removeToken = () => { ...@@ -13,7 +13,6 @@ export const removeToken = () => {
} }
export const getIdByToken= () => { export const getIdByToken= () => {
//const token = getToken(); //TODO: set up encryption and getID
//return apiClient.get('/user/getId'); return apiClient.get('/user/getId/' + getToken());
return 'UserName';
} }
\ No newline at end of file
...@@ -18,18 +18,16 @@ let answerId = 1; ...@@ -18,18 +18,16 @@ let answerId = 1;
const quizName = ref(''); const quizName = ref('');
const errorMsg = ''; //TODO: display error to user*/ const errorMsg = ''; //TODO: display error to user*/
//send list of question-ids?
export default { export default {
components: {NewQuestionModel, QuestionCard}, components: {NewQuestionModel, QuestionCard},
data() { data() {
return { return {
showNewQuestion: false, showNewQuestion: false,
creatorId: null,
quizId: null, quizId: null,
quizTitle: '', quizTitle: '',
questions: [ questions: [], //question list is just a list of q-ids!!
{id: 0, num: 1, text:'first question'},
{id: 1, num: 2, text:'second question'},
{id: 2, num: 3, text:'third question'}
],
category: '', category: '',
difficulty: '', difficulty: '',
errorMsg: '' errorMsg: ''
...@@ -43,18 +41,18 @@ export default { ...@@ -43,18 +41,18 @@ export default {
methods: { methods: {
getQuiz(quizId) { getQuiz(quizId) {
console.log('Fetching data for quiz: ', quizId); console.log('Fetching data for quiz: ', quizId);
/*
try { try {
apiClient.get('/quiz/quiz/' + this.quizId).then(response => { apiClient.get('/quiz/quiz/' + this.quizId).then(response => {
this.quizTitle = JSON.parse(response.data.title); 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.category = JSON.parse(response.data.category);
this.difficulty = JSON.parse(response.data.difficulty); this.difficulty = JSON.parse(response.data.difficulty);
this.questions = JSON.parse(JSON.stringify(response.data.questions));
}); });
} catch (error) { } catch (error) {
//TODO: proper error handling //TODO: proper error handling
this.errorMsg = 'Error retrieving quizzes'; this.errorMsg = 'Error retrieving quizzes';
}*/ }
}, },
newQuestion() { newQuestion() {
this.showNewQuestion = true; this.showNewQuestion = true;
...@@ -62,7 +60,10 @@ export default { ...@@ -62,7 +60,10 @@ export default {
}, },
hideNewQuestion() { hideNewQuestion() {
this.showNewQuestion = false; this.showNewQuestion = false;
//TODO: update answers, +answer count //TODO: questions answers, +question count
},
deleteQuiz() {
//API req, quizId
} }
}, },
}; };
...@@ -153,15 +154,14 @@ async function submitQuestion() { ...@@ -153,15 +154,14 @@ async function submitQuestion() {
<template> <template>
<body> <body>
<div class="createQuestion-page"> <div class="newQuizDiv">
<router-link to="/overviewQuiz"> <- </router-link> <router-link to="/overviewQuiz"> <- </router-link>
<h1>Edit quiz {{quizId}}</h1> <h1>Edit quiz {{quizId}}</h1>
<p>Add questions</p>
<div class="question-div"> <div class="question-div">
<QuestionCard question-id="questionCard" v-for="question in questions" <QuestionCard v-for="question in questions" :question-id=question.id
:key="question.id" :question-num="question.num" :question="question.text"/> :key="question.id"/>
</div> </div>
<NewQuestionModel v-if="showNewQuestion" @close="hideNewQuestion"/> <NewQuestionModel v-if="showNewQuestion" @close="hideNewQuestion" quiz-id="this.quizId"/>
<!-- <!--
<div class="question-table"> <div class="question-table">
<table class="table"> <table class="table">
...@@ -235,8 +235,9 @@ async function submitQuestion() { ...@@ -235,8 +235,9 @@ async function submitQuestion() {
</Teleport> </Teleport>
</div> </div>
--> -->
<div> <div class="footer">
<button @click="newQuestion" class="add-Btn"> Add Question </button> <br> <button @click="newQuestion" class="add-Btn"> Add Question </button>
<button class="delete-btn"> DELETE QUIZ </button>
<button class="save-Btn"> SAVE QUIZ </button> <button class="save-Btn"> SAVE QUIZ </button>
</div> </div>
</div> </div>
...@@ -245,7 +246,7 @@ async function submitQuestion() { ...@@ -245,7 +246,7 @@ async function submitQuestion() {
</template> </template>
<style> <style>
.createQuestion-page{ .newQuizDiv{
padding: 20px; 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
...@@ -9,13 +9,14 @@ ...@@ -9,13 +9,14 @@
</div> </div>
<div> <div>
<button class="add-Btn">Create Quiz</button> <button class="add-Btn">Create Quiz</button>
<router-link to="/createQuiz"> New quiz </router-link>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="quiz-div"> <div class="quiz-div">
<QuizCard id="quizCard" v-for= "quiz in quizList" :key="quiz.id" :quizDescription="quiz.description" :quizName="quiz.name" :quiz-id="quiz.id" /> <QuizCard id="quizCard" v-for= "quiz in quizList" :key="quiz.id" :quiz-id="quiz.id" />
</div> </div>
</div> </div>
</div> </div>
...@@ -25,6 +26,7 @@ ...@@ -25,6 +26,7 @@
<script> <script>
import QuizCard from "@/components/shared/QuizCard.vue"; import QuizCard from "@/components/shared/QuizCard.vue";
import {getIdByToken} from "@/tokenController.js"; import {getIdByToken} from "@/tokenController.js";
import {apiClient} from "@/api.js";
export default { export default {
components: { components: {
...@@ -32,19 +34,17 @@ export default { ...@@ -32,19 +34,17 @@ export default {
}, },
data() { data() {
return { return {
userName: '', userId: null,
quizNo: 0, quizNo: 0,
quizList: [ quizList: [],
{ name: 'Quiz 1', description: 'Description of Quiz 1', id: 1 },
{ name: 'Quiz 2', description: 'Description of Quiz 2', id: 2 },
{ name: 'Quiz 3', description: 'Description of Quiz 3', id: 3 },
{ name: 'Quiz 4', description: 'Description of Quiz 4', id: 3 },
{ name: 'Quiz 5', description: 'Description of Quiz 5', id: 3 }
], //TODO: replace with request-method when ready, using quiz-objects
}; };
}, },
mounted() {
this.setUserId();
this.populateQuizzes();
},
methods: { methods: {
/*
async populateQuizzes() { async populateQuizzes() {
try { try {
await apiClient.get('/quiz/creator/' + this.userId).then(response => { await apiClient.get('/quiz/creator/' + this.userId).then(response => {
...@@ -56,15 +56,12 @@ export default { ...@@ -56,15 +56,12 @@ export default {
//TODO: proper error handling //TODO: proper error handling
this.errorMsg = 'Error retrieving quizzes'; this.errorMsg = 'Error retrieving quizzes';
} }
},*/ },/*
populateQuizzes() { populateQuizzes() {
this.quizNo = this.quizList.length; this.quizNo = this.quizList.length;
}, },*/
newQuiz() {
//link to new quiz page
},
setUserId() { setUserId() {
this.userName = getIdByToken(); this.userId = getIdByToken();
} }
}, },
created() { created() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment