b2
parent
cb3d9994df
commit
6be7ee6f29
|
@ -4,8 +4,8 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --host --port 2008",
|
"dev": "astro dev --host --port 2020",
|
||||||
"start": "astro dev --host --port 2008",
|
"start": "astro dev --host --port 2020",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section class="container-fluid bg-green-600 mb-16">
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
|
<h1 class="text-4xl font-bold text-white py-1.5">Beanstalkedu <br> Exam Portal</h1>
|
||||||
|
</div>
|
||||||
|
<!-- <p v-for="items in dataa" :key="items.id">{{items.qs}}</p> -->
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto px-4 max-w-2xl">
|
||||||
|
<form @submit="submitForm" class="flex-flex-col">
|
||||||
|
<div @change="" >
|
||||||
|
<select v-model="identifier" name="" id="" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5 w-full">
|
||||||
|
<option v-for="idData in idfrData" :value="idData.identifier_name + idData.identifier_number">{{ idData.identifier_name }} {{ idData.identifier_number }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label for="question">Add Question:<span class="text-[#ff0000] text-xl">*</span></label>
|
||||||
|
<input v-model="question" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="question" name="question" type="text" placeholder="Question" required />
|
||||||
|
<div v-for="(field, index) in optionsField" :key="index" class="flex flex-col">
|
||||||
|
<label :for="'Question' + (index + 1)">Options: {{ index + 1 }}<span class="text-[#ff0000] text-xl">*</span></label>
|
||||||
|
<div class="flex flex-row place-items-center gap-2">
|
||||||
|
<input class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5 w-full" placeholder="Add Option" v-model="options[index]" :id="'Question' + (index + 1)" :name="'Question' + (index + 1)" type="text" required />
|
||||||
|
<span class="text-[#FF0000] text-2xl cursor-pointer" @click="deleteField()">✖</span>
|
||||||
|
<input v-model="ansNoDa[index]" :value="options" :name="options" type="checkbox" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="bg-green-500 text-white font-bold rounded-lg float-right p-1.5 mt-2 cursor-pointer" @click="addField()">Add More</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label for="answer">Correct Answer:<span class="text-[#ff0000] text-xl">*</span></label>
|
||||||
|
<input v-model="correctAnswer" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="answer" name="answer" type="text" placeholder="Correct Answer" required />
|
||||||
|
<label class="mt-2" for="answerNumber">Select Answer Number:<span class="text-[#ff0000] text-xl">*</span></label>
|
||||||
|
<select v-model="answerNumber" name="answerNumber" id="answerNumber" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" required>
|
||||||
|
<option value="0" selected>-Select-</option>
|
||||||
|
<option v-for="(field, index) in optionsField" :key="index" :value="index + 1" class="">{{ index +1 }}</option>
|
||||||
|
</select>
|
||||||
|
<input class="bg-green-500 text-white font-bold rounded-lg float-right p-2 mt-2 cursor-pointer mt-6" type="submit" value="Save">
|
||||||
|
</div>
|
||||||
|
<p>Answer {{ ansNoDa }}</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options: [''],
|
||||||
|
optionsField: 2,
|
||||||
|
question: '',
|
||||||
|
correctAnswer: '',
|
||||||
|
answerNumber: 0,
|
||||||
|
ansNoDa: [],
|
||||||
|
identifier: "",
|
||||||
|
identifierNumber: "",
|
||||||
|
idfrData: ""
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
indentifierValue(){
|
||||||
|
console.log(this.identifier.target.value)
|
||||||
|
},
|
||||||
|
addField() {
|
||||||
|
this.optionsField++;
|
||||||
|
this.options.push('');
|
||||||
|
},
|
||||||
|
deleteField() {
|
||||||
|
if (this.optionsField > 1) {
|
||||||
|
this.optionsField--;
|
||||||
|
this.options.pop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submitForm(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData();
|
||||||
|
// const idntyName = this.identifier;
|
||||||
|
const questionObject = {
|
||||||
|
identifier: this.identifier + '-' + this.identifierNumber,
|
||||||
|
id: Math.floor(Math.random() * 100000),
|
||||||
|
qs: this.question,
|
||||||
|
options: this.options,
|
||||||
|
answer: this.correctAnswer,
|
||||||
|
annswer_number: this.answerNumber,
|
||||||
|
};
|
||||||
|
formData.append('questions', JSON.stringify(questionObject));
|
||||||
|
// Make the fetch request
|
||||||
|
fetch('https://api8.siliconpin.com/items/exam_portal', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json', // Set the content type to JSON
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ questions: [questionObject] }), // Send an array of questions
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
// Handle success response
|
||||||
|
console.log('Success:', data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Handle error
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
fetch('https://api8.siliconpin.com/items/question_identifier')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.idfrData = data.data;
|
||||||
|
console.log(this.idfrData)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Something Wrong", error)
|
||||||
|
})
|
||||||
|
// console.log(this.ansNoDa)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -7,13 +7,13 @@
|
||||||
<!-- <p v-for="items in dataa" :key="items.id">{{items.qs}}</p> -->
|
<!-- <p v-for="items in dataa" :key="items.id">{{items.qs}}</p> -->
|
||||||
</section>
|
</section>
|
||||||
<section class="container mx-auto " >
|
<section class="container mx-auto " >
|
||||||
<div class="flex flex-col justify-center place-items-center">
|
<div class="flex flex-col md:flex-row justify-center gap-4">
|
||||||
<div class="border-t-2 rounded-2xl border-yellow-500 shadow-lg p-6 w-full max-w-2xl">
|
<div class="border-t-2 rounded-2xl border-yellow-500 shadow-lg p-6 w-full max-w-2xl">
|
||||||
<div class="flex flex-row place-content-between">
|
<div class="flex flex-row place-content-between">
|
||||||
<p class="text-xl font-bold">Question: {{ qPoint + 1 }} / {{ noOfQs }} </p>
|
<p class="text-xl font-bold">Question: {{ qPoint + 1 }} / {{ noOfQs }} </p>
|
||||||
<div class="flex flex-row place-items-center gap-x-2">
|
<div class="flex flex-row place-items-center gap-x-2">
|
||||||
<p class="text-xl font-bold">00:00</p>
|
<!-- <p class="text-xl font-bold">00:00</p> -->
|
||||||
<!-- <p class="text-xl font-bold">{{countdown}}</p> -->
|
<!-- <p class="text-xl font-bold" @click="remainingTime()">Start {{countdown}}</p> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -21,9 +21,9 @@
|
||||||
<span>Question ID: {{ qsActive.id }}</span>
|
<span>Question ID: {{ qsActive.id }}</span>
|
||||||
<p v-html="qsData[qPoint].qs"></p>
|
<p v-html="qsData[qPoint].qs"></p>
|
||||||
<div class="flex flex-col gap-y-4 h-[250px] overflow-y-auto">
|
<div class="flex flex-col gap-y-4 h-[250px] overflow-y-auto">
|
||||||
<div v-for="(item, index) in qsActive.options" :key="index" class="border-2 border-indigo-300 rounded p-2.5 bg-indigo-50 cursor-pointer" :class="{ 'selected-option': selectedOptionIndex === index }">
|
<div v-for="(item, index) in qsActive.options" :key="index + 1" class="border-2 border-indigo-300 rounded p-2.5 bg-indigo-50 cursor-pointer" @change="selectOption(index)" :class="{ 'selected-option': selectedOptionIndex === index }">
|
||||||
<span class="font-bold">{{ index + 1 }} </span>
|
<span class="font-bold">{{ index + 1 }} </span>
|
||||||
<input type="radio" :id="item" v-model="totalAnswer" :value="index + 1" @change="selectOption(index)"/>
|
<input type="radio" :id="item" v-model="saveAnswer" :value="index + 1" :class="{ 'selected-option': selectedOptionIndex === index }" />
|
||||||
<!-- <p v-else>Select kor age</p> -->
|
<!-- <p v-else>Select kor age</p> -->
|
||||||
<!-- <input v-model="selectedOptions[qPoint]" type="radio" name="questionOption" :id="item" :value="{ answer: item, questionId: qsActive.id, status: qsStatus }" @change="selectOption(index)" /> -->
|
<!-- <input v-model="selectedOptions[qPoint]" type="radio" name="questionOption" :id="item" :value="{ answer: item, questionId: qsActive.id, status: qsStatus }" @change="selectOption(index)" /> -->
|
||||||
<label :for="item" v-html="item"></label>
|
<label :for="item" v-html="item"></label>
|
||||||
|
@ -33,17 +33,23 @@
|
||||||
<button v-on:click="getPrevQs" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75" :disabled="qPoint <= 0">Previous Question</button>
|
<button v-on:click="getPrevQs" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75" :disabled="qPoint <= 0">Previous Question</button>
|
||||||
<div class="flex flex-col md:flex-row gap-2 md:gap-4">
|
<div class="flex flex-col md:flex-row gap-2 md:gap-4">
|
||||||
<!-- <input @click="saveAns();" type="submit" id="testdis" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg" value="Save Answer" /> -->
|
<!-- <input @click="saveAns();" type="submit" id="testdis" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg" value="Save Answer" /> -->
|
||||||
<button :disabled="this.totalAnswer <= 0" :class="{ 'button-visibility': this.totalAnswer <= 0 }" @click="saveAns();" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg">Save Answer</button>
|
<button :disabled="this.saveAnswer <= 0" :class="{ 'button-visibility': this.saveAnswer <= 0 }" @click="saveAns();" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg">Save Answer</button>
|
||||||
<!-- :class="{ 'button-visibility': this.totalAnswer <= 0 }" -->
|
<!-- :class="{ 'button-visibility': this.saveAnswer <= 0 }" -->
|
||||||
<button :disabled="this.totalAnswer >= 1" :class="{ 'button-visibility': this.totalAnswer >= 1 }" v-on:click="reviewLater" class="bg-[#7C4C23] float-right p-2.5 text-white font-bold rounded-lg">Review Later</button>
|
<button :disabled="this.saveAnswer >= 1" :class="{ 'button-visibility': this.saveAnswer >= 1 }" v-on:click="reviewLater" class="bg-[#7C4C23] float-right p-2.5 text-white font-bold rounded-lg">Review Later</button>
|
||||||
<!-- :class="{ 'button-visibility': this.totalAnswer >= 1 }" -->
|
<!-- :class="{ 'button-visibility': this.saveAnswer >= 1 }" -->
|
||||||
</div>
|
</div>
|
||||||
<button :disabled="qPoint >= noOfQs - 1" @click="getNextQs(); selectOption(index);" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75"> Next Question</button>
|
<button :disabled="qPoint >= noOfQs + 2" @click="getNextQs(); selectOption(index);" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75"> Next Question</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>No Data Found</div>
|
<div v-else>No Data Found</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col border-t-2 border-yellow-500 shadow-lg rounded-lg p-2">
|
||||||
|
<p class="text-center py-4 text-xl font-bold">Your Response</p>
|
||||||
|
<div class="grid grid-cols-3 gap-2">
|
||||||
|
<p class="bg-green-600 response-indicator shadow-md font-bold text-white text-xl" v-for="(response, index) in totalAnswer" :key="index " :class="{'response' : response.answer <= 0}"> {{ index + 1}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,8 +58,8 @@
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
totalAnswer: {},
|
saveAnswer: 0,
|
||||||
allAnswer: [],
|
totalAnswer: [],
|
||||||
qsData: "",
|
qsData: "",
|
||||||
noOfQs: 0,
|
noOfQs: 0,
|
||||||
qPoint: 0,
|
qPoint: 0,
|
||||||
|
@ -66,23 +72,27 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
resetRadioInputs() {
|
||||||
|
// this.selectedOptions = {};
|
||||||
|
this.saveAnswer = null;
|
||||||
|
},
|
||||||
saveAns() {
|
saveAns() {
|
||||||
// if (this.totalAnswer !== null) {
|
// if (this.saveAnswer !== null) {
|
||||||
const selectedAnswer = {
|
const selectedAnswer = {
|
||||||
answer: this.totalAnswer,
|
answer: this.saveAnswer,
|
||||||
questionId: this.qsData[this.qPoint].id,
|
questionId: this.qsData[this.qPoint].id,
|
||||||
view: this.viewStatus = 1, // Set status to 1 for "Save Answer"
|
view: this.viewStatus = 1, // Set status to 1 for "Save Answer"
|
||||||
};
|
};
|
||||||
this.allAnswer.push(selectedAnswer);
|
this.totalAnswer.push(selectedAnswer);
|
||||||
console.log('array', this.allAnswer);
|
console.log('array', this.totalAnswer);
|
||||||
// } else {
|
// } else {
|
||||||
// // Show an alert or set a message indicating that no option is selected
|
// // Show an alert or set a message indicating that no option is selected
|
||||||
// alert("Select an answer before saving.");
|
// alert("Select an answer before saving.");
|
||||||
// }
|
// }
|
||||||
},
|
this.resetRadioInputs();
|
||||||
resetRadioInputs() {
|
if (this.totalAnswer.length <= 24) {
|
||||||
// this.selectedOptions = {};
|
this.getNextQs();
|
||||||
this.totalAnswer = null;
|
}
|
||||||
},
|
},
|
||||||
getNextQs() {
|
getNextQs() {
|
||||||
this.qPoint++;
|
this.qPoint++;
|
||||||
|
@ -103,11 +113,18 @@ export default {
|
||||||
questionId: this.qsData[this.qPoint].id,
|
questionId: this.qsData[this.qPoint].id,
|
||||||
view: this.viewStatus = 1// Set status to 1 for "Save Answer"
|
view: this.viewStatus = 1// Set status to 1 for "Save Answer"
|
||||||
};
|
};
|
||||||
this.allAnswer.push(selectedAnswer);
|
this.totalAnswer.push(selectedAnswer);
|
||||||
|
console.log('array later', this.totalAnswer);
|
||||||
|
|
||||||
},
|
},
|
||||||
selectOption(index) {
|
selectOption(index) {
|
||||||
this.selectedOptionIndex = index;
|
this.selectedOptionIndex = index;
|
||||||
},
|
},
|
||||||
|
// submitExam(){
|
||||||
|
// if (this.qPoint == this.noOfQs) {
|
||||||
|
// aler
|
||||||
|
// }
|
||||||
|
// },
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
fetch('/assets/qs.json')
|
fetch('/assets/qs.json')
|
||||||
|
@ -122,19 +139,22 @@ export default {
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error fetching data:', error);
|
console.error('Error fetching data:', error);
|
||||||
});
|
});
|
||||||
let intervalId;
|
// this.remainingTime();
|
||||||
// Start countdown on mounted
|
|
||||||
intervalId = setInterval(() => {
|
|
||||||
if (this.countdown > 0) {
|
|
||||||
this.countdown--;
|
|
||||||
} else {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
.response-indicator{
|
||||||
|
width: 45px;
|
||||||
|
height: 45px;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.response{
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
.button-visibility{
|
.button-visibility{
|
||||||
/* display: none; */
|
/* display: none; */
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section class="container-fluid bg-green-600 mb-16">
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
|
<h1 class="text-4xl font-bold text-white py-1.5">Beanstalkedu <br> Exam Portal</h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto px-4 max-w-2xl">
|
||||||
|
<div class="shadow-lg rounded-xl p-6">
|
||||||
|
<p class="text-center">Add Question Identifier</p>
|
||||||
|
<form @submit.prevent="saveIdentifier()" name="identifierForm">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label for="identifierName" class="mt-4 ">Identifier Name:</label>
|
||||||
|
<input v-model="identifierName" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierName" name="identifierName" type="text" placeholder="Identifier Name" required />
|
||||||
|
<label for="identifierNumber" class="mt-4 ">Identifier Number:</label>
|
||||||
|
<input v-model="identifierNumber" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierNumber" name="identifierNumber" type="text" min="1" placeholder="Identifier Number" />
|
||||||
|
<div><input value="Add" type="submit" class="mt-4 rounded-lg bg-green-500 py-1.5 text-white font-bold px-6 float-right" /></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto px-4 mt-6 md:mt-16">
|
||||||
|
<div class="flex justify-center">
|
||||||
|
<table class="border-2">
|
||||||
|
<tr>
|
||||||
|
<th class="border-2">Sl No.</th>
|
||||||
|
<th class="border-2">Identifier</th>
|
||||||
|
<th class="border-2">Number</th>
|
||||||
|
<th class="border-2">Action</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="(items, index) in idfrData" :key="index">
|
||||||
|
<td class="border-2">{{ index + 1 }}</td>
|
||||||
|
<td class="border-2">{{ items.identifier_name }}</td>
|
||||||
|
<td class="border-2">{{ items.identifier_number }}</td>
|
||||||
|
<td class="border-2 flex flex-row gap-x-2">
|
||||||
|
<a href="">Edit</a>
|
||||||
|
<a href="">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
identifierName: "",
|
||||||
|
identifierNumber: "",
|
||||||
|
idfrData: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
saveIdentifier() {
|
||||||
|
fetch('https://api8.siliconpin.com/items/question_identifier', {
|
||||||
|
method: 'POST',
|
||||||
|
headers:{
|
||||||
|
'Content-Type' : 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
status: 'published',
|
||||||
|
identifier_name: this.identifierName,
|
||||||
|
identifier_number: this.identifierNumber,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if(response.ok){
|
||||||
|
return response.json();
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
return Promise.reject(response)
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((response) => {
|
||||||
|
console.log(response.status, response.statusText);
|
||||||
|
response.json().then((json) => {
|
||||||
|
console.log(json.errors[0].message);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
fetch('https://api8.siliconpin.com/items/question_identifier')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.idfrData = data.data;
|
||||||
|
console.log(this.idfrData)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Something Wrong", error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,34 +1,88 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section class="container-fluid bg-green-600 mb-16">
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
|
<h1 class="text-4xl font-bold text-white py-1.5">Beanstalkedu <br> Exam Portal</h1>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto px-4 max-w-2xl">
|
||||||
|
<div class="shadow-lg rounded-xl p-6">
|
||||||
|
<p class="text-center">Add Question Identifier</p>
|
||||||
|
<form @submit="saveIdentifier" name="identifierForm">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label for="identifierName" class="mt-4 ">Identifier Name:</label>
|
||||||
|
<input v-model="identifierName" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierName" name="identifierName" type="text" placeholder="Identifier Name" required />
|
||||||
|
<label for="identifierNumber" class="mt-4 ">Identifier Number:</label>
|
||||||
|
<input v-model="identifierNumber" class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierNumber" name="identifierNumber" type="text" min="1" placeholder="Identifier Number" />
|
||||||
|
<div><input value="Add" type="submit" class="mt-4 rounded-lg bg-green-500 py-1.5 text-white font-bold px-6 float-right" /></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto px-4 mt-6 md:mt-16">
|
||||||
|
<div class="flex justify-center">
|
||||||
|
<table class="border-2">
|
||||||
|
<tr>
|
||||||
|
<th class="border-2">Sl No.</th>
|
||||||
|
<th class="border-2">Identifier</th>
|
||||||
|
<th class="border-2">Number</th>
|
||||||
|
<th class="border-2">Action</th>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="(items, index) in idfrData" :key="index">
|
||||||
|
<td class="border-2">{{ index + 1 }}</td>
|
||||||
|
<td class="border-2">{{ items.identifier_name }}</td>
|
||||||
|
<td class="border-2">{{ items.identifier_number }}</td>
|
||||||
|
<td class="border-2 flex flex-row gap-x-2">
|
||||||
|
<a href="">Edit</a>
|
||||||
|
<a href="">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
// ... (other options)
|
data(){
|
||||||
|
return{
|
||||||
data() {
|
identifierName: null,
|
||||||
return {
|
identifierNumber: null,
|
||||||
// ... (other data properties)
|
idfrData: null,
|
||||||
totalAnswer: [], // Change this to an array
|
};
|
||||||
allAnswer: [],
|
},
|
||||||
};
|
methods:{
|
||||||
},
|
saveIdentifier(e) {
|
||||||
|
e.preventDefault();
|
||||||
methods: {
|
console.log('Identifier Name:', this.identifierName);
|
||||||
saveAns() {
|
console.log('Identifier Number:', this.identifierNumber);
|
||||||
const selectedAnswer = {
|
let formData = new FormData();
|
||||||
answer: this.totalAnswer,
|
formData.append('status', 'published');
|
||||||
questionId: this.qsData[this.qPoint].id,
|
formData.append('identifier_name', this.identifierName);
|
||||||
status: (this.qsStatus = 1), // Set status to 1 for "Save Answer"
|
formData.append('identifier_number', this.identifierNumber);
|
||||||
};
|
fetch('https://api8.siliconpin.com/items/question_identifier', {
|
||||||
|
method: 'POST',
|
||||||
// Push the selected answer into the allAnswer array
|
body: formData,
|
||||||
this.allAnswer.push(this.selectedAnswer);
|
})
|
||||||
|
.then(response => response.json())
|
||||||
console.log("selected options", selectedAnswer);
|
.then(data => {
|
||||||
console.log("question ID:" + this.qsActive.id);
|
console.log('Response:', data);
|
||||||
console.log("ans no: " + this.ansNo);
|
})
|
||||||
},
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
// ... (other methods)
|
});
|
||||||
},
|
}
|
||||||
};
|
},
|
||||||
|
mounted(){
|
||||||
|
fetch('https://api8.siliconpin.com/items/question_identifier')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.idfrData = data.data;
|
||||||
|
console.log(this.idfrData)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Something Wrong", error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
|
@ -0,0 +1,174 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<section class="container-fluid bg-green-600 mb-16">
|
||||||
|
<div class="container mx-auto px-4 ">
|
||||||
|
<h1 class="text-4xl font-bold text-white py-1.5">Beanstalkedu <br> Exam Portal</h1>
|
||||||
|
</div>
|
||||||
|
<!-- <p v-for="items in dataa" :key="items.id">{{items.qs}}</p> -->
|
||||||
|
</section>
|
||||||
|
<section class="container mx-auto " >
|
||||||
|
<div class="flex flex-col justify-center place-items-center">
|
||||||
|
<div class="border-t-2 rounded-2xl border-yellow-500 shadow-lg p-6 w-full max-w-2xl">
|
||||||
|
<div class="flex flex-row place-content-between">
|
||||||
|
<p class="text-xl font-bold">Question: {{ qPoint + 1 }} / {{ noOfQs }} </p>
|
||||||
|
<div class="flex flex-row place-items-center gap-x-2">
|
||||||
|
<p class="text-base font-bold">Time Remaining: {{ timer }} seconds</p>
|
||||||
|
<!-- <p class="text-xl font-bold">00:00</p> -->
|
||||||
|
<!-- <p class="text-xl font-bold" @click="remainingTime()">Start {{countdown}}</p> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="noOfQs>0" class="flex flex-col gap-y-4 rounded-lg mt-4">
|
||||||
|
<span>Question ID: {{ qsActive.id }}</span>
|
||||||
|
<p v-html="qsData[qPoint].qs"></p>
|
||||||
|
<div class="flex flex-col gap-y-4 h-[250px] overflow-y-auto">
|
||||||
|
<div v-for="(item, index) in qsActive.options" :key="index + 1" class="border-2 border-indigo-300 rounded p-2.5 bg-indigo-50 cursor-pointer" @change="selectOption(index)" :class="{ 'selected-option': selectedOptionIndex === index }">
|
||||||
|
<span class="font-bold">{{ index + 1 }} </span>
|
||||||
|
<input type="radio" :id="item" v-model="saveAnswer" :value="index + 1" :class="{ 'selected-option': selectedOptionIndex === index }" />
|
||||||
|
<!-- <p v-else>Select kor age</p> -->
|
||||||
|
<!-- <input v-model="selectedOptions[qPoint]" type="radio" name="questionOption" :id="item" :value="{ answer: item, questionId: qsActive.id, status: qsStatus }" @change="selectOption(index)" /> -->
|
||||||
|
<label :for="item" v-html="item"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row place-content-between mt-4 text-sm md:text-base">
|
||||||
|
<button v-on:click="getPrevQs" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75" :disabled="qPoint <= 0">Previous Question</button>
|
||||||
|
<div class="flex flex-col md:flex-row gap-2 md:gap-4">
|
||||||
|
<!-- <input @click="saveAns();" type="submit" id="testdis" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg" value="Save Answer" /> -->
|
||||||
|
<button :disabled="this.saveAnswer <= 0" :class="{ 'button-visibility': this.saveAnswer <= 0 }" @click="saveAns();" class="bg-green-700 float-right p-2.5 text-white font-bold rounded-lg">Save Answer</button>
|
||||||
|
<!-- :class="{ 'button-visibility': this.saveAnswer <= 0 }" -->
|
||||||
|
<button :disabled="this.saveAnswer >= 1" :class="{ 'button-visibility': this.saveAnswer >= 1 }" v-on:click="reviewLater" class="bg-[#7C4C23] float-right p-2.5 text-white font-bold rounded-lg">Review Later</button>
|
||||||
|
<!-- :class="{ 'button-visibility': this.saveAnswer >= 1 }" -->
|
||||||
|
</div>
|
||||||
|
<button :disabled="qPoint >= noOfQs - 1" @click="getNextQs(); selectOption(index);" class="bg-green-700 float-right p-1 sm:p-2.5 text-white font-bold rounded-lg active:bg-green-700/75"> Next Question</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>No Data Found</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
saveAnswer: {},
|
||||||
|
totalAnswer: [],
|
||||||
|
qsData: "",
|
||||||
|
noOfQs: 0,
|
||||||
|
qPoint: 0,
|
||||||
|
qsStatus: 0,
|
||||||
|
countdown: 10,
|
||||||
|
counting: false,
|
||||||
|
qsActive:[],
|
||||||
|
ansNo:0,
|
||||||
|
selectedOptionIndex: null, // Add this property
|
||||||
|
timer: 10,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
startTimer() {
|
||||||
|
let intervalId = setInterval(() => {
|
||||||
|
if (this.timer > 0) {
|
||||||
|
this.timer--;
|
||||||
|
} else {
|
||||||
|
// Time has expired, perform your action here
|
||||||
|
this.handleTimeExpired();
|
||||||
|
|
||||||
|
// Stop the interval
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
handleTimeExpired() {
|
||||||
|
console.log("Time expired for question", this.qsActive.id);
|
||||||
|
// this.getNextQs();
|
||||||
|
},
|
||||||
|
saveAns() {
|
||||||
|
// if (this.saveAnswer !== null) {
|
||||||
|
const selectedAnswer = {
|
||||||
|
answer: this.saveAnswer,
|
||||||
|
questionId: this.qsData[this.qPoint].id,
|
||||||
|
view: this.viewStatus = 1, // Set status to 1 for "Save Answer"
|
||||||
|
};
|
||||||
|
this.totalAnswer.push(selectedAnswer);
|
||||||
|
console.log('array', this.totalAnswer);
|
||||||
|
// } else {
|
||||||
|
// // Show an alert or set a message indicating that no option is selected
|
||||||
|
// alert("Select an answer before saving.");
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
resetRadioInputs() {
|
||||||
|
// this.selectedOptions = {};
|
||||||
|
this.saveAnswer = null;
|
||||||
|
},
|
||||||
|
getNextQs() {
|
||||||
|
this.timer = 10;
|
||||||
|
this.startTimer();
|
||||||
|
this.qPoint++;
|
||||||
|
this.qsActive=this.qsData[this.qPoint];
|
||||||
|
this.resetRadioInputs();
|
||||||
|
// this.resetRadioInputs();
|
||||||
|
// console.log(this.qsActive);
|
||||||
|
},
|
||||||
|
getPrevQs() {
|
||||||
|
this.qPoint--;
|
||||||
|
this.qsActive=this.qsData[this.qPoint];
|
||||||
|
this.selectOption();
|
||||||
|
},
|
||||||
|
reviewLater(){
|
||||||
|
this.getNextQs();
|
||||||
|
const selectedAnswer = {
|
||||||
|
answer: 0,
|
||||||
|
questionId: this.qsData[this.qPoint].id,
|
||||||
|
view: this.viewStatus = 1// Set status to 1 for "Save Answer"
|
||||||
|
};
|
||||||
|
this.totalAnswer.push(selectedAnswer);
|
||||||
|
console.log('array later', this.totalAnswer);
|
||||||
|
|
||||||
|
},
|
||||||
|
selectOption(index) {
|
||||||
|
this.selectedOptionIndex = index;
|
||||||
|
},
|
||||||
|
remainingTime(){
|
||||||
|
let intervalId;
|
||||||
|
// Start countdown on mounted
|
||||||
|
intervalId = setInterval(() => {
|
||||||
|
if (this.countdown > 0) {
|
||||||
|
this.countdown--;
|
||||||
|
} else {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
fetch('/assets/qs.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.qsData=data;
|
||||||
|
this.noOfQs = this.qsData.length;
|
||||||
|
this.qsActive=this.qsData[0];
|
||||||
|
// console.log(this.qsActive);
|
||||||
|
// console.log(this.noOfQs);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
});
|
||||||
|
this.startTimer();
|
||||||
|
// this.remainingTime();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.button-visibility{
|
||||||
|
/* display: none; */
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.selected-option {
|
||||||
|
background-color: #05b3a4;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
import AddQuestion from "../components/AddQuestion.vue";
|
||||||
|
---
|
||||||
|
<Layout title="Add New Question">
|
||||||
|
<AddQuestion client:visible />
|
||||||
|
</Layout>
|
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
import Layout from "../layouts/Layout.astro";
|
||||||
|
import QuestionIdentifier from "../components/QuestionIdentifier.vue";
|
||||||
|
---
|
||||||
|
<Layout title="">
|
||||||
|
<QuestionIdentifier client:visible />
|
||||||
|
<!-- <main>
|
||||||
|
<div>
|
||||||
|
<section class="container mx-auto px-4 max-w-2xl mt-20">
|
||||||
|
<form id="identifierForm">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<label for="identifierName" class="mt-4 ">Identifier Name:</label>
|
||||||
|
<input class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierName" name="identifierName" type="text" placeholder="Identifier Name" required />
|
||||||
|
<label for="identifierNumber" class="mt-4 ">Identifier Number:</label>
|
||||||
|
<input class="border-2 rounded-lg focus:outline-none focus:border-2 focus:border-green-500 p-1.5" id="identifierNumber" name="identifierNumber" type="text" min="1" placeholder="Identifier Number" />
|
||||||
|
<div><input value="Add" type="submit" class="mt-4 rounded-lg bg-green-500 py-1.5 text-white font-bold px-6 float-right" /></div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main> -->
|
||||||
|
</Layout>
|
||||||
|
<script is:inline>
|
||||||
|
// document.addEventListener('DOMContentLoaded', function(){
|
||||||
|
// const identifierForm = document.getElementById('identifierForm');
|
||||||
|
// const identifierName = document.getElementById('identifierName');
|
||||||
|
// const identifierNumber = document.getElementById('identifierNumber');
|
||||||
|
|
||||||
|
// identifierForm.addEventListener('submit', async function(event){
|
||||||
|
// event.preventDefault();
|
||||||
|
// const formData = {
|
||||||
|
// status: 'published',
|
||||||
|
// identifier_name: identifierName.value,
|
||||||
|
// identifier_number: identifierNumber.value,
|
||||||
|
// };
|
||||||
|
// console.log('Form Data', formData)
|
||||||
|
// const URL = 'https://api8.siliconpin.com/items/question_identifier'
|
||||||
|
// try{
|
||||||
|
// const response = await fetch(URL, {
|
||||||
|
// method: 'POST',
|
||||||
|
// headers: {
|
||||||
|
// 'Content-Type' : 'application/json'
|
||||||
|
// },
|
||||||
|
// body: JSON.stringify(formData)
|
||||||
|
// });
|
||||||
|
// if(response.ok){
|
||||||
|
// console.log('Data Saved Succefully')
|
||||||
|
// } else{
|
||||||
|
// console.error('Data not Saved')
|
||||||
|
// }
|
||||||
|
// } catch(error){
|
||||||
|
// console.error('Error occoured', error)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
</script>
|
||||||
|
<!-- https://api8.siliconpin.com/items/question_identifier -->
|
Loading…
Reference in New Issue