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