From 82bf3a87090513a538000dbad1d2777d0a04e58e Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Thu, 21 Aug 2025 10:38:38 +0700 Subject: [PATCH 1/2] update : image detail approval --- components/form/content/image-detail-form.tsx | 396 ++++++++++++++---- 1 file changed, 313 insertions(+), 83 deletions(-) diff --git a/components/form/content/image-detail-form.tsx b/components/form/content/image-detail-form.tsx index d16491e2..21c4c98b 100644 --- a/components/form/content/image-detail-form.tsx +++ b/components/form/content/image-detail-form.tsx @@ -171,11 +171,16 @@ export default function FormImageDetail() { satker: false, }); const [isLoading, setIsLoading] = useState(false); - const [checkedLevels, setCheckedLevels] = useState(new Set()); + const [checkedLevels, setCheckedLevels] = useState>(new Set()); const [selectedTarget, setSelectedTarget] = useState(""); const [files, setFiles] = useState([]); const [rejectedFiles, setRejectedFiles] = useState([]); - const [expandedPolda, setExpandedPolda] = useState([{}]); + const [expandedPolda, setExpandedPolda] = useState>({}); + + // State untuk melacak apakah perubahan berasal dari checkbox utama + const [isUpdatingFromMainCheckbox, setIsUpdatingFromMainCheckbox] = useState(false); + // State untuk melacak jenis perubahan spesifik + const [mainCheckboxChangeType, setMainCheckboxChangeType] = useState(""); const [wilayahPublish, setWilayahPublish] = React.useState({ semua: false, nasional: false, @@ -240,30 +245,175 @@ export default function FormImageDetail() { fetchPoldaPolres(); }, []); + // useEffect untuk sinkronisasi checkbox modal dengan checkbox utama useEffect(() => { - const updated = new Set(checkedLevels); + if (listDest.length > 0 && isUpdatingFromMainCheckbox && mainCheckboxChangeType) { + syncModalWithMainCheckbox(); + } + }, [isUpdatingFromMainCheckbox, mainCheckboxChangeType]); - if (unitSelection.polda) { - listDest.forEach((polda) => { - updated.add(polda.id); // hanya id polda + // useEffect untuk update checkbox utama ketika pilihan modal berubah + useEffect(() => { + if (!isUpdatingFromMainCheckbox && listDest.length > 0) { + updateMainCheckboxFromModal(); + } + }, [checkedLevels, isUpdatingFromMainCheckbox]); + + // Fungsi untuk update checkbox utama berdasarkan checkbox modal + const updateMainCheckboxFromModal = () => { + if (!isUpdatingFromMainCheckbox && listDest.length > 0) { + // Hitung item yang dipilih berdasarkan checkedLevels + const checkedPoldaCount = listDest.filter((item: any) => + item.levelNumber === 2 && + item.name !== "SATKER POLRI" && + checkedLevels.has(Number(item.id)) + ).length; + + const checkedPolresCount = listDest.reduce((total: number, item: any) => { + if (item.subDestination && item.name !== "SATKER POLRI") { + // Hanya hitung sub-item dari POLDA (bukan dari SATKER POLRI) + return total + item.subDestination.filter((sub: any) => checkedLevels.has(Number(sub.id))).length; + } + return total; + }, 0); + + const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI"); + const checkedSatkerCount = satkerItem ? ( + (checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) + + (satkerItem.subDestination?.filter((sub: any) => checkedLevels.has(Number(sub.id))).length || 0) + ) : 0; + + // Checkbox aktif jika ADA item yang dipilih dalam kategori tersebut + const hasSelectedPolda = checkedPoldaCount > 0; + const hasSelectedPolres = checkedPolresCount > 0; + const hasSelectedSatker = checkedSatkerCount > 0; + + // Update unitSelection berdasarkan yang dipilih di modal + setUnitSelection(prev => { + const newState = { ...prev }; + + // Update individual checkboxes + newState.polda = hasSelectedPolda; + newState.polres = hasSelectedPolres; + newState.satker = hasSelectedSatker; + + // Update checkbox "semua" berdasarkan semua checkbox yang aktif + newState.semua = newState.nasional && newState.wilayah && newState.international && hasSelectedPolda && hasSelectedPolres && hasSelectedSatker; + + return newState; }); } + }; - if (unitSelection.polres) { - listDest.forEach((polda) => { - polda?.subDestination?.forEach((polres: any) => { - updated.add(polres.id); // hanya id polres + // Fungsi untuk sinkronisasi checkbox modal dengan checkbox utama + const syncModalWithMainCheckbox = () => { + if (isUpdatingFromMainCheckbox) { + const newCheckedLevels = new Set(checkedLevels); + + // Handle checklist actions - menambahkan semua item ke modal + if (mainCheckboxChangeType === "polda_checked") { + // Checklist semua polda + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI") { + newCheckedLevels.add(Number(item.id)); + } }); - }); + } else if (mainCheckboxChangeType === "polres_checked") { + // Checklist semua polres, tapi hanya yang poldanya sudah di-checklist + // Jangan checklist sub-item SATKER POLRI + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI" && newCheckedLevels.has(Number(item.id))) { + if (item.subDestination) { + item.subDestination.forEach((polres: any) => { + newCheckedLevels.add(Number(polres.id)); + }); + } + } + }); + + // Tidak perlu menghapus SATKER ketika POLRES di-checklist + // Biarkan keduanya bisa aktif bersamaan + // SATKER dan POLRES adalah konsep yang berbeda: + // - SATKER: unit-unit seperti ITWASUM, BAINTELKAM, dll. + // - POLRES: unit-unit seperti POLRES METRO JAKARTA PUSAT, dll. + } else if (mainCheckboxChangeType === "satker_checked") { + // Checklist satker + const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI"); + if (satkerItem) { + newCheckedLevels.add(Number(satkerItem.id)); + // Checklist semua sub-item yang ada di bawah SATKER (bukan POLRES) + if (satkerItem.subDestination) { + satkerItem.subDestination.forEach((sub: any) => { + newCheckedLevels.add(Number(sub.id)); + }); + } + } + } else if (mainCheckboxChangeType === "semua_checked") { + // Checklist semua item + listDest.forEach((item: any) => { + newCheckedLevels.add(Number(item.id)); + // Checklist semua sub-item di bawah setiap item + if (item.subDestination) { + item.subDestination.forEach((sub: any) => { + newCheckedLevels.add(Number(sub.id)); + }); + } + }); + } + // Handle unchecklist actions - menghapus item dari modal + else if (mainCheckboxChangeType === "polres_unchecked") { + // Clear polres dari checkedLevels, tapi jangan hapus sub-item SATKER POLRI + listDest.forEach((item: any) => { + if (item.subDestination && item.name !== "SATKER POLRI") { + item.subDestination.forEach((polres: any) => { + newCheckedLevels.delete(Number(polres.id)); + }); + } + }); + } else if (mainCheckboxChangeType === "polda_unchecked") { + // Clear polda dan polres dari checkedLevels, tapi jangan hapus SATKER POLRI + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI") { + newCheckedLevels.delete(Number(item.id)); + if (item.subDestination) { + item.subDestination.forEach((polres: any) => { + newCheckedLevels.delete(Number(polres.id)); + }); + } + } + }); + } else if (mainCheckboxChangeType === "satker_unchecked") { + // Clear satker dan semua sub-item di bawahnya dari checkedLevels + const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI"); + if (satkerItem) { + newCheckedLevels.delete(Number(satkerItem.id)); + if (satkerItem.subDestination) { + satkerItem.subDestination.forEach((sub: any) => { + newCheckedLevels.delete(Number(sub.id)); + }); + } + } + } else if (mainCheckboxChangeType === "semua_unchecked") { + // Clear semua + newCheckedLevels.clear(); + } + + setCheckedLevels(newCheckedLevels); + + // Reset flag setelah sinkronisasi selesai + setIsUpdatingFromMainCheckbox(false); + setMainCheckboxChangeType(""); } - - setCheckedLevels(updated); - }, [unitSelection.polda, unitSelection.polres, listDest]); + }; const handleUnitChange = ( key: keyof typeof unitSelection, value: boolean ) => { + // Set flag bahwa perubahan berasal dari checkbox utama + setIsUpdatingFromMainCheckbox(true); + setMainCheckboxChangeType(key + (value ? "_checked" : "_unchecked")); + if (key === "semua") { // Jika klik Semua, set semua value ke true/false const newState = { @@ -277,6 +427,28 @@ export default function FormImageDetail() { }; setUnitSelection(newState); } else { + // Validasi khusus untuk POLRES + if (key === "polres" && value) { + // Cek apakah ada POLDA yang sudah dipilih di modal + const hasSelectedPolda = listDest.some((item: any) => + item.levelNumber === 2 && + item.name !== "SATKER POLRI" && + checkedLevels.has(Number(item.id)) + ); + + if (!hasSelectedPolda) { + // Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan + alert("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."); + // Reset flag karena perubahan dibatalkan + setIsUpdatingFromMainCheckbox(false); + setMainCheckboxChangeType(""); + return; // Batalkan perubahan + } + } + + // Tidak ada validasi khusus untuk SATKER dan POLRES + // Keduanya bisa aktif bersamaan + // Update salah satu saja const updatedSelection = { ...unitSelection, @@ -326,12 +498,38 @@ export default function FormImageDetail() { }; const handleCheckboxChangePlacement = (levelId: number) => { - setCheckedLevels((prev: any) => { - const updatedLevels = new Set(prev); - if (updatedLevels.has(levelId)) { + setCheckedLevels((prev: Set) => { + const updatedLevels = new Set(prev); + const isCurrentlyChecked = updatedLevels.has(levelId); + + if (isCurrentlyChecked) { updatedLevels.delete(levelId); + + // Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya + const poldaItem = listDest.find((item: any) => Number(item.id) === levelId) as any; + if (poldaItem && poldaItem.subDestination && poldaItem.name !== "SATKER POLRI") { + poldaItem.subDestination.forEach((polres: any) => { + updatedLevels.delete(Number(polres.id)); + }); + } + + // Jika ini adalah SATKER POLRI yang di-unchecklist, unchecklist juga semua sub-item di bawahnya + if (poldaItem && poldaItem.name === "SATKER POLRI") { + poldaItem.subDestination?.forEach((subItem: any) => { + updatedLevels.delete(Number(subItem.id)); + }); + } } else { updatedLevels.add(levelId); + + // Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya + const satkerItem = listDest.find((item: any) => Number(item.id) === levelId) as any; + if (satkerItem && satkerItem.name === "SATKER POLRI") { + // Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES) + satkerItem.subDestination?.forEach((subItem: any) => { + updatedLevels.add(Number(subItem.id)); + }); + } } return updatedLevels; }); @@ -395,7 +593,7 @@ export default function FormImageDetail() { setupPlacementCheck(details?.files?.length); if (details?.assignedToLevel) { - const levels = new Set( + const levels = new Set( details.assignedToLevel.split(",").map(Number) ); setCheckedLevels(levels); @@ -519,10 +717,23 @@ export default function FormImageDetail() { if (checked) { if (placement === "all") { temp[index] = ["all", "mabes", "polda", "international"]; + } else if (placement === "satker") { + // Ketika satker di-checklist, HANYA tambahkan satker saja + // JANGAN otomatis checklist polres + const now = temp[index] || []; + if (!now.includes("satker")) { + now.push("satker"); + } + temp[index] = now; } else { - const now = temp[index]; - now?.push(placement); - if (now.length === 3 && !now.includes("all")) { + const now = temp[index] || []; + if (!now.includes(placement)) { + now.push(placement); + } + // Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist + // JANGAN include satker dalam perhitungan auto "all" + const nonSatkerItems = now.filter(item => item !== "satker" && item !== "all"); + if (nonSatkerItems.length === 3 && !now.includes("all")) { now.push("all"); } temp[index] = now; @@ -534,9 +745,13 @@ export default function FormImageDetail() { const now = temp[index].filter((a) => a !== placement); console.log("now", now); temp[index] = now; - if (now.length === 3 && now.includes("all")) { - const newData = now.filter((b) => b !== "all"); - temp[index] = newData; + // Hapus "all" jika tidak semua item ter-checklist + if (now.includes("all")) { + const nonSatkerItems = now.filter(item => item !== "satker" && item !== "all"); + if (nonSatkerItems.length < 3) { + const newData = now.filter((b) => b !== "all"); + temp[index] = newData; + } } } } @@ -1031,45 +1246,30 @@ export default function FormImageDetail() {
- {listDest.map((polda: any) => { - const poldaChecked = - unitSelection.polda; - const polresChecked = - unitSelection.polres; - const isPoldaDisabled = - poldaChecked; - const isPolresDisabled = - polresChecked; - - return ( + {listDest.map((polda: any) => (
-
- ); - })} + ))}
From 3feb406715e5f62707ed03d79701b8e30928056e Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Thu, 21 Aug 2025 17:56:58 +0700 Subject: [PATCH 2/2] feat: update approval modals --- components/form/content/image-detail-form.tsx | 973 +++++++++++------- 1 file changed, 581 insertions(+), 392 deletions(-) diff --git a/components/form/content/image-detail-form.tsx b/components/form/content/image-detail-form.tsx index 21c4c98b..73b97aee 100644 --- a/components/form/content/image-detail-form.tsx +++ b/components/form/content/image-detail-form.tsx @@ -20,7 +20,7 @@ import { import { Checkbox } from "@/components/ui/checkbox"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; -import { register } from "module"; + import { Switch } from "@/components/ui/switch"; import Cookies from "js-cookie"; import { @@ -53,6 +53,7 @@ import { DialogContent, DialogTitle, DialogTrigger, + DialogClose, } from "@/components/ui/dialog"; import { Textarea } from "@/components/ui/textarea"; import { close, loading, successCallback } from "@/config/swal"; @@ -161,6 +162,21 @@ export default function FormImageDetail() { const [thumbsSwiper, setThumbsSwiper] = useState(null); const [isUserMabesApprover, setIsUserMabesApprover] = useState(false); const [approval, setApproval] = useState(); + // State untuk setiap file secara individual + const [fileUnitSelections, setFileUnitSelections] = useState>([]); + + // State untuk setiap file secara individual - checklist levels + const [fileCheckedLevels, setFileCheckedLevels] = useState>>([]); + + // State global untuk kompatibilitas (akan dihapus nanti) const [unitSelection, setUnitSelection] = useState({ semua: false, nasional: false, @@ -255,12 +271,12 @@ export default function FormImageDetail() { // useEffect untuk update checkbox utama ketika pilihan modal berubah useEffect(() => { if (!isUpdatingFromMainCheckbox && listDest.length > 0) { - updateMainCheckboxFromModal(); + updateMainCheckboxFromModalLegacy(); } }, [checkedLevels, isUpdatingFromMainCheckbox]); - // Fungsi untuk update checkbox utama berdasarkan checkbox modal - const updateMainCheckboxFromModal = () => { + // Fungsi untuk update checkbox utama berdasarkan checkbox modal (global/legacy) + const updateMainCheckboxFromModalLegacy = () => { if (!isUpdatingFromMainCheckbox && listDest.length > 0) { // Hitung item yang dipilih berdasarkan checkedLevels const checkedPoldaCount = listDest.filter((item: any) => @@ -406,6 +422,63 @@ export default function FormImageDetail() { } }; + // Fungsi untuk mengupdate state individual file + const handleFileUnitChange = ( + fileIndex: number, + key: keyof typeof unitSelection, + value: boolean + ) => { + setFileUnitSelections(prev => { + const newSelections = [...prev]; + const currentSelection = { ...newSelections[fileIndex] }; + + if (key === "semua") { + // Jika klik Semua, set semua value ke true/false + currentSelection.semua = value; + currentSelection.nasional = value; + currentSelection.wilayah = value; + currentSelection.international = value; + currentSelection.polda = value; + currentSelection.polres = value; + currentSelection.satker = value; + } else { + // Validasi khusus untuk POLRES - harus ada POLDA yang ter-checklist + if (key === "polres" && value) { + const currentFileCheckedLevels = fileCheckedLevels[fileIndex]; + const hasSelectedPolda = currentFileCheckedLevels && listDest.some((item: any) => + item.levelNumber === 2 && + item.name !== "SATKER POLRI" && + currentFileCheckedLevels.has(Number(item.id)) + ); + + if (!hasSelectedPolda) { + alert("Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."); + return prev; // Batalkan perubahan + } + } + + // Update salah satu saja + currentSelection[key] = value; + + // Cek apakah semua selain "semua" sudah dicentang + const allChecked = [ + "nasional", + "wilayah", + "international", + "polda", + "polres", + "satker", + ].every((k) => currentSelection[k as keyof typeof unitSelection]); + + currentSelection.semua = allChecked; + } + + newSelections[fileIndex] = currentSelection; + return newSelections; + }); + }; + + // Fungsi lama untuk kompatibilitas (akan dihapus nanti) const handleUnitChange = ( key: keyof typeof unitSelection, value: boolean @@ -497,6 +570,146 @@ export default function FormImageDetail() { ); }; + // Fungsi untuk mengupdate checklist levels untuk file tertentu + const handleFileCheckboxChangePlacement = (fileIndex: number, levelId: number) => { + setFileCheckedLevels((prev) => { + const newArray = [...prev]; + const currentFileLevels = new Set(newArray[fileIndex]); + const isCurrentlyChecked = currentFileLevels.has(levelId); + + if (isCurrentlyChecked) { + currentFileLevels.delete(levelId); + + // Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya + const poldaItem = listDest.find((item: any) => Number(item.id) === levelId) as any; + if (poldaItem && poldaItem.subDestination && poldaItem.name !== "SATKER POLRI") { + poldaItem.subDestination.forEach((polres: any) => { + currentFileLevels.delete(Number(polres.id)); + }); + } + + // Jika ini adalah SATKER POLRI yang di-unchecklist, unchecklist juga semua sub-item di bawahnya + if (poldaItem && poldaItem.name === "SATKER POLRI") { + poldaItem.subDestination?.forEach((subItem: any) => { + currentFileLevels.delete(Number(subItem.id)); + }); + } + } else { + currentFileLevels.add(levelId); + + // Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya + const satkerItem = listDest.find((item: any) => Number(item.id) === levelId) as any; + if (satkerItem && satkerItem.name === "SATKER POLRI") { + // Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES) + satkerItem.subDestination?.forEach((subItem: any) => { + currentFileLevels.add(Number(subItem.id)); + }); + } + } + + newArray[fileIndex] = currentFileLevels; + + // Update checkbox utama berdasarkan perubahan di modal + // Pindahkan ke sini agar state sudah ter-update + setTimeout(() => updateMainCheckboxFromModal(fileIndex), 0); + + return newArray; + }); + }; + + // Fungsi untuk menangani "Pilih Semua" sub-items di bawah POLDA + const handleSelectAllSubItems = (fileIndex: number, polda: any) => { + setFileCheckedLevels((prev) => { + const newArray = [...prev]; + const currentFileLevels = new Set(newArray[fileIndex]); + + // Cek apakah semua sub-items sudah ter-checklist + const allSubItemsChecked = polda.subDestination?.every((sub: any) => + currentFileLevels.has(Number(sub.id)) + ); + + if (allSubItemsChecked) { + // Jika semua sudah ter-checklist, unchecklist semuanya + polda.subDestination?.forEach((sub: any) => { + currentFileLevels.delete(Number(sub.id)); + }); + } else { + // Jika belum semua ter-checklist, checklist semuanya + // Checklist POLDA juga jika belum ter-checklist + if (!currentFileLevels.has(Number(polda.id))) { + currentFileLevels.add(Number(polda.id)); + } + // Checklist semua sub-items + polda.subDestination?.forEach((sub: any) => { + currentFileLevels.add(Number(sub.id)); + }); + } + + newArray[fileIndex] = currentFileLevels; + + // Update checkbox utama berdasarkan perubahan di modal + setTimeout(() => updateMainCheckboxFromModal(fileIndex), 0); + + return newArray; + }); + }; + + // Fungsi untuk mengupdate checkbox utama berdasarkan checklist di modal + const updateMainCheckboxFromModal = (fileIndex: number) => { + setFileUnitSelections((prev) => { + const newSelections = [...prev]; + const currentSelection = { ...newSelections[fileIndex] }; + const currentFileLevels = fileCheckedLevels[fileIndex]; + + if (!currentFileLevels) return prev; + + // Hitung total POLDA yang ada (bukan SATKER POLRI) + const totalPoldaCount = listDest.filter((item: any) => + item.levelNumber === 2 && item.name !== "SATKER POLRI" + ).length; + + // Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI) + const checkedPoldaCount = listDest.reduce((total: number, item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI" && currentFileLevels.has(Number(item.id))) { + return total + 1; + } + return total; + }, 0); + + // Hitung total POLRES yang ada dari POLDA yang ter-checklist + const totalPolresFromCheckedPolda = listDest.reduce((total: number, item: any) => { + if (item.subDestination && item.name !== "SATKER POLRI" && currentFileLevels.has(Number(item.id))) { + return total + item.subDestination.length; + } + return total; + }, 0); + + // Hitung berapa banyak POLRES yang ter-checklist + const checkedPolresCount = listDest.reduce((total: number, item: any) => { + if (item.subDestination && item.name !== "SATKER POLRI") { + // Hanya hitung sub-item dari POLDA (bukan dari SATKER POLRI) + return total + item.subDestination.filter((sub: any) => currentFileLevels.has(Number(sub.id))).length; + } + return total; + }, 0); + + // Cek apakah SATKER POLRI ter-checklist + const satkerItem = listDest.find((item: any) => item.name === "SATKER POLRI"); + const isSatkerChecked = satkerItem && currentFileLevels.has(Number(satkerItem.id)); + + // Update checkbox berdasarkan kondisi + // POLDA aktif jika ada minimal 1 POLDA ter-checklist + currentSelection.polda = checkedPoldaCount > 0; + // POLRES aktif jika ada minimal 1 POLRES ter-checklist + currentSelection.polres = checkedPolresCount > 0; + currentSelection.satker = Boolean(isSatkerChecked); + + newSelections[fileIndex] = currentSelection; + return newSelections; + }); + }; + + // Fungsi lama untuk kompatibilitas (akan dihapus nanti) const handleCheckboxChangePlacement = (levelId: number) => { setCheckedLevels((prev: Set) => { const updatedLevels = new Set(prev); @@ -570,10 +783,28 @@ export default function FormImageDetail() { const setupPlacementCheck = (length: number) => { const temp = []; + const unitSelections = []; + const checkedLevelsArray = []; + for (let i = 0; i < length; i++) { temp.push([]); + // Inisialisasi state untuk setiap file + unitSelections.push({ + semua: false, + nasional: false, + wilayah: false, + international: false, + polda: false, + polres: false, + satker: false, + }); + // Inisialisasi checkedLevels untuk setiap file + checkedLevelsArray.push(new Set()); } + setFilePlacements(temp); + setFileUnitSelections(unitSelections); + setFileCheckedLevels(checkedLevelsArray); }; useEffect(() => { @@ -673,12 +904,20 @@ export default function FormImageDetail() { }; async function save() { + // Gabungkan semua checkedLevels dari semua file + const allCheckedLevels = new Set(); + fileCheckedLevels.forEach((fileLevels) => { + fileLevels.forEach((levelId) => { + allCheckedLevels.add(levelId); + }); + }); + const data = { mediaUploadId: id, statusId: status, message: description, files: isUserMabesApprover ? getPlacement() : [], - customLocationPlacement: Array.from(checkedLevels).join(","), + customLocationPlacement: Array.from(allCheckedLevels).join(","), }; setModalOpen(false); loading(); @@ -756,6 +995,92 @@ export default function FormImageDetail() { } } setFilePlacements(temp); + + // Update checklist levels di modal berdasarkan placement yang diubah + updateModalChecklistLevels(index, placement, checked); + }; + + // Fungsi untuk mengupdate checklist levels di modal berdasarkan placement + const updateModalChecklistLevels = (fileIndex: number, placement: string, checked: boolean) => { + if (!listDest || listDest.length === 0) return; + + setFileCheckedLevels((prev) => { + const newArray = [...prev]; + const currentFileLevels = new Set(newArray[fileIndex]); + + if (checked) { + if (placement === "polda") { + // Checklist semua POLDA (bukan SATKER POLRI) + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI") { + currentFileLevels.add(Number(item.id)); + } + }); + } else if (placement === "polres") { + // Checklist POLRES hanya dari POLDA yang sudah ter-checklist + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI") { + // Hanya checklist POLRES jika POLDA-nya sudah ter-checklist + if (currentFileLevels.has(Number(item.id))) { + if (item.subDestination) { + item.subDestination.forEach((polres: any) => { + currentFileLevels.add(Number(polres.id)); + }); + } + } + } + }); + } else if (placement === "satker") { + // Checklist SATKER POLRI dan semua sub-item di bawahnya + const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI"); + if (satkerItem) { + currentFileLevels.add(Number(satkerItem.id)); + if (satkerItem.subDestination) { + satkerItem.subDestination.forEach((sub: any) => { + currentFileLevels.add(Number(sub.id)); + }); + } + } + } + } else { + if (placement === "polda") { + // Unchecklist semua POLDA dan POLRES di bawahnya + listDest.forEach((item: any) => { + if (item.levelNumber === 2 && item.name !== "SATKER POLRI") { + currentFileLevels.delete(Number(item.id)); + if (item.subDestination) { + item.subDestination.forEach((polres: any) => { + currentFileLevels.delete(Number(polres.id)); + }); + } + } + }); + } else if (placement === "polres") { + // Unchecklist semua POLRES + listDest.forEach((item: any) => { + if (item.subDestination && item.name !== "SATKER POLRI") { + item.subDestination.forEach((polres: any) => { + currentFileLevels.delete(Number(polres.id)); + }); + } + }); + } else if (placement === "satker") { + // Unchecklist SATKER POLRI dan semua sub-item di bawahnya + const satkerItem: any = listDest.find((item: any) => item.name === "SATKER POLRI"); + if (satkerItem) { + currentFileLevels.delete(Number(satkerItem.id)); + if (satkerItem.subDestination) { + satkerItem.subDestination.forEach((sub: any) => { + currentFileLevels.delete(Number(sub.id)); + }); + } + } + } + } + + newArray[fileIndex] = currentFileLevels; + return newArray; + }); }; function handleDeleteFileApproval(id: number) { @@ -1111,445 +1436,309 @@ export default function FormImageDetail() { )} */} - - - - {t("leave-comment", { defaultValue: "Leave Comment" })} + + + + {t("leave-comment", { defaultValue: "Kelola Persetujuan Konten" })} -
- {status == "2" - ? files?.map((file, index) => ( -
-
+ +
+ {status == "2" && files?.map((file, index) => ( +
+ {/* Header File */} +
+
+
{`files-${index handleImageLoad(e, index)} - className={`h-[100px] object-cover ${ - portraitMap[index] ? "w-auto" : "!w-[200px]" + className={`h-[80px] object-cover ${ + portraitMap[index] ? "w-auto" : "!w-[120px]" }`} />
-
-
- {file.fileName} - - handleDeleteFileApproval(file.id) - } - > - - +
+

File {index + 1}

+

{file.fileName}

+
+
+ +
+ + {/* Section Pengaturan Distribusi */} +
+
+ + Pengaturan Distribusi +
+ + {/* Checkbox Tingkat Utama */} +
+
+

Tingkat Distribusi:

+
+ {[ + { key: "semua", label: "Semua" }, + { key: "nasional", label: "Nasional" }, + { key: "wilayah", label: "Wilayah" }, + { key: "international", label: "Internasional" }, + ].map((item, idx) => ( +
+ { + handleFileUnitChange( + index, + item.key as keyof typeof unitSelection, + value as boolean + ); + setupPlacement(index, item.key, Boolean(value)); + }} + /> + +
+ ))}
-
- {/* --- Checkbox utama --- */} -
+
+ + {/* Detail Wilayah */} + {fileUnitSelections[index]?.wilayah && ( +
+

Detail Wilayah:

+ + {/* Checkbox Sub-kategori dengan tombol Kustom sejajar */} +
{[ - "semua", - "nasional", - "wilayah", - "international", - ].map((key, index) => ( -
+ { key: "polda", label: "POLDA" }, + { key: "polres", label: "POLRES" }, + { key: "satker", label: "SATKER" }, + ].map((item, idx) => ( +
{ - handleUnitChange( - key as keyof typeof unitSelection, + handleFileUnitChange( + index, + item.key as keyof typeof unitSelection, value as boolean ); - setupPlacement( - index, - key, - Boolean(value) - ); + setupPlacement(index, item.key, Boolean(value)); }} /> -
))} -
- - {/* --- Kalau wilayah dicentang baru tampilkan detail --- */} - {unitSelection.wilayah && ( -
-
- {["polda", "polres", "satker"].map( - (key, index) => ( -
- { - handleUnitChange( - key as keyof typeof unitSelection, - value as boolean - ); - setupPlacement( - index, - key, - Boolean(value) - ); - }} - /> - -
- ) - )} -
- - {/* --- Custom Button + Dialog --- */} + + {/* Tombol Kustom sejajar dengan checkbox */} +
- - - - - Daftar Wilayah Polda dan Polres + + + + Daftar Wilayah POLDA dan POLRES -
+
{listDest.map((polda: any) => ( -
-
- +
+ {/* Header POLDA */} +
+ + {polda.subDestination && ( -
- - {expandedPolda[polda.id] && ( -
- - {polda?.subDestination?.map( - (polres: any) => ( - - ) - )} -
)}
+ + {/* Sub-items */} + {polda.subDestination && expandedPolda[polda.id] && ( +
+ {/* Tombol Pilih Semua untuk sub-items */} +
+ {(() => { + const allSubItemsChecked = polda.subDestination?.every((sub: any) => + fileCheckedLevels[index]?.has(Number(sub.id)) + ); + return ( + + ); + })()} +
+
+ {polda.subDestination.map((sub: any) => ( + + ))} +
+
+ )} +
))}
+
+ + + + + + +
- )} -
- {/* {isUserMabesApprover && ( -
-
- - setupPlacement(index, "all", Boolean(e)) - } - /> - -
-
- - setupPlacement( - index, - "mabes", - Boolean(e) - ) - } - /> - -
-
- - setupPlacement( - index, - "polda", - Boolean(e) - ) - } - /> - - {wilayahPublish.polda && ( - - setSelectedPolda(data) - } - /> - )} -
- -
- - setupPlacement( - index, - "international", - Boolean(e) - ) - } - /> - -
- )} */} +
+ )} +
+
+
+ ))} +
+ + {/* Section Komentar */} +
+
+
+ +