HoshiAI-fe/src/pages/TestPage/TestPage.tsx

153 lines
4.7 KiB
TypeScript

import { useParams } from "react-router-dom";
import Container from "../../components/shared/Container";
import { useUserTestById } from "../../hooks/tests/useUserTestById";
import { useState } from "react";
import { Box, Button, Pagination, Typography } from "@mui/material";
import TestQuestion from "../../components/TestQuestion/TestQuestion";
import { useSubmitAnswer } from "../../hooks/tests/useSubmitAnswer";
import { useCompleteTest } from "../../hooks/tests/useCompleteTest";
import LearningAnswers from "../../components/Answers/Answers";
import { formatDate } from "../../utils/functions";
import NotFoundPage from "../NotFoundPage/NotFoundPage";
import { useAuth } from "../../context/AuthContext";
import { useGetTestById } from "../../hooks/tests/useGetTestById";
export const TestPage = () => {
const { id } = useParams();
const { user } = useAuth();
const { data: test, isLoading, error } = useUserTestById(Number(id));
const [currentQuestion, setCurrentQuestion] = useState(1);
const submitAnswerMutation = useSubmitAnswer();
const completeTestMutation = useCompleteTest();
const allAnswered = test?.answers?.every((ans) => ans.answer !== null);
const { data: createdTest } = useGetTestById(test?.test_id ?? undefined);
const handleCompleteTest = () => {
if (test) completeTestMutation.mutate(test.id);
};
if (isLoading)
return (
<Container>
<Typography variant="h6" color="textSecondary">
Loading your test, please wait...
</Typography>
</Container>
);
if (error) return <NotFoundPage />;
if (!test) return <NotFoundPage />;
if (!test.is_available && !test.is_completed && user?.type == "user")
return (
<Container>
<Typography variant="h6" color="textSecondary">
This test is no longer available.
</Typography>
</Container>
);
if (test.is_completed) {
return (
<Container>
<Typography variant="h2" sx={{ mb: 3 }}>
Results
</Typography>
<Typography variant="h5" color="secondary" sx={{ mb: 3 }}>
Your score: {test.score}%
</Typography>
{test?.answers?.map((ans) => (
<Box key={ans.question_id} sx={{ mb: 4 }}>
<Typography variant="h6">{ans.question.title}</Typography>
<Typography variant="body2" sx={{ mb: 1 }}>
{ans.question.description}
</Typography>
<LearningAnswers
type={ans.question.type as "single" | "multiple" | "text"}
variants={ans.question.variants}
correctAnswers={ans.question.correct_answers}
userAnswers={ans.answer as number[]}
/>
</Box>
))}
</Container>
);
}
const questionsAndAnswers = test.answers;
const currentQA = questionsAndAnswers?.[currentQuestion - 1];
return (
<Container>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
mb: 4,
}}
>
<Typography variant="h2">
{createdTest?.title ?? "User Test"}
</Typography>
<Typography variant="subtitle1">
Expires at: {test.closed_at ? formatDate(test.closed_at) : "N/A"}
</Typography>
</Box>
{currentQA ? (
<TestQuestion
qa={questionsAndAnswers[currentQuestion - 1]}
onSubmit={(ans) =>
submitAnswerMutation.mutate({
answerId: questionsAndAnswers[currentQuestion - 1].id,
answer: ans,
})
}
/>
) : (
<Typography>No question found.</Typography>
)}
<Box
sx={{
display: "flex",
justifyContent: "center",
mt: 2,
flexDirection: "column",
alignItems: "center",
}}
>
<Pagination
count={questionsAndAnswers?.length}
shape="rounded"
color="primary"
page={currentQuestion}
onChange={(_, page) => setCurrentQuestion(page)}
/>
{currentQuestion == questionsAndAnswers?.length && (
<Button
onClick={handleCompleteTest}
variant="contained"
color="success"
disabled={!allAnswered}
sx={{ mt: 15, fontSize: "32px" }}
>
Complete test
</Button>
)}
{currentQuestion == questionsAndAnswers?.length && !allAnswered && (
<Typography
variant="body2"
color="error"
sx={{ fontWeight: 500, textAlign: "center", mt: 2 }}
>
You must answer all questions before completing the test
</Typography>
)}
</Box>
</Container>
);
};