diff --git a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx
index 05846ec0..168b9e3f 100644
--- a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx
+++ b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx
@@ -21,7 +21,13 @@ import {
import { Calendar } from "@/components/ui/calendar";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
-import { Loader2, CalendarIcon, ChevronUp, ChevronDown } from "lucide-react";
+import {
+ Loader2,
+ CalendarIcon,
+ ChevronUp,
+ ChevronDown,
+ Music,
+} from "lucide-react";
import DeleteConfirmationDialog from "@/components/delete-confirmation-dialog";
import { CalendarCategory } from "./data";
import {
@@ -338,11 +344,17 @@ const EventModal = ({
await uploadResumableFile(index, String(id), item, "3", "0");
});
- if (audioFiles?.length === 0) {
+ if (audioFiles?.length == 0) {
setIsAudioUploadFinish(true);
}
- audioFiles?.map(async (item: any, index: number) => {
- await uploadResumableFile(index, String(id), item, "4", "0");
+ audioFiles.map(async (item: FileWithPreview, index: number) => {
+ await uploadResumableFile(
+ index,
+ String(id),
+ item, // Use .file to access the actual File object
+ "4",
+ "0" // Optional: Replace with actual duration if available
+ );
});
};
@@ -429,9 +441,15 @@ const EventModal = ({
audio.controls = true;
document.body.appendChild(audio);
- // Convert Blob to File
- const file = new File([blob], "voiceNote.webm", { type: "audio/webm" });
- setAudioFile(file);
+ // Convert Blob to File and add preview
+ const fileWithPreview: FileWithPreview = Object.assign(
+ new File([blob], "voiceNote.webm", { type: "audio/webm" }),
+ { preview: url }
+ );
+
+ // Add to state
+ setAudioFile(fileWithPreview);
+ setAudioFiles((prev) => [...prev, fileWithPreview]);
};
const handleDeleteAudio = () => {
@@ -993,8 +1011,7 @@ const EventModal = ({
))}
-
-
+
setAudioFiles(files)}
+ onDrop={(files) =>
+ setAudioFiles((prev) => [...prev, ...files])
+ }
className="mt-2"
/>
{audioUploadedFiles?.map((file: any, index: number) => (
@@ -1054,7 +1073,7 @@ const EventModal = ({
>
- {renderFilePreview(file.url)}
+
@@ -1078,7 +1097,10 @@ const EventModal = ({
{audioFile && (
-
Voice note ready to submit: {audioFile.name}
+
-
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
diff --git a/components/form/content/spit-convert-form.tsx b/components/form/content/spit-convert-form.tsx
index 0d89a2f0..f7898f04 100644
--- a/components/form/content/spit-convert-form.tsx
+++ b/components/form/content/spit-convert-form.tsx
@@ -96,6 +96,13 @@ interface PlacementData {
placements: string;
}
+type FileType = {
+ contentId: number;
+ contentFile: string;
+ thumbnailFileUrl: string;
+ fileName: string;
+};
+
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
@@ -122,7 +129,7 @@ export default function FormConvertSPIT() {
null
);
const [tags, setTags] = useState
([]);
- const [detail, setDetail] = useState();
+ const [detail, setDetail] = useState();
const [refresh, setRefresh] = useState(false);
const [selectedPublishers, setSelectedPublishers] = useState([]);
const [detailThumb, setDetailThumb] = useState([]);
@@ -150,7 +157,9 @@ export default function FormConvertSPIT() {
polres: false,
});
const [publishedFor, setPublishedFor] = useState([]);
- const [placementLength, setPlacementLength] = useState([]);
+ const [filePlacements, setFilePlacements] = useState([]);
+ const [isUserMabesApprover, setIsUserMabesApprover] = useState(false);
+ const [files, setFiles] = useState([]);
const options: Option[] = [
{ id: "all", label: "SEMUA" },
@@ -201,6 +210,17 @@ export default function FormConvertSPIT() {
initState();
}, []);
+ useEffect(() => {
+ if (
+ userLevelId != undefined &&
+ roleId != undefined &&
+ userLevelId == "216" &&
+ roleId == "3"
+ ) {
+ setIsUserMabesApprover(true);
+ }
+ }, [userLevelId, roleId]);
+
useEffect(() => {
if (
userLevelId != undefined &&
@@ -237,6 +257,47 @@ export default function FormConvertSPIT() {
}
};
+ const setupPlacement = (
+ index: number,
+ placement: string,
+ checked: boolean
+ ) => {
+ let temp = [...filePlacements];
+ if (checked) {
+ if (placement === "all") {
+ temp[index] = ["all", "mabes", "polda", "international"];
+ } else {
+ const now = temp[index];
+ now.push(placement);
+ if (now.length === 3 && !now.includes("all")) {
+ now.push("all");
+ }
+ temp[index] = now;
+ }
+ } else {
+ if (placement === "all") {
+ temp[index] = [];
+ } else {
+ const now = temp[index].filter((a) => a !== placement);
+ console.log("now", now);
+ temp[index] = now;
+ if (now.length === 3 && now.includes("all")) {
+ const newData = now.filter((b) => b !== "all");
+ temp[index] = newData;
+ }
+ }
+ }
+ setFilePlacements(temp);
+ };
+
+ const setupPlacementCheck = (length: number) => {
+ const temp = [];
+ for (let i = 0; i < length; i++) {
+ temp.push([]);
+ }
+ setFilePlacements(temp);
+ };
+
useEffect(() => {
async function initState() {
if (id) {
@@ -244,6 +305,8 @@ export default function FormConvertSPIT() {
const details = response?.data?.data;
setDetail(details);
+ setFiles(details?.contentList);
+ setupPlacementCheck(details?.contentList?.length);
const filesData = details.contentList || [];
const fileUrls = filesData.map((file: { contentFile: string }) =>
@@ -272,49 +335,6 @@ export default function FormConvertSPIT() {
}))
);
- const getPlacement = (): PlacementData[] => {
- return tempFile
- .filter((file: FileData) => (file.placement || []).length > 0) // Gunakan default array
- .map((file: FileData) => ({
- mediaFileId: Number(file.contentId),
- placements: (file.placement || []).join(","), // Gunakan default array
- }));
- };
-
- const setupPlacement = (value: string, id: number): void => {
- const updatedFiles = tempFile.map((file: FileData) => {
- if (file.contentId === id) {
- const currentPlacement = file.placement || [];
- if (currentPlacement.includes(value)) {
- // Remove the placement value
- file.placement = currentPlacement.filter((val) => val !== value);
- } else {
- // Add the placement value
- file.placement =
- value === "all"
- ? ["all", "mabes", "polda", "international"]
- : [...currentPlacement, value];
- if (file.placement.includes("all") && value !== "all") {
- file.placement = file.placement.filter((val) => val !== "all");
- }
- }
- }
- return file;
- });
-
- const placementLength = updatedFiles.reduce(
- (acc: any, file: any) => acc + (file.placement?.length || 0),
- 0
- );
-
- setTempFile(
- updatedFiles.sort((a: any, b: any) => a.contentId - b.contentId)
- );
- setPlacementLength(placementLength);
-
- console.log("Updated Files:", updatedFiles);
- };
-
const handleCheckboxChangeFile = (contentId: number, value: string) => {
setTempFile((prevTempFile: any) => {
return prevTempFile.map((file: any) => {
@@ -359,12 +379,32 @@ export default function FormConvertSPIT() {
}
};
+ const getPlacement = () => {
+ console.log("getPlaa", filePlacements);
+ const temp = [];
+ for (let i = 0; i < filePlacements?.length; i++) {
+ if (filePlacements[i].length !== 0) {
+ const now = filePlacements[i].filter((a) => a !== "all");
+ const data = {
+ mediaFileId: files[i].contentId,
+ placement: now.join(","),
+ };
+ temp.push(data);
+ }
+ }
+ return temp;
+ };
+
const save = async (data: {
contentTitle: string;
contentDescription: string;
contentRewriteDescription: string;
contentCreator: string;
}): Promise => {
+ const temp = [];
+ for (const element of detail.contentList) {
+ temp.push([]);
+ }
const description =
selectedFileType === "original"
? data.contentDescription
@@ -376,15 +416,16 @@ export default function FormConvertSPIT() {
description,
htmlDescription: description,
tags: "siap",
- categoryId: selectedCategoryId,
+ categoryId: 1,
publishedFor: publishedFor.join(","),
creator: data.contentCreator,
- files: getPlacement(), // Include placement data
+ files: isUserMabesApprover ? getPlacement() : [], // Include placement data
};
const response = await convertSPIT(requestData);
console.log("Form Data Submitted:", response);
-
+ setFilePlacements(temp);
+ setFiles(detail.files);
MySwal.fire({
title: "Sukses",
text: "Data berhasil disimpan.",
@@ -699,62 +740,96 @@ export default function FormConvertSPIT() {
- {isMabesApprover ? (
-
-
- {detailThumb.map((data: any) => (
-
-

-
- {[
- "all",
- "mabes",
- "polda",
- "satker",
- "internasional",
- ].map((value) => (
-
- ))}
+ {files?.map((file, index) => (
+
+

+
+
+
+
+
+
+ setupPlacement(index, "all", Boolean(e))
+ }
+ />
+
+
+
+
+ setupPlacement(index, "mabes", Boolean(e))
+ }
+ />
+
+
+
+
+ setupPlacement(index, "polda", Boolean(e))
+ }
+ />
+
+
+
+
+
+ setupPlacement(index, "international", Boolean(e))
+ }
+ />
+
- ))}
+
- ) : (
- ""
- )}
+ ))}
@@ -797,14 +872,16 @@ export default function FormConvertSPIT() {
- {detail?.contentTag?.split(",").map((tag, index) => (
-
- {tag.trim()}
-
- ))}
+ {detail?.contentTag
+ ?.split(",")
+ .map((tag: any, index: any) => (
+
+ {tag.trim()}
+
+ ))}
diff --git a/components/form/task/task-detail-form.tsx b/components/form/task/task-detail-form.tsx
index 768b1c00..8dfab668 100644
--- a/components/form/task/task-detail-form.tsx
+++ b/components/form/task/task-detail-form.tsx
@@ -40,7 +40,16 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
-import { ChevronDown, ChevronUp, DotSquare, TrashIcon } from "lucide-react";
+import {
+ ChevronDown,
+ ChevronUp,
+ Dock,
+ DotSquare,
+ ImageIcon,
+ Music,
+ TrashIcon,
+ VideoIcon,
+} from "lucide-react";
import dynamic from "next/dynamic";
import { Link } from "@/components/navigation";
import { Textarea } from "@/components/ui/textarea";
@@ -1064,7 +1073,7 @@ export default function FormTaskDetail() {
onClick={() => setSelectedVideo(file.url)}
>
- {renderFilePreview(file.url)}
+
@@ -1109,7 +1118,7 @@ export default function FormTaskDetail() {
onClick={() => setSelectedImage(file.url)}
>
- {renderFilePreview(file.url)}
+
@@ -1157,7 +1166,7 @@ export default function FormTaskDetail() {
onClick={() => setSelectedText(file.url)}
>
- {renderFilePreview(file.url)}
+
@@ -1228,7 +1237,7 @@ export default function FormTaskDetail() {
onClick={() => setSelectedAudio(file.url)}
>
- {renderFilePreview(file.url)}
+
diff --git a/components/form/task/task-edit-form.tsx b/components/form/task/task-edit-form.tsx
index d8eca6ad..a765b190 100644
--- a/components/form/task/task-edit-form.tsx
+++ b/components/form/task/task-edit-form.tsx
@@ -32,7 +32,14 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
-import { ChevronDown, ChevronUp } from "lucide-react";
+import {
+ ChevronDown,
+ ChevronUp,
+ Dock,
+ ImageIcon,
+ Music,
+ VideoIcon,
+} from "lucide-react";
import FileUploader from "../shared/file-uploader";
import { AudioRecorder } from "react-audio-voice-recorder";
import Image from "next/image";
@@ -376,8 +383,14 @@ export default function FormTaskEdit() {
if (audioFiles?.length == 0) {
setIsAudioUploadFinish(true);
}
- audioFiles?.map(async (item: any, index: number) => {
- await uploadResumableFile(index, String(id), item, "4", "0");
+ audioFiles.map(async (item: FileWithPreview, index: number) => {
+ await uploadResumableFile(
+ index,
+ String(id),
+ item, // Use .file to access the actual File object
+ "4",
+ "0" // Optional: Replace with actual duration if available
+ );
});
// MySwal.fire({
@@ -446,10 +459,17 @@ export default function FormTaskEdit() {
audio.controls = true;
document.body.appendChild(audio);
- // Convert Blob to File
- const file = new File([blob], "voiceNote.webm", { type: "audio/webm" });
- setAudioFile(file);
+ // Convert Blob to File and add preview
+ const fileWithPreview: FileWithPreview = Object.assign(
+ new File([blob], "voiceNote.webm", { type: "audio/webm" }),
+ { preview: url }
+ );
+
+ // Add to state
+ setAudioFile(fileWithPreview);
+ setAudioFiles((prev) => [...prev, fileWithPreview]);
};
+
const handleDeleteAudio = () => {
// Remove the audio file by setting state to null
setAudioFile(null);
@@ -835,7 +855,7 @@ export default function FormTaskEdit() {
- {videoUploadedFiles?.length > 0 &&
}
+
setImageFiles(files)}
+ onDrop={(files) => setVideoFiles(files)}
/>
{videoUploadedFiles?.map((file: any, index: number) => (
@@ -853,7 +873,7 @@ export default function FormTaskEdit() {
>
- {renderFilePreview(file.url)}
+
@@ -876,7 +896,7 @@ export default function FormTaskEdit() {
))}
- {imageUploadedFiles?.length > 0 &&
}
+
- {renderFilePreview(file.url)}
+
@@ -916,7 +936,7 @@ export default function FormTaskEdit() {
))}
- {textUploadedFiles?.length > 0 &&
}
+
- {renderFilePreview(file.url)}
+
@@ -956,7 +976,7 @@ export default function FormTaskEdit() {
))}
- {audioUploadedFiles?.length > 0 &&
}
+
setAudioFiles(files)}
+ onDrop={(files) =>
+ setAudioFiles((prev) => [...prev, ...files])
+ }
className="mt-2"
/>
{audioUploadedFiles?.map((file: any, index: number) => (
@@ -984,7 +1006,7 @@ export default function FormTaskEdit() {
>
- {renderFilePreview(file.url)}
+
@@ -1008,7 +1030,7 @@ export default function FormTaskEdit() {
{audioFile && (
-
Voice note ready to submit: {audioFile.name}
+
Voice Note
-
+
setAudioFiles(files)}
+ onDrop={(files) =>
+ setAudioFiles((prev) => [...prev, ...files])
+ }
className="mt-2"
/>
- {audioFile && (
-
-
Voice note ready to submit: {audioFile.name}
+ {audioFiles?.map((audio: any, idx: any) => (
+
+
Voice Note
- )}
+ ))}
{isRecording &&
Recording... {timer} seconds remaining
}{" "}
{/* Display remaining time */}