Skip to content

Commit

Permalink
FIXED:#44 Allowed Shuffling Of Quiz Questions and MCQ Options
Browse files Browse the repository at this point in the history
All questions and its options are shuffled before loading.
  • Loading branch information
areebahmeddd committed May 27, 2024
1 parent 7f0605f commit 09dd818
Showing 1 changed file with 77 additions and 81 deletions.
158 changes: 77 additions & 81 deletions app/[quizid]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
import React, { useState, useEffect } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { useRouter, useSearchParams } from 'next/navigation';
import { collection, getDocs , arrayUnion , addDoc , doc , updateDoc} from 'firebase/firestore';
import { collection, getDocs, arrayUnion, updateDoc, doc } from 'firebase/firestore';
import { auth, db } from '../firebase'; // Import Firestore and auth
import {formatDateTime} from '../Date';
import { formatDateTime } from '../Date';
import toast from 'react-hot-toast';





// Define a type for your quiz question
type QuizQuestion = {
question: string;
Expand All @@ -19,27 +15,32 @@ type QuizQuestion = {
};

function Quiz() {

const quizTime = 600000; // This can be updated to allow for custom quiz times

const router = useRouter();
const SearchParams = useSearchParams();
const quizId : any = SearchParams.get('id')
const quizName : any = SearchParams.get('name')
const course : any = SearchParams.get('course')
const courseCode : any = SearchParams.get('coursecode')
const searchParams = useSearchParams();
const quizId: any = searchParams.get('id');
const quizName: any = searchParams.get('name');
const course: any = searchParams.get('course');
const courseCode: any = searchParams.get('coursecode');
const [user, setUser] = useState(null); // User authentication state
const [questions, setQuestions] = useState<QuizQuestion[]>([]); // Provide type annotation for questions
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [selectedOptions, setSelectedOptions] = useState<(string | null)[]>([]);
const [score, setScore] = useState(0);
const [isFinalQuestion, setIsFinalQuestion] = useState(false);
const [isTimeUp, setIsTimeUp] = useState(false);
const [timeLeft, setTimeLeft] = useState(quizTime/1000); // Time limit in seconds
const [timeLeft, setTimeLeft] = useState(quizTime / 1000); // Time limit in seconds

// Function to shuffle an array
function shuffleArray(array: any[]) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}

async function fetchQuizData() {
let toReturn : any = null;
let toReturn: any = null;
const quizRef = collection(db, 'quizzes');
const quizDoc = await getDocs(quizRef);
if (quizDoc) {
Expand All @@ -48,35 +49,35 @@ function Quiz() {
const reqQuiz = quizData.data.id;
if (reqQuiz == quizId) {
toReturn = quizData.data;
// console.log(quizData.data)
// Shuffle options array for each question
toReturn.quizData.forEach((question: QuizQuestion) => {
shuffleArray(question.options);
});
}

});
return toReturn
}
else{
return null
});
return toReturn;
} else {
return null;
}

}

// Update the useEffect hook where the timer is set
useEffect(() => {
const timer = setTimeout(() => {
setIsTimeUp(true);
}, quizTime);

const interval = setInterval(() => {
setTimeLeft((prevTimeLeft) => prevTimeLeft - 1);
}, 1000); // Decrease timeLeft by 1 every second
useEffect(() => {
const timer = setTimeout(() => {
setIsTimeUp(true);
}, quizTime);

const interval = setInterval(() => {
setTimeLeft((prevTimeLeft) => prevTimeLeft - 1);
}, 1000); // Decrease timeLeft by 1 every second

// Clear the timer and the interval when the component unmounts or when the time is up
return () => {
clearTimeout(timer);
clearInterval(interval);
};
}, []);

// Clear the timer and the interval when the component unmounts or when the time is up
return () => {
clearTimeout(timer);
clearInterval(interval);
};
}, []);

