fix: fixing placement satker and maps
This commit is contained in:
commit
8c98175cdb
|
|
@ -115,7 +115,7 @@ const ViewEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/view-editor");
|
return import("@/components/editor/view-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface Destination {
|
interface Destination {
|
||||||
|
|
@ -204,6 +204,12 @@ export default function FormAudioDetail() {
|
||||||
satker: boolean;
|
satker: boolean;
|
||||||
}>
|
}>
|
||||||
>([]);
|
>([]);
|
||||||
|
const [creatorLevelNumber, setCreatorLevelNumber] = useState<number | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
const isContentFromSatker = creatorLevelNumber === 3;
|
||||||
|
const isContentFromMabesOrPolda =
|
||||||
|
creatorLevelNumber === 1 || creatorLevelNumber === 2;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
||||||
|
|
@ -215,7 +221,7 @@ export default function FormAudioDetail() {
|
||||||
const handleFileUnitChange = (
|
const handleFileUnitChange = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
setFileUnitSelections((prev) => {
|
setFileUnitSelections((prev) => {
|
||||||
const newSelections = [...prev];
|
const newSelections = [...prev];
|
||||||
|
|
@ -284,12 +290,12 @@ export default function FormAudioDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
currentFileCheckedLevels.has(Number(item.id))
|
currentFileCheckedLevels.has(Number(item.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasSelectedPolda) {
|
if (!hasSelectedPolda) {
|
||||||
alert(
|
alert(
|
||||||
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
|
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.",
|
||||||
);
|
);
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +416,7 @@ export default function FormAudioDetail() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (detail?.assignedToTopLevel) {
|
if (detail?.assignedToTopLevel) {
|
||||||
const outputSet = new Set(
|
const outputSet = new Set(
|
||||||
detail.assignedToTopLevel.split(",").map(Number)
|
detail.assignedToTopLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setUnitSelection({
|
setUnitSelection({
|
||||||
semua: outputSet.has(0),
|
semua: outputSet.has(0),
|
||||||
|
|
@ -435,7 +441,7 @@ export default function FormAudioDetail() {
|
||||||
acc[polda.id] = false;
|
acc[polda.id] = false;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
setExpandedPolda(initialExpandedState);
|
setExpandedPolda(initialExpandedState);
|
||||||
console.log("polres", initialExpandedState);
|
console.log("polres", initialExpandedState);
|
||||||
|
|
@ -470,7 +476,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
const handleUnitChange = (
|
const handleUnitChange = (
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (key === "semua") {
|
if (key === "semua") {
|
||||||
const newState = {
|
const newState = {
|
||||||
|
|
@ -580,7 +586,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
const handleCheckboxChange = (id: number) => {
|
const handleCheckboxChange = (id: number) => {
|
||||||
setSelectedPublishers((prev) =>
|
setSelectedPublishers((prev) =>
|
||||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -602,7 +608,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -653,6 +659,9 @@ export default function FormAudioDetail() {
|
||||||
// console.log("ISI FILES:", details?.files);
|
// console.log("ISI FILES:", details?.files);
|
||||||
|
|
||||||
setDetail(details);
|
setDetail(details);
|
||||||
|
if (details?.uploadedBy?.userLevel?.levelNumber) {
|
||||||
|
setCreatorLevelNumber(details.uploadedBy.userLevel.levelNumber);
|
||||||
|
}
|
||||||
setMain({
|
setMain({
|
||||||
type: details?.fileType.name,
|
type: details?.fileType.name,
|
||||||
url: details?.files[0]?.url,
|
url: details?.files[0]?.url,
|
||||||
|
|
@ -663,14 +672,14 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
if (details?.assignedToLevel) {
|
if (details?.assignedToLevel) {
|
||||||
const levels = new Set(
|
const levels = new Set(
|
||||||
details.assignedToLevel.split(",").map(Number)
|
details.assignedToLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setCheckedLevels(levels);
|
setCheckedLevels(levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details?.publishedForObject) {
|
if (details?.publishedForObject) {
|
||||||
const publisherIds = details?.publishedForObject.map(
|
const publisherIds = details?.publishedForObject.map(
|
||||||
(obj: any) => obj.id
|
(obj: any) => obj.id,
|
||||||
);
|
);
|
||||||
setSelectedPublishers(publisherIds);
|
setSelectedPublishers(publisherIds);
|
||||||
}
|
}
|
||||||
|
|
@ -820,7 +829,7 @@ export default function FormAudioDetail() {
|
||||||
const setupPlacement = (
|
const setupPlacement = (
|
||||||
index: number,
|
index: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
let temp = [...filePlacements];
|
let temp = [...filePlacements];
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
@ -838,7 +847,7 @@ export default function FormAudioDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Checklist semua item di modal
|
// Checklist semua item di modal
|
||||||
|
|
@ -888,7 +897,7 @@ export default function FormAudioDetail() {
|
||||||
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
||||||
// JANGAN include satker dalam perhitungan auto "all"
|
// JANGAN include satker dalam perhitungan auto "all"
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
||||||
now.push("all");
|
now.push("all");
|
||||||
|
|
@ -903,7 +912,7 @@ export default function FormAudioDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unchecklist semua item di modal
|
// Unchecklist semua item di modal
|
||||||
|
|
@ -937,7 +946,7 @@ export default function FormAudioDetail() {
|
||||||
// Hapus "all" jika tidak semua item ter-checklist
|
// Hapus "all" jika tidak semua item ter-checklist
|
||||||
if (now.includes("all")) {
|
if (now.includes("all")) {
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length < 3) {
|
if (nonSatkerItems.length < 3) {
|
||||||
const newData = now.filter((b) => b !== "all");
|
const newData = now.filter((b) => b !== "all");
|
||||||
|
|
@ -956,7 +965,7 @@ export default function FormAudioDetail() {
|
||||||
type: string,
|
type: string,
|
||||||
url: string,
|
url: string,
|
||||||
names: string,
|
names: string,
|
||||||
format: string
|
format: string,
|
||||||
) => {
|
) => {
|
||||||
// console.log("Test 3 :", type, url, names, format);
|
// console.log("Test 3 :", type, url, names, format);
|
||||||
setMain({
|
setMain({
|
||||||
|
|
@ -991,7 +1000,7 @@ export default function FormAudioDetail() {
|
||||||
const updateModalChecklistLevels = (
|
const updateModalChecklistLevels = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!listDest || listDest.length === 0) return;
|
if (!listDest || listDest.length === 0) return;
|
||||||
|
|
||||||
|
|
@ -1024,7 +1033,7 @@ export default function FormAudioDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.add(Number(satkerItem.id));
|
currentFileLevels.add(Number(satkerItem.id));
|
||||||
|
|
@ -1060,7 +1069,7 @@ export default function FormAudioDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.delete(Number(satkerItem.id));
|
currentFileLevels.delete(Number(satkerItem.id));
|
||||||
|
|
@ -1093,7 +1102,7 @@ export default function FormAudioDetail() {
|
||||||
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
||||||
const handleFileCheckboxChangePlacement = (
|
const handleFileCheckboxChangePlacement = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
levelId: number
|
levelId: number,
|
||||||
) => {
|
) => {
|
||||||
setFileCheckedLevels((prev) => {
|
setFileCheckedLevels((prev) => {
|
||||||
const newArray = [...prev];
|
const newArray = [...prev];
|
||||||
|
|
@ -1105,7 +1114,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
||||||
const poldaItem = listDest.find(
|
const poldaItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (
|
if (
|
||||||
poldaItem &&
|
poldaItem &&
|
||||||
|
|
@ -1128,7 +1137,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||||
|
|
@ -1159,7 +1168,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
||||||
const totalPoldaCount = listDest.filter(
|
const totalPoldaCount = listDest.filter(
|
||||||
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI"
|
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI",
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
||||||
|
|
@ -1186,7 +1195,7 @@ export default function FormAudioDetail() {
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
},
|
},
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Hitung berapa banyak POLRES yang ter-checklist
|
// Hitung berapa banyak POLRES yang ter-checklist
|
||||||
|
|
@ -1196,7 +1205,7 @@ export default function FormAudioDetail() {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
item.subDestination.filter((sub: any) =>
|
item.subDestination.filter((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
).length
|
).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1205,7 +1214,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
// Cek apakah SATKER POLRI ter-checklist
|
// Cek apakah SATKER POLRI ter-checklist
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
const isSatkerChecked =
|
const isSatkerChecked =
|
||||||
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
||||||
|
|
@ -1239,7 +1248,7 @@ export default function FormAudioDetail() {
|
||||||
|
|
||||||
// Cek apakah semua sub-items sudah ter-checklist
|
// Cek apakah semua sub-items sudah ter-checklist
|
||||||
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allSubItemsChecked) {
|
if (allSubItemsChecked) {
|
||||||
|
|
@ -1322,7 +1331,7 @@ export default function FormAudioDetail() {
|
||||||
{detail &&
|
{detail &&
|
||||||
!categories.find(
|
!categories.find(
|
||||||
(cat) =>
|
(cat) =>
|
||||||
String(cat.id) === String(detail.category.id)
|
String(cat.id) === String(detail.category.id),
|
||||||
) && (
|
) && (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={String(detail.category.id)}
|
key={String(detail.category.id)}
|
||||||
|
|
@ -1582,56 +1591,6 @@ export default function FormAudioDetail() {
|
||||||
Tingkat Distribusi:
|
Tingkat Distribusi:
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
{[
|
|
||||||
{ key: "semua", label: "Semua" },
|
|
||||||
{ key: "nasional", label: "Nasional" },
|
|
||||||
{ key: "wilayah", label: "Wilayah" },
|
|
||||||
{
|
|
||||||
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: "semua", label: "Semua" },
|
||||||
{ key: "nasional", label: "Nasional" },
|
{ key: "nasional", label: "Nasional" },
|
||||||
|
|
@ -1640,6 +1599,39 @@ export default function FormAudioDetail() {
|
||||||
key: "international",
|
key: "international",
|
||||||
label: "Internasional",
|
label: "Internasional",
|
||||||
},
|
},
|
||||||
|
] */}
|
||||||
|
{[
|
||||||
|
{ key: "semua", label: "Semua" },
|
||||||
|
|
||||||
|
...(isContentFromMabesOrPolda
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "wilayah",
|
||||||
|
label: "Wilayah",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
|
...(isContentFromSatker
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
|
|
@ -1656,12 +1648,12 @@ export default function FormAudioDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1672,256 +1664,267 @@ export default function FormAudioDetail() {
|
||||||
{item.label}
|
{item.label}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
))} */}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Detail Wilayah */}
|
{/* Detail Wilayah */}
|
||||||
{fileUnitSelections[index]?.wilayah && (
|
{/* {fileUnitSelections[index]?.wilayah && ( */}
|
||||||
<div className="border-t border-gray-200 pt-2">
|
{!isContentFromSatker &&
|
||||||
<p className="text-sm font-medium text-gray-700 mb-2">
|
fileUnitSelections[index]?.wilayah && (
|
||||||
Detail Wilayah:
|
<div className="border-t border-gray-200 pt-2">
|
||||||
</p>
|
<p className="text-sm font-medium text-gray-700 mb-2">
|
||||||
|
Detail Wilayah:
|
||||||
|
</p>
|
||||||
|
|
||||||
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
|
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
|
||||||
{[
|
{[
|
||||||
{ key: "polda", label: "POLDA" },
|
{ key: "polda", label: "POLDA" },
|
||||||
{ key: "polres", label: "POLRES" },
|
{ key: "polres", label: "POLRES" },
|
||||||
{ key: "satker", label: "SATKER" },
|
{ key: "satker", label: "SATKER" },
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
|
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"
|
|
||||||
>
|
>
|
||||||
{item.label}
|
<Checkbox
|
||||||
</Label>
|
id={`${item.key}-${index}`}
|
||||||
</div>
|
checked={
|
||||||
))}
|
fileUnitSelections[index]?.[
|
||||||
|
item.key as keyof typeof unitSelection
|
||||||
{/* Tombol Kustom sejajar dengan checkbox */}
|
] || false
|
||||||
<div className="flex items-center justify-center p-3">
|
}
|
||||||
<Dialog>
|
onCheckedChange={(value) => {
|
||||||
<DialogTrigger asChild>
|
handleFileUnitChange(
|
||||||
<Button
|
index,
|
||||||
variant="outline"
|
item.key as keyof typeof unitSelection,
|
||||||
size="sm"
|
value as boolean,
|
||||||
className="gap-2"
|
);
|
||||||
|
setupPlacement(
|
||||||
|
index,
|
||||||
|
item.key,
|
||||||
|
Boolean(value),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
htmlFor={`${item.key}-${index}`}
|
||||||
|
className="text-sm font-medium cursor-pointer"
|
||||||
>
|
>
|
||||||
<Icon
|
{item.label}
|
||||||
icon="material-symbols:tune"
|
</Label>
|
||||||
width={16}
|
</div>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Sub-items */}
|
{/* Tombol Kustom sejajar dengan checkbox */}
|
||||||
{polda.subDestination &&
|
<div className="flex items-center justify-center p-3">
|
||||||
expandedPolda[polda.id] && (
|
<Dialog>
|
||||||
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
|
<DialogTrigger asChild>
|
||||||
{/* Tombol Pilih Semua untuk sub-items */}
|
<Button
|
||||||
<div className="mb-2 flex justify-start">
|
variant="outline"
|
||||||
{(() => {
|
size="sm"
|
||||||
const allSubItemsChecked =
|
className="gap-2"
|
||||||
polda.subDestination?.every(
|
>
|
||||||
(sub: any) =>
|
<Icon
|
||||||
fileCheckedLevels[
|
icon="material-symbols:tune"
|
||||||
index
|
width={16}
|
||||||
]?.has(
|
height={16}
|
||||||
Number(
|
/>
|
||||||
sub.id
|
{t("custom", {
|
||||||
)
|
defaultValue: "Kustom",
|
||||||
)
|
})}
|
||||||
);
|
</Button>
|
||||||
return (
|
</DialogTrigger>
|
||||||
<Button
|
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
|
||||||
size="sm"
|
<DialogHeader className="border-b border-gray-200 pb-4">
|
||||||
variant="outline"
|
<DialogTitle className="text-lg font-semibold">
|
||||||
className="text-xs h-6 px-2"
|
Daftar Wilayah POLDA dan
|
||||||
onClick={() =>
|
POLRES
|
||||||
handleSelectAllSubItems(
|
</DialogTitle>
|
||||||
index,
|
</DialogHeader>
|
||||||
polda
|
<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}
|
||||||
{allSubItemsChecked ? (
|
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
|
||||||
<>
|
>
|
||||||
<Icon
|
{/* Header POLDA */}
|
||||||
icon="material-symbols:check-indeterminate-small"
|
<div className="flex items-center justify-between">
|
||||||
width={12}
|
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
|
||||||
height={
|
<Checkbox
|
||||||
12
|
checked={
|
||||||
}
|
fileCheckedLevels[
|
||||||
className="mr-1"
|
index
|
||||||
/>
|
]?.has(
|
||||||
Batal Semua
|
Number(polda.id),
|
||||||
</>
|
) || false
|
||||||
) : (
|
}
|
||||||
<>
|
onCheckedChange={() =>
|
||||||
<Icon
|
handleFileCheckboxChangePlacement(
|
||||||
icon="material-symbols:check-all"
|
index,
|
||||||
width={12}
|
Number(polda.id),
|
||||||
height={
|
)
|
||||||
12
|
}
|
||||||
}
|
/>
|
||||||
className="mr-1"
|
<span className="font-semibold text-gray-900 text-sm">
|
||||||
/>
|
{polda.name}
|
||||||
Pilih Semua
|
</span>
|
||||||
</>
|
</Label>
|
||||||
)}
|
{polda.subDestination && (
|
||||||
</Button>
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
toggleExpand(
|
||||||
|
polda.id,
|
||||||
);
|
);
|
||||||
})()}
|
}}
|
||||||
</div>
|
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
||||||
<div className="space-y-1">
|
>
|
||||||
{polda.subDestination.map(
|
<Icon
|
||||||
(sub: any) => (
|
icon={
|
||||||
<Label
|
expandedPolda[
|
||||||
key={sub.id}
|
polda.id
|
||||||
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
|
]
|
||||||
>
|
? "mdi:chevron-up"
|
||||||
<Checkbox
|
: "mdi:chevron-down"
|
||||||
checked={
|
}
|
||||||
|
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[
|
fileCheckedLevels[
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
) || false
|
),
|
||||||
}
|
);
|
||||||
onCheckedChange={() =>
|
return (
|
||||||
handleFileCheckboxChangePlacement(
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
onClick={() =>
|
||||||
|
handleSelectAllSubItems(
|
||||||
index,
|
index,
|
||||||
Number(
|
polda,
|
||||||
sub.id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
<span className="text-gray-700">
|
{allSubItemsChecked ? (
|
||||||
{sub.name}
|
<>
|
||||||
</span>
|
<Icon
|
||||||
</Label>
|
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>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
|
||||||
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
|
<DialogClose asChild>
|
||||||
<DialogClose asChild>
|
<Button variant="outline">
|
||||||
<Button variant="outline">
|
{t("cancel", {
|
||||||
{t("cancel", {
|
defaultValue: "Batal",
|
||||||
defaultValue: "Batal",
|
})}
|
||||||
})}
|
</Button>
|
||||||
</Button>
|
</DialogClose>
|
||||||
</DialogClose>
|
<DialogClose asChild>
|
||||||
<DialogClose asChild>
|
<Button>
|
||||||
<Button>
|
{/* {t("save", {
|
||||||
{/* {t("save", {
|
|
||||||
defaultValue: "Simpan",
|
defaultValue: "Simpan",
|
||||||
})} */}
|
})} */}
|
||||||
Simpan
|
Simpan
|
||||||
</Button>
|
</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -2000,7 +2003,7 @@ export default function FormAudioDetail() {
|
||||||
>
|
>
|
||||||
{template}
|
{template}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1806,7 +1806,7 @@ export default function FormAudio() {
|
||||||
</Card>
|
</Card>
|
||||||
<div className="flex flex-row justify-end gap-3">
|
<div className="flex flex-row justify-end gap-3">
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
{levelNumber !== "2" && levelNumber !== "3" && (
|
{levelNumber !== "2" && (
|
||||||
<Button type="submit" color="primary">
|
<Button type="submit" color="primary">
|
||||||
{t("submit", { defaultValue: "Submit" })}
|
{t("submit", { defaultValue: "Submit" })}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ const ViewEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/view-editor");
|
return import("@/components/editor/view-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface Destination {
|
interface Destination {
|
||||||
|
|
@ -173,6 +173,12 @@ export default function FormImageDetail() {
|
||||||
satker: boolean;
|
satker: boolean;
|
||||||
}>
|
}>
|
||||||
>([]);
|
>([]);
|
||||||
|
const [creatorLevelNumber, setCreatorLevelNumber] = useState<number | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
const isContentFromSatker = creatorLevelNumber === 3;
|
||||||
|
const isContentFromMabesOrPolda =
|
||||||
|
creatorLevelNumber === 1 || creatorLevelNumber === 2;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
||||||
|
|
@ -201,7 +207,7 @@ export default function FormImageDetail() {
|
||||||
const [files, setFiles] = useState<FileType[]>([]);
|
const [files, setFiles] = useState<FileType[]>([]);
|
||||||
const [rejectedFiles, setRejectedFiles] = useState<number[]>([]);
|
const [rejectedFiles, setRejectedFiles] = useState<number[]>([]);
|
||||||
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>(
|
const [expandedPolda, setExpandedPolda] = useState<Record<number, boolean>>(
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
// State untuk melacak apakah perubahan berasal dari checkbox utama
|
// State untuk melacak apakah perubahan berasal dari checkbox utama
|
||||||
|
|
@ -232,7 +238,7 @@ export default function FormImageDetail() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (detail?.assignedToTopLevel) {
|
if (detail?.assignedToTopLevel) {
|
||||||
const outputSet = new Set(
|
const outputSet = new Set(
|
||||||
detail.assignedToTopLevel.split(",").map(Number)
|
detail.assignedToTopLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setUnitSelection({
|
setUnitSelection({
|
||||||
semua: outputSet.has(0),
|
semua: outputSet.has(0),
|
||||||
|
|
@ -261,7 +267,7 @@ export default function FormImageDetail() {
|
||||||
acc[polda.id] = false;
|
acc[polda.id] = false;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
setExpandedPolda(initialExpandedState);
|
setExpandedPolda(initialExpandedState);
|
||||||
console.log("polres", initialExpandedState);
|
console.log("polres", initialExpandedState);
|
||||||
|
|
@ -300,7 +306,7 @@ export default function FormImageDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
checkedLevels.has(Number(item.id))
|
checkedLevels.has(Number(item.id)),
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
|
const checkedPolresCount = listDest.reduce((total: number, item: any) => {
|
||||||
|
|
@ -309,7 +315,7 @@ export default function FormImageDetail() {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
item.subDestination.filter((sub: any) =>
|
item.subDestination.filter((sub: any) =>
|
||||||
checkedLevels.has(Number(sub.id))
|
checkedLevels.has(Number(sub.id)),
|
||||||
).length
|
).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -317,12 +323,12 @@ export default function FormImageDetail() {
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
const checkedSatkerCount = satkerItem
|
const checkedSatkerCount = satkerItem
|
||||||
? (checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
|
? (checkedLevels.has(Number(satkerItem.id)) ? 1 : 0) +
|
||||||
(satkerItem.subDestination?.filter((sub: any) =>
|
(satkerItem.subDestination?.filter((sub: any) =>
|
||||||
checkedLevels.has(Number(sub.id))
|
checkedLevels.has(Number(sub.id)),
|
||||||
).length || 0)
|
).length || 0)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
|
|
@ -392,7 +398,7 @@ export default function FormImageDetail() {
|
||||||
} else if (mainCheckboxChangeType === "satker_checked") {
|
} else if (mainCheckboxChangeType === "satker_checked") {
|
||||||
// Checklist satker
|
// Checklist satker
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
newCheckedLevels.add(Number(satkerItem.id));
|
newCheckedLevels.add(Number(satkerItem.id));
|
||||||
|
|
@ -440,7 +446,7 @@ export default function FormImageDetail() {
|
||||||
} else if (mainCheckboxChangeType === "satker_unchecked") {
|
} else if (mainCheckboxChangeType === "satker_unchecked") {
|
||||||
// Clear satker dan semua sub-item di bawahnya dari checkedLevels
|
// Clear satker dan semua sub-item di bawahnya dari checkedLevels
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
newCheckedLevels.delete(Number(satkerItem.id));
|
newCheckedLevels.delete(Number(satkerItem.id));
|
||||||
|
|
@ -467,7 +473,7 @@ export default function FormImageDetail() {
|
||||||
const handleFileUnitChange = (
|
const handleFileUnitChange = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
setFileUnitSelections((prev) => {
|
setFileUnitSelections((prev) => {
|
||||||
const newSelections = [...prev];
|
const newSelections = [...prev];
|
||||||
|
|
@ -545,12 +551,12 @@ export default function FormImageDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
currentFileCheckedLevels.has(Number(item.id))
|
currentFileCheckedLevels.has(Number(item.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasSelectedPolda) {
|
if (!hasSelectedPolda) {
|
||||||
alert(
|
alert(
|
||||||
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
|
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.",
|
||||||
);
|
);
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
@ -664,7 +670,7 @@ export default function FormImageDetail() {
|
||||||
// Fungsi lama untuk kompatibilitas (akan dihapus nanti)
|
// Fungsi lama untuk kompatibilitas (akan dihapus nanti)
|
||||||
const handleUnitChange = (
|
const handleUnitChange = (
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
// Set flag bahwa perubahan berasal dari checkbox utama
|
// Set flag bahwa perubahan berasal dari checkbox utama
|
||||||
setIsUpdatingFromMainCheckbox(true);
|
setIsUpdatingFromMainCheckbox(true);
|
||||||
|
|
@ -690,13 +696,13 @@ export default function FormImageDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
checkedLevels.has(Number(item.id))
|
checkedLevels.has(Number(item.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasSelectedPolda) {
|
if (!hasSelectedPolda) {
|
||||||
// Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan
|
// Jika tidak ada POLDA yang dipilih, tampilkan peringatan dan batalkan
|
||||||
alert(
|
alert(
|
||||||
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
|
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.",
|
||||||
);
|
);
|
||||||
// Reset flag karena perubahan dibatalkan
|
// Reset flag karena perubahan dibatalkan
|
||||||
setIsUpdatingFromMainCheckbox(false);
|
setIsUpdatingFromMainCheckbox(false);
|
||||||
|
|
@ -752,14 +758,14 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
const handleCheckboxChange = (id: number) => {
|
const handleCheckboxChange = (id: number) => {
|
||||||
setSelectedPublishers((prev) =>
|
setSelectedPublishers((prev) =>
|
||||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
||||||
const handleFileCheckboxChangePlacement = (
|
const handleFileCheckboxChangePlacement = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
levelId: number
|
levelId: number,
|
||||||
) => {
|
) => {
|
||||||
setFileCheckedLevels((prev) => {
|
setFileCheckedLevels((prev) => {
|
||||||
const newArray = [...prev];
|
const newArray = [...prev];
|
||||||
|
|
@ -771,7 +777,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
||||||
const poldaItem = listDest.find(
|
const poldaItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (
|
if (
|
||||||
poldaItem &&
|
poldaItem &&
|
||||||
|
|
@ -794,7 +800,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||||
|
|
@ -822,7 +828,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Cek apakah semua sub-items sudah ter-checklist
|
// Cek apakah semua sub-items sudah ter-checklist
|
||||||
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allSubItemsChecked) {
|
if (allSubItemsChecked) {
|
||||||
|
|
@ -862,7 +868,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
||||||
const totalPoldaCount = listDest.filter(
|
const totalPoldaCount = listDest.filter(
|
||||||
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI"
|
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI",
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
||||||
|
|
@ -889,7 +895,7 @@ export default function FormImageDetail() {
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
},
|
},
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Hitung berapa banyak POLRES yang ter-checklist
|
// Hitung berapa banyak POLRES yang ter-checklist
|
||||||
|
|
@ -899,7 +905,7 @@ export default function FormImageDetail() {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
item.subDestination.filter((sub: any) =>
|
item.subDestination.filter((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
).length
|
).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -908,7 +914,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Cek apakah SATKER POLRI ter-checklist
|
// Cek apakah SATKER POLRI ter-checklist
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
const isSatkerChecked =
|
const isSatkerChecked =
|
||||||
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
||||||
|
|
@ -945,7 +951,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
||||||
const poldaItem = listDest.find(
|
const poldaItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (
|
if (
|
||||||
poldaItem &&
|
poldaItem &&
|
||||||
|
|
@ -968,7 +974,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||||
|
|
@ -999,7 +1005,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -1048,6 +1054,11 @@ export default function FormImageDetail() {
|
||||||
// console.log("detail", details);
|
// console.log("detail", details);
|
||||||
setFiles(details?.files);
|
setFiles(details?.files);
|
||||||
setDetail(details);
|
setDetail(details);
|
||||||
|
|
||||||
|
if (details?.uploadedBy?.userLevel?.levelNumber) {
|
||||||
|
setCreatorLevelNumber(details.uploadedBy.userLevel.levelNumber);
|
||||||
|
}
|
||||||
|
|
||||||
setMain({
|
setMain({
|
||||||
type: details?.fileType.name,
|
type: details?.fileType.name,
|
||||||
url: details?.files[0]?.url,
|
url: details?.files[0]?.url,
|
||||||
|
|
@ -1058,14 +1069,14 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
if (details?.assignedToLevel) {
|
if (details?.assignedToLevel) {
|
||||||
const levels = new Set<number>(
|
const levels = new Set<number>(
|
||||||
details.assignedToLevel.split(",").map(Number)
|
details.assignedToLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setCheckedLevels(levels);
|
setCheckedLevels(levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details?.publishedForObject) {
|
if (details?.publishedForObject) {
|
||||||
const publisherIds = details?.publishedForObject?.map(
|
const publisherIds = details?.publishedForObject?.map(
|
||||||
(obj: any) => obj.id
|
(obj: any) => obj.id,
|
||||||
);
|
);
|
||||||
setSelectedPublishers(publisherIds);
|
setSelectedPublishers(publisherIds);
|
||||||
}
|
}
|
||||||
|
|
@ -1075,7 +1086,7 @@ export default function FormImageDetail() {
|
||||||
|
|
||||||
const filesData = details.files || [];
|
const filesData = details.files || [];
|
||||||
const fileUrls = filesData.map((file: { thumbnailFileUrl: string }) =>
|
const fileUrls = filesData.map((file: { thumbnailFileUrl: string }) =>
|
||||||
file.thumbnailFileUrl ? file.thumbnailFileUrl : "default-image.jpg"
|
file.thumbnailFileUrl ? file.thumbnailFileUrl : "default-image.jpg",
|
||||||
);
|
);
|
||||||
setDetailThumb(fileUrls);
|
setDetailThumb(fileUrls);
|
||||||
|
|
||||||
|
|
@ -1195,7 +1206,7 @@ export default function FormImageDetail() {
|
||||||
const setupPlacement = (
|
const setupPlacement = (
|
||||||
index: number,
|
index: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
let temp = [...filePlacements];
|
let temp = [...filePlacements];
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
@ -1212,7 +1223,7 @@ export default function FormImageDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Checklist semua item di modal
|
// Checklist semua item di modal
|
||||||
|
|
@ -1262,7 +1273,7 @@ export default function FormImageDetail() {
|
||||||
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
||||||
// JANGAN include satker dalam perhitungan auto "all"
|
// JANGAN include satker dalam perhitungan auto "all"
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
||||||
now.push("all");
|
now.push("all");
|
||||||
|
|
@ -1277,7 +1288,7 @@ export default function FormImageDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unchecklist semua item di modal
|
// Unchecklist semua item di modal
|
||||||
|
|
@ -1311,7 +1322,7 @@ export default function FormImageDetail() {
|
||||||
// Hapus "all" jika tidak semua item ter-checklist
|
// Hapus "all" jika tidak semua item ter-checklist
|
||||||
if (now.includes("all")) {
|
if (now.includes("all")) {
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length < 3) {
|
if (nonSatkerItems.length < 3) {
|
||||||
const newData = now.filter((b) => b !== "all");
|
const newData = now.filter((b) => b !== "all");
|
||||||
|
|
@ -1330,7 +1341,7 @@ export default function FormImageDetail() {
|
||||||
const updateModalChecklistLevels = (
|
const updateModalChecklistLevels = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!listDest || listDest.length === 0) return;
|
if (!listDest || listDest.length === 0) return;
|
||||||
|
|
||||||
|
|
@ -1363,7 +1374,7 @@ export default function FormImageDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.add(Number(satkerItem.id));
|
currentFileLevels.add(Number(satkerItem.id));
|
||||||
|
|
@ -1399,7 +1410,7 @@ export default function FormImageDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.delete(Number(satkerItem.id));
|
currentFileLevels.delete(Number(satkerItem.id));
|
||||||
|
|
@ -1429,7 +1440,7 @@ export default function FormImageDetail() {
|
||||||
type: string,
|
type: string,
|
||||||
url: string,
|
url: string,
|
||||||
names: string,
|
names: string,
|
||||||
format: string
|
format: string,
|
||||||
) => {
|
) => {
|
||||||
// console.log("Test 3 :", type, url, names, format);
|
// console.log("Test 3 :", type, url, names, format);
|
||||||
setMain({
|
setMain({
|
||||||
|
|
@ -1532,7 +1543,7 @@ export default function FormImageDetail() {
|
||||||
{detail &&
|
{detail &&
|
||||||
!categories.find(
|
!categories.find(
|
||||||
(cat) =>
|
(cat) =>
|
||||||
String(cat.id) === String(detail.category.id)
|
String(cat.id) === String(detail.category.id),
|
||||||
) && (
|
) && (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={String(detail.category.id)}
|
key={String(detail.category.id)}
|
||||||
|
|
@ -1853,56 +1864,6 @@ export default function FormImageDetail() {
|
||||||
Tingkat Distribusi:
|
Tingkat Distribusi:
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
{[
|
|
||||||
{ key: "semua", label: "Semua" },
|
|
||||||
{ key: "nasional", label: "Nasional" },
|
|
||||||
{ key: "wilayah", label: "Wilayah" },
|
|
||||||
{
|
|
||||||
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: "semua", label: "Semua" },
|
||||||
{ key: "nasional", label: "Nasional" },
|
{ key: "nasional", label: "Nasional" },
|
||||||
|
|
@ -1911,6 +1872,39 @@ export default function FormImageDetail() {
|
||||||
key: "international",
|
key: "international",
|
||||||
label: "Internasional",
|
label: "Internasional",
|
||||||
},
|
},
|
||||||
|
] */}
|
||||||
|
{[
|
||||||
|
{ key: "semua", label: "Semua" },
|
||||||
|
|
||||||
|
...(isContentFromMabesOrPolda
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "wilayah",
|
||||||
|
label: "Wilayah",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
|
...(isContentFromSatker
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
|
|
@ -1927,12 +1921,12 @@ export default function FormImageDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1943,13 +1937,14 @@ export default function FormImageDetail() {
|
||||||
{item.label}
|
{item.label}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
))} */}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Detail Wilayah */}
|
{/* Detail Wilayah */}
|
||||||
{fileUnitSelections[index]?.wilayah &&
|
{/* {fileUnitSelections[index]?.wilayah && ( */}
|
||||||
!isUploadedBySatkerLevel3 && (
|
{!isContentFromSatker &&
|
||||||
|
fileUnitSelections[index]?.wilayah && (
|
||||||
<div className="border-t border-gray-200 pt-2">
|
<div className="border-t border-gray-200 pt-2">
|
||||||
<p className="text-sm font-medium text-gray-700 mb-2">
|
<p className="text-sm font-medium text-gray-700 mb-2">
|
||||||
Detail Wilayah:
|
Detail Wilayah:
|
||||||
|
|
@ -1977,12 +1972,12 @@ export default function FormImageDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2035,13 +2030,13 @@ export default function FormImageDetail() {
|
||||||
fileCheckedLevels[
|
fileCheckedLevels[
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(polda.id)
|
Number(polda.id),
|
||||||
) || false
|
) || false
|
||||||
}
|
}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
handleFileCheckboxChangePlacement(
|
handleFileCheckboxChangePlacement(
|
||||||
index,
|
index,
|
||||||
Number(polda.id)
|
Number(polda.id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2055,7 +2050,7 @@ export default function FormImageDetail() {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
toggleExpand(
|
toggleExpand(
|
||||||
polda.id
|
polda.id,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
||||||
|
|
@ -2091,9 +2086,9 @@ export default function FormImageDetail() {
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -2103,7 +2098,7 @@ export default function FormImageDetail() {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleSelectAllSubItems(
|
handleSelectAllSubItems(
|
||||||
index,
|
index,
|
||||||
polda
|
polda,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -2155,16 +2150,16 @@ export default function FormImageDetail() {
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
) || false
|
) || false
|
||||||
}
|
}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
handleFileCheckboxChangePlacement(
|
handleFileCheckboxChangePlacement(
|
||||||
index,
|
index,
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2172,7 +2167,7 @@ export default function FormImageDetail() {
|
||||||
{sub.name}
|
{sub.name}
|
||||||
</span>
|
</span>
|
||||||
</Label>
|
</Label>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2276,7 +2271,7 @@ export default function FormImageDetail() {
|
||||||
>
|
>
|
||||||
{template}
|
{template}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ const CustomEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/custom-editor");
|
return import("@/components/editor/custom-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
export default function FormImage() {
|
export default function FormImage() {
|
||||||
|
|
@ -117,7 +117,7 @@ export default function FormImage() {
|
||||||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||||
const [articleBody, setArticleBody] = useState<string>("");
|
const [articleBody, setArticleBody] = useState<string>("");
|
||||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||||
const [selectedWritingStyle, setSelectedWritingStyle] =
|
const [selectedWritingStyle, setSelectedWritingStyle] =
|
||||||
|
|
@ -183,17 +183,17 @@ export default function FormImage() {
|
||||||
.filter(
|
.filter(
|
||||||
(file) =>
|
(file) =>
|
||||||
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
||||||
file.size <= MAX_FILE_SIZE
|
file.size <= MAX_FILE_SIZE,
|
||||||
)
|
)
|
||||||
.map((file) =>
|
.map((file) =>
|
||||||
Object.assign(file, {
|
Object.assign(file, {
|
||||||
preview: URL.createObjectURL(file),
|
preview: URL.createObjectURL(file),
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (validFiles.length === 0) {
|
if (validFiles.length === 0) {
|
||||||
toast.error(
|
toast.error(
|
||||||
"File tidak valid. Hanya .jpg, .jpeg, .png maksimal 100MB yang diperbolehkan."
|
"File tidak valid. Hanya .jpg, .jpeg, .png maksimal 100MB yang diperbolehkan.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -227,12 +227,12 @@ export default function FormImage() {
|
||||||
files.every(
|
files.every(
|
||||||
(file: File) =>
|
(file: File) =>
|
||||||
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
["image/jpeg", "image/png", "image/jpg"].includes(file.type) &&
|
||||||
file.size <= 100 * 1024 * 1024
|
file.size <= 100 * 1024 * 1024,
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
message:
|
message:
|
||||||
"Hanya file .jpg, .jpeg, .png, maksimal 100MB yang diperbolehkan.",
|
"Hanya file .jpg, .jpeg, .png, maksimal 100MB yang diperbolehkan.",
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
|
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
|
||||||
tags: z
|
tags: z
|
||||||
|
|
@ -454,7 +454,7 @@ export default function FormImage() {
|
||||||
const articleData = await waitForStatusUpdate();
|
const articleData = await waitForStatusUpdate();
|
||||||
const cleanArticleBody = articleData?.articleBody?.replace(
|
const cleanArticleBody = articleData?.articleBody?.replace(
|
||||||
/<img[^>]*>/g,
|
/<img[^>]*>/g,
|
||||||
""
|
"",
|
||||||
);
|
);
|
||||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||||
setArticleBody(cleanArticleBody || "");
|
setArticleBody(cleanArticleBody || "");
|
||||||
|
|
@ -507,7 +507,7 @@ export default function FormImage() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -530,7 +530,7 @@ export default function FormImage() {
|
||||||
setPublishedFor(
|
setPublishedFor(
|
||||||
options
|
options
|
||||||
.filter((opt: any) => opt.id !== "all")
|
.filter((opt: any) => opt.id !== "all")
|
||||||
.map((opt: any) => opt.id)
|
.map((opt: any) => opt.id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -594,11 +594,16 @@ export default function FormImage() {
|
||||||
} else if (data.rewriteDescription && selectedFileType === "rewrite") {
|
} else if (data.rewriteDescription && selectedFileType === "rewrite") {
|
||||||
finalDescription = data.rewriteDescription;
|
finalDescription = data.rewriteDescription;
|
||||||
console.log("📤 Upload versi rewrite");
|
console.log("📤 Upload versi rewrite");
|
||||||
} else {
|
} else if (data.description?.trim()) {
|
||||||
// fallback: gunakan versi Indonesia original
|
finalDescription = data.description;
|
||||||
finalDescription = data.descriptionOri ?? "";
|
} else if (data.descriptionOri?.trim()) {
|
||||||
console.log("📤 Upload versi Indonesia (original)");
|
finalDescription = data.descriptionOri;
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// // fallback: gunakan versi Indonesia original
|
||||||
|
// finalDescription = data.descriptionOri ?? "";
|
||||||
|
// console.log("📤 Upload versi Indonesia (original)");
|
||||||
|
// }
|
||||||
|
|
||||||
if (!finalDescription?.trim()) {
|
if (!finalDescription?.trim()) {
|
||||||
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
||||||
|
|
@ -690,7 +695,7 @@ export default function FormImage() {
|
||||||
index,
|
index,
|
||||||
String(id),
|
String(id),
|
||||||
item,
|
item,
|
||||||
fileTypeId == "2" || fileTypeId == "4" ? item.duration : "0"
|
fileTypeId == "2" || fileTypeId == "4" ? item.duration : "0",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -717,7 +722,7 @@ export default function FormImage() {
|
||||||
idx: number,
|
idx: number,
|
||||||
id: string,
|
id: string,
|
||||||
file: any,
|
file: any,
|
||||||
duration: string
|
duration: string,
|
||||||
) {
|
) {
|
||||||
// console.log(idx, id, file, duration);
|
// console.log(idx, id, file, duration);
|
||||||
|
|
||||||
|
|
@ -753,7 +758,7 @@ export default function FormImage() {
|
||||||
onChunkComplete: (
|
onChunkComplete: (
|
||||||
chunkSize: any,
|
chunkSize: any,
|
||||||
bytesAccepted: any,
|
bytesAccepted: any,
|
||||||
bytesTotal: any
|
bytesTotal: any,
|
||||||
) => {
|
) => {
|
||||||
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
||||||
progressInfo[idx].percentage = uploadPersen;
|
progressInfo[idx].percentage = uploadPersen;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ const ViewEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/view-editor");
|
return import("@/components/editor/view-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface Destination {
|
interface Destination {
|
||||||
|
|
@ -189,6 +189,12 @@ export default function FormTeksDetail() {
|
||||||
satker: boolean;
|
satker: boolean;
|
||||||
}>
|
}>
|
||||||
>([]);
|
>([]);
|
||||||
|
const [creatorLevelNumber, setCreatorLevelNumber] = useState<number | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
const isContentFromSatker = creatorLevelNumber === 3;
|
||||||
|
const isContentFromMabesOrPolda =
|
||||||
|
creatorLevelNumber === 1 || creatorLevelNumber === 2;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
||||||
|
|
@ -200,7 +206,7 @@ export default function FormTeksDetail() {
|
||||||
const handleFileUnitChange = (
|
const handleFileUnitChange = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
setFileUnitSelections((prev) => {
|
setFileUnitSelections((prev) => {
|
||||||
const newSelections = [...prev];
|
const newSelections = [...prev];
|
||||||
|
|
@ -269,12 +275,12 @@ export default function FormTeksDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
currentFileCheckedLevels.has(Number(item.id))
|
currentFileCheckedLevels.has(Number(item.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasSelectedPolda) {
|
if (!hasSelectedPolda) {
|
||||||
alert(
|
alert(
|
||||||
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
|
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.",
|
||||||
);
|
);
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +403,7 @@ export default function FormTeksDetail() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (detail?.assignedToTopLevel) {
|
if (detail?.assignedToTopLevel) {
|
||||||
const outputSet = new Set(
|
const outputSet = new Set(
|
||||||
detail.assignedToTopLevel.split(",").map(Number)
|
detail.assignedToTopLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setUnitSelection({
|
setUnitSelection({
|
||||||
semua: outputSet.has(0),
|
semua: outputSet.has(0),
|
||||||
|
|
@ -422,7 +428,7 @@ export default function FormTeksDetail() {
|
||||||
acc[polda.id] = false;
|
acc[polda.id] = false;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
setExpandedPolda(initialExpandedState);
|
setExpandedPolda(initialExpandedState);
|
||||||
console.log("polres", initialExpandedState);
|
console.log("polres", initialExpandedState);
|
||||||
|
|
@ -457,7 +463,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
const handleUnitChange = (
|
const handleUnitChange = (
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (key === "semua") {
|
if (key === "semua") {
|
||||||
const newState = {
|
const newState = {
|
||||||
|
|
@ -536,7 +542,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
const handleCheckboxChange = (id: number) => {
|
const handleCheckboxChange = (id: number) => {
|
||||||
setSelectedPublishers((prev) =>
|
setSelectedPublishers((prev) =>
|
||||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -558,7 +564,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -607,6 +613,9 @@ export default function FormTeksDetail() {
|
||||||
// console.log("detail", details);
|
// console.log("detail", details);
|
||||||
setFiles(details?.files);
|
setFiles(details?.files);
|
||||||
setDetail(details);
|
setDetail(details);
|
||||||
|
if (details?.uploadedBy?.userLevel?.levelNumber) {
|
||||||
|
setCreatorLevelNumber(details.uploadedBy.userLevel.levelNumber);
|
||||||
|
}
|
||||||
setMain({
|
setMain({
|
||||||
type: details?.fileType.name,
|
type: details?.fileType.name,
|
||||||
url: details?.files[0]?.url,
|
url: details?.files[0]?.url,
|
||||||
|
|
@ -617,14 +626,14 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
if (details?.assignedToLevel) {
|
if (details?.assignedToLevel) {
|
||||||
const levels = new Set(
|
const levels = new Set(
|
||||||
details.assignedToLevel.split(",").map(Number)
|
details.assignedToLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setCheckedLevels(levels);
|
setCheckedLevels(levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details?.publishedForObject) {
|
if (details?.publishedForObject) {
|
||||||
const publisherIds = details?.publishedForObject?.map(
|
const publisherIds = details?.publishedForObject?.map(
|
||||||
(obj: any) => obj.id
|
(obj: any) => obj.id,
|
||||||
);
|
);
|
||||||
setSelectedPublishers(publisherIds);
|
setSelectedPublishers(publisherIds);
|
||||||
}
|
}
|
||||||
|
|
@ -796,7 +805,7 @@ export default function FormTeksDetail() {
|
||||||
type: string,
|
type: string,
|
||||||
url: string,
|
url: string,
|
||||||
names: string,
|
names: string,
|
||||||
format: string
|
format: string,
|
||||||
) => {
|
) => {
|
||||||
// console.log("Test 3 :", type, url, names, format);
|
// console.log("Test 3 :", type, url, names, format);
|
||||||
setMain({
|
setMain({
|
||||||
|
|
@ -823,7 +832,7 @@ export default function FormTeksDetail() {
|
||||||
const setupPlacement = (
|
const setupPlacement = (
|
||||||
index: number,
|
index: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
let temp = [...filePlacements];
|
let temp = [...filePlacements];
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
@ -841,7 +850,7 @@ export default function FormTeksDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Checklist semua item di modal
|
// Checklist semua item di modal
|
||||||
|
|
@ -891,7 +900,7 @@ export default function FormTeksDetail() {
|
||||||
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
||||||
// JANGAN include satker dalam perhitungan auto "all"
|
// JANGAN include satker dalam perhitungan auto "all"
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
||||||
now.push("all");
|
now.push("all");
|
||||||
|
|
@ -906,7 +915,7 @@ export default function FormTeksDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unchecklist semua item di modal
|
// Unchecklist semua item di modal
|
||||||
|
|
@ -940,7 +949,7 @@ export default function FormTeksDetail() {
|
||||||
// Hapus "all" jika tidak semua item ter-checklist
|
// Hapus "all" jika tidak semua item ter-checklist
|
||||||
if (now.includes("all")) {
|
if (now.includes("all")) {
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length < 3) {
|
if (nonSatkerItems.length < 3) {
|
||||||
const newData = now.filter((b) => b !== "all");
|
const newData = now.filter((b) => b !== "all");
|
||||||
|
|
@ -958,7 +967,7 @@ export default function FormTeksDetail() {
|
||||||
const updateModalChecklistLevels = (
|
const updateModalChecklistLevels = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!listDest || listDest.length === 0) return;
|
if (!listDest || listDest.length === 0) return;
|
||||||
|
|
||||||
|
|
@ -991,7 +1000,7 @@ export default function FormTeksDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.add(Number(satkerItem.id));
|
currentFileLevels.add(Number(satkerItem.id));
|
||||||
|
|
@ -1027,7 +1036,7 @@ export default function FormTeksDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.delete(Number(satkerItem.id));
|
currentFileLevels.delete(Number(satkerItem.id));
|
||||||
|
|
@ -1060,7 +1069,7 @@ export default function FormTeksDetail() {
|
||||||
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
||||||
const handleFileCheckboxChangePlacement = (
|
const handleFileCheckboxChangePlacement = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
levelId: number
|
levelId: number,
|
||||||
) => {
|
) => {
|
||||||
setFileCheckedLevels((prev) => {
|
setFileCheckedLevels((prev) => {
|
||||||
const newArray = [...prev];
|
const newArray = [...prev];
|
||||||
|
|
@ -1072,7 +1081,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
||||||
const poldaItem = listDest.find(
|
const poldaItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (
|
if (
|
||||||
poldaItem &&
|
poldaItem &&
|
||||||
|
|
@ -1095,7 +1104,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||||
|
|
@ -1126,7 +1135,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
||||||
const totalPoldaCount = listDest.filter(
|
const totalPoldaCount = listDest.filter(
|
||||||
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI"
|
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI",
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
||||||
|
|
@ -1153,7 +1162,7 @@ export default function FormTeksDetail() {
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
},
|
},
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Hitung berapa banyak POLRES yang ter-checklist
|
// Hitung berapa banyak POLRES yang ter-checklist
|
||||||
|
|
@ -1163,7 +1172,7 @@ export default function FormTeksDetail() {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
item.subDestination.filter((sub: any) =>
|
item.subDestination.filter((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
).length
|
).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1172,7 +1181,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
// Cek apakah SATKER POLRI ter-checklist
|
// Cek apakah SATKER POLRI ter-checklist
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
const isSatkerChecked =
|
const isSatkerChecked =
|
||||||
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
||||||
|
|
@ -1206,7 +1215,7 @@ export default function FormTeksDetail() {
|
||||||
|
|
||||||
// Cek apakah semua sub-items sudah ter-checklist
|
// Cek apakah semua sub-items sudah ter-checklist
|
||||||
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allSubItemsChecked) {
|
if (allSubItemsChecked) {
|
||||||
|
|
@ -1292,7 +1301,7 @@ export default function FormTeksDetail() {
|
||||||
{detail &&
|
{detail &&
|
||||||
!categories.find(
|
!categories.find(
|
||||||
(cat) =>
|
(cat) =>
|
||||||
String(cat.id) === String(detail.category.id)
|
String(cat.id) === String(detail.category.id),
|
||||||
) && (
|
) && (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={String(detail.category.id)}
|
key={String(detail.category.id)}
|
||||||
|
|
@ -1575,56 +1584,6 @@ export default function FormTeksDetail() {
|
||||||
Tingkat Distribusi:
|
Tingkat Distribusi:
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
{[
|
|
||||||
{ key: "semua", label: "Semua" },
|
|
||||||
{ key: "nasional", label: "Nasional" },
|
|
||||||
{ key: "wilayah", label: "Wilayah" },
|
|
||||||
{
|
|
||||||
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: "semua", label: "Semua" },
|
||||||
{ key: "nasional", label: "Nasional" },
|
{ key: "nasional", label: "Nasional" },
|
||||||
|
|
@ -1633,6 +1592,39 @@ export default function FormTeksDetail() {
|
||||||
key: "international",
|
key: "international",
|
||||||
label: "Internasional",
|
label: "Internasional",
|
||||||
},
|
},
|
||||||
|
] */}
|
||||||
|
{[
|
||||||
|
{ key: "semua", label: "Semua" },
|
||||||
|
|
||||||
|
...(isContentFromMabesOrPolda
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "wilayah",
|
||||||
|
label: "Wilayah",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
|
...(isContentFromSatker
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
|
|
@ -1649,12 +1641,12 @@ export default function FormTeksDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1665,256 +1657,267 @@ export default function FormTeksDetail() {
|
||||||
{item.label}
|
{item.label}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
))} */}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Detail Wilayah */}
|
{/* Detail Wilayah */}
|
||||||
{fileUnitSelections[index]?.wilayah && (
|
{/* {fileUnitSelections[index]?.wilayah && ( */}
|
||||||
<div className="border-t border-gray-200 pt-2">
|
{!isContentFromSatker &&
|
||||||
<p className="text-sm font-medium text-gray-700 mb-2">
|
fileUnitSelections[index]?.wilayah && (
|
||||||
Detail Wilayah:
|
<div className="border-t border-gray-200 pt-2">
|
||||||
</p>
|
<p className="text-sm font-medium text-gray-700 mb-2">
|
||||||
|
Detail Wilayah:
|
||||||
|
</p>
|
||||||
|
|
||||||
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
|
{/* Checkbox Sub-kategori dengan tombol Kustom sejajar */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-3">
|
||||||
{[
|
{[
|
||||||
{ key: "polda", label: "POLDA" },
|
{ key: "polda", label: "POLDA" },
|
||||||
{ key: "polres", label: "POLRES" },
|
{ key: "polres", label: "POLRES" },
|
||||||
{ key: "satker", label: "SATKER" },
|
{ key: "satker", label: "SATKER" },
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
className="flex items-center gap-2 p-3 border border-gray-200 rounded-md hover:bg-gray-50"
|
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"
|
|
||||||
>
|
>
|
||||||
{item.label}
|
<Checkbox
|
||||||
</Label>
|
id={`${item.key}-${index}`}
|
||||||
</div>
|
checked={
|
||||||
))}
|
fileUnitSelections[index]?.[
|
||||||
|
item.key as keyof typeof unitSelection
|
||||||
{/* Tombol Kustom sejajar dengan checkbox */}
|
] || false
|
||||||
<div className="flex items-center justify-center p-3">
|
}
|
||||||
<Dialog>
|
onCheckedChange={(value) => {
|
||||||
<DialogTrigger asChild>
|
handleFileUnitChange(
|
||||||
<Button
|
index,
|
||||||
variant="outline"
|
item.key as keyof typeof unitSelection,
|
||||||
size="sm"
|
value as boolean,
|
||||||
className="gap-2"
|
);
|
||||||
|
setupPlacement(
|
||||||
|
index,
|
||||||
|
item.key,
|
||||||
|
Boolean(value),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
htmlFor={`${item.key}-${index}`}
|
||||||
|
className="text-sm font-medium cursor-pointer"
|
||||||
>
|
>
|
||||||
<Icon
|
{item.label}
|
||||||
icon="material-symbols:tune"
|
</Label>
|
||||||
width={16}
|
</div>
|
||||||
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>
|
|
||||||
|
|
||||||
{/* Sub-items */}
|
{/* Tombol Kustom sejajar dengan checkbox */}
|
||||||
{polda.subDestination &&
|
<div className="flex items-center justify-center p-3">
|
||||||
expandedPolda[polda.id] && (
|
<Dialog>
|
||||||
<div className="max-h-[200px] overflow-y-auto border-t border-gray-100 pt-2">
|
<DialogTrigger asChild>
|
||||||
{/* Tombol Pilih Semua untuk sub-items */}
|
<Button
|
||||||
<div className="mb-2 flex justify-start">
|
variant="outline"
|
||||||
{(() => {
|
size="sm"
|
||||||
const allSubItemsChecked =
|
className="gap-2"
|
||||||
polda.subDestination?.every(
|
>
|
||||||
(sub: any) =>
|
<Icon
|
||||||
fileCheckedLevels[
|
icon="material-symbols:tune"
|
||||||
index
|
width={16}
|
||||||
]?.has(
|
height={16}
|
||||||
Number(
|
/>
|
||||||
sub.id
|
{t("custom", {
|
||||||
)
|
defaultValue: "Kustom",
|
||||||
)
|
})}
|
||||||
);
|
</Button>
|
||||||
return (
|
</DialogTrigger>
|
||||||
<Button
|
<DialogContent className="max-w-[95vw] lg:max-w-[1400px] max-h-[90vh]">
|
||||||
size="sm"
|
<DialogHeader className="border-b border-gray-200 pb-4">
|
||||||
variant="outline"
|
<DialogTitle className="text-lg font-semibold">
|
||||||
className="text-xs h-6 px-2"
|
Daftar Wilayah POLDA dan
|
||||||
onClick={() =>
|
POLRES
|
||||||
handleSelectAllSubItems(
|
</DialogTitle>
|
||||||
index,
|
</DialogHeader>
|
||||||
polda
|
<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}
|
||||||
{allSubItemsChecked ? (
|
className="border border-gray-200 rounded-lg p-2 bg-white hover:shadow-sm transition-shadow"
|
||||||
<>
|
>
|
||||||
<Icon
|
{/* Header POLDA */}
|
||||||
icon="material-symbols:check-indeterminate-small"
|
<div className="flex items-center justify-between">
|
||||||
width={12}
|
<Label className="flex items-center gap-3 flex-1 cursor-pointer">
|
||||||
height={
|
<Checkbox
|
||||||
12
|
checked={
|
||||||
}
|
fileCheckedLevels[
|
||||||
className="mr-1"
|
index
|
||||||
/>
|
]?.has(
|
||||||
Batal Semua
|
Number(polda.id),
|
||||||
</>
|
) || false
|
||||||
) : (
|
}
|
||||||
<>
|
onCheckedChange={() =>
|
||||||
<Icon
|
handleFileCheckboxChangePlacement(
|
||||||
icon="material-symbols:check-all"
|
index,
|
||||||
width={12}
|
Number(polda.id),
|
||||||
height={
|
)
|
||||||
12
|
}
|
||||||
}
|
/>
|
||||||
className="mr-1"
|
<span className="font-semibold text-gray-900 text-sm">
|
||||||
/>
|
{polda.name}
|
||||||
Pilih Semua
|
</span>
|
||||||
</>
|
</Label>
|
||||||
)}
|
{polda.subDestination && (
|
||||||
</Button>
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
toggleExpand(
|
||||||
|
polda.id,
|
||||||
);
|
);
|
||||||
})()}
|
}}
|
||||||
</div>
|
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
||||||
<div className="space-y-1">
|
>
|
||||||
{polda.subDestination.map(
|
<Icon
|
||||||
(sub: any) => (
|
icon={
|
||||||
<Label
|
expandedPolda[
|
||||||
key={sub.id}
|
polda.id
|
||||||
className="flex items-center gap-2 p-2 rounded-md hover:bg-gray-50 transition-colors cursor-pointer text-xs"
|
]
|
||||||
>
|
? "mdi:chevron-up"
|
||||||
<Checkbox
|
: "mdi:chevron-down"
|
||||||
checked={
|
}
|
||||||
|
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[
|
fileCheckedLevels[
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
) || false
|
),
|
||||||
}
|
);
|
||||||
onCheckedChange={() =>
|
return (
|
||||||
handleFileCheckboxChangePlacement(
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
onClick={() =>
|
||||||
|
handleSelectAllSubItems(
|
||||||
index,
|
index,
|
||||||
Number(
|
polda,
|
||||||
sub.id
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
<span className="text-gray-700">
|
{allSubItemsChecked ? (
|
||||||
{sub.name}
|
<>
|
||||||
</span>
|
<Icon
|
||||||
</Label>
|
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>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
|
||||||
<div className="flex justify-end gap-3 border-t border-gray-200 pt-4">
|
<DialogClose asChild>
|
||||||
<DialogClose asChild>
|
<Button variant="outline">
|
||||||
<Button variant="outline">
|
{t("cancel", {
|
||||||
{t("cancel", {
|
defaultValue: "Batal",
|
||||||
defaultValue: "Batal",
|
})}
|
||||||
})}
|
</Button>
|
||||||
</Button>
|
</DialogClose>
|
||||||
</DialogClose>
|
<DialogClose asChild>
|
||||||
<DialogClose asChild>
|
<Button>
|
||||||
<Button>
|
{/* {t("save", {
|
||||||
{/* {t("save", {
|
|
||||||
defaultValue: "Simpan",
|
defaultValue: "Simpan",
|
||||||
})} */}
|
})} */}
|
||||||
Simpan
|
Simpan
|
||||||
</Button>
|
</Button>
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -1993,7 +1996,7 @@ export default function FormTeksDetail() {
|
||||||
>
|
>
|
||||||
{template}
|
{template}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1776,7 +1776,7 @@ export default function FormTeks() {
|
||||||
{/* <Button type="submit" color="primary">
|
{/* <Button type="submit" color="primary">
|
||||||
{t("submit", { defaultValue: "Submit" })}
|
{t("submit", { defaultValue: "Submit" })}
|
||||||
</Button> */}
|
</Button> */}
|
||||||
{levelNumber !== "2" && levelNumber !== "3" && (
|
{levelNumber !== "2" && (
|
||||||
<Button type="submit" color="primary">
|
<Button type="submit" color="primary">
|
||||||
{t("submit", { defaultValue: "Submit" })}
|
{t("submit", { defaultValue: "Submit" })}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ const ViewEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/view-editor");
|
return import("@/components/editor/view-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface Destination {
|
interface Destination {
|
||||||
|
|
@ -192,6 +192,12 @@ export default function FormVideoDetail() {
|
||||||
satker: boolean;
|
satker: boolean;
|
||||||
}>
|
}>
|
||||||
>([]);
|
>([]);
|
||||||
|
const [creatorLevelNumber, setCreatorLevelNumber] = useState<number | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
const isContentFromSatker = creatorLevelNumber === 3;
|
||||||
|
const isContentFromMabesOrPolda =
|
||||||
|
creatorLevelNumber === 1 || creatorLevelNumber === 2;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
if (Number(userLevelId) === 216 && Number(roleId) === 3) {
|
||||||
|
|
@ -203,7 +209,7 @@ export default function FormVideoDetail() {
|
||||||
const handleFileUnitChange = (
|
const handleFileUnitChange = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
setFileUnitSelections((prev) => {
|
setFileUnitSelections((prev) => {
|
||||||
const newSelections = [...prev];
|
const newSelections = [...prev];
|
||||||
|
|
@ -272,12 +278,12 @@ export default function FormVideoDetail() {
|
||||||
(item: any) =>
|
(item: any) =>
|
||||||
item.levelNumber === 2 &&
|
item.levelNumber === 2 &&
|
||||||
item.name !== "SATKER POLRI" &&
|
item.name !== "SATKER POLRI" &&
|
||||||
currentFileCheckedLevels.has(Number(item.id))
|
currentFileCheckedLevels.has(Number(item.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hasSelectedPolda) {
|
if (!hasSelectedPolda) {
|
||||||
alert(
|
alert(
|
||||||
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES."
|
"Harap pilih POLDA di Modal terlebih dahulu sebelum mengaktifkan checkbox POLRES.",
|
||||||
);
|
);
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
@ -400,7 +406,7 @@ export default function FormVideoDetail() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (detail?.assignedToTopLevel) {
|
if (detail?.assignedToTopLevel) {
|
||||||
const outputSet = new Set(
|
const outputSet = new Set(
|
||||||
detail.assignedToTopLevel.split(",").map(Number)
|
detail.assignedToTopLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setUnitSelection({
|
setUnitSelection({
|
||||||
semua: outputSet.has(0),
|
semua: outputSet.has(0),
|
||||||
|
|
@ -425,7 +431,7 @@ export default function FormVideoDetail() {
|
||||||
acc[polda.id] = false;
|
acc[polda.id] = false;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
setExpandedPolda(initialExpandedState);
|
setExpandedPolda(initialExpandedState);
|
||||||
console.log("polres", initialExpandedState);
|
console.log("polres", initialExpandedState);
|
||||||
|
|
@ -460,7 +466,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
const handleUnitChange = (
|
const handleUnitChange = (
|
||||||
key: keyof typeof unitSelection,
|
key: keyof typeof unitSelection,
|
||||||
value: boolean
|
value: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (key === "semua") {
|
if (key === "semua") {
|
||||||
const newState = {
|
const newState = {
|
||||||
|
|
@ -539,7 +545,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
const handleCheckboxChange = (id: number) => {
|
const handleCheckboxChange = (id: number) => {
|
||||||
setSelectedPublishers((prev) =>
|
setSelectedPublishers((prev) =>
|
||||||
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -561,7 +567,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -584,6 +590,10 @@ export default function FormVideoDetail() {
|
||||||
// console.log("detail", details);
|
// console.log("detail", details);
|
||||||
setFiles(details?.files);
|
setFiles(details?.files);
|
||||||
setDetail(details);
|
setDetail(details);
|
||||||
|
if (details?.uploadedBy?.userLevel?.levelNumber) {
|
||||||
|
setCreatorLevelNumber(details.uploadedBy.userLevel.levelNumber);
|
||||||
|
}
|
||||||
|
|
||||||
setMain({
|
setMain({
|
||||||
type: details?.fileType.name,
|
type: details?.fileType.name,
|
||||||
url: details?.files[0]?.url,
|
url: details?.files[0]?.url,
|
||||||
|
|
@ -593,14 +603,14 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
if (details?.assignedToLevel) {
|
if (details?.assignedToLevel) {
|
||||||
const levels = new Set(
|
const levels = new Set(
|
||||||
details.assignedToLevel.split(",").map(Number)
|
details.assignedToLevel.split(",").map(Number),
|
||||||
);
|
);
|
||||||
setCheckedLevels(levels);
|
setCheckedLevels(levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details?.publishedForObject) {
|
if (details?.publishedForObject) {
|
||||||
const publisherIds = details?.publishedForObject?.map(
|
const publisherIds = details?.publishedForObject?.map(
|
||||||
(obj: any) => obj.id
|
(obj: any) => obj.id,
|
||||||
);
|
);
|
||||||
setSelectedPublishers(publisherIds);
|
setSelectedPublishers(publisherIds);
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +620,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
const filesData = details?.files || [];
|
const filesData = details?.files || [];
|
||||||
const fileUrls = filesData.map((files: { url: string }) =>
|
const fileUrls = filesData.map((files: { url: string }) =>
|
||||||
files.url ? files.url : "default-image.jpg"
|
files.url ? files.url : "default-image.jpg",
|
||||||
);
|
);
|
||||||
setDetailVideo(fileUrls);
|
setDetailVideo(fileUrls);
|
||||||
|
|
||||||
|
|
@ -788,7 +798,7 @@ export default function FormVideoDetail() {
|
||||||
const setupPlacement = (
|
const setupPlacement = (
|
||||||
index: number,
|
index: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
let temp = [...filePlacements];
|
let temp = [...filePlacements];
|
||||||
if (checked) {
|
if (checked) {
|
||||||
|
|
@ -806,7 +816,7 @@ export default function FormVideoDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Checklist semua item di modal
|
// Checklist semua item di modal
|
||||||
|
|
@ -856,7 +866,7 @@ export default function FormVideoDetail() {
|
||||||
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
// Hanya auto-checklist "all" jika polda, polres, dan mabes ter-checklist
|
||||||
// JANGAN include satker dalam perhitungan auto "all"
|
// JANGAN include satker dalam perhitungan auto "all"
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
if (nonSatkerItems.length === 3 && !now.includes("all")) {
|
||||||
now.push("all");
|
now.push("all");
|
||||||
|
|
@ -871,7 +881,7 @@ export default function FormVideoDetail() {
|
||||||
setFileCheckedLevels((prevLevels) => {
|
setFileCheckedLevels((prevLevels) => {
|
||||||
const newArray = [...prevLevels];
|
const newArray = [...prevLevels];
|
||||||
const currentFileLevels = new Set<number>(
|
const currentFileLevels = new Set<number>(
|
||||||
newArray[index] || new Set()
|
newArray[index] || new Set(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Unchecklist semua item di modal
|
// Unchecklist semua item di modal
|
||||||
|
|
@ -905,7 +915,7 @@ export default function FormVideoDetail() {
|
||||||
// Hapus "all" jika tidak semua item ter-checklist
|
// Hapus "all" jika tidak semua item ter-checklist
|
||||||
if (now.includes("all")) {
|
if (now.includes("all")) {
|
||||||
const nonSatkerItems = now.filter(
|
const nonSatkerItems = now.filter(
|
||||||
(item) => item !== "satker" && item !== "all"
|
(item) => item !== "satker" && item !== "all",
|
||||||
);
|
);
|
||||||
if (nonSatkerItems.length < 3) {
|
if (nonSatkerItems.length < 3) {
|
||||||
const newData = now.filter((b) => b !== "all");
|
const newData = now.filter((b) => b !== "all");
|
||||||
|
|
@ -923,7 +933,7 @@ export default function FormVideoDetail() {
|
||||||
const updateModalChecklistLevels = (
|
const updateModalChecklistLevels = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
placement: string,
|
placement: string,
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!listDest || listDest.length === 0) return;
|
if (!listDest || listDest.length === 0) return;
|
||||||
|
|
||||||
|
|
@ -956,7 +966,7 @@ export default function FormVideoDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
// Checklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.add(Number(satkerItem.id));
|
currentFileLevels.add(Number(satkerItem.id));
|
||||||
|
|
@ -992,7 +1002,7 @@ export default function FormVideoDetail() {
|
||||||
} else if (placement === "satker") {
|
} else if (placement === "satker") {
|
||||||
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
// Unchecklist SATKER POLRI dan semua sub-item di bawahnya
|
||||||
const satkerItem: any = listDest.find(
|
const satkerItem: any = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
if (satkerItem) {
|
if (satkerItem) {
|
||||||
currentFileLevels.delete(Number(satkerItem.id));
|
currentFileLevels.delete(Number(satkerItem.id));
|
||||||
|
|
@ -1021,7 +1031,7 @@ export default function FormVideoDetail() {
|
||||||
type: string,
|
type: string,
|
||||||
url: string,
|
url: string,
|
||||||
names: string,
|
names: string,
|
||||||
format: string
|
format: string,
|
||||||
) => {
|
) => {
|
||||||
// console.log("Test 3 :", type, url, names, format);
|
// console.log("Test 3 :", type, url, names, format);
|
||||||
setMain({
|
setMain({
|
||||||
|
|
@ -1062,7 +1072,7 @@ export default function FormVideoDetail() {
|
||||||
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
// Fungsi untuk mengupdate checklist levels untuk file tertentu
|
||||||
const handleFileCheckboxChangePlacement = (
|
const handleFileCheckboxChangePlacement = (
|
||||||
fileIndex: number,
|
fileIndex: number,
|
||||||
levelId: number
|
levelId: number,
|
||||||
) => {
|
) => {
|
||||||
setFileCheckedLevels((prev) => {
|
setFileCheckedLevels((prev) => {
|
||||||
const newArray = [...prev];
|
const newArray = [...prev];
|
||||||
|
|
@ -1074,7 +1084,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
// Jika ini adalah POLDA yang di-unchecklist, unchecklist juga semua polres di bawahnya
|
||||||
const poldaItem = listDest.find(
|
const poldaItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (
|
if (
|
||||||
poldaItem &&
|
poldaItem &&
|
||||||
|
|
@ -1097,7 +1107,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
// Jika ini adalah SATKER POLRI yang di-checklist, checklist juga semua sub-item di bawahnya
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => Number(item.id) === levelId
|
(item: any) => Number(item.id) === levelId,
|
||||||
) as any;
|
) as any;
|
||||||
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
if (satkerItem && satkerItem.name === "SATKER POLRI") {
|
||||||
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
// Checklist semua sub-item di bawah SATKER POLRI (bukan POLRES)
|
||||||
|
|
@ -1128,7 +1138,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
// Hitung total POLDA yang ada (bukan SATKER POLRI)
|
||||||
const totalPoldaCount = listDest.filter(
|
const totalPoldaCount = listDest.filter(
|
||||||
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI"
|
(item: any) => item.levelNumber === 2 && item.name !== "SATKER POLRI",
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
// Hitung berapa banyak POLDA yang ter-checklist (bukan SATKER POLRI)
|
||||||
|
|
@ -1155,7 +1165,7 @@ export default function FormVideoDetail() {
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
},
|
},
|
||||||
0
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Hitung berapa banyak POLRES yang ter-checklist
|
// Hitung berapa banyak POLRES yang ter-checklist
|
||||||
|
|
@ -1165,7 +1175,7 @@ export default function FormVideoDetail() {
|
||||||
return (
|
return (
|
||||||
total +
|
total +
|
||||||
item.subDestination.filter((sub: any) =>
|
item.subDestination.filter((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
).length
|
).length
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1174,7 +1184,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
// Cek apakah SATKER POLRI ter-checklist
|
// Cek apakah SATKER POLRI ter-checklist
|
||||||
const satkerItem = listDest.find(
|
const satkerItem = listDest.find(
|
||||||
(item: any) => item.name === "SATKER POLRI"
|
(item: any) => item.name === "SATKER POLRI",
|
||||||
);
|
);
|
||||||
const isSatkerChecked =
|
const isSatkerChecked =
|
||||||
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
satkerItem && currentFileLevels.has(Number(satkerItem.id));
|
||||||
|
|
@ -1208,7 +1218,7 @@ export default function FormVideoDetail() {
|
||||||
|
|
||||||
// Cek apakah semua sub-items sudah ter-checklist
|
// Cek apakah semua sub-items sudah ter-checklist
|
||||||
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
const allSubItemsChecked = polda.subDestination?.every((sub: any) =>
|
||||||
currentFileLevels.has(Number(sub.id))
|
currentFileLevels.has(Number(sub.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allSubItemsChecked) {
|
if (allSubItemsChecked) {
|
||||||
|
|
@ -1294,7 +1304,7 @@ export default function FormVideoDetail() {
|
||||||
{detail &&
|
{detail &&
|
||||||
!categories.find(
|
!categories.find(
|
||||||
(cat) =>
|
(cat) =>
|
||||||
String(cat.id) === String(detail.category.id)
|
String(cat.id) === String(detail.category.id),
|
||||||
) && (
|
) && (
|
||||||
<SelectItem
|
<SelectItem
|
||||||
key={String(detail.category.id)}
|
key={String(detail.category.id)}
|
||||||
|
|
@ -1579,56 +1589,6 @@ export default function FormVideoDetail() {
|
||||||
Tingkat Distribusi:
|
Tingkat Distribusi:
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
{[
|
|
||||||
{ key: "semua", label: "Semua" },
|
|
||||||
{ key: "nasional", label: "Nasional" },
|
|
||||||
{ key: "wilayah", label: "Wilayah" },
|
|
||||||
{
|
|
||||||
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: "semua", label: "Semua" },
|
||||||
{ key: "nasional", label: "Nasional" },
|
{ key: "nasional", label: "Nasional" },
|
||||||
|
|
@ -1637,6 +1597,39 @@ export default function FormVideoDetail() {
|
||||||
key: "international",
|
key: "international",
|
||||||
label: "Internasional",
|
label: "Internasional",
|
||||||
},
|
},
|
||||||
|
] */}
|
||||||
|
{[
|
||||||
|
{ key: "semua", label: "Semua" },
|
||||||
|
|
||||||
|
...(isContentFromMabesOrPolda
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "wilayah",
|
||||||
|
label: "Wilayah",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
|
...(isContentFromSatker
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "nasional",
|
||||||
|
label: "Nasional",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "international",
|
||||||
|
label: "Internasional",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
].map((item, idx) => (
|
].map((item, idx) => (
|
||||||
<div
|
<div
|
||||||
key={item.key}
|
key={item.key}
|
||||||
|
|
@ -1653,12 +1646,12 @@ export default function FormVideoDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1669,13 +1662,14 @@ export default function FormVideoDetail() {
|
||||||
{item.label}
|
{item.label}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
))} */}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Detail Wilayah */}
|
{/* Detail Wilayah */}
|
||||||
{fileUnitSelections[index]?.wilayah &&
|
{/* {fileUnitSelections[index]?.wilayah && ( */}
|
||||||
!isUploadedBySatkerLevel3 && (
|
{!isContentFromSatker &&
|
||||||
|
fileUnitSelections[index]?.wilayah && (
|
||||||
<div className="border-t border-gray-200 pt-2">
|
<div className="border-t border-gray-200 pt-2">
|
||||||
<p className="text-sm font-medium text-gray-700 mb-2">
|
<p className="text-sm font-medium text-gray-700 mb-2">
|
||||||
Detail Wilayah:
|
Detail Wilayah:
|
||||||
|
|
@ -1703,12 +1697,12 @@ export default function FormVideoDetail() {
|
||||||
handleFileUnitChange(
|
handleFileUnitChange(
|
||||||
index,
|
index,
|
||||||
item.key as keyof typeof unitSelection,
|
item.key as keyof typeof unitSelection,
|
||||||
value as boolean
|
value as boolean,
|
||||||
);
|
);
|
||||||
setupPlacement(
|
setupPlacement(
|
||||||
index,
|
index,
|
||||||
item.key,
|
item.key,
|
||||||
Boolean(value)
|
Boolean(value),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1761,13 +1755,13 @@ export default function FormVideoDetail() {
|
||||||
fileCheckedLevels[
|
fileCheckedLevels[
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(polda.id)
|
Number(polda.id),
|
||||||
) || false
|
) || false
|
||||||
}
|
}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
handleFileCheckboxChangePlacement(
|
handleFileCheckboxChangePlacement(
|
||||||
index,
|
index,
|
||||||
Number(polda.id)
|
Number(polda.id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1781,7 +1775,7 @@ export default function FormVideoDetail() {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
toggleExpand(
|
toggleExpand(
|
||||||
polda.id
|
polda.id,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
className="p-1 hover:bg-gray-100 rounded-md transition-colors"
|
||||||
|
|
@ -1817,9 +1811,9 @@ export default function FormVideoDetail() {
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -1829,7 +1823,7 @@ export default function FormVideoDetail() {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleSelectAllSubItems(
|
handleSelectAllSubItems(
|
||||||
index,
|
index,
|
||||||
polda
|
polda,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -1881,16 +1875,16 @@ export default function FormVideoDetail() {
|
||||||
index
|
index
|
||||||
]?.has(
|
]?.has(
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
) || false
|
) || false
|
||||||
}
|
}
|
||||||
onCheckedChange={() =>
|
onCheckedChange={() =>
|
||||||
handleFileCheckboxChangePlacement(
|
handleFileCheckboxChangePlacement(
|
||||||
index,
|
index,
|
||||||
Number(
|
Number(
|
||||||
sub.id
|
sub.id,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
@ -1898,7 +1892,7 @@ export default function FormVideoDetail() {
|
||||||
{sub.name}
|
{sub.name}
|
||||||
</span>
|
</span>
|
||||||
</Label>
|
</Label>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2007,7 +2001,7 @@ export default function FormVideoDetail() {
|
||||||
>
|
>
|
||||||
{template}
|
{template}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ const CustomEditor = dynamic(
|
||||||
() => {
|
() => {
|
||||||
return import("@/components/editor/custom-editor");
|
return import("@/components/editor/custom-editor");
|
||||||
},
|
},
|
||||||
{ ssr: false }
|
{ ssr: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface FileWithPreview extends File {
|
interface FileWithPreview extends File {
|
||||||
|
|
@ -111,11 +111,11 @@ export default function FormVideo() {
|
||||||
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
const [isGeneratedArticle, setIsGeneratedArticle] = useState(false);
|
||||||
const [articleBody, setArticleBody] = useState<string>("");
|
const [articleBody, setArticleBody] = useState<string>("");
|
||||||
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
const [selectedArticleId, setSelectedArticleId] = useState<string | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
||||||
const [publishedForError, setPublishedForError] = useState<string | null>(
|
const [publishedForError, setPublishedForError] = useState<string | null>(
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
const [selectedSize, setSelectedSize] = useState("");
|
const [selectedSize, setSelectedSize] = useState("");
|
||||||
const [detailData, setDetailData] = useState<any>(null);
|
const [detailData, setDetailData] = useState<any>(null);
|
||||||
|
|
@ -184,7 +184,7 @@ export default function FormVideo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesWithPreview = acceptedFiles.map((file) =>
|
const filesWithPreview = acceptedFiles.map((file) =>
|
||||||
Object.assign(file, { preview: URL.createObjectURL(file) })
|
Object.assign(file, { preview: URL.createObjectURL(file) }),
|
||||||
);
|
);
|
||||||
|
|
||||||
setFiles((prev) => {
|
setFiles((prev) => {
|
||||||
|
|
@ -211,11 +211,11 @@ export default function FormVideo() {
|
||||||
.refine(
|
.refine(
|
||||||
(files) =>
|
(files) =>
|
||||||
files.every((file: File) => ACCEPTED_FILE_TYPES.includes(file.type)),
|
files.every((file: File) => ACCEPTED_FILE_TYPES.includes(file.type)),
|
||||||
{ message: "File harus berformat mp4 atau mov" }
|
{ message: "File harus berformat mp4 atau mov" },
|
||||||
)
|
)
|
||||||
.refine(
|
.refine(
|
||||||
(files) => files.every((file: File) => file.size <= MAX_FILE_SIZE),
|
(files) => files.every((file: File) => file.size <= MAX_FILE_SIZE),
|
||||||
{ message: "Ukuran file maksimal 100 MB" }
|
{ message: "Ukuran file maksimal 100 MB" },
|
||||||
),
|
),
|
||||||
publishedFor: z
|
publishedFor: z
|
||||||
.array(z.string())
|
.array(z.string())
|
||||||
|
|
@ -423,7 +423,7 @@ export default function FormVideo() {
|
||||||
const articleData = await waitForStatusUpdate();
|
const articleData = await waitForStatusUpdate();
|
||||||
const cleanArticleBody = articleData?.articleBody?.replace(
|
const cleanArticleBody = articleData?.articleBody?.replace(
|
||||||
/<img[^>]*>/g,
|
/<img[^>]*>/g,
|
||||||
""
|
"",
|
||||||
);
|
);
|
||||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||||
setValue("description", cleanArticleBody || "");
|
setValue("description", cleanArticleBody || "");
|
||||||
|
|
@ -479,7 +479,7 @@ export default function FormVideo() {
|
||||||
|
|
||||||
if (scheduleId && scheduleType === "3") {
|
if (scheduleId && scheduleType === "3") {
|
||||||
const findCategory = resCategory.find((o) =>
|
const findCategory = resCategory.find((o) =>
|
||||||
o.name.toLowerCase().includes("pers rilis")
|
o.name.toLowerCase().includes("pers rilis"),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (findCategory) {
|
if (findCategory) {
|
||||||
|
|
@ -502,7 +502,7 @@ export default function FormVideo() {
|
||||||
setPublishedFor(
|
setPublishedFor(
|
||||||
options
|
options
|
||||||
.filter((opt: any) => opt.id !== "all")
|
.filter((opt: any) => opt.id !== "all")
|
||||||
.map((opt: any) => opt.id)
|
.map((opt: any) => opt.id),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -561,8 +561,8 @@ export default function FormVideo() {
|
||||||
translatedTitle && translatedTitle.trim() !== ""
|
translatedTitle && translatedTitle.trim() !== ""
|
||||||
? translatedTitle
|
? translatedTitle
|
||||||
: isSwitchOn
|
: isSwitchOn
|
||||||
? title
|
? title
|
||||||
: data.title;
|
: data.title;
|
||||||
|
|
||||||
// Tentukan deskripsi final:
|
// Tentukan deskripsi final:
|
||||||
// Jika ada hasil translate, kirim itu ke backend
|
// Jika ada hasil translate, kirim itu ke backend
|
||||||
|
|
@ -570,10 +570,10 @@ export default function FormVideo() {
|
||||||
translatedContent && translatedContent.trim() !== ""
|
translatedContent && translatedContent.trim() !== ""
|
||||||
? translatedContent
|
? translatedContent
|
||||||
: isSwitchOn
|
: isSwitchOn
|
||||||
? data.description
|
? data.description
|
||||||
: selectedFileType === "rewrite"
|
: selectedFileType === "rewrite"
|
||||||
? data.rewriteDescription
|
? data.rewriteDescription
|
||||||
: data.descriptionOri;
|
: data.descriptionOri;
|
||||||
|
|
||||||
if (!finalDescription?.trim()) {
|
if (!finalDescription?.trim()) {
|
||||||
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
MySwal.fire("Error", "Deskripsi tidak boleh kosong.", "error");
|
||||||
|
|
@ -695,7 +695,7 @@ export default function FormVideo() {
|
||||||
idx: number,
|
idx: number,
|
||||||
id: string,
|
id: string,
|
||||||
file: any,
|
file: any,
|
||||||
duration: string
|
duration: string,
|
||||||
) {
|
) {
|
||||||
// console.log(idx, id, file, duration);
|
// console.log(idx, id, file, duration);
|
||||||
|
|
||||||
|
|
@ -731,7 +731,7 @@ export default function FormVideo() {
|
||||||
onChunkComplete: (
|
onChunkComplete: (
|
||||||
chunkSize: any,
|
chunkSize: any,
|
||||||
bytesAccepted: any,
|
bytesAccepted: any,
|
||||||
bytesTotal: any
|
bytesTotal: any,
|
||||||
) => {
|
) => {
|
||||||
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100);
|
||||||
progressInfo[idx].percentage = uploadPersen;
|
progressInfo[idx].percentage = uploadPersen;
|
||||||
|
|
@ -1731,8 +1731,8 @@ export default function FormVideo() {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const updatedTags = (field.value ?? []).filter(
|
const updatedTags = field.value.filter(
|
||||||
(_, i) => i !== index
|
(_, i) => i !== index,
|
||||||
);
|
);
|
||||||
field.onChange(updatedTags);
|
field.onChange(updatedTags);
|
||||||
}}
|
}}
|
||||||
|
|
@ -1825,7 +1825,7 @@ export default function FormVideo() {
|
||||||
{/* <Button type="submit" color="primary">
|
{/* <Button type="submit" color="primary">
|
||||||
{t("submit", { defaultValue: "Submit" })}
|
{t("submit", { defaultValue: "Submit" })}
|
||||||
</Button> */}
|
</Button> */}
|
||||||
{levelNumber !== "2" && levelNumber !== "3" && (
|
{levelNumber !== "2" && (
|
||||||
<Button type="submit" color="primary">
|
<Button type="submit" color="primary">
|
||||||
{t("submit", { defaultValue: "Submit" })}
|
{t("submit", { defaultValue: "Submit" })}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
export const GoogleMapsAPI = "AIzaSyCuQHorDceMCzlSgrB9AEY5ns8KeriFsME";
|
// export const GoogleMapsAPI = "AIzaSyCuQHorDceMCzlSgrB9AEY5ns8KeriFsME";
|
||||||
|
export const GoogleMapsAPI = "AIzaSyA-Dci9RP4ZjyJCFfy74WvhtMZXSDLTPMQ";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue