120 lines
3.9 KiB
TypeScript
120 lines
3.9 KiB
TypeScript
import Link from "next/link";
|
|
import type { Metadata } from "next";
|
|
import { notFound, redirect } from "next/navigation";
|
|
import Footer from "@/components/landing-page/footer";
|
|
import LandingSiteNav from "@/components/landing-page/landing-site-nav";
|
|
import ArticleThumbnail from "@/components/landing-page/article-thumbnail";
|
|
import { ARTICLE_TYPE } from "@/constants/article-content-types";
|
|
import { fetchArticlePublic } from "@/lib/articles-public";
|
|
import { formatDate } from "@/utils/format-date";
|
|
|
|
type Props = {
|
|
params: Promise<{ idSlug: string }>;
|
|
};
|
|
|
|
function parseIdSlug(idSlug: string): { id: number; slug: string } | null {
|
|
const match = idSlug.match(/^(\d+)-(.*)$/);
|
|
if (!match) return null;
|
|
const id = parseInt(match[1], 10);
|
|
if (Number.isNaN(id)) return null;
|
|
return { id, slug: match[2] };
|
|
}
|
|
|
|
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
const { idSlug } = await params;
|
|
const parsed = parseIdSlug(idSlug);
|
|
if (!parsed) return { title: "Artikel" };
|
|
const article = await fetchArticlePublic(parsed.id);
|
|
if (!article || article.isPublish !== true) {
|
|
return { title: "Artikel tidak ditemukan" };
|
|
}
|
|
return {
|
|
title: article.title,
|
|
description:
|
|
article.description?.slice(0, 160) ||
|
|
article.title,
|
|
};
|
|
}
|
|
|
|
export default async function NewsDetailPage({ params }: Props) {
|
|
const { idSlug } = await params;
|
|
const parsed = parseIdSlug(idSlug);
|
|
if (!parsed) notFound();
|
|
|
|
const article = await fetchArticlePublic(parsed.id);
|
|
if (!article || article.isPublish !== true) notFound();
|
|
|
|
if (article.slug !== parsed.slug) {
|
|
redirect(`/news/detail/${article.id}-${article.slug}`);
|
|
}
|
|
|
|
const dateLabel = formatDate(article.publishedAt || article.createdAt);
|
|
const primaryFile = article.files?.[0];
|
|
const mediaUrl = primaryFile?.fileUrl?.trim() || "";
|
|
|
|
return (
|
|
<div className="relative min-h-screen bg-white">
|
|
<LandingSiteNav
|
|
newsHub
|
|
searchFormAction="/news-services"
|
|
searchPlaceholder="Cari berita, artikel, atau topik..."
|
|
/>
|
|
<article className="container mx-auto max-w-4xl px-6 pt-28 pb-16 md:pt-36">
|
|
<Link
|
|
href="/news-services"
|
|
className="mb-8 inline-block text-sm font-medium text-[#b07c18] hover:underline"
|
|
>
|
|
← Kembali ke Berita & Layanan
|
|
</Link>
|
|
|
|
<p className="mb-2 text-sm text-muted-foreground">
|
|
{dateLabel}
|
|
{article.categoryName ? ` · ${article.categoryName}` : ""}
|
|
</p>
|
|
|
|
<h1 className="mb-8 text-3xl font-bold leading-tight md:text-4xl">
|
|
{article.title}
|
|
</h1>
|
|
|
|
<div className="relative mb-10 h-[320px] w-full overflow-hidden rounded-2xl md:h-[420px]">
|
|
<ArticleThumbnail
|
|
src={article.thumbnailUrl}
|
|
alt={article.title}
|
|
sizes="(max-width: 896px) 100vw, 896px"
|
|
/>
|
|
</div>
|
|
|
|
{article.typeId === ARTICLE_TYPE.VIDEO && mediaUrl ? (
|
|
<div className="mb-10">
|
|
<video
|
|
src={mediaUrl}
|
|
controls
|
|
className="w-full max-w-3xl rounded-xl bg-black"
|
|
/>
|
|
</div>
|
|
) : null}
|
|
|
|
{article.typeId === ARTICLE_TYPE.AUDIO && mediaUrl ? (
|
|
<div className="mb-10">
|
|
<audio src={mediaUrl} controls className="w-full max-w-xl" />
|
|
</div>
|
|
) : null}
|
|
|
|
{article.description ? (
|
|
<p className="mb-8 text-lg leading-relaxed text-gray-700">
|
|
{article.description}
|
|
</p>
|
|
) : null}
|
|
|
|
{article.htmlDescription ? (
|
|
<div
|
|
className="max-w-none space-y-4 text-gray-800 [&_a]:text-[#b07c18] [&_a]:underline [&_img]:max-w-full [&_img]:rounded-lg [&_p]:leading-relaxed"
|
|
dangerouslySetInnerHTML={{ __html: article.htmlDescription }}
|
|
/>
|
|
) : null}
|
|
</article>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|