fix: placement content satker

This commit is contained in:
Sabda Yagra 2025-12-15 20:41:18 +07:00
parent 9c997fd85d
commit ae6e22e05f
4 changed files with 1262 additions and 585 deletions

View File

@ -184,6 +184,10 @@ export default function FormAudioDetail() {
const [isLoading, setIsLoading] = useState(false);
const [listDest, setListDest] = useState<Destination[]>([]);
const [checkedLevels, setCheckedLevels] = useState<any>(new Set());
const isUploadedBySatkerLevel3 =
Number(detail?.uploadedBy?.userLevel?.levelNumber) === 3;
// State untuk setiap file secara individual - checklist levels
const [fileCheckedLevels, setFileCheckedLevels] = useState<
Array<Set<number>>
@ -218,42 +222,60 @@ export default function FormAudioDetail() {
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;
// Update fileCheckedLevels untuk sinkronisasi dengan modal
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (isUploadedBySatkerLevel3) {
currentSelection.wilayah = false;
currentSelection.polda = false;
currentSelection.polres = false;
currentSelection.satker = false;
if (value) {
// Checklist semua item di modal
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
// Unchecklist semua item di modal
currentFileLevels.clear();
}
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
newArray[fileIndex] = currentFileLevels;
return newArray;
});
if (!value) {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
} else {
// 🔁 LOGIC LAMA (TIDAK DIUBAH)
currentSelection.wilayah = value;
currentSelection.polda = value;
currentSelection.polres = value;
currentSelection.satker = value;
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (value) {
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
}
} else {
// Validasi khusus untuk POLRES - harus ada POLDA yang ter-checklist
if (key === "polres" && value) {
const currentFileCheckedLevels = fileCheckedLevels[fileIndex];
const hasSelectedPolda =
@ -269,14 +291,12 @@ export default function FormAudioDetail() {
alert(
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
);
return prev; // Batalkan perubahan
return prev;
}
}
// Update salah satu saja
currentSelection[key] = value;
// Cek apakah semua selain "semua" sudah dicentang
const allChecked = [
"nasional",
"wilayah",
@ -294,6 +314,92 @@ export default function FormAudioDetail() {
});
};
// 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;
// // Update fileCheckedLevels untuk sinkronisasi dengan modal
// setFileCheckedLevels((prevLevels) => {
// const newArray = [...prevLevels];
// const currentFileLevels = new Set<number>(
// newArray[fileIndex] || new Set()
// );
// if (value) {
// // Checklist semua item di modal
// listDest.forEach((item: any) => {
// currentFileLevels.add(Number(item.id));
// if (item.subDestination) {
// item.subDestination.forEach((sub: any) => {
// currentFileLevels.add(Number(sub.id));
// });
// }
// });
// } else {
// // Unchecklist semua item di modal
// currentFileLevels.clear();
// }
// newArray[fileIndex] = currentFileLevels;
// return newArray;
// });
// } 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;
// });
// };
const toggleExpand = (id: number) => {
setExpandedPolda((prev) => ({
...prev,
@ -718,8 +824,15 @@ export default function FormAudioDetail() {
) => {
let temp = [...filePlacements];
if (checked) {
// if (placement === "all") {
// temp[index] = ["all", "mabes", "polda", "international"];
if (placement === "all") {
temp[index] = ["all", "mabes", "polda", "international"];
if (isUploadedBySatkerLevel3) {
temp[index] = ["mabes", "international"];
} else {
temp[index] = ["all", "mabes", "polda", "international"];
}
// Update fileCheckedLevels untuk sinkronisasi dengan modal ketika "all" diklik
setFileCheckedLevels((prevLevels) => {
@ -1477,6 +1590,56 @@ export default function FormAudioDetail() {
key: "international",
label: "Internasional",
},
]
.filter(
(item) =>
!(
isUploadedBySatkerLevel3 &&
item.key === "wilayah"
)
)
.map((item) => (
<div
key={item.key}
className="flex items-center gap-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
{item.label}
</Label>
</div>
))}
{/* {[
{ key: "semua", label: "Semua" },
{ key: "nasional", label: "Nasional" },
{ key: "wilayah", label: "Wilayah" },
{
key: "international",
label: "Internasional",
},
].map((item, idx) => (
<div
key={item.key}
@ -1509,7 +1672,7 @@ export default function FormAudioDetail() {
{item.label}
</Label>
</div>
))}
))} */}
</div>
</div>

View File

@ -474,42 +474,69 @@ export default function FormImageDetail() {
const currentSelection = { ...newSelections[fileIndex] };
if (key === "semua") {
// Jika klik Semua, set semua value ke true/false
// Jika klik Semua
currentSelection.semua = value;
// ✅ Tetap berlaku untuk semua kondisi
currentSelection.nasional = value;
currentSelection.wilayah = value;
currentSelection.international = value;
currentSelection.polda = value;
currentSelection.polres = value;
currentSelection.satker = value;
// Update fileCheckedLevels untuk sinkronisasi dengan modal
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (isUploadedBySatkerLevel3) {
// 🔹 TAMBAHAN: KHUSUS SATKER level 3
currentSelection.wilayah = false;
currentSelection.polda = false;
currentSelection.polres = false;
currentSelection.satker = false;
if (value) {
// Checklist semua item di modal
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
// Unchecklist semua item di modal
currentFileLevels.clear();
}
// 🔹 Sinkronisasi modal: JANGAN checklist wilayah
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
newArray[fileIndex] = currentFileLevels;
return newArray;
});
if (!value) {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
} else {
// 🔁 LOGIC LAMA (TIDAK DIUBAH)
currentSelection.wilayah = value;
currentSelection.polda = value;
currentSelection.polres = value;
currentSelection.satker = value;
// LOGIC LAMA modal
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (value) {
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
}
} else {
// Validasi khusus untuk POLRES - harus ada POLDA yang ter-checklist
// 🔁 SELURUH LOGIC LAMA — TIDAK DISENTUH
// Validasi khusus untuk POLRES
if (key === "polres" && value) {
const currentFileCheckedLevels = fileCheckedLevels[fileIndex];
const hasSelectedPolda =
@ -525,14 +552,12 @@ export default function FormImageDetail() {
alert(
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
);
return prev; // Batalkan perubahan
return prev;
}
}
// Update salah satu saja
currentSelection[key] = value;
// Cek apakah semua selain "semua" sudah dicentang
const allChecked = [
"nasional",
"wilayah",
@ -550,6 +575,92 @@ export default function FormImageDetail() {
});
};
// 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;
// // Update fileCheckedLevels untuk sinkronisasi dengan modal
// setFileCheckedLevels((prevLevels) => {
// const newArray = [...prevLevels];
// const currentFileLevels = new Set<number>(
// newArray[fileIndex] || new Set()
// );
// if (value) {
// // Checklist semua item di modal
// listDest.forEach((item: any) => {
// currentFileLevels.add(Number(item.id));
// if (item.subDestination) {
// item.subDestination.forEach((sub: any) => {
// currentFileLevels.add(Number(sub.id));
// });
// }
// });
// } else {
// // Unchecklist semua item di modal
// currentFileLevels.clear();
// }
// newArray[fileIndex] = currentFileLevels;
// return newArray;
// });
// } 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,
@ -1088,8 +1199,14 @@ export default function FormImageDetail() {
) => {
let temp = [...filePlacements];
if (checked) {
// if (placement === "all") {
// temp[index] = ["all", "mabes", "polda", "international"];
if (placement === "all") {
temp[index] = ["all", "mabes", "polda", "international"];
if (isUploadedBySatkerLevel3) {
temp[index] = ["mabes", "international"];
} else {
temp[index] = ["all", "mabes", "polda", "international"];
}
// Update fileCheckedLevels untuk sinkronisasi dengan modal ketika "all" diklik
setFileCheckedLevels((prevLevels) => {
@ -1359,6 +1476,9 @@ export default function FormImageDetail() {
// console.log("portrai", portraitMap);
}, [portraitMap]);
const isUploadedBySatkerLevel3 =
Number(detail?.uploadedBy?.userLevel?.levelNumber) === 3;
return (
<form>
{detail !== undefined ? (
@ -1741,6 +1861,56 @@ export default function FormImageDetail() {
key: "international",
label: "Internasional",
},
]
.filter(
(item) =>
!(
isUploadedBySatkerLevel3 &&
item.key === "wilayah"
)
)
.map((item) => (
<div
key={item.key}
className="flex items-center gap-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
{item.label}
</Label>
</div>
))}
{/* {[
{ key: "semua", label: "Semua" },
{ key: "nasional", label: "Nasional" },
{ key: "wilayah", label: "Wilayah" },
{
key: "international",
label: "Internasional",
},
].map((item, idx) => (
<div
key={item.key}
@ -1773,251 +1943,261 @@ export default function FormImageDetail() {
{item.label}
</Label>
</div>
))}
))} */}
</div>
</div>
{/* Detail Wilayah */}
{fileUnitSelections[index]?.wilayah && (
<div className="border-t border-gray-200 pt-2">
<p className="text-sm font-medium text-gray-700 mb-2">
Detail Wilayah:
</p>
{fileUnitSelections[index]?.wilayah &&
!isUploadedBySatkerLevel3 && (
<div className="border-t border-gray-200 pt-2">
<p className="text-sm font-medium text-gray-700 mb-2">
Detail Wilayah:
</p>
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
{[
{ key: "polda", label: "POLDA" },
{ key: "polres", label: "POLRES" },
{ key: "satker", label: "SATKER" },
].map((item, idx) => (
<div
key={item.key}
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
{[
{ key: "polda", label: "POLDA" },
{ key: "polres", label: "POLRES" },
{ key: "satker", label: "SATKER" },
].map((item, idx) => (
<div
key={item.key}
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
>
{item.label}
</Label>
</div>
))}
{/* Tombol Kustom sejajar dengan checkbox */}
<div className="flex items-center justify-center p-3">
<Dialog>
<DialogTrigger asChild>
<Button
variant="outline"
size="sm"
className="gap-2"
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
<Icon
icon="material-symbols:tune"
width={16}
height={16}
/>
{t("custom", {
defaultValue: "Kustom",
})}
</Button>
</DialogTrigger>
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
<DialogHeader className="border-b border-gray-200 pb-4">
<DialogTitle className="text-lg font-semibold">
Daftar Wilayah POLDA dan POLRES
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 max-h-[70vh] overflow-y-auto p-1">
{listDest.map((polda: any) => (
<div
key={polda.id}
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
>
{/* Header POLDA */}
<div className="flex items-center justify-between">
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(polda.id)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(polda.id)
)
}
/>
<span className="font-semibold text-gray-900 text-sm">
{polda.name}
</span>
</Label>
{polda.subDestination && (
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(
polda.id
);
}}
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
>
<Icon
icon={
expandedPolda[
polda.id
]
? "mdi:chevron-up"
: "mdi:chevron-down"
}
width={16}
height={16}
/>
</button>
)}
</div>
{item.label}
</Label>
</div>
))}
{/* Sub-items */}
{polda.subDestination &&
expandedPolda[polda.id] && (
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
{/* Tombol Pilih Semua untuk sub-items */}
<div className="mb-2 flex justify-start">
{(() => {
const allSubItemsChecked =
polda.subDestination?.every(
(sub: any) =>
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
)
);
return (
<Button
size="sm"
variant="outline"
className="text-xs h-6 px-2"
onClick={() =>
handleSelectAllSubItems(
index,
polda
)
}
>
{allSubItemsChecked ? (
<>
<Icon
icon="material-symbols:check-indeterminate-small"
width={12}
height={
12
}
className="mr-1"
/>
Batal Semua
</>
) : (
<>
<Icon
icon="material-symbols:check-all"
width={12}
height={
12
}
className="mr-1"
/>
Pilih Semua
</>
)}
</Button>
{/* Tombol Kustom sejajar dengan checkbox */}
<div className="flex items-center justify-center p-3">
<Dialog>
<DialogTrigger asChild>
<Button
variant="outline"
size="sm"
className="gap-2"
>
<Icon
icon="material-symbols:tune"
width={16}
height={16}
/>
{t("custom", {
defaultValue: "Kustom",
})}
</Button>
</DialogTrigger>
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
<DialogHeader className="border-b border-gray-200 pb-4">
<DialogTitle className="text-lg font-semibold">
Daftar Wilayah POLDA dan
POLRES
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 max-h-[70vh] overflow-y-auto p-1">
{listDest.map((polda: any) => (
<div
key={polda.id}
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
>
{/* Header POLDA */}
<div className="flex items-center justify-between">
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(polda.id)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(polda.id)
)
}
/>
<span className="font-semibold text-gray-900 text-sm">
{polda.name}
</span>
</Label>
{polda.subDestination && (
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(
polda.id
);
})()}
</div>
<div className="space-y-1">
{polda.subDestination.map(
(sub: any) => (
<Label
key={sub.id}
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
>
<Checkbox
checked={
}}
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
>
<Icon
icon={
expandedPolda[
polda.id
]
? "mdi:chevron-up"
: "mdi:chevron-down"
}
width={16}
height={16}
/>
</button>
)}
</div>
{/* Sub-items */}
{polda.subDestination &&
expandedPolda[
polda.id
] && (
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
{/* Tombol Pilih Semua untuk sub-items */}
<div className="mb-2 flex justify-start">
{(() => {
const allSubItemsChecked =
polda.subDestination?.every(
(sub: any) =>
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
)
);
return (
<Button
size="sm"
variant="outline"
className="text-xs h-6 px-2"
onClick={() =>
handleSelectAllSubItems(
index,
Number(
sub.id
)
polda
)
}
/>
<span className="text-gray-700">
{sub.name}
</span>
</Label>
)
)}
>
{allSubItemsChecked ? (
<>
<Icon
icon="material-symbols:check-indeterminate-small"
width={
12
}
height={
12
}
className="mr-1"
/>
Batal
Semua
</>
) : (
<>
<Icon
icon="material-symbols:check-all"
width={
12
}
height={
12
}
className="mr-1"
/>
Pilih
Semua
</>
)}
</Button>
);
})()}
</div>
<div className="space-y-1">
{polda.subDestination.map(
(sub: any) => (
<Label
key={sub.id}
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
>
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(
sub.id
)
)
}
/>
<span className="text-gray-700">
{sub.name}
</span>
</Label>
)
)}
</div>
</div>
</div>
)}
</div>
))}
</div>
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
<DialogClose asChild>
<Button variant="outline">
{t("cancel", {
defaultValue: "Batal",
})}
</Button>
</DialogClose>
<DialogClose asChild>
<Button>Simpan</Button>
</DialogClose>
</div>
</DialogContent>
</Dialog>
)}
</div>
))}
</div>
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
<DialogClose asChild>
<Button variant="outline">
{t("cancel", {
defaultValue: "Batal",
})}
</Button>
</DialogClose>
<DialogClose asChild>
<Button>Simpan</Button>
</DialogClose>
</div>
</DialogContent>
</Dialog>
</div>
</div>
</div>
</div>
)}
)}
</div>
</div>
) : (

View File

@ -207,42 +207,60 @@ export default function FormTeksDetail() {
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;
// Update fileCheckedLevels untuk sinkronisasi dengan modal
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (isUploadedBySatkerLevel3) {
currentSelection.wilayah = false;
currentSelection.polda = false;
currentSelection.polres = false;
currentSelection.satker = false;
if (value) {
// Checklist semua item di modal
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
// Unchecklist semua item di modal
currentFileLevels.clear();
}
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
newArray[fileIndex] = currentFileLevels;
return newArray;
});
if (!value) {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
} else {
// 🔁 LOGIC LAMA (TIDAK DIUBAH)
currentSelection.wilayah = value;
currentSelection.polda = value;
currentSelection.polres = value;
currentSelection.satker = value;
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (value) {
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
}
} else {
// Validasi khusus untuk POLRES - harus ada POLDA yang ter-checklist
if (key === "polres" && value) {
const currentFileCheckedLevels = fileCheckedLevels[fileIndex];
const hasSelectedPolda =
@ -258,14 +276,12 @@ export default function FormTeksDetail() {
alert(
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
);
return prev; // Batalkan perubahan
return prev;
}
}
// Update salah satu saja
currentSelection[key] = value;
// Cek apakah semua selain "semua" sudah dicentang
const allChecked = [
"nasional",
"wilayah",
@ -283,6 +299,92 @@ export default function FormTeksDetail() {
});
};
// 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;
// // Update fileCheckedLevels untuk sinkronisasi dengan modal
// setFileCheckedLevels((prevLevels) => {
// const newArray = [...prevLevels];
// const currentFileLevels = new Set<number>(
// newArray[fileIndex] || new Set()
// );
// if (value) {
// // Checklist semua item di modal
// listDest.forEach((item: any) => {
// currentFileLevels.add(Number(item.id));
// if (item.subDestination) {
// item.subDestination.forEach((sub: any) => {
// currentFileLevels.add(Number(sub.id));
// });
// }
// });
// } else {
// // Unchecklist semua item di modal
// currentFileLevels.clear();
// }
// newArray[fileIndex] = currentFileLevels;
// return newArray;
// });
// } 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;
// });
// };
let fileTypeId = "3";
const toggleExpand = (id: number) => {
@ -725,8 +827,15 @@ export default function FormTeksDetail() {
) => {
let temp = [...filePlacements];
if (checked) {
// if (placement === "all") {
// temp[index] = ["all", "mabes", "polda", "international"];
if (placement === "all") {
temp[index] = ["all", "mabes", "polda", "international"];
if (isUploadedBySatkerLevel3) {
temp[index] = ["mabes", "international"];
} else {
temp[index] = ["all", "mabes", "polda", "international"];
}
// Update fileCheckedLevels untuk sinkronisasi dengan modal ketika "all" diklik
setFileCheckedLevels((prevLevels) => {
@ -1126,6 +1235,9 @@ export default function FormTeksDetail() {
});
};
const isUploadedBySatkerLevel3 =
Number(detail?.uploadedBy?.userLevel?.levelNumber) === 3;
return (
<form>
{detail !== undefined ? (
@ -1471,6 +1583,56 @@ export default function FormTeksDetail() {
key: "international",
label: "Internasional",
},
]
.filter(
(item) =>
!(
isUploadedBySatkerLevel3 &&
item.key === "wilayah"
)
)
.map((item) => (
<div
key={item.key}
className="flex items-center gap-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
{item.label}
</Label>
</div>
))}
{/* {[
{ key: "semua", label: "Semua" },
{ key: "nasional", label: "Nasional" },
{ key: "wilayah", label: "Wilayah" },
{
key: "international",
label: "Internasional",
},
].map((item, idx) => (
<div
key={item.key}
@ -1503,7 +1665,7 @@ export default function FormTeksDetail() {
{item.label}
</Label>
</div>
))}
))} */}
</div>
</div>

View File

@ -210,42 +210,60 @@ export default function FormVideoDetail() {
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;
// Update fileCheckedLevels untuk sinkronisasi dengan modal
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (isUploadedBySatkerLevel3) {
currentSelection.wilayah = false;
currentSelection.polda = false;
currentSelection.polres = false;
currentSelection.satker = false;
if (value) {
// Checklist semua item di modal
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
// Unchecklist semua item di modal
currentFileLevels.clear();
}
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
newArray[fileIndex] = currentFileLevels;
return newArray;
});
if (!value) {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
} else {
// 🔁 LOGIC LAMA (TIDAK DIUBAH)
currentSelection.wilayah = value;
currentSelection.polda = value;
currentSelection.polres = value;
currentSelection.satker = value;
setFileCheckedLevels((prevLevels) => {
const newArray = [...prevLevels];
const currentFileLevels = new Set<number>(
newArray[fileIndex] || new Set()
);
if (value) {
listDest.forEach((item: any) => {
currentFileLevels.add(Number(item.id));
if (item.subDestination) {
item.subDestination.forEach((sub: any) => {
currentFileLevels.add(Number(sub.id));
});
}
});
} else {
currentFileLevels.clear();
}
newArray[fileIndex] = currentFileLevels;
return newArray;
});
}
} else {
// Validasi khusus untuk POLRES - harus ada POLDA yang ter-checklist
if (key === "polres" && value) {
const currentFileCheckedLevels = fileCheckedLevels[fileIndex];
const hasSelectedPolda =
@ -261,14 +279,12 @@ export default function FormVideoDetail() {
alert(
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
);
return prev; // Batalkan perubahan
return prev;
}
}
// Update salah satu saja
currentSelection[key] = value;
// Cek apakah semua selain "semua" sudah dicentang
const allChecked = [
"nasional",
"wilayah",
@ -286,6 +302,92 @@ export default function FormVideoDetail() {
});
};
// 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;
// // Update fileCheckedLevels untuk sinkronisasi dengan modal
// setFileCheckedLevels((prevLevels) => {
// const newArray = [...prevLevels];
// const currentFileLevels = new Set<number>(
// newArray[fileIndex] || new Set()
// );
// if (value) {
// // Checklist semua item di modal
// listDest.forEach((item: any) => {
// currentFileLevels.add(Number(item.id));
// if (item.subDestination) {
// item.subDestination.forEach((sub: any) => {
// currentFileLevels.add(Number(sub.id));
// });
// }
// });
// } else {
// // Unchecklist semua item di modal
// currentFileLevels.clear();
// }
// newArray[fileIndex] = currentFileLevels;
// return newArray;
// });
// } 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;
// });
// };
let fileTypeId = "2";
const toggleExpand = (id: number) => {
@ -690,8 +792,15 @@ export default function FormVideoDetail() {
) => {
let temp = [...filePlacements];
if (checked) {
// if (placement === "all") {
// temp[index] = ["all", "mabes", "polda", "international"];
if (placement === "all") {
temp[index] = ["all", "mabes", "polda", "international"];
if (isUploadedBySatkerLevel3) {
temp[index] = ["mabes", "international"];
} else {
temp[index] = ["all", "mabes", "polda", "international"];
}
// Update fileCheckedLevels untuk sinkronisasi dengan modal ketika "all" diklik
setFileCheckedLevels((prevLevels) => {
@ -1128,6 +1237,9 @@ export default function FormVideoDetail() {
});
};
const isUploadedBySatkerLevel3 =
Number(detail?.uploadedBy?.userLevel?.levelNumber) === 3;
return (
<form>
{detail !== undefined ? (
@ -1475,6 +1587,56 @@ export default function FormVideoDetail() {
key: "international",
label: "Internasional",
},
]
.filter(
(item) =>
!(
isUploadedBySatkerLevel3 &&
item.key === "wilayah"
)
)
.map((item) => (
<div
key={item.key}
className="flex items-center gap-2 p-2 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
{item.label}
</Label>
</div>
))}
{/* {[
{ key: "semua", label: "Semua" },
{ key: "nasional", label: "Nasional" },
{ key: "wilayah", label: "Wilayah" },
{
key: "international",
label: "Internasional",
},
].map((item, idx) => (
<div
key={item.key}
@ -1507,256 +1669,266 @@ export default function FormVideoDetail() {
{item.label}
</Label>
</div>
))}
))} */}
</div>
</div>
{/* Detail Wilayah */}
{fileUnitSelections[index]?.wilayah && (
<div className="border-t border-gray-200 pt-2">
<p className="text-sm font-medium text-gray-700 mb-2">
Detail Wilayah:
</p>
{fileUnitSelections[index]?.wilayah &&
!isUploadedBySatkerLevel3 && (
<div className="border-t border-gray-200 pt-2">
<p className="text-sm font-medium text-gray-700 mb-2">
Detail Wilayah:
</p>
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
{[
{ key: "polda", label: "POLDA" },
{ key: "polres", label: "POLRES" },
{ key: "satker", label: "SATKER" },
].map((item, idx) => (
<div
key={item.key}
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
>
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
{[
{ key: "polda", label: "POLDA" },
{ key: "polres", label: "POLRES" },
{ key: "satker", label: "SATKER" },
].map((item, idx) => (
<div
key={item.key}
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
>
{item.label}
</Label>
</div>
))}
{/* Tombol Kustom sejajar dengan checkbox */}
<div className="flex items-center justify-center p-3">
<Dialog>
<DialogTrigger asChild>
<Button
variant="outline"
size="sm"
className="gap-2"
<Checkbox
id={`${item.key}-${index}`}
checked={
fileUnitSelections[index]?.[
item.key as keyof typeof unitSelection
] || false
}
onCheckedChange={(value) => {
handleFileUnitChange(
index,
item.key as keyof typeof unitSelection,
value as boolean
);
setupPlacement(
index,
item.key,
Boolean(value)
);
}}
/>
<Label
htmlFor={`${item.key}-${index}`}
className="text-sm font-medium cursor-pointer"
>
<Icon
icon="material-symbols:tune"
width={16}
height={16}
/>
{t("custom", {
defaultValue: "Kustom",
})}
</Button>
</DialogTrigger>
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
<DialogHeader className="border-b border-gray-200 pb-4">
<DialogTitle className="text-lg font-semibold">
Daftar Wilayah POLDA dan POLRES
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 max-h-[70vh] overflow-y-auto p-1">
{listDest.map((polda: any) => (
<div
key={polda.id}
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
>
{/* Header POLDA */}
<div className="flex items-center justify-between">
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(polda.id)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(polda.id)
)
}
/>
<span className="font-semibold text-gray-900 text-sm">
{polda.name}
</span>
</Label>
{polda.subDestination && (
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(
polda.id
);
}}
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
>
<Icon
icon={
expandedPolda[
polda.id
]
? "mdi:chevron-up"
: "mdi:chevron-down"
}
width={16}
height={16}
/>
</button>
)}
</div>
{item.label}
</Label>
</div>
))}
{/* Sub-items */}
{polda.subDestination &&
expandedPolda[polda.id] && (
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
{/* Tombol Pilih Semua untuk sub-items */}
<div className="mb-2 flex justify-start">
{(() => {
const allSubItemsChecked =
polda.subDestination?.every(
(sub: any) =>
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
)
);
return (
<Button
size="sm"
variant="outline"
className="text-xs h-6 px-2"
onClick={() =>
handleSelectAllSubItems(
index,
polda
)
}
>
{allSubItemsChecked ? (
<>
<Icon
icon="material-symbols:check-indeterminate-small"
width={12}
height={
12
}
className="mr-1"
/>
Batal Semua
</>
) : (
<>
<Icon
icon="material-symbols:check-all"
width={12}
height={
12
}
className="mr-1"
/>
Pilih Semua
</>
)}
</Button>
{/* Tombol Kustom sejajar dengan checkbox */}
<div className="flex items-center justify-center p-3">
<Dialog>
<DialogTrigger asChild>
<Button
variant="outline"
size="sm"
className="gap-2"
>
<Icon
icon="material-symbols:tune"
width={16}
height={16}
/>
{t("custom", {
defaultValue: "Kustom",
})}
</Button>
</DialogTrigger>
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
<DialogHeader className="border-b border-gray-200 pb-4">
<DialogTitle className="text-lg font-semibold">
Daftar Wilayah POLDA dan
POLRES
</DialogTitle>
</DialogHeader>
<div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-4 max-h-[70vh] overflow-y-auto p-1">
{listDest.map((polda: any) => (
<div
key={polda.id}
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
>
{/* Header POLDA */}
<div className="flex items-center justify-between">
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(polda.id)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(polda.id)
)
}
/>
<span className="font-semibold text-gray-900 text-sm">
{polda.name}
</span>
</Label>
{polda.subDestination && (
<button
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
toggleExpand(
polda.id
);
})()}
</div>
<div className="space-y-1">
{polda.subDestination.map(
(sub: any) => (
<Label
key={sub.id}
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
>
<Checkbox
checked={
}}
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
>
<Icon
icon={
expandedPolda[
polda.id
]
? "mdi:chevron-up"
: "mdi:chevron-down"
}
width={16}
height={16}
/>
</button>
)}
</div>
{/* Sub-items */}
{polda.subDestination &&
expandedPolda[
polda.id
] && (
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
{/* Tombol Pilih Semua untuk sub-items */}
<div className="mb-2 flex justify-start">
{(() => {
const allSubItemsChecked =
polda.subDestination?.every(
(sub: any) =>
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
)
);
return (
<Button
size="sm"
variant="outline"
className="text-xs h-6 px-2"
onClick={() =>
handleSelectAllSubItems(
index,
Number(
sub.id
)
polda
)
}
/>
<span className="text-gray-700">
{sub.name}
</span>
</Label>
)
)}
>
{allSubItemsChecked ? (
<>
<Icon
icon="material-symbols:check-indeterminate-small"
width={
12
}
height={
12
}
className="mr-1"
/>
Batal
Semua
</>
) : (
<>
<Icon
icon="material-symbols:check-all"
width={
12
}
height={
12
}
className="mr-1"
/>
Pilih
Semua
</>
)}
</Button>
);
})()}
</div>
<div className="space-y-1">
{polda.subDestination.map(
(sub: any) => (
<Label
key={sub.id}
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
>
<Checkbox
checked={
fileCheckedLevels[
index
]?.has(
Number(
sub.id
)
) || false
}
onCheckedChange={() =>
handleFileCheckboxChangePlacement(
index,
Number(
sub.id
)
)
}
/>
<span className="text-gray-700">
{sub.name}
</span>
</Label>
)
)}
</div>
</div>
</div>
)}
</div>
))}
</div>
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
<DialogClose asChild>
<Button variant="outline">
{t("cancel", {
defaultValue: "Batal",
})}
</Button>
</DialogClose>
<DialogClose asChild>
<Button>
{/* {t("save", {
)}
</div>
))}
</div>
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
<DialogClose asChild>
<Button variant="outline">
{t("cancel", {
defaultValue: "Batal",
})}
</Button>
</DialogClose>
<DialogClose asChild>
<Button>
{/* {t("save", {
defaultValue: "Simpan",
})} */}
Simpan
</Button>
</DialogClose>
</div>
</DialogContent>
</Dialog>
Simpan
</Button>
</DialogClose>
</div>
</DialogContent>
</Dialog>
</div>
</div>
</div>
</div>
)}
)}
</div>
</div>
) : (