useEffect(() => {
if (isTimeUp) {
console.log('Time is up!');
Expand All @@ -96,14 +97,16 @@ useEffect(() => {
}
});

async function fetchData() {
const data = await fetchQuizData().then((data) => { return data });
// console.log(data.quizData)
setQuestions(data.quizData);
async function fetchData() {
const data = await fetchQuizData();
if (data) {
// Shuffle the questions before setting them in state
shuffleArray(data.quizData);
setQuestions(data.quizData);
}
fetchData();
}
fetchData();
}, []);


useEffect(() => {
setIsFinalQuestion(currentQuestionIndex === questions.length - 1);
Expand All @@ -120,7 +123,7 @@ useEffect(() => {
// Increase the score if the selected option is correct
setScore((prevScore) => prevScore + 1);
}

if (currentQuestionIndex < questions.length - 1) {
setCurrentQuestionIndex(currentQuestionIndex + 1);
}
Expand All @@ -132,36 +135,33 @@ useEffect(() => {
}
}



const handleQuizSubmit = async () => {
const handleQuizSubmit = async () => {
const user = auth.currentUser;
if (!user) {
console.error('User not authenticated');
toast.error("User not authenticated")
toast.error("User not authenticated");
return;
}

let myScore = 0
const correctAnswers = questions.map((question : any) => question.correctAnswer)

//check if all questions are attempted

if (selectedOptions.length !== correctAnswers.length && !isTimeUp){
toast.error("Please attempt all of the questions")
return
let myScore = 0;
const correctAnswers = questions.map((question: any) => question.correctAnswer);

// Check if all questions are attempted
if (selectedOptions.length !== correctAnswers.length && !isTimeUp) {
toast.error("Please attempt all of the questions");
return;
}
for(let i = 0; i < selectedOptions.length; i++){
if(selectedOptions[i] == correctAnswers[i]){
myScore = myScore + 1

for (let i = 0; i < selectedOptions.length; i++) {
if (selectedOptions[i] == correctAnswers[i]) {
myScore = myScore + 1;
}
}

var d = new Date();
var n = formatDateTime(d);
const quizResults = {
score : myScore,
score: myScore,
totalQuestions: questions.length,
selectedOptions,
correctAnswers: questions.map((question) => question.correctAnswer),
Expand All @@ -173,31 +173,28 @@ useEffect(() => {
time: n
};

try {
// Create a reference to the user's document
const userDocRef = doc(db, 'users', user.uid);
try {
// Create a reference to the user's document
const userDocRef = doc(db, 'users', user.uid);

await updateDoc(userDocRef as any, {
quizData: arrayUnion(quizResults),
});
console.log(`Quiz Completed! Your Score: ${score}/${questions.length}`);
toast.success('Quiz Submitted Succesfully!');
// Redirect to the results page
router.push(`/results`);
await updateDoc(userDocRef as any, {
quizData: arrayUnion(quizResults),
});
console.log(`Quiz Completed! Your Score: ${score}/${questions.length}`);
toast.success('Quiz Submitted Successfully!');
// Redirect to the results page
router.push(`/results`);

} catch (error) {
console.error('Error storing quiz results:', error);
toast.error('Error storing quiz results, Check Console');
}
}

const currentQuestion = questions[currentQuestionIndex];


const currentQuestion = questions[currentQuestionIndex];

return (
<div className="min-h-screen flex items-center justify-center">

{currentQuestion ? (
<div className="bg-slate-800 text-white p-8 rounded-lg shadow-lg w-4/6 h-4/6">
<h2 className="text-xl mb-4">Question {currentQuestionIndex + 1}:</h2>
Expand All @@ -206,11 +203,10 @@ useEffect(() => {
{currentQuestion.options.map((option, index) => (
<div
key={index}
className={`p-4 text-lg cursor-pointer rounded-lg transition duration-300 ${
selectedOptions[currentQuestionIndex] === option
className={`p-4 text-lg cursor-pointer rounded-lg transition duration-300 ${selectedOptions[currentQuestionIndex] === option
? 'bg-blue-500 text-white'
: 'bg-gray-700 hover:bg-gray-500'
}`}
}`}
onClick={() => handleOptionSelect(option)}
>
{option}
Expand All @@ -227,8 +223,8 @@ useEffect(() => {
</button>
)}
<div className=" bg-slate-600 text-white p-2 rounded-lg shadow-lg">
Time left: {timeLeft} seconds
</div>
Time left: {timeLeft} seconds
</div>
{isFinalQuestion ? (
<button
className="px-4 py-2 bg-blue-500 hover-bg-blue-700 text-white rounded-md"
Expand Down

0 comments on commit 09dd818

Please sign in to comment.