115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import React from "react";
|
||
|
|
import Link from "next/link";
|
||
|
|
import { useQuery } from "@tanstack/react-query";
|
||
|
|
import newsApi from "@/shared/services/news";
|
||
|
|
import { Button } from "@/shared/components/button/button";
|
||
|
|
import { NewsMainCard } from "./news-main-card";
|
||
|
|
import { NewsSecondaryCard } from "./news-secondary-card";
|
||
|
|
import {
|
||
|
|
NewsMainCardSketelon,
|
||
|
|
NewsSecondaryCardSkeleton,
|
||
|
|
} from "./_components/news-card-skeleton";
|
||
|
|
import Image from "next/image";
|
||
|
|
import { ErrorState } from "@/shared/components/error-state";
|
||
|
|
|
||
|
|
export function NewsSection() {
|
||
|
|
const {
|
||
|
|
data: news,
|
||
|
|
isLoading,
|
||
|
|
isError,
|
||
|
|
error,
|
||
|
|
isSuccess,
|
||
|
|
refetch,
|
||
|
|
isFetching,
|
||
|
|
} = useQuery({
|
||
|
|
queryKey: ["news"],
|
||
|
|
queryFn: () =>
|
||
|
|
newsApi
|
||
|
|
.getNewsList(
|
||
|
|
{
|
||
|
|
limit: 5,
|
||
|
|
filter: ["is_active=true"],
|
||
|
|
},
|
||
|
|
{ skipAuth: true },
|
||
|
|
)
|
||
|
|
.then((res) => res.items),
|
||
|
|
staleTime: 5000,
|
||
|
|
retry: 1,
|
||
|
|
});
|
||
|
|
|
||
|
|
const showSkeleton = isLoading || (isFetching && !isSuccess);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<section
|
||
|
|
id="news"
|
||
|
|
className="bg-biru-300 font-onest relative mt-40 min-h-[540px] py-18"
|
||
|
|
>
|
||
|
|
<Image
|
||
|
|
src={"/landing/ornaments/ornament2.webp"}
|
||
|
|
alt="ornament"
|
||
|
|
width={340}
|
||
|
|
height={340}
|
||
|
|
className="absolute bottom-0 left-0 mix-blend-overlay"
|
||
|
|
/>
|
||
|
|
<div className="@container relative container">
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<div className="flex flex-col justify-start gap-y-2">
|
||
|
|
<div className="flex items-center text-white">
|
||
|
|
<div className="h-8 w-1 rounded-full bg-white"></div>
|
||
|
|
<h2 className="font-onest ms-3 text-3xl font-bold">
|
||
|
|
Berita & Pengumuman
|
||
|
|
</h2>
|
||
|
|
</div>
|
||
|
|
<p className="text-md text-white">
|
||
|
|
Informasi terbaru seputar perkembangan data geospasial Jawa
|
||
|
|
Timur
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<Link href="/news">
|
||
|
|
<Button variant={"whiteOutlined"}>Lihat Semua</Button>
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
{(() => {
|
||
|
|
if (showSkeleton) {
|
||
|
|
return (
|
||
|
|
<div className="mt-8 grid gap-8 md:grid-cols-2 lg:grid-cols-3 lg:grid-rows-2">
|
||
|
|
<div className="lg:col-span-2 lg:row-span-2">
|
||
|
|
<NewsMainCardSketelon />
|
||
|
|
</div>
|
||
|
|
<NewsSecondaryCardSkeleton />
|
||
|
|
<NewsSecondaryCardSkeleton />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isError) {
|
||
|
|
return <ErrorState message={error?.message} onRetry={refetch} />;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isSuccess && (!news || news.length === 0)) {
|
||
|
|
return (
|
||
|
|
<div className="mt-6 rounded-xl border border-zinc-200 bg-white p-6 text-zinc-600">
|
||
|
|
Belum ada berita untuk ditampilkan.
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (isSuccess && news && news.length > 0) {
|
||
|
|
return (
|
||
|
|
<div className="mt-8 grid gap-8 md:grid-cols-2 lg:grid-cols-3 lg:grid-rows-2">
|
||
|
|
<NewsMainCard news={news[0]} />
|
||
|
|
<NewsSecondaryCard news={news[1]} />
|
||
|
|
<NewsSecondaryCard news={news[2]} />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
})()}
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|