Update : fixed position on the left and right sides, can only scroll for the middle

This commit is contained in:
percyfikri 2024-10-23 15:31:13 +07:00
parent d4c8e90670
commit 54e496355b

View File

@ -23,7 +23,7 @@ import {
getQuestionsAllQueryOptions, getQuestionsAllQueryOptions,
toggleFlagAnswer, toggleFlagAnswer,
} from "@/modules/assessmentManagement/queries/assessmentQueries"; } from "@/modules/assessmentManagement/queries/assessmentQueries";
import { TbFlagFilled, TbUpload, TbChevronRight, TbChevronUp } from "react-icons/tb"; import { TbFlagFilled, TbUpload, TbChevronRight, TbChevronDown } from "react-icons/tb";
import FinishAssessmentModal from "@/modules/assessmentManagement/modals/ConfirmModal"; import FinishAssessmentModal from "@/modules/assessmentManagement/modals/ConfirmModal";
import ValidationModal from "@/modules/assessmentManagement/modals/ValidationModal"; import ValidationModal from "@/modules/assessmentManagement/modals/ValidationModal";
import { useState, useRef, useEffect } from "react"; import { useState, useRef, useEffect } from "react";
@ -505,58 +505,63 @@ export default function AssessmentPage() {
{/* LEFT-SIDE */} {/* LEFT-SIDE */}
{/* Aspek dan Sub-Aspek */} {/* Aspek dan Sub-Aspek */}
<Flex direction="column" gap="xs" className="w-64"> <div className="fixed h-screen w-64 overflow-auto">
<div className="space-y-2"> <Flex direction="column" gap="xs" className="w-64">
{/* Aspek */} <div className="space-y-2">
{aspectsQuery.data?.data {/* Aspek */}
.filter((aspect) => {aspectsQuery.data?.data
aspect.subAspects.some((subAspect) => .filter((aspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) aspect.subAspects.some((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
)
) )
) .map((aspect) => (
.map((aspect) => (
<div
key={aspect.id}
className="p-2 "
>
<div <div
className="flex justify-between cursor-pointer" key={aspect.id}
onClick={() => toggleAspect(aspect.id)} className="p-2 "
> >
<div className="text-sm font-bold px-3">{aspect.name}</div> <div
<div> className="flex justify-between cursor-pointer"
{openAspects[aspect.id] ? ( onClick={() => toggleAspect(aspect.id)}
<TbChevronUp size={25} /> >
) : ( <div className="text-sm font-bold px-3">{aspect.name}</div>
<TbChevronRight size={25} /> <div>
)} {openAspects[aspect.id] ? (
<TbChevronDown size={25} />
) : (
<TbChevronRight size={25} />
)}
</div>
</div> </div>
</div>
{/* Sub-Aspek */} {/* Sub-Aspek */}
{openAspects[aspect.id] && ( {openAspects[aspect.id] && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
{aspect.subAspects {aspect.subAspects
.filter((subAspect) => .filter((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id) data?.data.some((question) => question.subAspectId === subAspect.id)
) )
.map((subAspect) => ( .map((subAspect) => (
<div <div
key={subAspect.id} key={subAspect.id}
className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`} className={`flex justify-between cursor-pointer p-2 px-6 rounded-sm transition-colors duration-150 ${selectedSubAspectId === subAspect.id ? 'text-black font-medium bg-gray-200' : 'text-gray-500'}`}
onClick={() => setSelectedSubAspectId(subAspect.id)} onClick={() => setSelectedSubAspectId(subAspect.id)}
> >
<div className="text-xs">{subAspect.name}</div> <div className="text-xs">{subAspect.name}</div>
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
))} ))}
</div> </div>
</Flex> </Flex>
</div>
{/* MIDDLE */}
{/* Pertanyaan */} {/* Pertanyaan */}
{/* <div className="w-full ml-64"></div> */}
<div className="ml-64 mr-72 flex-1 overflow-y-auto h-full">
<Stack gap="sm" style={{ flex: 1 }}> <Stack gap="sm" style={{ flex: 1 }}>
<Text className="text-2xl font-bold ml-6"> <Text className="text-2xl font-bold ml-6">
Harap menjawab semua pertanyaan yang tersedia Harap menjawab semua pertanyaan yang tersedia
@ -580,9 +585,9 @@ export default function AssessmentPage() {
<Stack gap="sm"> <Stack gap="sm">
<Flex justify="space-between" align="flex-start" style={{ width: "100%" }}> <Flex justify="space-between" align="flex-start" style={{ width: "100%" }}>
{/* Question */} {/* Question */}
<Text className="font-bold mx-3 p-1">{startIndex + index + 1}.</Text> <Text className="font-bold mx-3 p-1 text-sm">{startIndex + index + 1}.</Text>
<div className="flex-grow"> <div className="flex-grow">
<Text className="font-bold break-words text-sm"> <Text className="font-bold break-words text-sm p-1">
{question.questionText} {question.questionText}
</Text> </Text>
</div> </div>
@ -703,7 +708,7 @@ export default function AssessmentPage() {
)} )}
</div> </div>
<div className="ml-6"> <div className="mx-11 px-1">
{uploadedFiles[question.questionId] && ( {uploadedFiles[question.questionId] && (
<Stack gap="sm" mt="sm"> <Stack gap="sm" mt="sm">
<Text className="font-bold">File yang diunggah:</Text> <Text className="font-bold">File yang diunggah:</Text>
@ -728,93 +733,96 @@ export default function AssessmentPage() {
}) })
)} )}
</Stack> </Stack>
</div>
{/* RIGHT-SIDE */}
{/* Navigasi dan Pagination */} {/* Navigasi dan Pagination */}
<Flex direction="column" gap="xs" className="mx-4"> <div className="fixed h-screen right-0 w-72 overflow-auto mr-4">
<Flex direction="column" gap="xs" className="mx-4">
{/* Navigasi (Number of Questions) */} {/* Navigasi (Number of Questions) */}
<div className="grid grid-cols-5 gap-2"> <div className="grid grid-cols-5 gap-2">
{filteredQuestions.map((question, index) => { {filteredQuestions.map((question, index) => {
const questionId = question.questionId; const questionId = question.questionId;
if (!questionId) return null; if (!questionId) return null;
// Menentukan nomor soal berdasarkan indeks pertanyaan yang difilter // Menentukan nomor soal berdasarkan indeks pertanyaan yang difilter
const questionNumber = index + 1; // Nomor pertanyaan dimulai dari 1 const questionNumber = index + 1; // Nomor pertanyaan dimulai dari 1
return ( return (
<div key={questionId} className="flex justify-center relative"> <div key={questionId} className="flex justify-center relative">
<button <button
className={`w-9 h-9 border rounded-sm flex items-center justify-center relative text-md className={`w-9 h-9 border rounded-sm flex items-center justify-center relative text-md
${flaggedQuestions[questionId] ? "text-black" : "bg-transparent text-black"}`} ${flaggedQuestions[questionId] ? "text-black" : "bg-transparent text-black"}`}
onClick={() => scrollToQuestion(questionId)} onClick={() => scrollToQuestion(questionId)}
> >
{questionNumber} {/* Menampilkan nomor pertanyaan yang sudah difilter */} {questionNumber} {/* Menampilkan nomor pertanyaan yang sudah difilter */}
</button>
{flaggedQuestions[questionId] && (
<div className="absolute top-0 right-0 w-0 h-0 border-b-[20px] border-b-transparent border-r-[20px] border-r-black rounded-e-md" />
)}
</div>
);
})}
</div>
<div className="mt-4 flex justify-center">
<Pagination
value={page}
total={Math.ceil(totalQuestions / limit)}
onChange={handlePageChange}
/>
</div>
{/* Skor Aspek dan Sub-Aspek */}
<div className="mt-4">
<Card shadow="sm" p="md" radius="md" withBorder>
<Stack>
{/* Skor Aspek */}
<div>
{filteredAspects.length > 0 ? (
filteredAspects.map((aspect) => (
<div key={aspect.aspectId} className="flex justify-between items-center">
<Text className="text-base text-gray-400">{aspect.aspectName}</Text>
<Text className="text-base font-bold">
{parseFloat(aspect.averageScore).toFixed(2)}
</Text>
</div>
))
) : (
<Text className="text-lg text-gray-400">Data aspek kosong</Text>
)}
</div>
{/* Garis pembatas */}
<div>
<hr className="border-t-2 border-gray-300 w-full mx-auto" />
</div>
{/* Skor Sub-Aspek */}
<div>
{filteredSubAspects.length > 0 ? (
filteredSubAspects.map((subAspect) => (
<div key={subAspect.subAspectId} className="flex justify-between items-center"> {/* Change key to 'id' */}
<Text className="text-sm text-gray-400">{subAspect.subAspectName}</Text> {/* Change to 'name' */}
<Text className="text-sm font-bold">
{parseFloat(subAspect.averageScore).toFixed(2)}
</Text>
</div>
))
) : (
<Text className="text-lg text-gray-400">Data sub-aspek kosong</Text>
)}
</div>
</Stack>
{/* Tombol Selesai */}
<div className="mt-6">
<button onClick={handleFinishClick} className="bg-blue-500 text-white font-bold rounded-md py-2 w-full text-sm">
Selesai
</button> </button>
{flaggedQuestions[questionId] && (
<div className="absolute top-0 right-0 w-0 h-0 border-b-[20px] border-b-transparent border-r-[20px] border-r-black rounded-e-md" />
)}
</div> </div>
);
})}
</div>
<div className="mt-4 flex justify-center">
<Pagination
value={page}
total={Math.ceil(totalQuestions / limit)}
onChange={handlePageChange}
/>
</div>
{/* Skor Aspek dan Sub-Aspek */}
<div className="mt-4">
<Card shadow="sm" p="md" radius="md" withBorder>
<Stack>
{/* Skor Aspek */}
<div>
{filteredAspects.length > 0 ? (
filteredAspects.map((aspect) => (
<div key={aspect.aspectId} className="flex justify-between items-center">
<Text className="text-base text-gray-400">{aspect.aspectName}</Text>
<Text className="text-base font-bold">
{parseFloat(aspect.averageScore).toFixed(2)}
</Text>
</div>
))
) : (
<Text className="text-lg text-gray-400">Data aspek kosong</Text>
)}
</div>
{/* Garis pembatas */}
<div>
<hr className="border-t-2 border-gray-300 w-full mx-auto" />
</div>
{/* Skor Sub-Aspek */}
<div>
{filteredSubAspects.length > 0 ? (
filteredSubAspects.map((subAspect) => (
<div key={subAspect.subAspectId} className="flex justify-between items-center"> {/* Change key to 'id' */}
<Text className="text-sm text-gray-400">{subAspect.subAspectName}</Text> {/* Change to 'name' */}
<Text className="text-sm font-bold">
{parseFloat(subAspect.averageScore).toFixed(2)}
</Text>
</div>
))
) : (
<Text className="text-lg text-gray-400">Data sub-aspek kosong</Text>
)}
</div>
</Stack>
{/* Tombol Selesai */}
<div className="mt-6">
<button onClick={handleFinishClick} className="bg-blue-500 text-white font-bold rounded-md py-2 w-full text-sm">
Selesai
</button>
</div>
{/* Modal untuk konfirmasi selesai asesmen */} {/* Modal untuk konfirmasi selesai asesmen */}
<FinishAssessmentModal <FinishAssessmentModal
@ -833,6 +841,7 @@ export default function AssessmentPage() {
</Card> </Card>
</div> </div>
</Flex> </Flex>
</div>
</Flex> </Flex>
</Stack> </Stack>
</div> </div>