import React, { useState, useEffect } from "react";
import { FaMedal } from "react-icons/fa";
import axios from "axios";
import Apis from "../../APIs";
import { useAuth } from "../Auth/AuthContext";
import { useNavigate } from "react-router-dom";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const Assessment = () => {
const { user, setUser } = useAuth();
const navigate = useNavigate();
const [questions, setQuestions] = useState([]);
const [answers, setAnswers] = useState([]);
const [score, setScore] = useState(0);
const [result, setResult] = useState(false);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [assessmentRecordId, setAssessmentRecordId] = useState(null);
const [redirectPage, setRedirectPage] = useState(null);
const optionLabels = ["A", "B", "C", "D"];
useEffect(() => {
const fetchQuestions = async () => {
try {
const response = await axios.get(Apis.QUESTION_API);
const fetchedQuestions = response.data;
setQuestions(fetchedQuestions);
setAnswers(fetchedQuestions.map(() => Array(4).fill(null)));
setLoading(false);
} catch (err) {
console.error("Error fetching questions:", err);
setError("Failed to load questions. Please try again later.");
setLoading(false);
}
};
fetchQuestions();
}, []);
const handleRatingSelect = (qIndex, oIndex, rating) => {
const newAnswers = [...answers];
if (newAnswers[qIndex][oIndex] === rating) {
newAnswers[qIndex][oIndex] = null;
} else {
const isRatingUsed = newAnswers[qIndex].some(
(selectedRating, index) => selectedRating === rating && index !== oIndex
);
if (isRatingUsed) {
toast.error(
`You have already used rating ${rating} for another option in this question.`
);
return;
}
newAnswers[qIndex][oIndex] = rating;
}
setAnswers(newAnswers);
};
const handleSubmit = async () => {
const incompleteQuestions = questions.some((question, qIndex) =>
answers[qIndex].some((rating) => rating === null)
);
if (incompleteQuestions) {
toast.error("Please Complete all the Assessments");
return;
}
setResult(true);
const formattedResponses = questions.map((question, qIndex) => ({
questionId: question._id,
ratings: answers[qIndex].map((rating) => ({ rating })),
}));
const userId = user._id;
const payload = {
userId: userId,
responses: formattedResponses,
};
try {
const response = await axios.post(Apis.ASSESSMENT_API, payload);
setAssessmentRecordId(response.data._id);
fetchAssessmentRecord(response.data._id);
if (user.feedbackStatus === "newUser") {
const updatedUserData = { feedbackStatus: "feedbackPending" };
await axios.put(`${Apis.USER_API}/${user._id}`, updatedUserData);
setUser({ ...user, feedbackStatus: "feedbackPending" });
}
} catch (error) {
console.error("Error submitting assessment:", error);
}
};
const fetchAssessmentRecord = async (recordId) => {
try {
const response = await axios.get(
`${Apis.ASSESSMENT_API}/getAssessmentRecord/${recordId}`
);
const optionStats = response.data.optionStats;
determineRedirect(optionStats);
} catch (error) {
console.error("Error fetching assessment record:", error);
}
};
const determineRedirect = (optionStats) => {
const maxOption = Object.entries(optionStats).reduce(
(acc, [key, value]) => {
if (value[1] > acc.count) {
return { key, count: value[1] };
}
return acc;
},
{ key: null, count: 0 }
);
switch (maxOption.key) {
case 'option1':
setRedirectPage("/PdfD");
break;
case 'option2':
setRedirectPage("/PdfG");
break;
case 'option3':
setRedirectPage("/PdfC");
break;
case 'option4':
setRedirectPage("/PdfS");
break;
default:
setRedirectPage("/dashboard");
}
};
const handleOkClick = async () => {
const fetchUserData = async () => {
try {
const response = await axios.get(`${Apis.USER_API}/${user._id}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
});
const updatedUserData = response.data;
setUser(updatedUserData);
} catch (error) {
console.error("Error refreshing user data:", error);
}
};
const updatePdfAccess = async () => {
try {
const pdfName = redirectPage.replace("/", "");
await axios.put(
`${Apis.USER_API}/${user._id}`,
{ pdfAccess: [...user.pdfAccess, pdfName] },
{
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
}
);
await fetchUserData();
} catch (error) {
console.error("Error updating pdfAccess:", error);
toast.error("Failed to update PDF access. Please try again later.");
}
};
await updatePdfAccess();
navigate(redirectPage);
};
if (loading) {
return (
<div className="min-h-screen w-full flex items-center justify-center bg-primary-gradient">
<l-infinity
size="200"
stroke="4"
stroke-length="0.15"
bg-opacity="0.1"
speed="1.3"
color="white"
></l-infinity>
</div>
);
}
if (error) {
return (
<section className="min-h-screen w-full bg-primary-gradient flex items-center justify-center">
<div className="text-white text-2xl">{error}</div>
</section>
);
}
return (
<>
<section className="min-h-screen w-full bg-primary-gradient flex flex-col items-center justify-center p-5">
{result ? (
<div className="min-h-[400px] w-80 md:w-[400px] rounded-lg bg-secondary p-5 flex items-center justify-center flex-col gap-5">
<h2 className="text-3xl text-center">
Thank you for giving the assessment
</h2>
<h2 className="text-3xl text-center">
To See Your Result Click Ok
</h2>
<FaMedal className="text-4xl text-yellow-400" />
<button
onClick={handleOkClick}
className="h-10 w-full rounded-lg bg-green-500 text-white hover:bg-green-700"
>
Ok
</button>
</div>
) : (
<>
<div className=" w-screen max-w-[90%] md:max-w-[900px] rounded-lg bg-secondary p-5">
<h2 className="font-bold text-xl mb-5">
Know Your Competency (KYC) - Assessment on DGCS Leadership Style :
-{" "}
</h2>
<h2 className="font-semibold text-base mb-5">
Please choose your rating based on your preference. Rank 1 - Most
Agreed; 2 - Agreed; 3 - Lesser agreed; 4 - Least Agreed. -{" "}
</h2>
<h2 className="font-semibold text-base mb-5">
only one option should be given for each rank for each questions.
For the question one - if you give rank 4 for 1st option, the same
rank 4 cannot be given for the other 3 options : -{" "}
</h2>
</div>
<div className=" w-screen max-w-[90%] md:max-w-[900px] rounded-lg bg-secondary p-5 mt-10">
{questions.map((q, qIndex) => (
<div key={q._id} className="mb-6">
<h3 className="font-semibold text-lg mb-3">
{qIndex + 1}. {q.mainQuestion}
</h3>
<div className="flex flex-col gap-3">
{q.options.map((option, oIndex) => (
<div
key={option._id}
className="items-start justify-start flex flex-col md:flex-row md:items-center md:justify-between "
>
<span>{`(${optionLabels[oIndex]}) ${option.option}`}</span>
<div className="flex gap-10">
{[1, 2, 3, 4].map((rating) => {
const isRatingUsed = answers[qIndex].some(
(selectedRating, index) =>
selectedRating === rating && index !== oIndex
);
return (
<button
key={rating}
onClick={() =>
handleRatingSelect(qIndex, oIndex, rating)
}
className={`w-8 h-8 rounded-full border-2 flex items-center justify-center ${
answers[qIndex][oIndex] === rating
? "bg-green-500 text-white"
: isRatingUsed
? "bg-gray-300 text-white"
: "border-gray-300 hover:bg-green-400"
}`}
disabled={isRatingUsed}
>
{rating}
</button>
);
})}
</div>
</div>
))}
</div>
</div>
))}
<div className="mt-5 flex justify-end">
<button
onClick={handleSubmit}
className="h-10 w-32 rounded-lg bg-green-500 text-white hover:bg-green-700"
>
Submit
</button>
</div>
</div>
</>
)}
</section>
<ToastContainer />
</>
);
};
export default Assessment;
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter