2024-12-19 15:20:03 +00:00
"use client" ;
2025-01-11 14:24:28 +00:00
import { useParams , usePathname , useSearchParams } from "next/navigation" ;
2025-01-15 15:59:19 +00:00
import React , { useEffect , useRef , useState } from "react" ;
2024-12-19 15:20:03 +00:00
import { Icon } from "@iconify/react/dist/iconify.js" ;
import NewContent from "@/components/landing-page/new-content" ;
2025-01-05 13:46:18 +00:00
import { Link , useRouter } from "@/i18n/routing" ;
2024-12-19 15:20:03 +00:00
import { Textarea } from "@/components/ui/textarea" ;
import { BarWave } from "react-cssfx-loading" ;
2025-01-05 13:46:18 +00:00
import { useToast } from "@/components/ui/use-toast" ;
2025-01-21 14:25:14 +00:00
import { checkWishlistStatus , createPublicSuggestion , deletePublicSuggestion , deleteWishlist , getDetail , getPublicSuggestionList , saveWishlist } from "@/service/landing/landing" ;
2025-01-05 13:46:18 +00:00
import { getCookiesDecrypt } from "@/lib/utils" ;
2025-01-21 14:25:14 +00:00
import { close , error , loading , successCallback , warning } from "@/config/swal" ;
2025-01-11 14:24:28 +00:00
import { sendMediaUploadToEmail } from "@/service/media-tracking/media-tracking" ;
import { Popover , PopoverContent , PopoverTrigger } from "@/components/ui/popover" ;
import { Input } from "@/components/ui/input" ;
import { Button } from "@/components/ui/button" ;
2025-01-21 14:25:14 +00:00
import withReactContent from "sweetalert2-react-content" ;
import Swal from "sweetalert2" ;
import { checkMaliciousText , getPublicLocaleTimestamp } from "@/utils/globals" ;
import parse from "html-react-parser" ;
import $ from "jquery" ;
2025-01-15 15:59:19 +00:00
const formWaveSurferOptions = ( ref : any ) = > ( {
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 ,
} ) ;
2024-12-19 15:20:03 +00:00
const DetailAudio = ( ) = > {
const [ selectedSize , setSelectedSize ] = useState < string > ( "L" ) ;
const router = useRouter ( ) ;
const pathname = usePathname ( ) ;
const params = useParams ( ) ;
2025-01-05 13:46:18 +00:00
const slug = String ( params ? . slug ) ;
2024-12-19 15:20:03 +00:00
const [ detailDataAudio , setDetailDataAudio ] = useState < any > ( ) ;
2025-01-05 13:46:18 +00:00
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 < any > ( ) ;
const [ resolutionSelected , setResolutionSelected ] = useState ( "720" ) ;
const [ imageSizeSelected , setImageSizeSelected ] = useState ( "l" ) ;
const userId = getCookiesDecrypt ( "uie" ) ;
2025-01-11 14:24:28 +00:00
const [ emailShareList , setEmailShareList ] = useState < any > ( ) ;
const [ emailShareInput , setEmailShareInput ] = useState < any > ( ) ;
const [ emailMessageInput , setEmailMessageInput ] = useState ( ) ;
const searchParams = useSearchParams ( ) ;
const id = searchParams ? . get ( "id" ) ;
const [ width , setWidth ] = useState < any > ( ) ;
const [ content , setContent ] = useState < any > ( [ ] ) ;
const userRoleId = getCookiesDecrypt ( "urie" ) ;
2025-01-15 15:59:19 +00:00
const [ playing , setPlaying ] = useState ( false ) ;
const wavesurfer = useRef < any > ( null ) ;
const waveformRef = useRef ( null ) ;
const [ audioLoaded , setAudioLoaded ] = useState ( false ) ;
const [ volume , setVolume ] = useState < any > ( 0.5 ) ;
2025-01-21 14:25:14 +00:00
const [ message , setMessage ] = useState ( "" ) ;
const [ listSuggestion , setListSuggestion ] = useState < any > ( ) ;
const MySwal = withReactContent ( Swal ) ;
2025-01-11 14:24:28 +00:00
2025-01-15 15:59:19 +00:00
let typeString = "audio" ;
2024-12-19 15:20:03 +00:00
useEffect ( ( ) = > {
initFetch ( ) ;
2025-01-05 13:46:18 +00:00
checkWishlist ( ) ;
2024-12-19 15:20:03 +00:00
} , [ ] ) ;
const initFetch = async ( ) = > {
const response = await getDetail ( String ( slug ) ) ;
console . log ( "detailAudio" , response ) ;
2025-01-21 14:25:14 +00:00
const responseGet = await getPublicSuggestionList ( slug ? . split ( "-" ) ? . [ 0 ] ) ;
2025-01-05 13:46:18 +00:00
setIsFromSPIT ( response ? . data ? . data ? . isFromSPIT ) ;
2025-01-11 14:24:28 +00:00
setWidth ( window . innerWidth ) ;
2025-01-16 16:55:04 +00:00
setContent ( response ? . data ? . data ) ;
2025-01-21 14:25:14 +00:00
setListSuggestion ( responseGet . data ? . data ) ;
2025-01-05 13:46:18 +00:00
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 ,
} ) ;
2024-12-19 15:20:03 +00:00
setDetailDataAudio ( response ? . data ? . data ) ;
} ;
2025-01-05 13:46:18 +00:00
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
// const response = await postActivityLog(data, token);
// console.log(response);
}
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 ( ) ;
} ;
2024-12-19 15:20:03 +00:00
const sizes = [
{ label : "XL" , value : "3198 x 1798 px" } ,
{ label : "L" , value : "2399 x 1349 px" } ,
{ label : "M" , value : "1599 x 899 px" } ,
{ label : "S" , value : "1066 x 599 px" } ,
{ label : "XS" , value : "800 x 450 px" } ,
] ;
2025-01-11 14:24:28 +00:00
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" ) ;
}
}
2025-01-15 15:59:19 +00:00
const handlePlayPause = ( ) = > {
setPlaying ( ! playing ) ;
wavesurfer ? . current ? . playPause ( ) ;
} ;
2025-01-11 14:24:28 +00:00
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 ;
} ;
2025-01-15 15:59:19 +00:00
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 ( ":" ) ;
} ;
2025-01-16 16:55:04 +00:00
console . log ( "AUDIO" , main ? . url ) ;
2025-01-15 15:59:19 +00:00
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 ] ) ;
const onVolumeChange = ( e : any ) = > {
const { target } = e ;
const newVolume = + target ? . value ;
if ( newVolume ) {
setVolume ( newVolume ) ;
wavesurfer ? . current ? . setVolume ( newVolume || 1 ) ;
}
} ;
2025-01-21 14:25:14 +00:00
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 ( "hidden" ) ;
} ;
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 ) ;
}
} ;
2024-12-19 15:20:03 +00:00
return (
< >
< div className = "min-h-screen px-4 md:px-24 py-4" >
{ /* Container Utama */ }
< div className = "rounded-md overflow-hidden md:flex" >
{ /* Bagian Kiri */ }
< div className = "md:w-3/4" >
2025-01-16 16:55:04 +00:00
< div className = "relative flex flex-row" >
2025-01-15 15:59:19 +00:00
< button onClick = { handlePlayPause } >
< img src = { ` /assets/ ${ playing ? "stop-icon.png" : "play-icon.png" } ` } / >
< / button >
< div
className = "flex items-center "
style = {
audioLoaded
? {
display : "none" ,
}
: { }
}
>
2025-01-21 14:25:14 +00:00
< BarWave color = "#ffc831" width = "60px" height = "25px" duration = "2s " / >
2025-01-15 15:59:19 +00:00
< / div >
2025-01-16 16:55:04 +00:00
< div id = "waveform" ref = { waveformRef } className = "w-[700px] ml-12" / >
2024-12-19 15:20:03 +00:00
< / div >
2025-01-15 15:59:19 +00:00
< div
className = "flex flex-row mt-2"
style = {
audioLoaded
? { }
: {
display : "none !important" ,
}
}
>
< Icon icon = "fa:volume-up" / >
{ /* <Slider onChange={onVolumeChange} defaultValue={volume} /> */ }
< input
type = "range"
id = "volume"
2025-01-21 14:25:14 +00:00
name = "volume"
2025-01-15 15:59:19 +00:00
min = "0.01"
max = "1"
step = ".025"
onChange = { onVolumeChange }
defaultValue = { volume }
/ >
< / div >
2024-12-24 16:16:20 +00:00
{ /* Footer Informasi */ }
< div className = "p-4 text-sm text-gray-500 flex justify-between items-center border-t mt-4" >
< p className = "flex flex-row items-center" >
oleh & nbsp ; < span className = "font-semibold text-black" > { detailDataAudio ? . uploadedBy ? . userLevel ? . name } < / span > & nbsp ; | & nbsp ; Diupdate pada { detailDataAudio ? . updatedAt } WIB & nbsp ; | & nbsp ;
< Icon icon = "formkit:eye" width = "15" height = "15" / >
& nbsp ;
{ detailDataAudio ? . clickCount }
< / p >
< p > Kreator : { detailDataAudio ? . creatorName } < / p >
< / div >
{ /* Keterangan */ }
2025-01-15 15:59:19 +00:00
< div className = "w-full" >
2024-12-24 16:16:20 +00:00
< h1 className = "flex flex-row font-bold text-2xl mx-5 my-8" > { detailDataAudio ? . title } < / h1 >
< div className = "font-light text-justify" dangerouslySetInnerHTML = { { __html : detailDataAudio?.htmlDescription } } / >
< / div >
2024-12-19 15:20:03 +00:00
< / div >
{ /* Bagian Kanan */ }
2024-12-24 16:16:20 +00:00
< div className = "md:w-1/4 p-4 h-fit bg-gray-300 rounded-lg mx-4" >
2025-01-05 13:46:18 +00:00
{ isSaved ? (
< a onClick = { ( ) = > handleDeleteWishlist ( ) } className = "flex flex-col mb-3 items-center justify-center cursor-pointer" >
< Icon icon = "material-symbols:bookmark" width = { 40 } / >
< p className = "text-base lg:text-lg" > Hapus < / p >
< / a >
) : (
< a onClick = { ( ) = > doBookmark ( ) } className = "flex flex-col mb-3 items-center justify-center cursor-pointer" >
< Icon icon = "material-symbols:bookmark-outline" width = { 40 } / >
< p className = "text-base lg:text-lg" > Simpan < / p >
< / a >
) }
2024-12-19 15:20:03 +00:00
{ /* garis */ }
< div className = "border-t border-black my-4" > < / div >
2025-01-05 13:46:18 +00:00
< Link href = { ` /all/filter?title=polda&category= ${ detailDataAudio ? . category . id } ` } className = "bg-red-600 text-white text-xs font-bold px-3 py-3 my-3 flex justify-center items-center rounded" >
2024-12-19 15:20:03 +00:00
{ detailDataAudio ? . category ? . name }
< / Link >
< div className = "flex justify-center flex-wrap gap-2 mb-4" >
2025-01-05 13:46:18 +00:00
{ detailDataAudio ? . tags ? . split ( "," ) . map ( ( tag : string ) = > (
< a onClick = { ( ) = > router . push ( ` /all/filter?tag= ${ tag } ` ) } key = { tag } className = "bg-gray-200 text-gray-700 text-xs px-3 py-1 rounded-full cursor-pointer hover:bg-gray-500" >
{ tag }
< / a >
) ) }
2024-12-19 15:20:03 +00:00
< / div >
< div className = "border-t border-black my-4" > < / div >
{ /* Opsi Ukuran Foto */ }
2025-01-05 13:46:18 +00:00
< h4 className = "flex text-lg justify-center items-center font-semibold my-3" > Opsi Ukuran Audio < / h4 >
2024-12-19 15:20:03 +00:00
< div className = "border-t border-black my-4" > < / div >
< div className = "space-y-2" >
2025-01-05 13:46:18 +00:00
{ sizes . map ( ( size : any ) = > (
< div className = "flex flex-row justify-between" >
< div key = { size . label } className = "items-center flex flex-row gap-2 cursor-pointer" >
< input type = "radio" name = "size" value = { size . label } checked = { selectedSize === size . label } onChange = { ( ) = > setSelectedSize ( size . label ) } className = "text-red-600 focus:ring-red-600" / >
< div className = "text-sm" > { size . label } < / div >
< / div >
< div className = "" >
< div className = "text-sm" > { size . value } < / div >
2024-12-19 15:20:03 +00:00
< / div >
2025-01-05 13:46:18 +00:00
< / div >
2024-12-19 15:20:03 +00:00
) ) }
< / div >
{ /* Download Semua */ }
< div className = "mt-4" >
< label className = "flex items-center space-x-2 text-sm" >
2025-01-05 13:46:18 +00:00
< input type = "checkbox" className = "text-red-600 focus:ring-red-600" onChange = { ( ) = > setIsDownloadAll ( ! isDownloadAll ) } / >
2024-12-19 15:20:03 +00:00
< span > Download Semua File ? < / span >
< / label >
< / div >
{ /* Tombol Download */ }
2025-01-05 13:46:18 +00:00
< button onClick = { handleDownload } className = "mt-4 bg-red-600 text-white w-full py-2 flex justify-center items-center gap-1 rounded-md text-sm hover:bg-red-700" >
2024-12-19 15:20:03 +00:00
< svg xmlns = "http://www.w3.org/2000/svg" width = "1em" height = "1em" viewBox = "0 0 24 24" >
< path fill = "white" d = "m12 16l-5-5l1.4-1.45l2.6 2.6V4h2v8.15l2.6-2.6L17 11zm-6 4q-.825 0-1.412-.587T4 18v-3h2v3h12v-3h2v3q0 .825-.587 1.413T18 20z" / >
< / svg >
Download
< / button >
2025-01-11 14:24:28 +00:00
{ /* Tombol Bagikan */ }
< div className = "flex flex-row py-3" >
< p className = "text-base font-semibold" > Bagikan < / p >
< a className = "ml-8 cursor-pointer" onClick = { ( ) = > handleShare ( "fb" , ` https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmediahub.polri.go.id%2F ${ typeString } %2Fdetail%2F ${ content ? . id } "e= ${ content ? . title } ` ) } >
< Icon icon = "brandico:facebook" height = "20" className = "px-auto text-red-600 text-center" / >
< / a >
< a className = "ml-5 cursor-pointer" onClick = { ( ) = > handleShare ( "tw" , ` https://twitter.com/share?url=https%3A%2F%2Fmediahub.polri.go.id%2F ${ typeString } %2Fdetail%2F ${ content ? . id } &text= ${ content ? . title } ` ) } >
< Icon icon = "mdi:twitter" width = "23" className = "text-red-600 text-center" / >
< / a >
< a className = "ml-5 cursor-pointer" onClick = { ( ) = > handleShare ( "wa" , ` text= ${ content ? . title } %0D%0A%0D%0Ahttps%3A%2F%2Fmediahub.polri.go.id%2F ${ typeString } %2Fdetail%2F ${ content ? . id } ` ) } >
< Icon icon = "ri:whatsapp-fill" width = "23" className = "text-red-600 text-center" / >
< / a >
< Popover >
< PopoverTrigger className = "flex justify-end gap-1 cursor-pointer" asChild >
< a className = "ml-5 cursor-pointer" data - toggle = "dropdown" href = "#" aria - expanded = "false" >
< Icon icon = "material-symbols-light:mail" width = "23" className = "text-red-600 text-center" / >
< / a >
< / PopoverTrigger >
< PopoverContent >
< div className = "flex flex-col" >
< h1 className = "mb-2" > Share Ke Email < / h1 >
< div className = "flex flex-col mb-2" >
< p className = "text-base font-semibold mb-1" > Email Tujuan : < / p >
< Input value = { emailShareInput } onChange = { ( event ) = > setEmailShareInput ( event . target . value ) } onKeyPress = { handleEmailList } type = "email" placeholder = "Tekan Enter untuk input Email" / >
< / div >
< Button className = "bg-blue-500 text-white p-2 w-fit rounded-lg" onClick = { ( ) = > shareToEmail ( ) } >
Kirim
< / Button >
< / div >
< / PopoverContent >
< / Popover >
< / div >
2024-12-19 15:20:03 +00:00
< / div >
< / div >
< / div >
2024-12-24 16:16:20 +00:00
2024-12-19 15:20:03 +00:00
< div className = "w-full mb-8" >
{ /* Comment */ }
2025-01-21 14:25:14 +00:00
< div className = "flex flex-col my-16 p-10 bg-[#f7f7f7]" >
< div className = "gap-5 flex flex-col px-4 lg:px-14" >
< p className = "flex items-start text-lg" > Berikan Komentar < / p >
< Textarea placeholder = "Type your comments here." className = "flex w-full py-8" onChange = { getInputValue } / >
< button onClick = { ( ) = > postData ( ) } className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1" >
Kirim
< / button >
< / div >
< div className = "border-b-2 border-slate-300 mt-4 w-auto" > < / div >
< div className = "overflow-y-auto" >
{ listSuggestion ? . map ( ( data : any ) = > (
< div className = "flex flex-col" >
< div className = "flex flex-row mt-2 px-4 lg:px-14" >
< img src = { data ? . suggestionFrom ? . profilePictureUrl } className = "h-16 w-16 mr-2" onError = { addDefaultProfile } alt = "" / >
< div className = "border border-slate-300 w-full p-4 bg-white gap-1" >
< p className = "text-slate-500 text-base border-b-2 border-slate-200 mb-2" >
{ Number ( data . suggestionFrom ? . roleId ) == 2 || Number ( data . suggestionFrom ? . roleId ) == 3 || Number ( data . suggestionFrom ? . roleId ) == 4 ? "HUMAS POLRI" : data . suggestionFrom ? . fullname }
{ getPublicLocaleTimestamp ( new Date ( data . createdAt ) ) }
< / p >
< p className = "text-slate-500 text-sm mb-4" > { data ? . message } < / p >
< div >
< a
style = {
Number ( data . suggestionFrom ? . id ) == Number ( userId )
? {
display : "none" ,
}
: { }
}
onClick = { ( ) = > showInput ( ` comment-id- ${ data . id } ` ) }
className = "mr-2"
>
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Balas < / small >
< / a >
{ Number ( data . suggestionFrom ? . id ) == Number ( userId ) || Number ( userRoleId ) == 2 ? (
< a onClick = { ( ) = > deleteData ( data . id ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Hapus < / small >
< / a >
) : (
""
) }
< / div >
< / div >
< / div >
< div id = { ` comment-id- ${ data . id } ` } className = "px-4 lg:px-28 mt-2" >
< Textarea id = { ` input-comment- ${ data . id } ` } className = "p-4 focus:outline-none focus:border-sky-500" placeholder = "Masukkan balasan anda" / >
< div className = "flex flex-row gap-3" >
< a onClick = { ( ) = > postDataChild ( data . id ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 mt-2 cursor-pointer" > Kirim < / small >
< / a >
< a onClick = { ( ) = > showInput ( ` comment-id- ${ data . id } ` ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg mt-2 w-fit text-white px-4 py-1 cursor-pointer" > Batal < / small >
< / a >
< / div >
< / div >
{ data . children . length > 0
? data . children ? . map ( ( child1 : any ) = > (
< div className = "flex flex-col" >
< div className = "flex flex-row mt-2 px-4 lg:px-32" >
< img src = { child1 . suggestionFrom ? . profilePictureUrl } onError = { addDefaultProfile } alt = "" className = "h-16 w-16 mr-2" / >
< div className = "border border-slate-300 w-full p-4 bg-white gap-1" >
< p className = "text-slate-500 text-base border-b-2 border-slate-200 mb-2" >
{ " " }
< b > { Number ( child1 . suggestionFrom ? . roleId ) == 2 || Number ( child1 . suggestionFrom ? . roleId ) == 3 || Number ( child1 . suggestionFrom ? . roleId ) == 4 ? "HUMAS POLRI" : child1 . suggestionFrom ? . fullname } < / b > { " " }
{ getPublicLocaleTimestamp ( new Date ( child1 . createdAt ) ) }
< / p >
< p className = "text-slate-500 text-sm mb-4" > { parse ( String ( child1 ? . message ) ) } < / p >
< div >
< a
style = {
Number ( child1 . suggestionFrom ? . id ) == Number ( userId )
? {
display : "none" ,
}
: { }
}
onClick = { ( ) = > showInput ( ` comment-id- ${ child1 . id } ` ) }
>
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Balas < / small >
< / a >
< a
style = {
Number ( child1 . suggestionFrom ? . id ) == Number ( userId )
? { }
: {
display : "none" ,
}
}
onClick = { ( ) = > deleteData ( child1 . id ) }
>
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Hapus < / small >
< / a >
< / div >
< / div >
< / div >
< div id = { ` comment-id- ${ child1 . id } ` } className = "px-4 lg:px-40" >
< Textarea name = "" className = "mt-2 " id = { ` input-comment- ${ child1 . id } ` } placeholder = "Masukkan balasan anda" / >
< div className = "flex flex-row mt-2 gap-3" >
< a onClick = { ( ) = > postDataChild ( child1 . id ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Kirim < / small >
< / a >
< a onClick = { ( ) = > showInput ( ` comment-id- ${ child1 . id } ` ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Batal < / small >
< / a >
< / div >
< / div >
{ child1 . children . length > 0
? child1 . children ? . map ( ( child2 : any ) = > (
< div className = "" >
< div className = "flex flex-row mt-2 px-4 lg:px-48" >
< img src = { child2 . suggestionFrom ? . profilePictureUrl } className = "h-16 w-16 mr-2" onError = { addDefaultProfile } alt = "" / >
< div className = "border border-slate-300 w-full p-4 bg-white gap-1" >
< p className = "text-slate-500 text-base border-b-2 border-slate-200 mb-2" >
{ " " }
< b > { Number ( child2 . suggestionFrom ? . roleId ) == 2 || Number ( child2 . suggestionFrom ? . roleId ) == 3 || Number ( child2 . suggestionFrom ? . roleId ) == 4 ? "HUMAS POLRI" : child2 . suggestionFrom ? . fullname } < / b > { " " }
{ getPublicLocaleTimestamp ( new Date ( child2 . createdAt ) ) }
< / p >
< p className = "text-slate-500 text-sm mb-4" > { parse ( String ( child2 ? . message ) ) } < / p >
< div >
< a
style = {
Number ( child2 . suggestionFrom ? . id ) == Number ( userId )
? {
display : "none" ,
}
: { }
}
onClick = { ( ) = > showInput ( ` comment-id- ${ child2 . id } ` ) }
>
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Balas < / small >
< / a >
< a
style = {
Number ( child2 . suggestionFrom ? . id ) == Number ( userId )
? { }
: {
display : "none" ,
}
}
onClick = { ( ) = > deleteData ( child2 . id ) }
>
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Hapus < / small >
< / a >
< / div >
< / div >
< / div >
< div id = { ` comment-id- ${ child2 . id } ` } className = "px-4 lg:px-52" >
< Textarea name = "" id = { ` input-comment- ${ child2 . id } ` } className = "my-2" placeholder = "Masukkan balasan anda" / >
< div className = "flex flex-row gap-3" >
< a onClick = { ( ) = > postDataChild ( child2 . id ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Kirim < / small >
< / a >
< a onClick = { ( ) = > showInput ( ` comment-id- ${ child2 . id } ` ) } >
< small className = "flex items-start bg-[#bb3523] rounded-lg w-fit text-white px-4 py-1 cursor-pointer" > Batal < / small >
< / a >
< / div >
< / div >
< / div >
) )
: "" }
< / div >
) )
: "" }
< / div >
) ) }
< / div >
2024-12-19 15:20:03 +00:00
< / div >
{ /* Konten Serupa */ }
< div className = "px-4" >
2025-01-07 17:44:23 +00:00
< NewContent group = "mabes" type = { "similar" } / >
2024-12-19 15:20:03 +00:00
< / div >
< / div >
< / >
) ;
} ;
export default DetailAudio ;