web-humas-fe/components/landing/HeaderNews.tsx

468 lines
18 KiB
TypeScript

"use client";
import {
Button,
Card,
CardFooter,
CircularProgress,
ScrollShadow,
Skeleton,
} from "@heroui/react";
import { ChevronLeftIcon, ChevronRightIcon, EyeIcon } from "../icons";
import { Swiper, SwiperSlide, useSwiper } from "swiper/react";
import "swiper/css";
import "swiper/css/navigation";
import { Autoplay, Pagination, Navigation, Controller } from "swiper/modules";
import Link from "next/link";
import GPRKominfo from "../ui/social-media/gpr-kominfo";
import { useEffect, useState } from "react";
import { getListArticle } from "@/services/article";
import { convertDateFormat, textEllipsis } from "@/utils/global";
import { useTranslations } from "next-intl";
import { data } from "autoprefixer";
import { Controller as FormController } from "react-hook-form";
import { Nabla } from "next/font/google";
import Image from "next/image";
export default function HeaderNews() {
const [article, setArticle] = useState<any>([]);
// const t = useTranslations("Landing");
const [selectedTab, setSelectedTab] = useState("media");
const [hotNews, setHotNews] = useState<any>([]);
const [banner, setBanner] = useState<any>([]);
// useEffect(() => {
// }, []);
useEffect(() => {
getArticle();
getBanner();
getHotNews();
}, []);
async function getArticle() {
const req = {
page: 1,
search: "",
limit: "10",
sort: "desc",
isPublish: true,
};
const response = await getListArticle(req);
setArticle(response?.data?.data);
}
async function getBanner() {
const req = {
page: 1,
search: "",
limit: "10",
sort: "desc",
isPublish: true,
isBanner: true,
};
const response = await getListArticle(req);
setBanner(response?.data?.data);
}
async function getHotNews() {
const req = {
page: 1,
search: "",
limit: "10",
sortBy: "view_count",
sort: "desc",
category: "586",
isPublish: true,
};
const response = await getListArticle(req);
setHotNews(response?.data?.data);
}
const [portraitMap, setPortraitMap] = useState<any>({});
const handleImageLoad = (e: any, index: number) => {
const { naturalWidth, naturalHeight } = e.target;
const isPortrait = naturalHeight > naturalWidth;
setPortraitMap((prev: any) => ({
...prev,
[index]: isPortrait,
}));
};
return (
<div className="w-full">
<div className="flex flex-col lg:flex-row gap-3 lg:gap-8 bg-white dark:bg-black p-1 lg:p-8 lg:h-[540px] w-full lg:w-[75%] lg:mx-auto">
<div className="lg:hidden w-[90%] h-[200px] md:h-[400px] mx-auto mt-1">
{hotNews?.length > 0 ? (
<Swiper
centeredSlides={true}
autoplay={{
delay: 5000,
disableOnInteraction: false,
}}
navigation={true}
className="mySwiper"
modules={[Autoplay, Controller, Navigation]}
onSwiper={(swiper) => {
swiper.navigation.nextEl?.classList.add(
"bg-white/70",
"!text-black",
"rounded-full",
"!w-[32px]",
"!h-[32px]"
);
swiper.navigation.prevEl?.classList.add(
"bg-white/70",
"!text-black",
"rounded-full",
"!w-[32px]",
"!h-[32px]"
);
}}
>
{hotNews?.map((newsItem: any, index: number) => (
<SwiperSlide
key={newsItem?.id}
className="!w-full h-[200px] md:h-[400px]"
>
<Card
isFooterBlurred
radius="lg"
className="border-none h-[200px] md:h-[400px] shadow-none dark:bg-stone-800 bg-[#f0f0f0]"
>
<div className="relative w-full h-[200px] md:h-[400px]">
<Image
alt="headernews"
width={480}
height={480}
onLoad={(e) => handleImageLoad(e, index)}
src={
newsItem?.thumbnailUrl === ""
? "/no-image.jpg"
: newsItem?.thumbnailUrl
}
className={`!object-cover !rounded-none ${
portraitMap[index]
? "!w-auto object-cover mx-auto"
: "!w-[90vw]"
} !h-[200px] md:!h-[400px]`}
/>
<div className="absolute inset-0 bg-black/20 flex items-center justify-center text-white text-lg font-semibold"></div>
</div>
<CardFooter className="mb-1 max-h-[50px] before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 absolute bottom-0 before:rounded-xl rounded-large w-[calc(100%_-_8px)] shadow-small ml-1 z-10">
<div className="text-white py-1">
<Link
href={`news/detail/${newsItem.id}-${newsItem?.slug}`}
>
<p className="text-left font-semibold text-sm">
{textEllipsis(newsItem.title, 40)}
</p>
</Link>
<p className="py-[2px] text-left text-xs">
{convertDateFormat(newsItem.createdAt)} WIB
</p>
<p className="flex items-center gap-1 text-xs">
<EyeIcon className="text-white" />
{newsItem.viewCount === null ? 0 : newsItem.viewCount}
</p>
</div>
</CardFooter>
</Card>
</SwiperSlide>
))}
</Swiper>
) : (
<Skeleton className="rounded-lg">
<div className="w-full !h-[500px] rounded-lg bg-default-300" />
</Skeleton>
)}
</div>
<div className="w-[90%] lg:w-[25%] p-2 dark:bg-stone-800 bg-[#f0f0f0] dark:text-white text-black rounded-xl mb-2 md:mb-0 h-[40vh] lg:h-[500px] mx-auto">
<p className="text-base font-bold text-center dark:text-white text-black">
Hot Topik
</p>
<ScrollShadow hideScrollBar className="h-[29vh] lg:h-[400px] ">
{hotNews?.length > 0 ? (
hotNews?.map((data: any, index: number) => (
<div
className="text-xs text-left m-2 p-2 dark:bg-[#1E1616] bg-white rounded-md flex flex-row gap-2"
key={data?.id}
>
<div>
<Link
href={`/news/detail/${data?.id}-${data?.slug}`}
className="lg:hidden"
>
{textEllipsis(data.title, 40)}
</Link>
<Link
href={`/news/detail/${data?.id}-${data?.slug}`}
key={data?.id}
className="hidden lg:block"
>
{textEllipsis(data.title, 66)}
</Link>
<div className="flex flex-row gap-2 text-[10px]">
<p className="py-[2px]">
{convertDateFormat(data.createdAt)} WIB
</p>
<p className="flex items-center gap-1">
<EyeIcon size={14} />
{data.viewCount === null ? 0 : data.viewCount}
</p>
</div>
</div>
</div>
))
) : (
<div className="flex flex-col gap-2">
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
</div>
)}
</ScrollShadow>
<div className="m-2">
<Link href="/news/all?category_id=586">
<Button
className="w-full bg-gradient-to-r from-red-700 to-[#bb3523] text-white font-bold rounded-md focus:outline-none"
radius="none"
>
{/* {t("semua")} */}
Lihat Semua
</Button>
</Link>
</div>
</div>
<div className="hidden lg:block w-full lg:w-[50%] h-[500px]">
{hotNews?.length > 0 ? (
<Swiper
centeredSlides={true}
autoplay={{
delay: 5000,
disableOnInteraction: false,
}}
navigation={true}
modules={[Autoplay, Controller, Navigation]}
className="mySwiper"
onSwiper={(swiper) => {
swiper.navigation.nextEl?.classList.add(
"bg-white/70",
"!text-black",
"rounded-full",
"!w-[40px]",
"!h-[40px]"
);
swiper.navigation.prevEl?.classList.add(
"bg-white/70",
"!text-black",
"rounded-full",
"!w-[40px]",
"!h-[40px]"
);
}}
>
{hotNews?.map((newsItem: any, index: number) => (
<SwiperSlide key={newsItem?.id} className="!w-full h-[50vh]">
<Card
isFooterBlurred
radius="lg"
className="border-none h-[50vh] lg:h-[500px] shadow-none dark:bg-stone-800 bg-[#f0f0f0]"
>
<div className="relative w-full h-[50vh] lg:h-[500px]">
<Image
alt="headernews"
width={1080}
height={1080}
onLoad={(e) => handleImageLoad(e, index)}
src={
newsItem?.thumbnailUrl === ""
? "/no-image.jpg"
: newsItem?.thumbnailUrl + "?isBanner=true"
}
className={`!object-cover !rounded-none ${
portraitMap[index]
? "!w-auto object-cover mx-auto"
: "!w-full"
} !h-[500px]`}
/>
<div className="absolute inset-0 bg-black/20 flex items-center justify-center text-white text-lg font-semibold"></div>
</div>
<CardFooter className="mb-1 max-h-[20vh] before:bg-white/10 border-white/20 border-1 overflow-hidden py-1 md:absolute before:rounded-xl rounded-large bottom-1 w-[calc(100%_-_8px)] shadow-small ml-1 z-10">
<div className="text-white">
<Link
href={`news/detail/${newsItem.id}-${newsItem?.slug}`}
>
<p className="text-left font-semibold text-lg lg:text-2xl">
{newsItem.title}
</p>
</Link>
<div className="flex flex-row gap-1">
<p className="py-[2px] text-left text-sm">
{convertDateFormat(newsItem.createdAt)} WIB
</p>
<p className="flex items-center gap-1 text-sm">
<EyeIcon />
{newsItem.viewCount === null
? 0
: newsItem.viewCount}
</p>
</div>
</div>
</CardFooter>
</Card>
</SwiperSlide>
))}
</Swiper>
) : (
<Skeleton className="rounded-lg">
<div className="w-full !h-[500px] rounded-lg bg-default-300" />
</Skeleton>
)}
</div>
<div className="w-[90%] lg:w-[25%] h-[50vh] lg:h-[500px] rounded-md text-white dark:text-black mx-auto lg:mx-0">
{selectedTab === "media" ? (
<div className="lg:h-[500px] p-2 dark:bg-stone-800 bg-[#f0f0f0] text-black dark:text-white rounded-lg">
<div className="text-sm flex flex-row gap-3 mx-2 mb-2">
<a
onClick={() => setSelectedTab("media")}
className={
"text-black dark:text-white border-b-3 border-red-400 cursor-pointer p-0"
}
>
{/* {t("terkini")} */}
Berita Terkini
</a>
<a
onClick={() => setSelectedTab("video")}
className={"text-slate-300 cursor-pointer"}
>
Video Virtual
</a>
</div>
<ScrollShadow hideScrollBar className="h-[39vh] lg:h-[400px]">
{article.length > 0 ? (
article.map((list: any, index: number) => (
<div
key={list?.id}
className="text-xs text-left m-2 p-2 dark:bg-[#1E1616] bg-white rounded-md"
>
<Link href={`news/detail/${list?.id}`}>
<p className="text-left font-semibold">{list?.title}</p>
</Link>
<div className="flex flex-row gap-1">
<p className="py-[2px] text-left text-xs">
{convertDateFormat(list?.createdAt)} WIB
</p>
<p className="flex items-center gap-1 text-xs">
<EyeIcon />
{list?.viewCount === null ? 0 : list?.viewCount}
</p>
</div>
</div>
))
) : (
<div className="flex flex-col gap-2">
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
<Skeleton className="rounded-lg">
<div className="h-16 rounded-lg bg-default-300" />
</Skeleton>
</div>
)}
</ScrollShadow>
<Link href="/news/all">
<Button
className="w-full bg-gradient-to-r from-red-700 to-[#bb3523] text-white font-bold rounded-md focus:outline-none"
radius="none"
>
Lihat Semua
</Button>
</Link>
</div>
) : (
<div className="lg:!h-[50vh] p-2 dark:bg-stone-800 bg-[#f0f0f0] text-black dark:text-white rounded-lg">
<div className="text-sm flex flex-row gap-3 mx-2 mb-2">
<a
className={"text-slate-300 cursor-pointer"}
onClick={() => setSelectedTab("media")}
>
{/* {t("terkini")} */}
Berita Terkini
</a>
<a
onClick={() => setSelectedTab("video")}
className={
"text-black dark:text-white border-b-3 border-red-400 cursor-pointer p-0"
}
>
Video Virtual
</a>
</div>
<ScrollShadow hideScrollBar className="h-[39vh]">
<div className="p-2 flex flex-col gap-2 text-sm">
<Link
target="_blank"
href="https://www.youtube.com/watch?v=6_g_PyiFcNo"
className="dark:bg-[#1E1616] bg-white rounded-lg p-3 text-xs"
>
IKLAN LAYANAN MASYARAKAT DIVHUMAS POLRI - POLRI PRESISI
UNTUK INDONESIA
</Link>
<Link
target="_blank"
href="https://www.youtube.com/watch?v=p0AJEwvJ7gU"
className="dark:bg-[#1E1616] bg-white rounded-lg p-3 text-xs"
>
ILM DIVHUMAS POLRI - POLRI PRESISI MENGAWAL PROSES VAKSINASI
UNTUK MENGATASI PANDEMI COVID 19
</Link>
<Link
target="_blank"
href="https://www.youtube.com/watch?v=jaihQPjxcy4"
className="dark:bg-[#1E1616] bg-white rounded-lg p-3 text-xs"
>
IKLAN LAYANAN MASYARAKAT DIVHUMAS POLRI - INDONESIA MENOLAK
RADIKALISME
</Link>
<Link
target="_blank"
href="https://www.youtube.com/watch?v=umPEo0FYTQk"
className="dark:bg-[#1E1616] bg-white rounded-lg p-3 text-xs"
>
IKLAN LAYANAN MASYARAKAT DIVHUMAS POLRI - BHABINKAMTIBMAS
SAHABAT MASYARAKAT
</Link>
</div>
</ScrollShadow>
</div>
)}
</div>
</div>
</div>
);
}