// "use client"; import React, { useState, useEffect, useRef, Fragment } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useForm, Controller } from "react-hook-form"; import { cn, getCookiesDecrypt } from "@/lib/utils"; import { format } from "date-fns"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Calendar } from "@/components/ui/calendar"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { Loader2, CalendarIcon, ChevronUp, ChevronDown, Music, } from "lucide-react"; import DeleteConfirmationDialog from "@/components/delete-confirmation-dialog"; import { CalendarCategory } from "./data"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Textarea } from "@/components/ui/textarea"; import { error, loading, success } from "@/lib/swal"; import Cookies from "js-cookie"; import Swal from "sweetalert2"; import withReactContent from "sweetalert2-react-content"; import { postSchedule } from "@/service/schedule/schedule"; import { deleteAgendaSettings, getAgendaSettingsById, publishAgendaSettings, saveAgendaSettings, } from "@/service/agenda-setting/agenda-setting"; import { Checkbox } from "@/components/ui/checkbox"; import { getUserLevelForAssignments } from "@/service/task"; import { AudioRecorder } from "react-audio-voice-recorder"; import FileUploader from "@/components/form/shared/file-uploader"; import { Upload } from "tus-js-client"; import { getCsrfToken } from "@/service/auth"; import { Icon } from "@iconify/react"; import Image from "next/image"; import { UnitMapping } from "./unit-mapping"; import { useToast } from "@/components/ui/use-toast"; import { usePathname, useRouter } from "next/navigation"; import { Card } from "@/components/ui/card"; import WavesurferPlayer from "@wavesurfer/react"; import WaveSurfer from "wavesurfer.js"; const schema = z.object({ title: z.string().min(3, { message: "Required" }), description: z .string() .min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }), }); interface FileWithPreview extends File { preview: string; } interface FileUploaded { id: number; url: string; } const EventModal = ({ open, onClose, categories, event, selectedDate, }: { open: boolean; onClose: () => void; categories: any; event: any; selectedDate: any; }) => { const roleId = Number(getCookiesDecrypt("urie")) || 0; const [detail, setDetail] = useState(); const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(new Date()); const [isPending, startTransition] = React.useTransition(); const [listDest, setListDest] = useState([]); const [deleteModalOpen, setDeleteModalOpen] = useState(false); const [eventIdToDelete, setEventIdToDelete] = useState(null); const MySwal = withReactContent(Swal); const router = useRouter(); const pathname = usePathname(); const [isLoading, setIsLoading] = useState(false); const [checkedLevels, setCheckedLevels] = useState(new Set()); const [expandedPolda, setExpandedPolda] = useState([{}]); const [audioFile, setAudioFile] = useState(null); const [isRecording, setIsRecording] = useState(false); const [timer, setTimer] = useState(120); const [detailData, setDetailData] = useState(); const [imageFiles, setImageFiles] = useState([]); const [videoFiles, setVideoFiles] = useState([]); const [textFiles, setTextFiles] = useState([]); const [audioFiles, setAudioFiles] = useState([]); const [imageUploadedFiles, setImageUploadedFiles] = useState( [] ); const [videoUploadedFiles, setVideoUploadedFiles] = useState( [] ); const [textUploadedFiles, setTextUploadedFiles] = useState( [] ); const [audioUploadedFiles, setAudioUploadedFiles] = useState( [] ); const { toast } = useToast(); const [isImageUploadFinish, setIsImageUploadFinish] = useState(false); const [isVideoUploadFinish, setIsVideoUploadFinish] = useState(false); const [isTextUploadFinish, setIsTextUploadFinish] = useState(false); const [isAudioUploadFinish, setIsAudioUploadFinish] = useState(false); const [unitData, setUnitData] = useState([]); const [satkerData, setSatkerData] = useState([]); let progressInfo: any = []; let counterUpdateProgress = 0; const [progressList, setProgressList] = useState([]); let uploadPersen = 0; const [isStartUpload, setIsStartUpload] = useState(false); const [counterProgress, setCounterProgress] = useState(0); const [wilayahPublish, setWilayahPublish] = React.useState({ semua: false, nasional: false, polda: false, polres: false, satker: false, international: false, }); const [agendaType, setAgendaType] = React.useState(""); // State untuk agendaType const [selectedPolda, setSelectedPolda] = React.useState([]); // Untuk data Polda const [selectedSatker, setSelectedSatker] = React.useState([]); const [selectedPolres, setSelectedPolres] = React.useState([]); const [wavesurfer, setWavesurfer] = useState(); const [isPlaying, setIsPlaying] = useState(false); const [isPublishing, setIsPublishing] = useState(false); const { register, control, reset, setValue, formState: { errors }, handleSubmit, } = useForm({ resolver: zodResolver(schema), mode: "all", }); useEffect(() => { async function fetchDetailData() { const res = await getAgendaSettingsById(event?.event?.id); const detail = res?.data?.data; setDetailData(detail); const description = res?.data?.data?.description; console.log("description", res?.data?.data?.description); // Set nilai awal description ke form control if (description) { setValue("description", description); } const attachments = detail?.attachments; setImageUploadedFiles( attachments?.filter((file: any) => file.fileTypeId == 1) ); setVideoUploadedFiles( attachments?.filter((file: any) => file.fileTypeId == 2) ); setTextUploadedFiles( attachments?.filter((file: any) => file.fileTypeId == 3) ); setAudioUploadedFiles( attachments?.filter((file: any) => file.fileTypeId == 4) ); const agendaType = detail?.agendaType; setWilayahPublish({ semua: agendaType === "all", nasional: agendaType === "mabes", polda: agendaType === "polda", polres: agendaType === "polres", satker: agendaType === "satker", international: agendaType === "international", }); } fetchDetailData(); }, [event, setValue]); // useEffect(() => { // async function fetchPoldaPolres() { // setIsLoading(true); // try { // const response = await getUserLevelForAssignments(); // const levelList = response?.data?.data.list; // let listFiltered = []; // if (agendaType == "polda") { // listFiltered = levelList.filter( // (level: any) => level.name != "SATKER POLRI" // ); // } else if (agendaType == "polres") { // listFiltered = levelList.filter( // (level: any) => level.name != "SATKER POLRI" // ); // } else if (agendaType == "satker") { // listFiltered = levelList.filter( // (level: any) => level.name == "SATKER POLRI" // ); // } // setListDest(listFiltered); // const initialExpandedState = listFiltered.reduce( // (acc: any, polda: any) => { // acc[polda.id] = false; // return acc; // }, // {} // ); // setExpandedPolda(initialExpandedState); // } catch (error) { // console.error("Error fetching Polda/Polres data:", error); // } finally { // setIsLoading(false); // } // } // fetchPoldaPolres(); // }, [agendaType]); const handleCheckboxChange = (levelId: number) => { setCheckedLevels((prev) => { const updatedLevels = new Set(prev); if (updatedLevels.has(levelId)) { updatedLevels.delete(levelId); } else { updatedLevels.add(levelId); } return updatedLevels; }); }; const toggleWilayah = (key: string) => { setWilayahPublish((prev: any) => { const newState = { ...prev, [key]: !prev[key] }; // Handle "semua" logic to check all options if (key === "semua" && newState.semua) { setAgendaType("all"); return { semua: true, nasional: true, polda: true, polres: true, satker: true, international: true, }; } // Uncheck "semua" if any other option is selected if (key !== "semua") { newState.semua = false; } // Set agendaType based on the selected checkbox if (newState.nasional) setAgendaType("mabes"); else if (newState.polda) setAgendaType("polda"); else if (newState.polres) setAgendaType("polres"); else if (newState.satker) setAgendaType("satker"); else if (newState.international) setAgendaType("international"); else setAgendaType(""); // Reset if no checkbox is selected return newState; }); }; const save = async (data: any, publish = false) => { const publishTo = []; if (wilayahPublish.semua) publishTo.push("all"); if (wilayahPublish.nasional) publishTo.push("mabes"); if (wilayahPublish.polda) publishTo.push(...selectedPolda); if (wilayahPublish.polres) publishTo.push(...selectedPolres); if (wilayahPublish.satker) publishTo.push(...selectedSatker); if (wilayahPublish.international) publishTo.push("international"); const reqData = { id: detailData?.id, title: data.title, description: data.description, agendaType, // Include agendaType in request publishTo, startDate: format(startDate, "yyyy-MM-dd"), endDate: format(endDate, "yyyy-MM-dd"), }; console.log("Submitted Data:", reqData); const response = await saveAgendaSettings(reqData); if (response?.error) { error(response?.message); return false; } const id = response?.data?.data.id; loading(); if (imageFiles?.length === 0) { setIsImageUploadFinish(true); } imageFiles?.map(async (item: any, index: number) => { await uploadResumableFile(index, String(id), item, "1", "0"); }); if (videoFiles?.length === 0) { setIsVideoUploadFinish(true); } videoFiles?.map(async (item: any, index: number) => { await uploadResumableFile(index, String(id), item, "2", "0"); }); if (textFiles?.length === 0) { setIsTextUploadFinish(true); } textFiles?.map(async (item: any, index: number) => { await uploadResumableFile(index, String(id), item, "3", "0"); }); if (audioFiles?.length == 0) { setIsAudioUploadFinish(true); } 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 ); }); if (publish) { setIsPublishing(true); const publishResponse = await publishAgendaSettings(id); setIsPublishing(false); if (publishResponse?.error) { error(publishResponse?.message); return false; } success("Agenda berhasil dipublikasikan!"); } }; const onSubmit = (data: any) => { if ( (wilayahPublish.polda && selectedPolda.length === 0) || (wilayahPublish.satker && selectedSatker.length === 0) || (wilayahPublish.polres && selectedPolres.length === 0) ) { toast({ title: "Pilih ID untuk Polda/Satker", variant: "destructive", }); return; } save(data); }; useEffect(() => { if (selectedDate) { setStartDate(selectedDate.date); setEndDate(selectedDate.date); } if (event) { setStartDate(event?.event?.start); setEndDate(event?.event?.end); const eventCalendar = event?.event?.extendedProps?.calendar; setAgendaType(eventCalendar || categories[0].value); } setValue("title", event?.event?.title || ""); setValue("description", event?.event?.description || ""); }, [event, selectedDate, open, categories, setValue]); const onDeleteEventAction = async () => { try { } catch (error) {} }; const handleOpenDeleteModal = (eventId: string) => { setEventIdToDelete(eventId); setDeleteModalOpen(true); onClose(); }; const toggleExpand = (poldaId: any) => { console.log("Toogle : ", expandedPolda); setExpandedPolda((prev: any) => ({ ...prev, [poldaId]: !prev[poldaId], })); }; const onRecordingStart = () => { setIsRecording(true); // Start a timer that stops the recording after 2 minutes (120 seconds) const countdown = setInterval(() => { setTimer((prevTimer) => { if (prevTimer <= 1) { clearInterval(countdown); // Stop the timer when it reaches 0 return 0; } return prevTimer - 1; }); }, 1000); // Update every second // Automatically stop recording after 2 minutes setTimeout(() => { if (isRecording) { handleStopRecording(); } }, 120000); // Stop after 2 minutes (120,000 ms) }; const handleStopRecording = () => { setIsRecording(false); setTimer(120); // Reset the timer to 2 minutes for the next recording }; const addAudioElement = (blob: Blob) => { const url = URL.createObjectURL(blob); const audio = document.createElement("audio"); audio.src = url; audio.controls = true; document.body.appendChild(audio); // 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); const audioElements = document.querySelectorAll("audio"); audioElements.forEach((audio) => audio.remove()); }; async function uploadResumableFile( idx: number, id: string, file: any, fileTypeId: string, duration: string ) { console.log(idx, id, file, fileTypeId, duration); const resCsrf = await getCsrfToken(); const csrfToken = resCsrf?.data?.token; console.log("CSRF TOKEN : ", csrfToken); const headers = { "X-XSRF-TOKEN": csrfToken, }; const upload = new Upload(file, { endpoint: `${process.env.NEXT_PUBLIC_API}/agenda-settings/file/upload`, headers: headers, retryDelays: [0, 3000, 6000, 12_000, 24_000], chunkSize: 20_000, metadata: { agendaSettingId: id, filename: file.name, contentType: file.type, fileTypeId: fileTypeId, duration, }, onBeforeRequest: function (req) { var xhr = req.getUnderlyingObject(); xhr.withCredentials = true; }, onError: async (e: any) => { console.log("Error upload :", e); error(e); }, onChunkComplete: ( chunkSize: any, bytesAccepted: any, bytesTotal: any ) => { // const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100); // progressInfo[idx].percentage = uploadPersen; // counterUpdateProgress++; // console.log(counterUpdateProgress); // setProgressList(progressInfo); // setCounterProgress(counterUpdateProgress); }, onSuccess: async () => { // uploadPersen = 100; // progressInfo[idx].percentage = 100; // counterUpdateProgress++; // setCounterProgress(counterUpdateProgress); successTodo(); if (fileTypeId == "1") { setIsImageUploadFinish(true); } else if (fileTypeId == "2") { setIsVideoUploadFinish(true); } if (fileTypeId == "3") { setIsTextUploadFinish(true); } if (fileTypeId == "4") { setIsAudioUploadFinish(true); } }, }); upload.start(); } useEffect(() => { successTodo(); }, [ isImageUploadFinish, isVideoUploadFinish, isAudioUploadFinish, isTextUploadFinish, ]); function successTodo() { if ( isImageUploadFinish && isVideoUploadFinish && isAudioUploadFinish && isTextUploadFinish ) { successSubmit("/in/contributor/agenda-setting"); } } const successSubmit = (redirect: string) => { MySwal.fire({ title: "Sukses", text: "Data berhasil disimpan.", icon: "success", confirmButtonColor: "#3085d6", confirmButtonText: "OK", }).then(() => { router.push(redirect); }); }; const renderFilePreview = (url: string) => { return ( {"file ); }; const handleRemoveFile = (id: number) => {}; async function doDelete(id: any) { loading(); const resDelete = await deleteAgendaSettings(id); if (resDelete?.error) { error(resDelete.message); return false; } close(); successSubmitDelete("/in/contributor/agenda-setting"); window.location.reload(); } const handleDelete = (id: any) => { MySwal.fire({ title: "Hapus Data?", text: "", icon: "warning", showCancelButton: true, cancelButtonColor: "#3085d6", confirmButtonColor: "#d33", confirmButtonText: "Hapus", }).then((result) => { if (result.isConfirmed) { doDelete(id); } }); }; function successSubmitDelete(redirect: string) { MySwal.fire({ title: "Sukses", icon: "success", confirmButtonColor: "#3085d6", confirmButtonText: "OK", }).then(() => { if (redirect === window.location.pathname) { fetch(redirect, { method: "GET", cache: "reload" }).then(() => { console.log("Data diperbarui."); }); } else { window.location.href = redirect; } }); } const onReady = (ws: any) => { setWavesurfer(ws); setIsPlaying(false); }; const onPlayPause = () => { wavesurfer && wavesurfer.playPause(); }; return ( <> setDeleteModalOpen(false)} onConfirm={onDeleteEventAction} defaultToast={false} /> {event?.length > 1 ? "Edit Agenda Setting" : "Create Agenda Setting"}{" "} {event?.title}
( )} /> {errors?.title?.message && (
{typeof errors?.title?.message === "string" ? errors?.title?.message : JSON.stringify(errors?.title?.message)}
)}
( setStartDate(date as Date)} initialFocus /> )} />
( setEndDate(date as Date)} initialFocus /> )} />
toggleWilayah("semua")} />
toggleWilayah("nasional")} />
toggleWilayah("polda")} /> {wilayahPublish.polda && ( setSelectedPolda(data) } /> )}
toggleWilayah("polres")} /> {wilayahPublish.polres && ( setSelectedPolres(data) } /> )}
toggleWilayah("satker")} /> {wilayahPublish.satker && ( setSelectedSatker(data) } /> )}
toggleWilayah("international")} />
(