mediahub-fe/components/landing-page/all-content-page.tsx

209 lines
5.9 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { listDataRegional } from "@/service/landing/landing";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
interface ContentItem {
id: number;
slug: string;
title: string;
thumbnailLink?: string;
categoryName?: string;
}
interface RegionOrSatker {
name: string;
slug: string;
logo: string;
}
interface AllContentPageProps {
typeId: string; // 1 = image, 2 = video, 3 = text, 4 = audio
title: string;
basePath: "image" | "video" | "document" | "audio";
mode: "polda" | "satker";
dataList: RegionOrSatker[];
}
export default function AllContentPage({
typeId,
title,
basePath,
mode,
dataList,
}: AllContentPageProps) {
const [contents, setContents] = useState<Record<string, ContentItem[]>>({});
useEffect(() => {
async function fetchData() {
const promises = dataList.map(async (region) => {
try {
const res = await listDataRegional(
typeId,
"",
"",
"",
"",
"",
"",
"",
"",
10,
0,
"createdAt"
);
return { slug: region.slug, data: res?.data?.data?.content || [] };
} catch {
return { slug: region.slug, data: [] };
}
});
const resultsArray = await Promise.all(promises);
const results: Record<string, ContentItem[]> = {};
resultsArray.forEach((r) => {
results[r.slug] = r.data;
});
setContents(results);
}
fetchData();
}, [typeId, dataList]);
function renderCard(item: ContentItem, regionSlug: string) {
const href = `/${mode}/${regionSlug}/${basePath}/detail/${item.slug}`;
if (basePath === "image" || basePath === "video") {
return (
<Link
href={href}
className="block border rounded-md overflow-hidden hover:shadow-md transition"
>
{item.thumbnailLink && (
<Image
src={item.thumbnailLink}
alt={item.title}
width={400}
height={250}
className="w-full h-40 object-cover"
/>
)}
<div className="p-2 text-sm font-medium truncate">{item.title}</div>
</Link>
);
}
if (basePath === "document") {
return (
<Link
href={href}
className="cursor-pointer rounded-lg shadow-md overflow-hidden bg-white dark:bg-black dark:border dark:border-gray-500 block"
>
<div className="bg-[#e0c350] flex items-center justify-center h-[170px] text-white">
<svg
xmlns="http://www.w3.org/2000/svg"
width="80"
height="80"
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.4a1.5 1.5 0 0 0-.44-1.06L9.6 1.4A1.5 1.5 0 0 0 8.6 1z"
/>
</svg>
</div>
<div className="p-4">
<div className="text-[12px] font-bold text-red-600 uppercase">
{item.categoryName?.toUpperCase() ?? "Document"}
</div>
<div className="font-semibold text-gray-900 dark:text-white text-xl leading-snug line-clamp-3">
{item.title}
</div>
</div>
</Link>
);
}
if (basePath === "audio") {
return (
<Link
href={href}
className="cursor-pointer bg-white dark:bg-black dark:border dark:border-gray-500 rounded-xl shadow-md hover:shadow-lg transition overflow-hidden block"
>
<div className="flex items-center justify-center bg-[#bb3523] w-full h-[170px] text-white">
<svg
xmlns="http://www.w3.org/2000/svg"
width="80"
height="80"
viewBox="0 0 20 20"
>
<path
fill="currentColor"
d="M14.7 2.2A1 1 0 0 1 16 3.2v6L8 11v6.5a2.5 2.5 0 1 1-1-2V5.4a1 1 0 0 1 .7-1z"
/>
</svg>
</div>
<div className="p-4">
<p className="text-[12px] font-bold text-[#bb3523] uppercase mb-1">
{item.categoryName?.toUpperCase() ?? "Audio"}
</p>
<p className="text-xl font-semibold text-black dark:text-white line-clamp-3">
{item.title}
</p>
</div>
</Link>
);
}
}
return (
<div className="max-w-7xl mx-auto px-4 py-8">
<h1 className="text-2xl font-bold mb-6">{title}</h1>
{dataList.map((region) => (
<div key={region.slug} className="mb-12">
{/* Header */}
<div className="flex items-center gap-3 mb-4">
<Image
src={region.logo}
alt={region.name}
width={40}
height={40}
className="rounded-full"
/>
<h2 className="text-lg font-semibold">{region.name}</h2>
</div>
{/* Carousel Konten */}
{contents[region.slug]?.length > 0 ? (
<Carousel className="w-full">
<CarouselContent>
{contents[region.slug].map((item) => (
<CarouselItem
key={item.id}
className="basis-2/3 md:basis-1/3 lg:basis-1/4"
>
{renderCard(item, region.slug)}
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
) : (
<p className="text-gray-500">Tidak ada konten di {region.name}</p>
)}
</div>
))}
</div>
);
}