kontenhumas-fe/components/landing-page/header.tsx

193 lines
5.8 KiB
TypeScript

"use client";
import Image from "next/image";
import Link from "next/link";
import { ThumbsUp, ThumbsDown } from "lucide-react";
import { useEffect, useState } from "react";
import {
getListContent,
listData,
listArticles,
listStaticBanner,
} from "@/service/landing/landing";
import { data } from "framer-motion/client";
export default function Header() {
const [data, setData] = useState<any[]>([]);
const [selectedTab, setSelectedTab] = useState("image");
useEffect(() => {
const fetchData = async () => {
try {
// Use new Articles API
const response = await listArticles(1, 5, undefined, undefined, undefined, "createdAt");
console.log("Articles API response:", response);
if (response?.error) {
console.error("Articles API failed, falling back to old API");
// Fallback to old API
const fallbackResponse = await listData(
"",
"",
"",
5,
0,
"createdAt",
"",
"",
""
);
const content = fallbackResponse?.data?.data?.content || [];
setData(content);
return;
}
// Handle new API response structure
const articlesData = response?.data?.data || [];
console.log("Articles data:", articlesData);
// Transform articles data to match old structure for backward compatibility
const transformedData = articlesData.map((article: any) => ({
id: article.id,
title: article.title,
categoryName: article.categoryName || (article.categories && article.categories[0]?.title) || "",
createdAt: article.createdAt,
smallThumbnailLink: article.thumbnailUrl,
fileTypeId: article.typeId,
label: article.typeId === 1 ? "Image" : article.typeId === 2 ? "Video" : article.typeId === 3 ? "Text" : article.typeId === 4 ? "Audio" : "",
...article
}));
setData(transformedData);
} catch (error) {
console.error("Gagal memuat data:", error);
// Try fallback to old API if new API fails
try {
const fallbackResponse = await listData(
"",
"",
"",
5,
0,
"createdAt",
"",
"",
""
);
const content = fallbackResponse?.data?.data?.content || [];
setData(content);
} catch (fallbackError) {
console.error("Fallback API also failed:", fallbackError);
}
}
};
fetchData();
}, []);
return (
<section className="max-w-[1350px] mx-auto px-4">
<div className="flex flex-col lg:flex-row gap-6 py-6">
{data.length > 0 && <Card item={data[0]} isBig />}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 w-full">
{data.slice(1, 5).map((item) => (
<Card key={item.id} item={item} />
))}
</div>
</div>
<div className="relative w-full h-48 sm:h-64 md:h-80 lg:h-[460px] mt-4 rounded-xl">
<Image
src={"/PPS.png"}
alt={"pps"}
fill
className="object-cover rounded-xl"
/>
</div>
</section>
);
}
function Card({ item, isBig = false }: { item: any; isBig?: boolean }) {
const getLink = () => {
switch (item?.fileTypeId) {
case 1:
return `/content/image/detail/${item?.id}`;
case 2:
return `/content/video/detail/${item?.id}`;
case 3:
return `/content/text/detail/${item?.id}`;
case 4:
return `/content/audio/detail/${item?.id}`;
default:
return "#"; // fallback kalau type tidak dikenali
}
};
return (
<Link href={getLink()}>
<div
className={`rounded-xl overflow-hidden shadow hover:shadow-lg transition-all bg-white ${
isBig
? "w-full lg:max-w-[670px] lg:min-h-[680px]"
: "w-full h-[350px] md:h-[330px]"
}`}
>
<div
className={`relative ${
isBig ? "aspect-[3/2] lg:h-[525px]" : "aspect-video"
} w-full`}
>
<Image
src={item.smallThumbnailLink || "/contributor.png"}
alt={item.title}
fill
className="object-cover"
/>
</div>
<div className="p-4 space-y-2">
<div className="flex items-center gap-2 text-xs font-semibold flex-wrap">
<span className="bg-emerald-600 text-white px-2 py-0.5 rounded">
{item.categoryName}
</span>
<span className="text-orange-600">{item.label}</span>
</div>
<div className="text-xs text-gray-500">
{new Date(item.createdAt)
.toLocaleString("id-ID", {
day: "2-digit",
month: "short",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: false,
timeZone: "Asia/Jakarta",
})
.replace(".", ":")}{" "}
WIB
</div>
<h3 className="text-sm font-semibold leading-snug line-clamp-2">
{item.title}
</h3>
<div className="flex justify-between items-center pt-2">
<div className="flex gap-2 text-gray-500">
<ThumbsUp
size={18}
className="cursor-pointer hover:text-blue-600"
/>
<ThumbsDown
size={18}
className="cursor-pointer hover:text-red-600"
/>
</div>
<button className="text-sm bg-blue-600 text-white px-3 py-1 rounded-md hover:bg-blue-700">
Save
</button>
</div>
</div>
</div>
</Link>
);
}