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) => (
-
- ); - })} + ))}