From 521d39f7f66dd339844557923d30f2b64ed1af1e Mon Sep 17 00:00:00 2001 From: abiyasa05 Date: Tue, 22 Oct 2024 08:14:00 +0700 Subject: [PATCH] update: index lazy for upload file on database and local storage --- .../assessment/index.lazy.tsx | 316 ++++++++++++------ 1 file changed, 206 insertions(+), 110 deletions(-) diff --git a/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx b/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx index 11c3a74..2efc965 100644 --- a/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx +++ b/apps/frontend/src/routes/_dashboardLayout/assessment/index.lazy.tsx @@ -14,6 +14,7 @@ import { } from "@mantine/core"; import { useQuery, useMutation } from "@tanstack/react-query"; import { + uploadFileMutationOptions, submitValidationMutationOptions, submitOptionMutationOptions, getAverageScoreQueryOptions, @@ -63,6 +64,7 @@ export default function AssessmentPage() { const [assessmentId, setAssessmentId] = useState(null); const [answers, setAnswers] = useState<{ [key: string]: string }>({}); const [validationInformation, setValidationInformation] = useState<{ [key: string]: string }>({}); + const [uploadedFiles, setUploadedFiles] = useState<{ [key: string]: File | null }>({}); // Fetch aspects and sub-aspects const aspectsQuery = useQuery({ @@ -233,6 +235,9 @@ export default function AssessmentPage() { } }; + // Mutation for file upload + const uploadFileMutation = useMutation(uploadFileMutationOptions()); + // Drag and Drop handlers const handleDragOver = (event: React.DragEvent) => { event.preventDefault(); @@ -243,12 +248,59 @@ export default function AssessmentPage() { setDragActive(false); }; - const handleDrop = (event: React.DragEvent) => { + // Load uploaded files from local storage when the component mounts + 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 + })); + } + }); + }, [assessmentId]); + + const handleDrop = (event: React.DragEvent, question: { questionId: string }) => { event.preventDefault(); setDragActive(false); const droppedFiles = Array.from(event.dataTransfer.files); - setFiles((prevFiles) => [...prevFiles, ...droppedFiles]); - }; + if (droppedFiles.length > 0) { + const formData = new FormData(); + formData.append('file', droppedFiles[0]); // Hanya menyertakan file pertama + + // 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 + } + + // 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]: droppedFiles[0], // Simpan file berdasarkan questionId + })); + localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({ + name: droppedFiles[0].name, + type: droppedFiles[0].type, + lastModified: droppedFiles[0].lastModified, + })); // Simpan info file ke local storage + } + }; const handleClick = () => { if (fileInputRef.current) { @@ -256,17 +308,51 @@ export default function AssessmentPage() { } }; - const handleFileChange = (event: React.ChangeEvent) => { + const handleFileChange = (event: React.ChangeEvent, question: { questionId: string }) => { if (event.target.files) { - const fileArray = Array.from(event.target.files); // Ubah ke array hanya jika files tidak null - setFiles((prevFiles) => [...prevFiles, ...fileArray]); - } - }; + const fileArray = Array.from(event.target.files); + if (fileArray.length > 0) { + const formData = new FormData(); + formData.append('file', fileArray[0]); // Hanya menyertakan file pertama - const handleRemoveFile = (fileIndex: number) => { - setFiles((prevFiles) => - prevFiles.filter((_, index) => index !== fileIndex) - ); + // 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]: fileArray[0], // Simpan file berdasarkan questionId + })); + localStorage.setItem(`uploadedFile_${assessmentId}_${question.questionId}`, JSON.stringify({ + name: fileArray[0].name, + type: fileArray[0].type, + lastModified: fileArray[0].lastModified, + })); // Simpan info file ke local storage + } + } + }; + + const handleRemoveFile = (question: { questionId: string }) => { + setUploadedFiles(prev => ({ + ...prev, + [question.questionId]: null, // Hapus file yang diunggah untuk pertanyaan ini + })); + localStorage.removeItem(`uploadedFile_${assessmentId}_${question.questionId}`); // Hapus info file dari local storage }; // Function to scroll to the specific question @@ -316,7 +402,7 @@ export default function AssessmentPage() { }); return ( - +
@@ -372,10 +458,10 @@ export default function AssessmentPage() { {/* 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. @@ -386,28 +472,21 @@ export default function AssessmentPage() { if (!questionId) return null; return ( - (questionRefs.current[questionId] = el)} - style={{ position: "relative" }} + className="space-y-4" > - - {startIndex + index + 1}. {question.questionText} - + {startIndex + index + 1}. +
+ + {question.questionText} + +
+ {/* Action Icon */} { setFlaggedQuestions((prevFlags) => ({ @@ -440,92 +519,109 @@ export default function AssessmentPage() {
+ {/* Opsi Radio Button */} {question.options?.length > 0 ? ( - -
- {question.options.map((option: any) => ( - - ))} -
-
+
+ +
+ {question.options.map((option: any) => ( + + ))} +
+
+
) : ( Tidak ada opsi untuk pertanyaan ini. )} -