qudoco-fe/app/news-services/page.tsx

100 lines
2.6 KiB
TypeScript

import Footer from "@/components/landing-page/footer";
import FloatingMenuNews from "@/components/landing-page/floating-news";
import NewsAndServicesHeader from "@/components/landing-page/headers-news-services";
import ContentLatest from "@/components/landing-page/content-latest";
import ContentPopular from "@/components/landing-page/content-popular";
import ContentCategory from "@/components/landing-page/category-content";
import {
aggregateTagStats,
fetchPublishedArticles,
type PublicArticle,
} from "@/lib/articles-public";
import {
NEWS_SERVICES_TAB_ORDER,
NEWS_TAB_TO_TYPE_ID,
type NewsServicesTab,
} from "@/constants/news-services";
import { Suspense } from "react";
function emptyByTab(): Record<NewsServicesTab, PublicArticle[]> {
return {
"audio-visual": [],
audio: [],
foto: [],
teks: [],
};
}
async function loadArticlesForTabs(options: {
sortBy: string;
sort: string;
limit: number;
title?: string;
}): Promise<Record<NewsServicesTab, PublicArticle[]>> {
const out = emptyByTab();
await Promise.all(
NEWS_SERVICES_TAB_ORDER.map(async (tab) => {
const typeId = NEWS_TAB_TO_TYPE_ID[tab];
const res = await fetchPublishedArticles({
typeId,
limit: options.limit,
sortBy: options.sortBy,
sort: options.sort,
title: options.title,
});
out[tab] = res?.items ?? [];
}),
);
return out;
}
type PageProps = {
searchParams?: Promise<{ q?: string }>;
};
export default async function NewsAndServicesPage({ searchParams }: PageProps) {
const sp = searchParams ? await searchParams : {};
const q = sp.q?.trim() || undefined;
const [latestByTab, popularByTab, wideList] = await Promise.all([
loadArticlesForTabs({
sortBy: "created_at",
sort: "desc",
limit: 8,
title: q,
}),
loadArticlesForTabs({
sortBy: "view_count",
sort: "desc",
limit: 8,
title: q,
}),
fetchPublishedArticles({
limit: 100,
page: 1,
sortBy: "view_count",
sort: "desc",
title: q,
}),
]);
const featured = (wideList?.items ?? []).slice(0, 5);
const tagStats = aggregateTagStats(wideList?.items ?? [], 8);
return (
<div className="relative min-h-screen bg-white">
<FloatingMenuNews />
<Suspense fallback={null}>
<NewsAndServicesHeader
featured={featured}
defaultSearch={q ?? ""}
/>
</Suspense>
<ContentLatest articlesByTab={latestByTab} />
<ContentPopular articlesByTab={popularByTab} />
<ContentCategory tagStats={tagStats} />
<Footer />
</div>
);
}