import { QuestionTypes } from "@/api/types"; import { useAnswerMutation, useCompleteTestMutation, useUserTest, } from "@/api/userTests"; import Question from "@/components/question"; import { AlertDialog, AlertDialogBackdrop, AlertDialogBody, AlertDialogContent, AlertDialogFooter, AlertDialogHeader, } from "@/components/ui/alert-dialog"; import Answer from "@/components/ui/answer"; import { Button, ButtonText } from "@/components/ui/button"; import Content from "@/components/ui/content"; import CustomButton from "@/components/ui/custom-button"; import { Divider } from "@/components/ui/divider"; import Panel from "@/components/ui/panel"; import { Textarea, TextareaInput } from "@/components/ui/textarea"; import { ThemedText } from "@/components/ui/themed-text"; import getErrorAxiosMessage from "@/utils/get-error-axios-message"; import getUserTestTitle from "@/utils/get-user-test-title"; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { ScrollView, StyleSheet, View } from "react-native"; import { useToast } from "react-native-toast-notifications"; const DoingUserTestScreen = () => { const { id: idParam } = useLocalSearchParams<{ id: string }>(); const [answer, setAnswer] = useState<(string | number)[]>([]); const [page, setPage] = useState(0); const [openCompleteDialog, setOpenCompleteDialog] = useState(false); const id = +idParam; const { data: userTest, refetch: refetchUserTest } = useUserTest(id); const { mutateAsync: mutateAsyncAnswer, isPending: answerPending } = useAnswerMutation(); const { mutate: mutateCompleteTest, isPending: completePending } = useCompleteTestMutation(); const toast = useToast(); useEffect(() => { if (!userTest) return; setAnswer(userTest.answers[page].answer || []); }, [userTest, page]); if (!userTest) return ( <> ); const currentAnswer = userTest.answers[page]; const currentQuestion = currentAnswer.question; const pages = Array.from({ length: userTest.answers.length }).map( (_, i) => i ); const countAnsweredQuestion = userTest.answers.filter( (answer) => answer.answer ).length; const isAllAnswered = countAnsweredQuestion === userTest.answers.length; const isLastPage = page === pages.length - 1; const userTextAnswer = answer ? (answer[0] as string) : ""; const alertDialogMessage = isAllAnswered ? "Finish the test to see your results." : "Warning: You haven't answered all questions. Are you sure you want to finish?"; const handleSetAnswer = (value: number | string) => { if (currentQuestion.type === QuestionTypes.Text) { setAnswer([value]); } if (currentQuestion.type === QuestionTypes.Single) { setAnswer([value as number]); } if (currentQuestion.type === QuestionTypes.Multiple) { if ((answer as number[]).includes(value as number)) { setAnswer((prev) => prev.filter((v) => v !== value)); } else { setAnswer((prev) => { const set = new Set(prev as number[]); set.add(value as number); return Array.from(set); }); } } }; const handleSaveAnswer = async () => { let ans = answer; if (currentQuestion.type === QuestionTypes.Text && answer) { ans = [(answer[0] as string).trim()]; } try { await mutateAsyncAnswer( { answerId: currentAnswer.id, answer: ans, }, { onSuccess: () => { toast.show("Your answer was saved", { type: "success" }); if(!isLastPage) goPage(page + 1); }, onError: (error) => { toast.show(getErrorAxiosMessage(error), { type: "danger" }); }, } ); } catch {} await refetchUserTest(); }; const handleCompleteTest = () => { mutateCompleteTest({ testId: userTest.id }, { onSuccess: () => { router.replace(`/user-tests/${userTest.id}`); }, onError: (error) => { toast.show(getErrorAxiosMessage(error), { type: "danger" }); } }) }; const goPage = (page: number) => { setAnswer([]); setPage(page); }; return ( <> {pages.map((p) => ( ))} {currentQuestion.variants.map((variant) => ( handleSetAnswer(variant.id)} displayUserAnswer={true} /> ))} {currentQuestion.type === QuestionTypes.Text && ( Your answer: )} Save answer {(isAllAnswered || isLastPage) && ( )} setOpenCompleteDialog(false)} > Complete test {alertDialogMessage} Complete ); }; const styles = StyleSheet.create({ container: { flex: 1, width: "100%" }, top: { width: "100%", marginBottom: 15, }, topScrollView: { flexDirection: "row", alignItems: "flex-start", gap: 10, }, content: { flex: 1, width: "100%", }, }); export default DoingUserTestScreen;