- {/* Aspek */}
- {aspectsQuery.data?.data
- .filter((aspect) =>
- aspect.subAspects.some((subAspect) =>
- data?.data.some((question) => question.subAspectId === subAspect.id)
- )
+
@@ -920,73 +914,71 @@ export default function AssessmentPage() {
Nilai Sementara
-
- {filteredAspects.length > 0 ? (
- filteredAspects.map((aspect) => {
- const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
- const aspectScoreValue = parseFloat(aspectScore);
+
+ {filteredAspects.length > 0 ? (
+ filteredAspects.map((aspect) => {
+ const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
+ const aspectScoreValue = parseFloat(aspectScore);
- return (
-
-
{aspect.aspectName}
-
= 4.5
- ? "text-green-700"
- : aspectScoreValue >= 3.5
- ? "text-green-400"
- : aspectScoreValue >= 2.5
+ return (
+
+ {aspect.aspectName}
+ = 4.5
+ ? "text-green-700"
+ : aspectScoreValue >= 3.5
+ ? "text-green-400"
+ : aspectScoreValue >= 2.5
? "text-yellow-400"
: aspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
+ ? "text-orange-500"
+ : "text-red-500"
}`}
- >
- {aspectScore}
-
-
- );
- })
- ) : (
- Data aspek ini kosong
- )}
-
+ >
+ {aspectScore}
+
+
+ );
+ })
+ ) : (
+
Data aspek ini kosong
+ )}
+
- {/* Divider */}
-
+ {/* Divider */}
+
- {/* Skor Sub-Aspek */}
-
- {filteredSubAspects.length > 0 ? (
- filteredSubAspects.map((subAspect) => {
- const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
- const subAspectScoreValue = parseFloat(subAspectScore);
+ {/* Skor Sub-Aspek */}
+
+ {filteredSubAspects.length > 0 ? (
+ filteredSubAspects.map((subAspect) => {
+ const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
+ const subAspectScoreValue = parseFloat(subAspectScore);
- return (
-
-
{subAspect.subAspectName}
-
= 4.5
- ? "text-green-700"
- : subAspectScoreValue >= 3.5
- ? "text-green-400"
- : subAspectScoreValue >= 2.5
+ return (
+
+ {subAspect.subAspectName}
+ = 4.5
+ ? "text-green-700"
+ : subAspectScoreValue >= 3.5
+ ? "text-green-400"
+ : subAspectScoreValue >= 2.5
? "text-yellow-400"
: subAspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
+ ? "text-orange-500"
+ : "text-red-500"
}`}
- >
- {subAspectScore}
-
-
- );
- })
- ) : (
- Data sub-aspek ini kosong
- )}
-
+ >
+ {subAspectScore}
+
+
+ );
+ })
+ ) : (
+
Data sub-aspek ini kosong
+ )}
+
{/* Finish Button */}
@@ -1019,11 +1011,11 @@ export default function AssessmentPage() {
{/* Sidebar for desktop (always visible) */}
-
-
-
- Nomor Soal
-
+
+
+
+ Nomor Soal
+
{/* Navigasi (Number of Questions) */}
@@ -1050,126 +1042,128 @@ export default function AssessmentPage() {
) : null;
})}
+
-
-
{
- if (selectedSubAspectId) {
- handlePageChange(selectedSubAspectId, newPage);
- }
- }}
- >
- Halaman {currentPage} dari {totalPages}
-
-
+ {/* Pagination */}
+
+
{
+ if (selectedSubAspectId) {
+ handlePageChange(selectedSubAspectId, newPage);
+ }
+ }}
+ >
+ Halaman {currentPage} dari {totalPages}
+
+
+
{/* Skor Aspek dan Sub-Aspek */}
-
+
Nilai Sementara
-
-
-
-
- {filteredAspects.length > 0 ? (
- filteredAspects.map((aspect) => {
- const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
- const aspectScoreValue = parseFloat(aspectScore);
-
- return (
-
- {aspect.aspectName}
- = 4.5
- ? "text-green-700"
- : aspectScoreValue >= 3.5
- ? "text-green-400"
- : aspectScoreValue >= 2.5
- ? "text-yellow-400"
- : aspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
- }`}
- >
- {aspectScore}
-
-
- );
- })
- ) : (
- Data aspek ini kosong
- )}
-
-
- {/* Garis pembatas */}
-
-
- {/* Skor Sub-Aspek */}
- {filteredSubAspects.length > 0 ? (
- filteredSubAspects.map((subAspect) => {
- const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
- const subAspectScoreValue = parseFloat(subAspectScore);
+
+
+
+
+ {filteredAspects.length > 0 ? (
+ filteredAspects.map((aspect) => {
+ const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
+ const aspectScoreValue = parseFloat(aspectScore);
return (
-
-
{subAspect.subAspectName}
-
= 4.5
- ? "text-green-700"
- : subAspectScoreValue >= 3.5
+
+ {aspect.aspectName}
+ = 4.5
+ ? "text-green-700"
+ : aspectScoreValue >= 3.5
? "text-green-400"
- : subAspectScoreValue >= 2.5
- ? "text-yellow-400"
- : subAspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
- }`}
+ : aspectScoreValue >= 2.5
+ ? "text-yellow-400"
+ : aspectScoreValue >= 1.5
+ ? "text-orange-500"
+ : "text-red-500"
+ }`}
>
- {subAspectScore}
-
+ {aspectScore}
+
);
})
) : (
- Data sub-aspek ini kosong
+ Data aspek ini kosong
)}
-
- {/* Tombol Selesai */}
-
-
- Selesai
-
-
-
+
- {/* Modal untuk konfirmasi selesai asesmen */}
- setModalOpen(false)}
- onConfirm={handleConfirmFinish}
- assessmentId={assessmentId}
- />
+ {/* Garis pembatas */}
+
- {/* Modal untuk peringatan jika ada pertanyaan yang belum dijawab */}
- setValidationModalOpen(false)}
- unansweredQuestions={unansweredQuestions}
- />
+ {/* Skor Sub-Aspek */}
+ {filteredSubAspects.length > 0 ? (
+ filteredSubAspects.map((subAspect) => {
+ const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
+ const subAspectScoreValue = parseFloat(subAspectScore);
+
+ return (
+
+ {subAspect.subAspectName}
+ = 4.5
+ ? "text-green-700"
+ : subAspectScoreValue >= 3.5
+ ? "text-green-400"
+ : subAspectScoreValue >= 2.5
+ ? "text-yellow-400"
+ : subAspectScoreValue >= 1.5
+ ? "text-orange-500"
+ : "text-red-500"
+ }`}
+ >
+ {subAspectScore}
+
+
+ );
+ })
+ ) : (
+ Data sub-aspek ini kosong
+ )}
+
+
+ {/* Tombol Selesai */}
+
+
+ Selesai
+
+
+
+
+ {/* Modal untuk konfirmasi selesai asesmen */}
+ setModalOpen(false)}
+ onConfirm={handleConfirmFinish}
+ assessmentId={assessmentId}
+ />
+
+ {/* Modal untuk peringatan jika ada pertanyaan yang belum dijawab */}
+ setValidationModalOpen(false)}
+ unansweredQuestions={unansweredQuestions}
+ />
-
+
-
-
+
+
);
}
\ No newline at end of file
diff --git a/apps/frontend/src/routes/_verifyingLayout/verifying/index.lazy.tsx b/apps/frontend/src/routes/_verifyingLayout/verifying/index.lazy.tsx
index 771a45d..fedceff 100644
--- a/apps/frontend/src/routes/_verifyingLayout/verifying/index.lazy.tsx
+++ b/apps/frontend/src/routes/_verifyingLayout/verifying/index.lazy.tsx
@@ -1,12 +1,6 @@
import { createLazyFileRoute } from "@tanstack/react-router";
import {
- Flex,
- Stack,
- Text,
Loader,
- ActionIcon,
- CloseButton,
- Group,
} from "@mantine/core";
import {
Card,
@@ -32,25 +26,22 @@ import {
} from "@/shadcn/components/ui/leftsheet";
import { useQuery, useMutation } from "@tanstack/react-query";
import {
- submitAssessmentMutationOptions,
uploadFileMutationOptions,
fetchAspects,
getQuestionsAllQueryOptions,
- toggleFlagAnswer,
} from "@/modules/assessmentManagement/queries/assessmentQueries";
-import {
+import {
getAnswersRevisionQueryOptions,
submitAssessmentRevisionMutationOptions,
updateOptionQuery,
updateValidationQuery,
} from "@/modules/assessmentResultsManagement/queries/assessmentResultsManagaementQueries";
-import {
+import {
getAllVerifiedAspectsAverageScore,
} from "@/modules/assessmentResult/queries/assessmentResultQueries";
import { TbLayoutSidebarLeftCollapseFilled, TbChevronRight, TbChevronDown } from "react-icons/tb";
import FinishAssessmentModal from "@/modules/assessmentManagement/modals/ConfirmModal";
import ValidationModal from "@/modules/assessmentManagement/modals/ValidationModal";
-import FileSizeValidationModal from "@/modules/assessmentManagement/modals/FileSizeValidationModal";
import { useState, useRef, useEffect } from "react";
import AppHeader from "@/components/AppHeader";
@@ -137,13 +128,13 @@ export default function AssessmentPage() {
useEffect(() => {
const id = getQueryParam("id");
-
+
if (!id) {
setAssessmentId(null);
} else {
setAssessmentId(id);
}
-
+
// Check if aspectsQuery.data is defined
if (aspectsQuery.data?.data && aspectsQuery.data.data.length > 0) {
// If no sub-aspect is selected, find a suitable default
@@ -153,15 +144,15 @@ export default function AssessmentPage() {
.find((subAspect) =>
data?.data.some((question) => question.subAspectId === subAspect.id)
);
-
+
if (firstMatchingSubAspect) {
setSelectedSubAspectId(firstMatchingSubAspect.id);
-
+
// Find the parent aspect and set its id as the selectedAspectId
const parentAspect = aspectsQuery.data.data.find((aspect) =>
aspect.subAspects.some((sub) => sub.id === firstMatchingSubAspect.id)
);
-
+
if (parentAspect) {
setSelectedAspectId(parentAspect.id); // Use `id` from the parent aspect
setOpenAspects({ [parentAspect.id]: true }); // Open only relevant aspects
@@ -172,7 +163,7 @@ export default function AssessmentPage() {
const matchingAspect = aspectsQuery.data.data.find((aspect) =>
aspect.subAspects.some((subAspect) => subAspect.id === selectedSubAspectId)
);
-
+
if (matchingAspect) {
setSelectedAspectId(matchingAspect.id); // Use `id` from the matching aspect
setOpenAspects({ [matchingAspect.id]: true }); // Close all other dropdowns and open only the newly selected aspect
@@ -185,17 +176,17 @@ export default function AssessmentPage() {
}
}, [aspectsQuery.data, selectedSubAspectId, data?.data]);
-// Fetching answers for the assessment
-const { data: answersData } = useQuery(
- getAnswersRevisionQueryOptions(assessmentId || "")
-);
+ // Fetching answers for the assessment
+ const { data: answersData } = useQuery(
+ getAnswersRevisionQueryOptions(assessmentId || "")
+ );
-const formattedResult = answersData?.data.reduce((acc, item) => {
- if (item.questionId != null && item.newOptionId != null) {
+ const formattedResult = answersData?.data.reduce((acc, item) => {
+ if (item.questionId != null && item.newOptionId != null) {
acc[item.questionId] = item.newOptionId;
- }
- return acc;
-}, {} as Record
);
+ }
+ return acc;
+ }, {} as Record);
// Effect untuk mengatur answers dari data yang diambil
useEffect(() => {
@@ -203,27 +194,27 @@ const formattedResult = answersData?.data.reduce((acc, item) => {
console.error();
return;
}
-
+
if (formattedResult) {
setAnswers(formattedResult);
}
- }, [answersData, assessmentId]);
+ }, [answersData, assessmentId]);
// Fungsi untuk memeriksa pertanyaan yang belum dijawab
const checkUnansweredQuestions = () => {
console.log("answer validation data:", answers);
// Filter pertanyaan yang belum dijawab berdasarkan data `answers`
const unanswered = data?.data.filter(question => {
- return question.questionId !== null && !answers[question.questionId];
+ return question.questionId !== null && !answers[question.questionId];
}) || [];
-console.log("unanswered questions:", unanswered.length);
+ console.log("unanswered questions:", unanswered.length);
setUnansweredQuestions(unanswered.length);
// Tampilkan modal berdasarkan jumlah pertanyaan yang belum dijawab
if (unanswered.length > 0) {
- setValidationModalOpen(true);
+ setValidationModalOpen(true);
} else {
- setModalOpen(true);
+ setModalOpen(true);
}
};
@@ -234,19 +225,19 @@ console.log("unanswered questions:", unanswered.length);
const handleConfirmFinish = async (assessmentId: string) => {
try {
- // Skip counting unanswered questions here to prevent duplication
- const mutation = submitAssessmentRevisionMutationOptions(assessmentId);
- const response = await mutation.mutationFn();
+ // Skip counting unanswered questions here to prevent duplication
+ const mutation = submitAssessmentRevisionMutationOptions(assessmentId);
+ const response = await mutation.mutationFn();
- // Navigate to results
- const newUrl = `/assessmentResult?id=${assessmentId}`;
- window.history.pushState({}, "", newUrl);
- console.log("Navigated to:", newUrl);
- console.log(response.message);
+ // Navigate to results
+ const newUrl = `/assessmentResult?id=${assessmentId}`;
+ window.history.pushState({}, "", newUrl);
+ console.log("Navigated to:", newUrl);
+ console.log(response.message);
} catch (error) {
- console.error("Error finishing assessment:", error);
+ console.error("Error finishing assessment:", error);
} finally {
- setModalOpen(false);
+ setModalOpen(false);
}
};
@@ -266,8 +257,8 @@ console.log("unanswered questions:", unanswered.length);
// Filter aspects by selected aspectId
const filteredAspects = selectedAspectId
- ? aspects.filter((aspect) => aspect.aspectId === selectedAspectId) // Use 'id' instead of 'aspectId'
- : aspects;
+ ? aspects.filter((aspect) => aspect.aspectId === selectedAspectId) // Use 'id' instead of 'aspectId'
+ : aspects;
// Get the currently selected aspect to show all related sub-aspects
const currentAspect = aspects.find(aspect => aspect.aspectId === selectedAspectId);
@@ -288,43 +279,20 @@ console.log("unanswered questions:", unanswered.length);
}
}, [flaggedQuestions]);
- // Mutation function to toggle flag
- // const toggleFlagMutation = useMutation({
- // mutationFn: toggleFlagAnswer,
- // onSuccess: (response) => {
- // if (response && response.answer) {
- // const { answer } = response;
- // setFlaggedQuestions((prevFlags) => {
- // const newFlags = {
- // ...prevFlags,
- // [answer.id]: answer.isFlagged !== null ? answer.isFlagged : false,
- // };
- // // Simpan perubahan ke localStorage
- // localStorage.setItem("flaggedQuestions", JSON.stringify(newFlags));
- // return newFlags;
- // });
- // }
- // },
-
- // onError: (error) => {
- // console.error("Error toggling flag:", error);
- // },
- // });
-
// Usage of the mutation in your component
const { mutate: submitOption } = useMutation({
mutationFn: (form: {
- assessmentId: string;
- questionId: string;
- optionId: string;
+ assessmentId: string;
+ questionId: string;
+ optionId: string;
}) => updateOptionQuery(form),
onSuccess: () => {
averageScoreQuery.refetch();
- // Tindakan yang diambil setelah berhasil
- console.log("Option updated successfully!");
+ // Tindakan yang diambil setelah berhasil
+ console.log("Option updated successfully!");
},
onError: (error) => {
- console.error("Error updating option:", error);
+ console.error("Error updating option:", error);
},
});
@@ -333,8 +301,8 @@ console.log("unanswered questions:", unanswered.length);
// Memastikan assessmentId adalah string yang valid
if (!assessmentId) {
- console.error("Assessment ID tidak ditemukan");
- return; // Keluar jika assessmentId tidak ada
+ console.error("Assessment ID tidak ditemukan");
+ return; // Keluar jika assessmentId tidak ada
}
// Update jawaban untuk pertanyaan tertentu
@@ -345,21 +313,21 @@ console.log("unanswered questions:", unanswered.length);
// Call the mutation to submit the option
submitOption({
- assessmentId, // Menggunakan assessmentId yang diperoleh dari parameter
- questionId,
- optionId, // Mengirim ID opsi yang dipilih
+ assessmentId, // Menggunakan assessmentId yang diperoleh dari parameter
+ questionId,
+ optionId, // Mengirim ID opsi yang dipilih
});
};
const validationResult = answersData?.data.reduce((acc, item) => {
if (item.questionId != null && item.newValidationInformation != null) {
- acc[item.questionId] = item.newValidationInformation;
+ acc[item.questionId] = item.newValidationInformation;
}
return acc;
}, {} as Record);
// Mengambil data dari database saat komponen dimuat
- useEffect(() => {
+ useEffect(() => {
if (validationResult) {
setValidationInformation(validationResult);
}
@@ -368,16 +336,16 @@ console.log("unanswered questions:", unanswered.length);
// Mutation untuk mengirim data ke backend
const { mutate: submitValidation } = useMutation({
mutationFn: (form: {
- assessmentId: string;
- questionId: string;
- newValidationInformation: string;
+ assessmentId: string;
+ questionId: string;
+ newValidationInformation: string;
}) => updateValidationQuery(form),
onSuccess: () => {
- // Tindakan yang diambil setelah berhasil
- console.log("Validation updated successfully!");
+ // Tindakan yang diambil setelah berhasil
+ console.log("Validation updated successfully!");
},
onError: (error) => {
- console.error("Error updating validation:", error);
+ console.error("Error updating validation:", error);
},
});
@@ -385,20 +353,20 @@ console.log("unanswered questions:", unanswered.length);
const handleTextareaChange = (questionId: string, value: string) => {
// Memperbarui state validationInformation
setValidationInformation((prev) => ({
- ...prev,
- [questionId]: value,
+ ...prev,
+ [questionId]: value,
}));
// Pastikan assessmentId tidak null sebelum mengirimkan data ke server
if (assessmentId) {
- // Kirim data validasi ke server
- submitValidation({
- assessmentId,
- questionId,
- newValidationInformation: value,
- });
+ // Kirim data validasi ke server
+ submitValidation({
+ assessmentId,
+ questionId,
+ newValidationInformation: value,
+ });
} else {
- console.error("Assessment ID tidak ditemukan");
+ console.error("Assessment ID tidak ditemukan");
}
};
@@ -419,14 +387,14 @@ console.log("unanswered questions:", unanswered.length);
useEffect(() => {
const keys = Object.keys(localStorage);
keys.forEach((key) => {
- if (key.startsWith(`uploadedFile_${assessmentId}_`)) { // Menggunakan assessmentId
- const fileData = JSON.parse(localStorage.getItem(key) || '{}');
- const questionId = key.replace(`uploadedFile_${assessmentId}_`, ''); // Ambil questionId dari kunci
- setUploadedFiles(prev => ({
- ...prev,
- [questionId]: new File([fileData], fileData.name, { type: fileData.type }), // Buat objek File baru
- }));
- }
+ if (key.startsWith(`uploadedFile_${assessmentId}_`)) { // Menggunakan assessmentId
+ const fileData = JSON.parse(localStorage.getItem(key) || '{}');
+ const questionId = key.replace(`uploadedFile_${assessmentId}_`, ''); // Ambil questionId dari kunci
+ setUploadedFiles(prev => ({
+ ...prev,
+ [questionId]: new File([fileData], fileData.name, { type: fileData.type }), // Buat objek File baru
+ }));
+ }
});
}, [assessmentId]);
@@ -437,51 +405,51 @@ console.log("unanswered questions:", unanswered.length);
event.preventDefault();
setDragActive(false);
const droppedFiles = Array.from(event.dataTransfer.files);
-
+
if (droppedFiles.length > 0) {
- const file = droppedFiles[0];
-
- // Validate file size
- if (file.size > MAX_FILE_SIZE) {
- setExceededFileName(file.name); // Simpan nama file yang melebihi ukuran
- setModalOpenFileSize(true); // Tampilkan modal
- return;
- }
+ const file = droppedFiles[0];
- const formData = new FormData();
- formData.append('file', file); // Hanya menyertakan file pertama
+ // Validate file size
+ if (file.size > MAX_FILE_SIZE) {
+ setExceededFileName(file.name); // Simpan nama file yang melebihi ukuran
+ setModalOpenFileSize(true); // Tampilkan modal
+ return;
+ }
- // Pastikan assessmentId tidak null sebelum menambahkannya ke FormData
- if (assessmentId) {
- formData.append('assessmentId', assessmentId);
- } else {
- console.error("assessmentId is null");
- return; // Atau tangani sesuai kebutuhan
- }
+ const formData = new FormData();
+ formData.append('file', file); // Hanya menyertakan file pertama
- // Tambahkan questionId ke FormData
- if (question.questionId) {
- formData.append('questionId', question.questionId);
- } else {
- console.error("questionId is null");
- return; // Atau tangani sesuai kebutuhan
- }
+ // Pastikan assessmentId tidak null sebelum menambahkannya ke FormData
+ if (assessmentId) {
+ formData.append('assessmentId', assessmentId);
+ } else {
+ console.error("assessmentId is null");
+ return; // Atau tangani sesuai kebutuhan
+ }
- uploadFileMutation.mutate(formData); // Unggah file
+ // Tambahkan questionId ke FormData
+ if (question.questionId) {
+ formData.append('questionId', question.questionId);
+ } else {
+ console.error("questionId is null");
+ return; // Atau tangani sesuai kebutuhan
+ }
- // Simpan file dalam state dan local storage menggunakan questionId dan assessmentId sebagai kunci
- setUploadedFiles(prev => ({
- ...prev,
- [question.questionId]: file, // Simpan file berdasarkan questionId
- }));
-
- localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({
- name: file.name,
- type: file.type,
- lastModified: file.lastModified,
- }));
+ uploadFileMutation.mutate(formData); // Unggah file
+
+ // Simpan file dalam state dan local storage menggunakan questionId dan assessmentId sebagai kunci
+ setUploadedFiles(prev => ({
+ ...prev,
+ [question.questionId]: file, // Simpan file berdasarkan questionId
+ }));
+
+ localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({
+ name: file.name,
+ type: file.type,
+ lastModified: file.lastModified,
+ }));
}
- };
+ };
const handleClick = () => {
if (fileInputRef.current) {
@@ -491,57 +459,57 @@ console.log("unanswered questions:", unanswered.length);
const handleFileChange = (event: React.ChangeEvent, question: { questionId: string }) => {
if (event.target.files) {
- const fileArray = Array.from(event.target.files);
- if (fileArray.length > 0) {
- const file = fileArray[0];
+ const fileArray = Array.from(event.target.files);
+ if (fileArray.length > 0) {
+ const file = fileArray[0];
- // Validate file size
- if (file.size > MAX_FILE_SIZE) {
- setExceededFileName(file.name); // Simpan nama file yang melebihi ukuran
- setModalOpenFileSize(true); // Tampilkan modal
- return; // Hentikan eksekusi fungsi jika ukuran file melebihi batas
- }
-
- const formData = new FormData();
- formData.append('file', file); // Hanya menyertakan file pertama
-
- // Tambahkan assessmentId ke FormData
- if (assessmentId) {
- formData.append('assessmentId', assessmentId);
- } else {
- console.error("assessmentId is null");
- return; // Atau tangani sesuai kebutuhan
- }
-
- // Tambahkan questionId ke FormData
- if (question.questionId) {
- formData.append('questionId', question.questionId);
- } else {
- console.error("questionId is null");
- return; // Atau tangani sesuai kebutuhan
- }
-
- uploadFileMutation.mutate(formData); // Unggah file
-
- // Simpan file dalam state dan local storage menggunakan questionId dan assessmentId sebagai kunci
- setUploadedFiles(prev => ({
- ...prev,
- [question.questionId]: file, // Simpan file berdasarkan questionId
- }));
-
- localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({
- name: file.name,
- type: file.type,
- lastModified: file.lastModified,
- }));
+ // Validate file size
+ if (file.size > MAX_FILE_SIZE) {
+ setExceededFileName(file.name); // Simpan nama file yang melebihi ukuran
+ setModalOpenFileSize(true); // Tampilkan modal
+ return; // Hentikan eksekusi fungsi jika ukuran file melebihi batas
}
+
+ const formData = new FormData();
+ formData.append('file', file); // Hanya menyertakan file pertama
+
+ // Tambahkan assessmentId ke FormData
+ if (assessmentId) {
+ formData.append('assessmentId', assessmentId);
+ } else {
+ console.error("assessmentId is null");
+ return; // Atau tangani sesuai kebutuhan
+ }
+
+ // Tambahkan questionId ke FormData
+ if (question.questionId) {
+ formData.append('questionId', question.questionId);
+ } else {
+ console.error("questionId is null");
+ return; // Atau tangani sesuai kebutuhan
+ }
+
+ uploadFileMutation.mutate(formData); // Unggah file
+
+ // Simpan file dalam state dan local storage menggunakan questionId dan assessmentId sebagai kunci
+ setUploadedFiles(prev => ({
+ ...prev,
+ [question.questionId]: file, // Simpan file berdasarkan questionId
+ }));
+
+ localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({
+ name: file.name,
+ type: file.type,
+ lastModified: file.lastModified,
+ }));
+ }
}
- };
+ };
const handleRemoveFile = (question: { questionId: string }) => {
setUploadedFiles(prev => ({
- ...prev,
- [question.questionId]: null, // Hapus file yang diunggah untuk pertanyaan ini
+ ...prev,
+ [question.questionId]: null, // Hapus file yang diunggah untuk pertanyaan ini
}));
localStorage.removeItem(`uploadedFile_${assessmentId}_${question.questionId}`); // Hapus info file dari local storage
};
@@ -561,9 +529,9 @@ console.log("unanswered questions:", unanswered.length);
if (isError) {
return (
-
+
Error: {error?.message || "Terjadi kesalahan saat memuat pertanyaan."}
-
+
);
}
@@ -571,9 +539,9 @@ console.log("unanswered questions:", unanswered.length);
return (
-
+
Error: Data Asesmen tidak ditemukan. Harap akses halaman melalui link yang valid.
-
+
);
@@ -602,20 +570,20 @@ console.log("unanswered questions:", unanswered.length);
const totalQuestionsInSubAspect = data?.data?.filter(
(question) => question.subAspectId === selectedSubAspectId
)?.length || 0;
-
+
const totalPages = Math.ceil(totalQuestionsInSubAspect / questionsPerPage);
return (
-
-
+
+
{/* LEFT-SIDE */}
{/* Aspek dan Sub-Aspek */}
{/* Sidebar for Mobile */}
@@ -623,7 +591,7 @@ console.log("unanswered questions:", unanswered.length);
setIsLeftSidebarOpen(open)}>
Aspek Menu
-
+
{/* Aspek */}
{aspectsQuery.data?.data
@@ -658,7 +626,7 @@ console.log("unanswered questions:", unanswered.length);
.map((subAspect) => (
setSelectedSubAspectId(subAspect.id)}
>
{subAspect.name}
@@ -669,75 +637,75 @@ console.log("unanswered questions:", unanswered.length);
))}
-
+
)}
{/* Sidebar for Desktop (Always Visible) */}
-
-
Aspek Menu
-
-
- {/* Aspek */}
- {aspectsQuery.data?.data
- .filter((aspect) =>
- aspect.subAspects.some((subAspect) =>
- data?.data.some((question) => question.subAspectId === subAspect.id)
- )
+
+
Aspek Menu
+
+
+ {/* Aspek */}
+ {aspectsQuery.data?.data
+ .filter((aspect) =>
+ aspect.subAspects.some((subAspect) =>
+ data?.data.some((question) => question.subAspectId === subAspect.id)
)
- .map((aspect) => (
-
-
toggleAspect(aspect.id)}
- >
-
{aspect.name}
-
- {openAspects[aspect.id] ? (
-
- ) : (
-
- )}
-
+ )
+ .map((aspect) => (
+
+
toggleAspect(aspect.id)}
+ >
+
{aspect.name}
+
+ {openAspects[aspect.id] ? (
+
+ ) : (
+
+ )}
-
- {/* Sub-Aspek */}
- {openAspects[aspect.id] && (
-
- {aspect.subAspects
- .filter((subAspect) =>
- data?.data.some((question) => question.subAspectId === subAspect.id)
- )
- .map((subAspect) => (
-
setSelectedSubAspectId(subAspect.id)}
- >
-
{subAspect.name}
-
- ))}
-
- )}
- ))}
-
-
+
+ {/* Sub-Aspek */}
+ {openAspects[aspect.id] && (
+
+ {aspect.subAspects
+ .filter((subAspect) =>
+ data?.data.some((question) => question.subAspectId === subAspect.id)
+ )
+ .map((subAspect) => (
+
setSelectedSubAspectId(subAspect.id)}
+ >
+
{subAspect.name}
+
+ ))}
+
+ )}
+
+ ))}
+
-
+
+
{/* MIDDLE */}
{/* Pertanyaan */}
-
-
+
+
Harap menjawab semua pertanyaan yang tersedia
-
- Semua jawaban Anda akan ditinjau
+
+
Semua jawaban Anda akan ditinjau
{filteredQuestions.length === 0 ? (
-
+
Pertanyaan tidak ada untuk sub-aspek yang dipilih.
-
+
) : (
filteredQuestions.map((question: any, index: number) => {
const questionId = question.questionId;
@@ -749,71 +717,69 @@ console.log("unanswered questions:", unanswered.length);
ref={(el) => (questionRefs.current[questionId] = el)}
className="space-y-4"
>
-
-
- {/* Question Number */}
-
{startIndex + index + 1}.
+
+ {/* Question Number */}
+ {startIndex + index + 1}.
- {/* Question Text */}
- {question.questionText}
-
+ {/* Question Text */}
+
{question.questionText}
+
- {/* Radio Button Options */}
- {question.options?.length > 0 ? (
-
-
handleAnswerChange(questionId, value)}
- className="flex flex-col gap-2"
- >
- {question.options.map((option: any) => (
- handleAnswerChange(questionId, option.optionId)}
- >
-
-
- {option.optionText}
-
-
- ))}
-
-
- ) : (
- Tidak ada opsi untuk pertanyaan ini.
- )}
-
- {/* Textarea for additional information */}
+ {/* Radio Button Options */}
+ {question.options?.length > 0 ? (
+ ) : (
+ Tidak ada opsi untuk pertanyaan ini.
+ )}
- {/* Divider between questions */}
-
-
-
-
+ {/* Textarea for additional information */}
+
+
+
+ {/* Divider between questions */}
+
+
+
);
})
)}
-
+
{/* Pagination for mobile */}
- Halaman {currentPage} dari {totalPages}
+ Halaman {currentPage} dari {totalPages}
@@ -884,73 +850,71 @@ console.log("unanswered questions:", unanswered.length);
Nilai Sementara
-
- {filteredAspects.length > 0 ? (
- filteredAspects.map((aspect) => {
- const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
- const aspectScoreValue = parseFloat(aspectScore);
+
+ {filteredAspects.length > 0 ? (
+ filteredAspects.map((aspect) => {
+ const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
+ const aspectScoreValue = parseFloat(aspectScore);
- return (
-
-
{aspect.aspectName}
-
= 4.5
- ? "text-green-700"
- : aspectScoreValue >= 3.5
- ? "text-green-400"
- : aspectScoreValue >= 2.5
+ return (
+
+ {aspect.aspectName}
+ = 4.5
+ ? "text-green-700"
+ : aspectScoreValue >= 3.5
+ ? "text-green-400"
+ : aspectScoreValue >= 2.5
? "text-yellow-400"
: aspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
+ ? "text-orange-500"
+ : "text-red-500"
}`}
- >
- {aspectScore}
-
-
- );
- })
- ) : (
- Data aspek ini kosong
- )}
-
+ >
+ {aspectScore}
+
+
+ );
+ })
+ ) : (
+
Data aspek ini kosong
+ )}
+
- {/* Divider */}
-
+ {/* Divider */}
+
- {/* Skor Sub-Aspek */}
-
- {filteredSubAspects.length > 0 ? (
- filteredSubAspects.map((subAspect) => {
- const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
- const subAspectScoreValue = parseFloat(subAspectScore);
+ {/* Skor Sub-Aspek */}
+
+ {filteredSubAspects.length > 0 ? (
+ filteredSubAspects.map((subAspect) => {
+ const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
+ const subAspectScoreValue = parseFloat(subAspectScore);
- return (
-
-
{subAspect.subAspectName}
-
= 4.5
- ? "text-green-700"
- : subAspectScoreValue >= 3.5
- ? "text-green-400"
- : subAspectScoreValue >= 2.5
+ return (
+
+ {subAspect.subAspectName}
+ = 4.5
+ ? "text-green-700"
+ : subAspectScoreValue >= 3.5
+ ? "text-green-400"
+ : subAspectScoreValue >= 2.5
? "text-yellow-400"
: subAspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
+ ? "text-orange-500"
+ : "text-red-500"
}`}
- >
- {subAspectScore}
-
-
- );
- })
- ) : (
- Data sub-aspek ini kosong
- )}
-
+ >
+ {subAspectScore}
+
+
+ );
+ })
+ ) : (
+
Data sub-aspek ini kosong
+ )}
+
{/* Finish Button */}
@@ -982,11 +946,11 @@ console.log("unanswered questions:", unanswered.length);
{/* Sidebar for desktop (always visible) */}
-
-
-
- Nomor Soal
-
+
+
+
+ Nomor Soal
+
{/* Navigasi (Number of Questions) */}
@@ -1013,126 +977,128 @@ console.log("unanswered questions:", unanswered.length);
) : null;
})}
+
-
-
{
- if (selectedSubAspectId) {
- handlePageChange(selectedSubAspectId, newPage);
- }
- }}
- >
- Halaman {currentPage} dari {totalPages}
-
-
+ {/* Pagination */}
+
+
{
+ if (selectedSubAspectId) {
+ handlePageChange(selectedSubAspectId, newPage);
+ }
+ }}
+ >
+ Halaman {currentPage} dari {totalPages}
+
+
+
{/* Skor Aspek dan Sub-Aspek */}
-
+
Nilai Sementara
-
-
-
-
- {filteredAspects.length > 0 ? (
- filteredAspects.map((aspect) => {
- const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
- const aspectScoreValue = parseFloat(aspectScore);
-
- return (
-
- {aspect.aspectName}
- = 4.5
- ? "text-green-700"
- : aspectScoreValue >= 3.5
- ? "text-green-400"
- : aspectScoreValue >= 2.5
- ? "text-yellow-400"
- : aspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
- }`}
- >
- {aspectScore}
-
-
- );
- })
- ) : (
- Data aspek ini kosong
- )}
-
-
- {/* Garis pembatas */}
-
-
- {/* Skor Sub-Aspek */}
- {filteredSubAspects.length > 0 ? (
- filteredSubAspects.map((subAspect) => {
- const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
- const subAspectScoreValue = parseFloat(subAspectScore);
+
+
+
+
+ {filteredAspects.length > 0 ? (
+ filteredAspects.map((aspect) => {
+ const aspectScore = parseFloat(aspect.averageScore).toFixed(2);
+ const aspectScoreValue = parseFloat(aspectScore);
return (
-
-
{subAspect.subAspectName}
-
= 4.5
- ? "text-green-700"
- : subAspectScoreValue >= 3.5
+
+ {aspect.aspectName}
+ = 4.5
+ ? "text-green-700"
+ : aspectScoreValue >= 3.5
? "text-green-400"
- : subAspectScoreValue >= 2.5
- ? "text-yellow-400"
- : subAspectScoreValue >= 1.5
- ? "text-orange-500"
- : "text-red-500"
- }`}
+ : aspectScoreValue >= 2.5
+ ? "text-yellow-400"
+ : aspectScoreValue >= 1.5
+ ? "text-orange-500"
+ : "text-red-500"
+ }`}
>
- {subAspectScore}
-
+ {aspectScore}
+
);
})
) : (
- Data sub-aspek ini kosong
+ Data aspek ini kosong
)}
-
- {/* Tombol Selesai */}
-
-
- Selesai
-
-
-
+
- {/* Modal untuk konfirmasi selesai asesmen */}
- setModalOpen(false)}
- onConfirm={handleConfirmFinish}
- assessmentId={assessmentId}
- />
+ {/* Garis pembatas */}
+
- {/* Modal untuk peringatan jika ada pertanyaan yang belum dijawab */}
- setValidationModalOpen(false)}
- unansweredQuestions={unansweredQuestions}
- />
+ {/* Skor Sub-Aspek */}
+ {filteredSubAspects.length > 0 ? (
+ filteredSubAspects.map((subAspect) => {
+ const subAspectScore = parseFloat(subAspect.averageScore).toFixed(2);
+ const subAspectScoreValue = parseFloat(subAspectScore);
+
+ return (
+
+ {subAspect.subAspectName}
+ = 4.5
+ ? "text-green-700"
+ : subAspectScoreValue >= 3.5
+ ? "text-green-400"
+ : subAspectScoreValue >= 2.5
+ ? "text-yellow-400"
+ : subAspectScoreValue >= 1.5
+ ? "text-orange-500"
+ : "text-red-500"
+ }`}
+ >
+ {subAspectScore}
+
+
+ );
+ })
+ ) : (
+ Data sub-aspek ini kosong
+ )}
+
+
+ {/* Tombol Selesai */}
+
+
+ Selesai
+
+
+
+
+ {/* Modal untuk konfirmasi selesai asesmen */}
+ setModalOpen(false)}
+ onConfirm={handleConfirmFinish}
+ assessmentId={assessmentId}
+ />
+
+ {/* Modal untuk peringatan jika ada pertanyaan yang belum dijawab */}
+ setValidationModalOpen(false)}
+ unansweredQuestions={unansweredQuestions}
+ />
-
+
-
-
-
+
+
+
);
}
\ No newline at end of file