diff --git a/components/main/content/audio-detail.tsx b/components/main/content/audio-detail.tsx index 3040843..24cff34 100644 --- a/components/main/content/audio-detail.tsx +++ b/components/main/content/audio-detail.tsx @@ -1,158 +1,152 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import { Calendar, Eye } from "lucide-react"; import { Button } from "@/components/ui/button"; import Link from "next/link"; -import { - FaFacebookF, - FaTiktok, - FaYoutube, - FaWhatsapp, - FaInstagram, - FaTwitter, - FaCheck, - FaLink, - FaShareAlt, -} from "react-icons/fa"; import { getDetail } from "@/service/landing/landing"; +import { BarWave } from "react-cssfx-loading"; +import WaveSurfer from "wavesurfer.js"; import { getArticleDetail } from "@/service/content/content"; export default function AudioDetail({ id }: { id: number }) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); - const [copied, setCopied] = useState(false); - const [showShareMenu, setShowShareMenu] = useState(false); + const [audioLoaded, setAudioLoaded] = useState(false); + const [playing, setPlaying] = useState(false); + const [volume, setVolume] = useState(0.5); + const waveformRef = useRef(null); + const wavesurfer = useRef(null); const [selectedAudio, setSelectedAudio] = useState(0); - // Salin tautan - const handleCopyLink = async () => { - try { - await navigator.clipboard.writeText(window.location.href); - setCopied(true); - setTimeout(() => setCopied(false), 2000); - } catch (err) { - console.error("Gagal menyalin link:", err); - } - }; - - const SocialItem = ({ - icon, - label, - }: { - icon: React.ReactNode; - label: string; - }) => ( -
-
{icon}
- {label} -
- ); - + // Ambil data audio dari API lama useEffect(() => { - const fetchDetail = async () => { - try { - setLoading(true); - - // 1️⃣ Coba API baru - const res = await getArticleDetail(id); - console.log("Audio detail API response:", res); - - const article = res?.data?.data; - - if (article) { - const mappedData = { - id: article.id, - title: article.title, - description: article.description, - createdAt: article.createdAt, - clickCount: article.viewCount, - creatorGroupLevelName: article.createdByName || "Unknown", - uploadedBy: { - publisher: article.createdByName || "MABES POLRI", - }, - files: - article.files?.map((f: any) => ({ - id: f.id, - fileName: f.file_name, - url: f.file_url, - secondaryUrl: f.file_url, - fileAlt: f.file_alt, - size: f.size, - createdAt: f.created_at, - updatedAt: f.updated_at, - })) || [], - }; - setData(mappedData); - return; - } - - // 2️⃣ Fallback ke API lama - // const fallback = await getDetail(id); - // setData(fallback?.data?.data); - } catch (err) { - console.error("Gagal memuat audio:", err); - // try { - // const fallback = await getDetail(id); - // setData(fallback?.data?.data); - // } catch (err2) { - // console.error("Fallback gagal:", err2); - // } - } finally { - setLoading(false); - } + const fetchData = async () => { + setLoading(true); + const res = await getArticleDetail(id); + const detail = res?.data?.data; + if (detail) setData(detail); + setLoading(false); }; - - if (id) fetchDetail(); + fetchData(); }, [id]); - if (loading) { - return ( -
-

Memuat data audio...

-
- ); - } + // Inisialisasi WaveSurfer + useEffect(() => { + if (!data?.files?.[selectedAudio]?.url) return; - if (!data) { - return ( -
-

Data tidak ditemukan

-
- ); - } + // Hancurkan instance sebelumnya jika ada + if (wavesurfer.current) wavesurfer.current.destroy(); + + const url = data.files[selectedAudio].url; + + const options = { + container: waveformRef.current!, + waveColor: "#E0E0E0", + progressColor: "#FFC831", + cursorColor: "#000", + barWidth: 2, + barRadius: 2, + responsive: true, + height: 80, + normalize: true, + partialRender: true, + }; + + const ws = WaveSurfer.create(options); + wavesurfer.current = ws; + ws.load(url); + + ws.on("ready", () => { + setAudioLoaded(true); + ws.setVolume(volume); + }); + + ws.on("finish", () => { + setPlaying(false); + }); + + return () => { + ws.destroy(); + }; + }, [data?.files, selectedAudio]); + + const handlePlayPause = () => { + if (!wavesurfer.current) return; + wavesurfer.current.playPause(); + setPlaying(!playing); + }; + + const handleVolumeChange = (e: any) => { + const vol = parseFloat(e.target.value); + setVolume(vol); + wavesurfer.current?.setVolume(vol); + }; + + if (loading) return

Memuat audio...

; + if (!data) return

Data tidak ditemukan

; return ( -
- {/* Pemutar Audio Utama */} -
- +
+ {/* 🎵 Player */} +
+
+ + + {/* Loading sebelum waveform siap */} + {!audioLoaded && ( + + )} + + {/* Waveform */} +
+
+ + {/* Volume control */} + {audioLoaded && ( +
+ 🔊 + +
+ )}
- {/* Pilihan file audio */} -
+ {/* 🔸 Daftar File Audio */} +
{data?.files?.map((file: any, index: number) => ( ))}
- {/* Informasi artikel */} + {/* 🗓️ Informasi Artikel */}
- by {data?.uploadedBy?.publisher || "MABES POLRI"} + by {data?.uploadedBy?.userLevel?.name || "MABES POLRI"} @@ -173,65 +167,16 @@ export default function AudioDetail({ id }: { id: number }) { {data.clickCount || 0} - - Creator: {data.creatorGroupLevelName} - + Creator: {data.creatorName}
- {/* Deskripsi */} -
-
-

{data.title}

-
-

{data.description}

-
- - {/* Tombol aksi bawah */} -
-
- - COPY LINK -
-
- - SHARE - {showShareMenu && ( -
- } label="Facebook" /> - } label="TikTok" /> - } label="YouTube" /> - } label="WhatsApp" /> - } label="Instagram" /> - } label="Twitter" /> -
- )} -
-
- - - COMMENT - -
-
-
+ {/* 📝 Deskripsi */} +
+

{data.title}

+
); diff --git a/components/main/content/document-detail.tsx b/components/main/content/document-detail.tsx index 6df4662..0164a6d 100644 --- a/components/main/content/document-detail.tsx +++ b/components/main/content/document-detail.tsx @@ -70,14 +70,26 @@ export default function DocumentDetail({ id }: { id: number }) { uploadedBy: { publisher: article.createdByName || "MABES POLRI", }, + // files: + // article.files?.map((f: any) => ({ + // id: f.id, + // fileName: f.file_name, + // url: f.file_url, + // secondaryUrl: f.file_url, + // fileThumbnail: f.file_thumbnail, + // fileAlt: f.file_alt, + // size: f.size, + // createdAt: f.created_at, + // updatedAt: f.updated_at, + // })) || [], files: article.files?.map((f: any) => ({ id: f.id, - fileName: f.file_name, - url: f.file_url, - secondaryUrl: f.file_url, - fileThumbnail: f.file_thumbnail, - fileAlt: f.file_alt, + fileName: f.fileName || f.file_name, + url: f.fileUrl || f.file_url, + secondaryUrl: f.fileUrl || f.file_url, // 🟢 gunakan field yang benar + fileThumbnail: f.fileThumbnail || f.file_thumbnail, + fileAlt: f.fileAlt || f.file_alt, size: f.size, createdAt: f.created_at, updatedAt: f.updated_at, @@ -125,13 +137,45 @@ export default function DocumentDetail({ id }: { id: number }) { return (
{/* Viewer dokumen utama */} - {/*
-