2025-09-16 08:29:07 +00:00
|
|
|
|
"use client";
|
2025-10-15 17:03:41 +00:00
|
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
|
|
import { Calendar, Eye } from "lucide-react";
|
2025-09-16 08:29:07 +00:00
|
|
|
|
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";
|
2025-10-15 17:03:41 +00:00
|
|
|
|
import { getDetail } from "@/service/landing/landing";
|
|
|
|
|
|
import { getArticleDetail } from "@/service/content/content";
|
2025-09-16 08:29:07 +00:00
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
export default function DocumentDetail({ id }: { id: number }) {
|
2025-09-16 08:29:07 +00:00
|
|
|
|
const [data, setData] = useState<any>(null);
|
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
2025-10-15 17:03:41 +00:00
|
|
|
|
const [copied, setCopied] = useState(false);
|
|
|
|
|
|
const [showShareMenu, setShowShareMenu] = useState(false);
|
2025-09-16 08:29:07 +00:00
|
|
|
|
const [selectedDoc, setSelectedDoc] = useState(0);
|
|
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
// Copy link
|
2025-09-16 08:29:07 +00:00
|
|
|
|
const handleCopyLink = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await navigator.clipboard.writeText(window.location.href);
|
|
|
|
|
|
setCopied(true);
|
|
|
|
|
|
setTimeout(() => setCopied(false), 2000);
|
|
|
|
|
|
} catch (err) {
|
2025-10-15 17:03:41 +00:00
|
|
|
|
console.error("Gagal menyalin:", err);
|
2025-09-16 08:29:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const SocialItem = ({
|
|
|
|
|
|
icon,
|
|
|
|
|
|
label,
|
|
|
|
|
|
}: {
|
|
|
|
|
|
icon: React.ReactNode;
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
}) => (
|
|
|
|
|
|
<div className="flex items-center gap-3 cursor-pointer hover:opacity-80">
|
|
|
|
|
|
<div className="bg-[#C6A455] p-2 rounded-full text-white">{icon}</div>
|
|
|
|
|
|
<span className="text-sm">{label}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
const fetchDetail = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true);
|
2025-09-17 02:47:48 +00:00
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
// 1️⃣ Coba ambil dari API baru
|
|
|
|
|
|
const res = await getArticleDetail(id);
|
|
|
|
|
|
console.log("Response artikel:", 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",
|
2025-09-17 02:47:48 +00:00
|
|
|
|
uploadedBy: {
|
2025-10-15 17:03:41 +00:00
|
|
|
|
publisher: article.createdByName || "MABES POLRI",
|
2025-09-17 02:47:48 +00:00
|
|
|
|
},
|
2025-10-15 17:03:41 +00:00
|
|
|
|
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,
|
|
|
|
|
|
})) || [],
|
2025-09-17 02:47:48 +00:00
|
|
|
|
};
|
2025-10-15 17:03:41 +00:00
|
|
|
|
setData(mappedData);
|
|
|
|
|
|
return;
|
2025-09-17 02:47:48 +00:00
|
|
|
|
}
|
2025-10-15 17:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
// 2️⃣ Fallback ke API lama
|
|
|
|
|
|
// const fallback = await getDetail(id);
|
|
|
|
|
|
// setData(fallback?.data?.data);
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.error("Gagal ambil detail:", err);
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// const fallback = await getDetail(id);
|
|
|
|
|
|
// setData(fallback?.data?.data);
|
|
|
|
|
|
// } catch (err2) {
|
|
|
|
|
|
// console.error("Fallback gagal:", err2);
|
|
|
|
|
|
// }
|
2025-09-16 08:29:07 +00:00
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2025-10-15 17:03:41 +00:00
|
|
|
|
|
2025-09-16 08:29:07 +00:00
|
|
|
|
if (id) fetchDetail();
|
|
|
|
|
|
}, [id]);
|
|
|
|
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="max-w-6xl mx-auto px-4 py-6">
|
2025-10-15 17:03:41 +00:00
|
|
|
|
<p>Memuat data...</p>
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="max-w-6xl mx-auto px-4 py-6">
|
|
|
|
|
|
<p>Data tidak ditemukan</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className="max-w-6xl mx-auto px-4 py-6 space-y-6">
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{/* Viewer dokumen utama */}
|
|
|
|
|
|
{/* <div className="relative">
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<iframe
|
2025-10-15 17:03:41 +00:00
|
|
|
|
src={data?.files?.[selectedDoc]?.secondaryUrl || ""}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
className="rounded-lg h-[300px] w-screen lg:h-[600px] lg:w-full"
|
|
|
|
|
|
/>
|
2025-10-15 17:03:41 +00:00
|
|
|
|
</div> */}
|
|
|
|
|
|
<div className="bg-[#e0c350] flex items-center justify-center h-[170px] text-white">
|
|
|
|
|
|
<svg
|
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
|
width="150"
|
|
|
|
|
|
height="150"
|
|
|
|
|
|
viewBox="0 0 16 16"
|
|
|
|
|
|
>
|
|
|
|
|
|
<path
|
|
|
|
|
|
fill="currentColor"
|
|
|
|
|
|
d="M5 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V5.414a1.5 1.5 0 0 0-.44-1.06L9.647 1.439A1.5 1.5 0 0 0 8.586 1zM4 3a1 1 0 0 1 1-1h3v2.5A1.5 1.5 0 0 0 9.5 6H12v7a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1zm7.793 2H9.5a.5.5 0 0 1-.5-.5V2.207zM7 7.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M7.5 9a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1zM7 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5M5.5 8a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1M6 9.5a.5.5 0 1 1-1 0a.5.5 0 0 1 1 0M5.5 12a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</svg>
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{/* Pilihan dokumen */}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<div className="py-4 px-1 flex flex-row gap-3 flex-wrap">
|
|
|
|
|
|
{data?.files?.map((file: any, index: number) => (
|
|
|
|
|
|
<button
|
2025-10-15 17:03:41 +00:00
|
|
|
|
key={file.id}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
onClick={() => setSelectedDoc(index)}
|
|
|
|
|
|
className={`px-4 py-2 rounded-md border cursor-pointer hover:bg-gray-100 ${
|
|
|
|
|
|
selectedDoc === index ? "border-red-600 bg-gray-50" : ""
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
📄 {file?.fileName || `Dokumen ${index + 1}`}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{/* Informasi artikel */}
|
|
|
|
|
|
<div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
|
|
|
|
|
|
<span className="font-semibold text-black border-r-2 pr-2 border-black">
|
|
|
|
|
|
by {data?.uploadedBy?.publisher || "MABES POLRI"}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span className="flex items-center gap-1 text-black">
|
|
|
|
|
|
<Calendar className="w-4 h-4" />
|
|
|
|
|
|
{new Date(data.createdAt)
|
|
|
|
|
|
.toLocaleString("id-ID", {
|
|
|
|
|
|
day: "2-digit",
|
|
|
|
|
|
month: "short",
|
|
|
|
|
|
year: "numeric",
|
|
|
|
|
|
hour: "2-digit",
|
|
|
|
|
|
minute: "2-digit",
|
|
|
|
|
|
hour12: false,
|
|
|
|
|
|
timeZone: "Asia/Jakarta",
|
|
|
|
|
|
})
|
|
|
|
|
|
.replace(".", ":")}{" "}
|
|
|
|
|
|
WIB
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span className="flex items-center gap-1 border-r-2 pr-2 border-black text-black">
|
|
|
|
|
|
<Eye className="w-4 h-4" />
|
|
|
|
|
|
{data.clickCount || 0}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
<span className="text-black">
|
|
|
|
|
|
Creator: {data.creatorGroupLevelName}
|
|
|
|
|
|
</span>
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{/* Konten deskripsi */}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<div className="flex flex-col md:flex-row gap-6 mt-6">
|
|
|
|
|
|
<div className="flex-1 space-y-4">
|
|
|
|
|
|
<h1 className="text-xl font-bold">{data.title}</h1>
|
|
|
|
|
|
<div className="text-base text-gray-700 leading-relaxed space-y-3">
|
|
|
|
|
|
<p>{data.description}</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{/* Tombol aksi bawah */}
|
|
|
|
|
|
<div className="flex flex-wrap justify-center gap-4 my-20">
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<div className="flex gap-2 items-center">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
onClick={handleCopyLink}
|
|
|
|
|
|
size="lg"
|
|
|
|
|
|
className="justify-start bg-black text-white rounded-full"
|
|
|
|
|
|
>
|
|
|
|
|
|
{copied ? <FaCheck /> : <FaLink />}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<span>COPY LINK</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex gap-2 items-center">
|
|
|
|
|
|
<Button
|
|
|
|
|
|
onClick={() => setShowShareMenu(!showShareMenu)}
|
|
|
|
|
|
size="lg"
|
|
|
|
|
|
className="justify-start bg-[#C6A455] text-white rounded-full"
|
|
|
|
|
|
>
|
|
|
|
|
|
<FaShareAlt />
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<span>SHARE</span>
|
2025-10-15 17:03:41 +00:00
|
|
|
|
{showShareMenu && (
|
|
|
|
|
|
<div className="absolute mt-10 bg-white p-4 rounded-lg shadow-lg flex flex-col gap-3 w-48 z-10">
|
|
|
|
|
|
<SocialItem icon={<FaFacebookF />} label="Facebook" />
|
|
|
|
|
|
<SocialItem icon={<FaTiktok />} label="TikTok" />
|
|
|
|
|
|
<SocialItem icon={<FaYoutube />} label="YouTube" />
|
|
|
|
|
|
<SocialItem icon={<FaWhatsapp />} label="WhatsApp" />
|
|
|
|
|
|
<SocialItem icon={<FaInstagram />} label="Instagram" />
|
|
|
|
|
|
<SocialItem icon={<FaTwitter />} label="Twitter" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
<div className="flex gap-2 items-center">
|
2025-09-17 02:47:48 +00:00
|
|
|
|
<Link href={`/content/video/comment/${id}`}>
|
2025-09-16 08:29:07 +00:00
|
|
|
|
<Button
|
|
|
|
|
|
variant="default"
|
|
|
|
|
|
size="lg"
|
|
|
|
|
|
className="justify-start bg-[#FFAD10] rounded-full mr-2 text-white"
|
|
|
|
|
|
>
|
2025-10-15 17:03:41 +00:00
|
|
|
|
💬
|
2025-09-16 08:29:07 +00:00
|
|
|
|
</Button>
|
|
|
|
|
|
COMMENT
|
|
|
|
|
|
</Link>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
2025-10-15 17:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
// "use client";
|
|
|
|
|
|
// import Image from "next/image";
|
|
|
|
|
|
// import { Calendar, Clock, Eye } from "lucide-react";
|
|
|
|
|
|
// import { Button } from "@/components/ui/button";
|
|
|
|
|
|
// import Link from "next/link";
|
|
|
|
|
|
// import { useState, useEffect } from "react";
|
|
|
|
|
|
// import {
|
|
|
|
|
|
// FaFacebookF,
|
|
|
|
|
|
// FaTiktok,
|
|
|
|
|
|
// FaYoutube,
|
|
|
|
|
|
// FaWhatsapp,
|
|
|
|
|
|
// FaInstagram,
|
|
|
|
|
|
// FaTwitter,
|
|
|
|
|
|
// FaCheck,
|
|
|
|
|
|
// FaLink,
|
|
|
|
|
|
// FaShareAlt,
|
|
|
|
|
|
// } from "react-icons/fa";
|
|
|
|
|
|
// import { getDetail, getArticleDetail } from "@/service/landing/landing";
|
|
|
|
|
|
|
|
|
|
|
|
// export default function DocumentDetail({ id }: { id: string }) {
|
|
|
|
|
|
// const [copied, setCopied] = useState(false);
|
|
|
|
|
|
// const [showShareMenu, setShowShareMenu] = useState(false);
|
|
|
|
|
|
// const [data, setData] = useState<any>(null);
|
|
|
|
|
|
// const [loading, setLoading] = useState(true);
|
|
|
|
|
|
// const [selectedDoc, setSelectedDoc] = useState(0);
|
|
|
|
|
|
// const [isLoading, setIsLoading] = useState<any>(true);
|
|
|
|
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
|
// const timer = setTimeout(() => {
|
|
|
|
|
|
// setIsLoading(false);
|
|
|
|
|
|
// }, 3000);
|
|
|
|
|
|
|
|
|
|
|
|
// return () => clearTimeout(timer);
|
|
|
|
|
|
// }, []);
|
|
|
|
|
|
|
|
|
|
|
|
// const handleCopyLink = async () => {
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// await navigator.clipboard.writeText(window.location.href);
|
|
|
|
|
|
// setCopied(true);
|
|
|
|
|
|
// setTimeout(() => setCopied(false), 2000);
|
|
|
|
|
|
// } catch (err) {
|
|
|
|
|
|
// console.error("Failed to copy: ", err);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
// const SocialItem = ({
|
|
|
|
|
|
// icon,
|
|
|
|
|
|
// label,
|
|
|
|
|
|
// }: {
|
|
|
|
|
|
// icon: React.ReactNode;
|
|
|
|
|
|
// label: string;
|
|
|
|
|
|
// }) => (
|
|
|
|
|
|
// <div className="flex items-center gap-3 cursor-pointer hover:opacity-80">
|
|
|
|
|
|
// <div className="bg-[#C6A455] p-2 rounded-full text-white">{icon}</div>
|
|
|
|
|
|
// <span className="text-sm">{label}</span>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
|
// const fetchDetail = async () => {
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// setLoading(true);
|
|
|
|
|
|
|
|
|
|
|
|
// // Try new Articles API first
|
|
|
|
|
|
// const response = await getArticleDetail(id);
|
|
|
|
|
|
// console.log("Article Detail API response:", response);
|
|
|
|
|
|
|
|
|
|
|
|
// if (response?.error) {
|
|
|
|
|
|
// console.error("Articles API failed, falling back to old API");
|
|
|
|
|
|
// // Fallback to old API
|
|
|
|
|
|
// const fallbackResponse = await getDetail(id);
|
|
|
|
|
|
// setData(fallbackResponse?.data?.data);
|
|
|
|
|
|
// console.log(
|
|
|
|
|
|
// "doc",
|
|
|
|
|
|
// fallbackResponse?.data?.data.files[selectedDoc]?.secondaryUrl
|
|
|
|
|
|
// );
|
|
|
|
|
|
// return;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// // Handle new API response structure
|
|
|
|
|
|
// const articleData = response?.data?.data;
|
|
|
|
|
|
// if (articleData) {
|
|
|
|
|
|
// // Transform article data to match old structure for backward compatibility
|
|
|
|
|
|
// const transformedData = {
|
|
|
|
|
|
// id: articleData.id,
|
|
|
|
|
|
// title: articleData.title,
|
|
|
|
|
|
// description: articleData.description,
|
|
|
|
|
|
// createdAt: articleData.createdAt,
|
|
|
|
|
|
// clickCount: articleData.viewCount,
|
|
|
|
|
|
// creatorGroupLevelName: articleData.createdByName || "Unknown",
|
|
|
|
|
|
// uploadedBy: {
|
|
|
|
|
|
// publisher: articleData.createdByName || "MABES POLRI"
|
|
|
|
|
|
// },
|
|
|
|
|
|
// files: articleData.files?.map((file: any) => ({
|
|
|
|
|
|
// id: file.id,
|
|
|
|
|
|
// url: file.file_url,
|
|
|
|
|
|
// fileName: file.file_name,
|
|
|
|
|
|
// filePath: file.file_path,
|
|
|
|
|
|
// fileThumbnail: file.file_thumbnail,
|
|
|
|
|
|
// fileAlt: file.file_alt,
|
|
|
|
|
|
// widthPixel: file.width_pixel,
|
|
|
|
|
|
// heightPixel: file.height_pixel,
|
|
|
|
|
|
// size: file.size,
|
|
|
|
|
|
// downloadCount: file.download_count,
|
|
|
|
|
|
// createdAt: file.created_at,
|
|
|
|
|
|
// updatedAt: file.updated_at,
|
|
|
|
|
|
// secondaryUrl: file.file_url, // For document files, use same URL
|
|
|
|
|
|
// ...file
|
|
|
|
|
|
// })) || [],
|
|
|
|
|
|
// ...articleData
|
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
|
|
// setData(transformedData);
|
|
|
|
|
|
// console.log(
|
|
|
|
|
|
// "doc",
|
|
|
|
|
|
// transformedData.files[selectedDoc]?.secondaryUrl
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
|
// console.error("Error fetching detail:", error);
|
|
|
|
|
|
// // Try fallback to old API if new API fails
|
|
|
|
|
|
// try {
|
|
|
|
|
|
// const fallbackResponse = await getDetail(id);
|
|
|
|
|
|
// setData(fallbackResponse?.data?.data);
|
|
|
|
|
|
// console.log(
|
|
|
|
|
|
// "doc",
|
|
|
|
|
|
// fallbackResponse?.data?.data.files[selectedDoc]?.secondaryUrl
|
|
|
|
|
|
// );
|
|
|
|
|
|
// } catch (fallbackError) {
|
|
|
|
|
|
// console.error("Fallback API also failed:", fallbackError);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// } finally {
|
|
|
|
|
|
// setLoading(false);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// };
|
|
|
|
|
|
// if (id) fetchDetail();
|
|
|
|
|
|
// }, [id]);
|
|
|
|
|
|
|
|
|
|
|
|
// if (loading) {
|
|
|
|
|
|
// return (
|
|
|
|
|
|
// <div className="max-w-6xl mx-auto px-4 py-6">
|
|
|
|
|
|
// <p>Loading...</p>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// if (!data) {
|
|
|
|
|
|
// return (
|
|
|
|
|
|
// <div className="max-w-6xl mx-auto px-4 py-6">
|
|
|
|
|
|
// <p>Data tidak ditemukan</p>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// return (
|
|
|
|
|
|
// <div className="max-w-6xl mx-auto px-4 py-6 space-y-6">
|
|
|
|
|
|
// <div className="relative">
|
|
|
|
|
|
// <iframe
|
|
|
|
|
|
// src={data?.files[selectedDoc]?.secondaryUrl}
|
|
|
|
|
|
// className="rounded-lg h-[300px] w-screen lg:h-[600px] lg:w-full"
|
|
|
|
|
|
// />
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// <div className="py-4 px-1 flex flex-row gap-3 flex-wrap">
|
|
|
|
|
|
// {data?.files?.map((file: any, index: number) => (
|
|
|
|
|
|
// <button
|
|
|
|
|
|
// key={file?.id}
|
|
|
|
|
|
// onClick={() => setSelectedDoc(index)}
|
|
|
|
|
|
// className={`px-4 py-2 rounded-md border cursor-pointer hover:bg-gray-100 ${
|
|
|
|
|
|
// selectedDoc === index ? "border-red-600 bg-gray-50" : ""
|
|
|
|
|
|
// }`}
|
|
|
|
|
|
// >
|
|
|
|
|
|
// 📄 {file?.fileName || `Dokumen ${index + 1}`}
|
|
|
|
|
|
// </button>
|
|
|
|
|
|
// ))}
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// <div className="flex flex-col md:flex-row md:items-center md:justify-between text-sm text-muted-foreground">
|
|
|
|
|
|
// <div className="flex flex-wrap items-center gap-2">
|
|
|
|
|
|
// <span className="font-semibold text-black border-r-2 pr-2 border-black">
|
|
|
|
|
|
// by {data?.uploadedBy?.publisher || "MABES POLRI"}
|
|
|
|
|
|
// </span>
|
|
|
|
|
|
// <span className="flex items-center gap-1 text-black">
|
|
|
|
|
|
// <Calendar className="w-4 h-4" />
|
|
|
|
|
|
// {new Date(data.createdAt)
|
|
|
|
|
|
// .toLocaleString("id-ID", {
|
|
|
|
|
|
// day: "2-digit",
|
|
|
|
|
|
// month: "short",
|
|
|
|
|
|
// year: "numeric",
|
|
|
|
|
|
// hour: "2-digit",
|
|
|
|
|
|
// minute: "2-digit",
|
|
|
|
|
|
// hour12: false,
|
|
|
|
|
|
// timeZone: "Asia/Jakarta",
|
|
|
|
|
|
// })
|
|
|
|
|
|
// .replace(".", ":")}{" "}
|
|
|
|
|
|
// WIB
|
|
|
|
|
|
// </span>
|
|
|
|
|
|
// {/* <span className="flex items-center gap-1 border-r-2 pr-2 border-black text-black">
|
|
|
|
|
|
// <Clock className="w-4 h-4" />
|
|
|
|
|
|
// {data.time || "-"}
|
|
|
|
|
|
// </span> */}
|
|
|
|
|
|
// <span className="flex items-center gap-1 border-r-2 pr-2 border-black text-black">
|
|
|
|
|
|
// <Eye className="w-4 h-4" />
|
|
|
|
|
|
// {data.clickCount || 0}
|
|
|
|
|
|
// </span>
|
|
|
|
|
|
// <span className="text-black">
|
|
|
|
|
|
// {" "}
|
|
|
|
|
|
// Creator: {data.creatorGroupLevelName}
|
|
|
|
|
|
// </span>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// <div className="flex flex-col md:flex-row gap-6 mt-6">
|
|
|
|
|
|
// {/* Sidebar actions */}
|
|
|
|
|
|
// <div className="hidden md:flex flex-col gap-4 relative z-10">
|
|
|
|
|
|
// <div className="flex gap-2 items-center">
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// onClick={handleCopyLink}
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-black text-white rounded-full"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// {copied ? <FaCheck /> : <FaLink />}
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// <span>COPY LINK</span>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// <div className="flex gap-2 items-center relative">
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// onClick={() => setShowShareMenu(!showShareMenu)}
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-[#C6A455] text-white rounded-full"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <FaShareAlt />
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// <span>SHARE</span>
|
|
|
|
|
|
|
|
|
|
|
|
// {showShareMenu && (
|
|
|
|
|
|
// <div className="absolute left-16 top-0 bg-white p-4 rounded-lg shadow-lg flex flex-col gap-3 w-48">
|
|
|
|
|
|
// <SocialItem icon={<FaFacebookF />} label="Facebook" />
|
|
|
|
|
|
// <SocialItem icon={<FaTiktok />} label="TikTok" />
|
|
|
|
|
|
// <SocialItem icon={<FaYoutube />} label="YouTube" />
|
|
|
|
|
|
// <SocialItem icon={<FaWhatsapp />} label="WhatsApp" />
|
|
|
|
|
|
// <SocialItem icon={<FaInstagram />} label="Instagram" />
|
|
|
|
|
|
// <SocialItem icon={<FaTwitter />} label="Twitter" />
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// )}
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// <div className="flex gap-2 items-center">
|
|
|
|
|
|
// <Link href={`/content/video/comment/${id}`}>
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// variant="default"
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-[#FFAD10] rounded-full mr-2 text-white"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <svg
|
|
|
|
|
|
// xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
|
// width="15"
|
|
|
|
|
|
// height="15"
|
|
|
|
|
|
// viewBox="0 0 24 24"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <path
|
|
|
|
|
|
// fill="currentColor"
|
|
|
|
|
|
// d="M10 3h4a8 8 0 1 1 0 16v3.5c-5-2-12-5-12-11.5a8 8 0 0 1 8-8"
|
|
|
|
|
|
// />
|
|
|
|
|
|
// </svg>
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// COMMENT
|
|
|
|
|
|
// </Link>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Content */}
|
|
|
|
|
|
// <div className="flex-1 space-y-4">
|
|
|
|
|
|
// <h1 className="text-xl font-bold">{data.title}</h1>
|
|
|
|
|
|
// <div className="text-base text-gray-700 leading-relaxed space-y-3">
|
|
|
|
|
|
// <p>{data.description}</p>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
|
|
|
|
|
|
// {/* Actions bawah */}
|
|
|
|
|
|
// <div className="flex flex-wrap md:flex-row justify-center gap-4 my-20">
|
|
|
|
|
|
// <div className="flex gap-2 items-center">
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// onClick={handleCopyLink}
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-black text-white rounded-full"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// {copied ? <FaCheck /> : <FaLink />}
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// <span>COPY LINK</span>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// <div className="flex gap-2 items-center">
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// onClick={() => setShowShareMenu(!showShareMenu)}
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-[#C6A455] text-white rounded-full"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <FaShareAlt />
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// <span>SHARE</span>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// <div className="flex gap-2 items-center">
|
|
|
|
|
|
// <Link href={`/content/video/comment/${id}`}>
|
|
|
|
|
|
// <Button
|
|
|
|
|
|
// variant="default"
|
|
|
|
|
|
// size="lg"
|
|
|
|
|
|
// className="justify-start bg-[#FFAD10] rounded-full mr-2 text-white"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <svg
|
|
|
|
|
|
// xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
|
// width="15"
|
|
|
|
|
|
// height="15"
|
|
|
|
|
|
// viewBox="0 0 24 24"
|
|
|
|
|
|
// >
|
|
|
|
|
|
// <path
|
|
|
|
|
|
// fill="currentColor"
|
|
|
|
|
|
// d="M10 3h4a8 8 0 1 1 0 16v3.5c-5-2-12-5-12-11.5a8 8 0 0 1 8-8"
|
|
|
|
|
|
// />
|
|
|
|
|
|
// </svg>
|
|
|
|
|
|
// </Button>
|
|
|
|
|
|
// COMMENT
|
|
|
|
|
|
// </Link>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// </div>
|
|
|
|
|
|
// );
|
|
|
|
|
|
// }
|