From 0c8a08554bfa5a3104d255839263588dd011e9c8 Mon Sep 17 00:00:00 2001 From: abiyasa05 Date: Wed, 9 Oct 2024 11:48:04 +0700 Subject: [PATCH] create: add file index for assessment --- .../assessment/index.lazy.tsx | 450 ++++++++++++++++++ .../_dashboardLayout/assessment/index.tsx | 18 + 2 files changed, 468 insertions(+) create mode 100644 apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx create mode 100644 apps/frontend/src/routes/_dashboardLayout/assessment/index.tsx diff --git a/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx b/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx new file mode 100644 index 0000000..5ca5be0 --- /dev/null +++ b/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx @@ -0,0 +1,450 @@ +import { createLazyFileRoute } from "@tanstack/react-router"; +import { + Card, + Flex, + Pagination, + Stack, + Radio, + Text, + Textarea, + Loader, + ActionIcon, + CloseButton, + Group, +} from "@mantine/core"; +import { useQuery, useMutation } from "@tanstack/react-query"; +import { + getAverageScoreSubAspectQueryOptions, + getAverageScoreQueryOptions, + fetchAspects, + submitAnswerMutationOptions, + getQuestionsAllQueryOptions, + toggleFlagAnswer, +} from "@/modules/assessmentManagement/queries/assessmentQueries"; +import { TbFlag, TbUpload, TbChevronRight, TbChevronUp } from "react-icons/tb"; +import { useState, useRef } from "react"; + +export const Route = createLazyFileRoute("/_dashboardLayout/assessment/")({ + component: AssessmentPage, +}); + +interface ToggleFlagResponse { + message: string; + answer: { + id: string; + createdAt: string | null; + updatedAt: string | null; + optionId: string | null; + assessmentId: string | null; + isFlagged: boolean | null; + filename: string | null; + validationInformation: string; + }; +} + +export default function AssessmentPage() { + const [page, setPage] = useState(1); + const limit = 2; + const questionRefs = useRef<{ [key: string]: HTMLDivElement | null }>({}); + const [files, setFiles] = useState([]); + const [dragActive, setDragActive] = useState(false); + const [flaggedQuestions, setFlaggedQuestions] = useState<{ + [key: string]: boolean; + }>({}); + const fileInputRef = useRef(null); + + // Fetching questions data using useQuery + const { data, isLoading, isError, error } = useQuery( + getQuestionsAllQueryOptions(page, limit) + ); + + // Tambahkan state untuk aspek yang terbuka + const [openAspects, setOpenAspects] = useState<{ [key: string]: boolean }>({}); + + const toggleAspect = (aspectId: string) => { + setOpenAspects((prev) => ({ + ...prev, + [aspectId]: !prev[aspectId], // Toggle state untuk aspek yang diklik + })); + }; + + // Fetch aspects and sub-aspects + const aspectsQuery = useQuery({ + queryKey: ["aspects"], + queryFn: fetchAspects, + }); + + // Fetch average scores + const assessmentId = "aqduqcdc1mhnbz8zrpnmx9oj"; // Replace with actual assessment ID + const averageScoreQuery = useQuery( + getAverageScoreQueryOptions(assessmentId) + ); + + // Fetch average scores for sub-aspects + const averageScoreSubAspectQuery = useQuery( + getAverageScoreSubAspectQueryOptions(assessmentId) + ); + + // Mutation function to toggle flag + const toggleFlagMutation = useMutation({ + mutationFn: toggleFlagAnswer, + onSuccess: (response) => { + if (response && response.answer) { + const { answer } = response; + setFlaggedQuestions((prevFlags) => ({ + ...prevFlags, + [answer.id]: answer.isFlagged !== null ? answer.isFlagged : false, + })); + } + }, + + onError: (error) => { + console.error("Error toggling flag:", error); + }, + }); + + // Inside the AssessmentPage function: + const submitAnswerMutation = useMutation(submitAnswerMutationOptions()); + + // Drag and Drop handlers + const handleDragOver = (event: React.DragEvent) => { + event.preventDefault(); + setDragActive(true); + }; + + const handleDragLeave = () => { + setDragActive(false); + }; + + const handleDrop = (event: React.DragEvent) => { + event.preventDefault(); + setDragActive(false); + const droppedFiles = Array.from(event.dataTransfer.files); + setFiles((prevFiles) => [...prevFiles, ...droppedFiles]); + }; + + const handleClick = () => { + if (fileInputRef.current) { + fileInputRef.current.click(); + } + }; + + const handleFileChange = (event: React.ChangeEvent) => { + if (event.target.files) { + const fileArray = Array.from(event.target.files); // Ubah ke array hanya jika files tidak null + setFiles((prevFiles) => [...prevFiles, ...fileArray]); + } + }; + + const handleRemoveFile = (fileIndex: number) => { + setFiles((prevFiles) => + prevFiles.filter((_, index) => index !== fileIndex) + ); + }; + + // Function to scroll to the specific question + const scrollToQuestion = (questionId: string) => { + const questionElement = questionRefs.current[questionId]; + if (questionElement) { + questionElement.scrollIntoView({ behavior: "smooth" }); + } + }; + + // Handle pagination + const handlePageChange = (newPage: number) => { + setPage(newPage); + }; + + // Render conditions + if (isLoading) { + return ; + } + + if (isError) { + return ( + + Error: {error?.message || "Terjadi kesalahan saat memuat pertanyaan."} + + ); + } + + const totalQuestions = data?.data?.length || 0; + const averageScores = averageScoreQuery.data?.aspects; + const averageScoresSubAspect = averageScoreSubAspectQuery.data?.subAspects; + + return ( + + + + Harap menjawab semua pertanyaan yang tersedia + + Semua jawaban Anda akan ditinjau + + + {/* Pertanyaan */} + + {data?.data?.map((question: any, index: number) => { + const questionId = question.questionId; + if (!questionId) return null; + + return ( + (questionRefs.current[questionId] = el)} + style={{ position: "relative" }} + > + + + + {index + 1}. {question.questionText} + + + { + setFlaggedQuestions((prevFlags) => ({ + ...prevFlags, + [questionId]: !prevFlags[questionId], + })); + toggleFlagMutation.mutate(questionId); + }} + title="Tandai" + color={flaggedQuestions[questionId] ? "red" : "gray"} + > + + + + + {question.options?.length > 0 ? ( + +
+ {question.options.map((option: any) => ( + + ))} +
+
+ ) : ( + Tidak ada opsi untuk pertanyaan ini. + )} + +