From 1cd3019c6bc7322892002e456fd2ceeef62b6839 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Tue, 6 May 2025 14:21:11 +0800 Subject: [PATCH] [QUDO-27] feat:update meta data --- .../task-ta/components/columns.tsx | 28 +- .../(public)/audio/detail/[slug]/page.tsx | 954 +------------ .../(public)/document/detail/[slug]/page.tsx | 803 +---------- .../(public)/image/detail/[slug]/page.tsx | 1155 +--------------- .../(public)/video/detail/[slug]/page.tsx | 816 +---------- components/main/audio-detail.tsx | 1200 +++++++++++++++++ components/main/document-detail.tsx | 1029 ++++++++++++++ components/main/image-detail.tsx | 1146 ++++++++++++++++ components/main/video-detail.tsx | 1060 +++++++++++++++ .../visualization/performance-polres.tsx | 2 +- .../http-config/http-interceptor-service.ts | 28 +- service/landing/landing.ts | 111 +- 12 files changed, 4725 insertions(+), 3607 deletions(-) create mode 100644 components/main/audio-detail.tsx create mode 100644 components/main/document-detail.tsx create mode 100644 components/main/image-detail.tsx create mode 100644 components/main/video-detail.tsx diff --git a/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx b/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx index 9a9ae4db..0350e387 100644 --- a/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx +++ b/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx @@ -159,18 +159,22 @@ const useTableColumns = () => { - - - - View - - - - - - Edit - - + {roleId == 11 && ( + + + + View + + + )} + {roleId == 11 && ( + + + + Edit + + + )} {roleId == 12 && ( ({ - container: ref, - waveColor: "#eee", - progressColor: "OrangeRed", - cursorColor: "OrangeRed", - barWidth: 3, - barRadius: 3, - responsive: true, - height: 150, // If true, normalize by the maximum peak instead of 1.0. - normalize: true, // Use the PeakCache to improve rendering speed of large waveforms. - partialRender: true, -}); - -const DetailAudio = () => { - const [selectedSize, setSelectedSize] = useState("L"); - const router = useRouter(); - const pathname = usePathname(); - const params = useParams(); - const slug = String(params?.slug); - const [detailDataAudio, setDetailDataAudio] = useState(); - const [isSaved, setIsSaved] = useState(false); - const [wishlistId, setWishlistId] = useState(); - const { toast } = useToast(); - const [isDownloadAll, setIsDownloadAll] = useState(false); - const [downloadProgress, setDownloadProgress] = useState(0); - const [isFromSPIT, setIsFromSPIT] = useState(false); - const [main, setMain] = useState(); - const userId = getCookiesDecrypt("uie"); - const [emailShareList, setEmailShareList] = useState(); - const [emailShareInput, setEmailShareInput] = useState(); - const [emailMessageInput, setEmailMessageInput] = useState(); - const searchParams = useSearchParams(); - const id = searchParams?.get("id"); - const [width, setWidth] = useState(); - const [content, setContent] = useState([]); - const userRoleId = getCookiesDecrypt("urie"); - const [playing, setPlaying] = useState(false); - const wavesurfer = useRef(null); - const waveformRef = useRef(null); - const [audioLoaded, setAudioLoaded] = useState(false); - const [volume, setVolume] = useState(0.5); - const [message, setMessage] = useState(""); - const [listSuggestion, setListSuggestion] = useState(); - const MySwal = withReactContent(Swal); - const [visibleInput, setVisibleInput] = useState(null); - const t = useTranslations("LandingPage"); - - let typeString = "audio"; - - useEffect(() => { - initFetch(); - checkWishlist(); - sendActivityLog(2); - }, []); - - const initFetch = async () => { - const response = await getDetail(String(slug)); - console.log("detailAudio", response); - const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]); - - setIsFromSPIT(response?.data?.data?.isFromSPIT); - setWidth(window.innerWidth); - setContent(response?.data?.data); - setListSuggestion(responseGet.data?.data); - setMain({ - id: response?.data?.data?.files[0]?.id, - type: response?.data?.data?.fileType.name, - url: - Number(response?.data?.data?.fileType?.id) == 4 - ? response?.data?.data?.files[0]?.secondaryUrl - : Number(response?.data?.data?.fileType?.id) == 2 - ? `${process.env.NEXT_PUBLIC_API}/media/view?id=${response?.data?.data?.files[0]?.id}&operation=file&type=video` - : response?.data?.data?.files[0]?.url, - thumbnailFileUrl: response?.data?.data?.files[0]?.thumbnailFileUrl, - names: response?.data?.data?.files[0]?.fileName, - format: response?.data?.data?.files[0]?.format, - widthPixel: response?.data?.data?.files[0]?.widthPixel, - heightPixel: response?.data?.data?.files[0]?.heightPixel, - size: response?.data?.data?.files[0]?.size, - caption: response?.data?.data?.files[0]?.caption, - }); - setDetailDataAudio(response?.data?.data); +type Props = { + params: { + title: string; + slug: string; + description: string; + thumbnailLink: string; }; - - const doBookmark = async () => { - if (userId) { - const data = { - mediaUploadId: slug?.split("-")?.[0], - }; - - loading(); - const res = await saveWishlist(data); - if (res?.error) { - error(res.message); - return false; - } - close(); - toast({ - title: "Konten berhasil disimpan", - }); - checkWishlist(); - } else { - router.push("/auth"); - } - }; - async function checkWishlist() { - if (userId) { - const res = await checkWishlistStatus(slug.split("-")?.[0]); - console.log(res?.data?.data); - const isAlreadyOnWishlist = res?.data?.data !== "-1"; - setWishlistId(res?.data?.data); - setIsSaved(isAlreadyOnWishlist); - } - } - - const handleDeleteWishlist = async () => { - if (userId) { - loading(); - const res = await deleteWishlist(wishlistId); - - if (res?.error) { - error(res.message); - return false; - } - - toast({ - title: "Konten berhasil dihapus", - }); - close(); - checkWishlist(); - } else { - router.push("/auth"); - } - }; - - async function sendActivityLog(activityTypeId: number) { - const data = { - activityTypeId, - mediaId: slug.split("-")?.[0], - url: window.location.href, - }; - // set activity - await postActivityLog(data); - } - - const handleDownload = () => { - if (downloadProgress === 0) { - if (!userId) { - router.push("/auth/login"); - } else { - sendActivityLog(2); - sendActivityLog(3); - - if (isDownloadAll) { - let url: string; - const baseId = slug.split("-")?.[0]; - - // if (type === "1") { - // url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}&resolution=${resolutionSelected}`; - // } else if (type === "2") { - // url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}&resolution=${imageSizeSelected}`; - // } else { - url = `${process.env.NEXT_PUBLIC_API}/media/file/download-zip?id=${baseId}`; - // } - - downloadFile(url, "FileDownload.zip"); - } else { - if (isFromSPIT && main?.url?.includes("spit.humas")) { - downloadFile(`${main?.url}`, `${main.names}`); - } else { - downloadFile(`${main?.url}`, `${main.names}`); - } - } - // } else if (type === "1" && resolutionSelected?.length > 0) { - // if (isFromSPIT && main?.url?.includes("spit.humas")) { - // downloadFile(`${main?.url}`, `${main.names}`); - // } else { - // const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=video&resolution=${resolutionSelected}p`; - // downloadFile(url, `${main.names}`); - // } - // } else if (type === "2" && imageSizeSelected?.length > 0) { - // const url = `${process.env.NEXT_PUBLIC_API}/media/view?id=${main?.id}&operation=file&type=image&resolution=${imageSizeSelected}`; - // downloadFile(url, `${main.names}`); - // } else if (type === "3" || type === "4") { - // downloadFile(`${main?.url}`, `${main.names}`); - // } - } - } - }; - - const downloadFile = (fileUrl: string, name: string) => { - const xhr = new XMLHttpRequest(); - - xhr.open("GET", fileUrl, true); - xhr.responseType = "blob"; - - xhr.addEventListener("progress", (event) => { - if (event.lengthComputable) { - const percentCompleted = Math.round((event.loaded / event.total) * 100); - setDownloadProgress(percentCompleted); - } - }); - - xhr.addEventListener("readystatechange", () => { - if (xhr.readyState === 4 && xhr.status === 200) { - const contentType = xhr.getResponseHeader("content-type") || "application/octet-stream"; - const extension = contentType.split("/")[1]; - const filename = `${name}.${extension}`; - - const blob = new Blob([xhr.response], { - type: contentType, - }); - const downloadUrl = URL.createObjectURL(blob); - const a = document.createElement("a"); - - a.href = downloadUrl; - a.download = filename; - document.body.append(a); - a.click(); - a.remove(); - } - }); - - xhr.onloadend = () => { - setDownloadProgress(0); - }; - - xhr.send(); - }; - - const sizes = [ - { label: "MP3", value: "... MB" }, - { label: "WAV", value: "... MB" }, - ]; - - const handleShare = (type: any, url: any) => { - if (Number(userRoleId) < 1 || userRoleId == undefined) { - router.push("/auth/login"); - } else { - sendActivityLog(2); - sendActivityLog(4); - if (type == "wa" && width <= 768) { - window.open(`whatsapp://send?${url}`, "_blank"); - } else if (type == "wa" && width > 768) { - window.open(`https://web.whatsapp.com/send?${url}`, "_blank", "noreferrer"); - } else { - window.open(url); - } - } - }; - - async function shareToEmail() { - if (Number(userRoleId) < 1 || userRoleId == undefined) { - router.push("/auth/login"); - } else { - const data = { - mediaUploadId: id?.split("-")?.[0], - email: emailShareList || [emailShareInput], - message: emailMessageInput, - url: window.location.href, - }; - loading(); - const res = await sendMediaUploadToEmail(data); - if (res?.error) { - error(res.message); - return false; - } - close(); - successCallback("Konten Telah Dikirim"); - } - } - - const handlePlayPause = () => { - setPlaying(!playing); - wavesurfer?.current?.playPause(); - }; - - const handleEmailList = (e: any) => { - const arrayEmail: any = []; - for (let i = 0; i < emailShareList?.length; i += 1) { - arrayEmail.push(emailShareList[i]); - } - if (e.which == 13) { - if (e.target.value) { - arrayEmail.push(e.target.value); - setEmailShareList(arrayEmail); - setEmailShareInput(""); - } - e.preventDefault(); - } - return false; - }; - - // useEffect(() => { - // function initState() { - // if (typeString == "audio" && main?.url != undefined) { - // const init = async () => { - // const { default: WaveSurfer } = await import("wavesurfer.js"); - - // setPlaying(false); - - // const formatTime = function (time: any) { - // return [ - // Math.floor((time % 3600) / 60), - // // minutes - // `00${Math.floor(time % 60)}`.slice(-2), // seconds - // ].join(":"); - // }; - // console.log("AUDIO", main?.url); - - // const options = formWaveSurferOptions(waveformRef.current); - - // wavesurfer.current = WaveSurfer.create(options); - - // wavesurfer.current.load(main?.url); - - // wavesurfer.current.on("ready", () => { - // // https://wavesurfer-js.org/docs/methods.html - // // wavesurfer.current.playPause(); - // // setPlaying(true); - // setAudioLoaded(true); - // // make sure object stillavailable when file loaded - // if (wavesurfer.current) { - // wavesurfer.current.setVolume(volume); - // let volumeNow = volume; - // setVolume(volumeNow); - // } - - // $(".waveform__duration").text(formatTime(wavesurfer.current.getDuration())); - // }); - - // // Show current time - // wavesurfer.current.on("audioprocess", () => { - // $(".waveform__counter").text(formatTime(wavesurfer.current.getCurrentTime())); - // }); - - // wavesurfer.current.on("finish", () => { - // setPlaying(false); - // }); - // }; - - // init(); - // // Removes events, elements and disconnects Web Audio nodes. - // // when component unmount - - // return () => wavesurfer?.current?.destroy(); - // } - // } - - // initState(); - // }, [main?.url]); - - useEffect(() => { - if (typeString === "audio" && main?.url) { - const init = async () => { - const { default: WaveSurfer } = await import("wavesurfer.js"); - - if (wavesurfer.current) { - wavesurfer.current.destroy(); // 🔥 Hapus instance lama sebelum membuat yang baru - } - - setPlaying(false); - - const formatTime = function (time: any) { - return [ - Math.floor((time % 3600) / 60), - // minutes - `00${Math.floor(time % 60)}`.slice(-2), // seconds - ].join(":"); - }; - - const options = formWaveSurferOptions(waveformRef.current); - wavesurfer.current = WaveSurfer.create(options); - wavesurfer.current.load(main?.url); - - wavesurfer.current.on("ready", () => { - setAudioLoaded(true); - wavesurfer.current.setVolume(volume); - $(".waveform__duration").text(formatTime(wavesurfer.current.getDuration())); - }); - - wavesurfer.current.on("audioprocess", () => { - $(".waveform__counter").text(formatTime(wavesurfer.current.getCurrentTime())); - }); - - wavesurfer.current.on("finish", () => { - setPlaying(false); - }); - }; - - init(); - - return () => { - if (wavesurfer.current) { - wavesurfer.current.destroy(); // 🔥 Hapus saat unmount - } - }; - } - }, [main?.url]); - - const onVolumeChange = (e: any) => { - const { target } = e; - const newVolume = +target?.value; - - if (newVolume) { - setVolume(newVolume); - wavesurfer?.current?.setVolume(newVolume || 1); - } - }; - - async function sendSuggestionChild(parentId: any) { - const inputElement = document.querySelector(`#input-comment-${parentId}`) as HTMLInputElement; - - if (inputElement && inputElement.value.length > 3) { - loading(); - const data = { - mediaUploadId: slug?.split("-")?.[0], - message: inputElement.value, - parentId, - }; - - console.log(data); - const response = await createPublicSuggestion(data); - console.log(response); - const responseGet: any = await getPublicSuggestionList(slug?.split("-")?.[0]); - console.log(responseGet.data?.data); - setListSuggestion(responseGet.data?.data); - - // Reset input field - inputElement.value = ""; - - // document.querySelector("#comment-id-" + parentId)?.style.display = "none"; - - close(); - } - } - async function deleteDataSuggestion(dataId: any) { - loading(); - const response = await deletePublicSuggestion(dataId); - console.log(response); - const responseGet = await getPublicSuggestionList(slug.split("-")?.[0]); - console.log(responseGet.data?.data); - setListSuggestion(responseGet.data?.data); - close(); - } - const deleteData = (dataId: any) => { - MySwal.fire({ - title: "Delete Comment", - icon: "warning", - showCancelButton: true, - cancelButtonColor: "#3085d6", - confirmButtonColor: "#d33", - confirmButtonText: "Delete", - }).then((result: any) => { - if (result.isConfirmed) { - deleteDataSuggestion(dataId); - console.log(dataId); - } - }); - }; - const showInput = (e: any) => { - console.log(document.querySelector(`#${e}`)?.classList); - document.querySelector(`#${e}`)?.classList.toggle("none"); - setVisibleInput(visibleInput === e ? null : e); - }; - - function addDefaultProfile(ev: any) { - ev.target.src = "/assets/avatar-profile.png"; - } - - async function sendSuggestionParent() { - if (message?.length > 3) { - loading(); - const data = { - mediaUploadId: slug?.split("-")?.[0], - message, - parentId: null, - }; - - const response = await createPublicSuggestion(data); - - console.log(response); - setMessage(""); - - const responseGet = await getPublicSuggestionList(slug?.split("-")?.[0]); - console.log(responseGet?.data?.data); - setListSuggestion(responseGet?.data?.data); - - // Hapus nilai semua input secara manual jika perlu - const inputs = document.querySelectorAll("input"); - inputs.forEach((input) => { - input.value = ""; - }); - - close(); - } - } - const getInputValue = (e: any) => { - const message = e.target.value; - console.log(message); - setMessage(message); - }; - const postData = () => { - const checkMessage = checkMaliciousText(message); - if (checkMessage == "") { - if (Number(userRoleId) < 1 || userRoleId == undefined) { - router.push("/auth"); - } else { - sendSuggestionParent(); - } - } else { - warning(checkMessage); - } - }; - const postDataChild = (id: any) => { - const checkMessage = checkMaliciousText(message); - if (checkMessage == "") { - if (Number(userRoleId) < 1 || userRoleId == undefined) { - router.push("/auth"); - } else { - sendSuggestionChild(id); - } - } else { - warning(checkMessage); - } - }; - - return ( - <> -
- {/* Container Utama */} -
- {/* Bagian Kiri */} -
-
- -
- -
-
-
-
- - {/* */} - -
- - {/* Footer Informasi */} -
-
-

- {t("by")} {detailDataAudio?.uploadedBy?.userLevel?.name} -

- {/*

-  | {t("updatedOn")} {detailDataAudio?.updatedAt} WIB  |  -

*/} -

-  | {t("updatedOn")}  - {formatDateToIndonesian(new Date(detailDataAudio?.updatedAt))} {"WIB"} -

-

-  |   - -  {detailDataAudio?.clickCount}  -

-
-
-

- {t("creator")} {detailDataAudio?.creatorName} -

-
-
- {/* Keterangan */} -
-

{detailDataAudio?.title}

-
-
-
- - {/* Bagian Kanan */} -
- {isSaved ? ( - handleDeleteWishlist()} className="flex flex-col mb-3 items-center justify-center cursor-pointer"> - -

{t("delete")}

-
- ) : ( - doBookmark()} className="flex flex-col mb-3 items-center justify-center cursor-pointer"> - -

{t("save")}

-
- )} - - {/* garis */} -
- - - {detailDataAudio?.category?.name} - - - - -
- - {/* Opsi Ukuran Foto */} -

{t("audioSize")}

- -
- -
- {sizes.map((size: any) => ( -
-
- setSelectedSize(size.label)} className="text-red-600 focus:ring-red-600" /> -
{size.label}
-
-
-
{size.value}
-
-
- ))} -
- - {/* Download Semua */} -
- -
- - {/* Tombol Download */} - - - {/* Tombol Bagikan */} - -
-
-
- -
- {/* Comment */} -
-
-

{t("comment")}

-