2026-02-17 09:05:22 +00:00
|
|
|
import Footer from "@/components/landing-page/footer";
|
2026-04-10 20:03:46 +00:00
|
|
|
import FloatingMenuNews from "@/components/landing-page/floating-news";
|
2026-02-17 09:05:22 +00:00
|
|
|
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";
|
2026-04-10 20:03:46 +00:00
|
|
|
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";
|
2026-02-19 05:35:31 +00:00
|
|
|
import { Suspense } from "react";
|
2026-02-17 09:05:22 +00:00
|
|
|
|
2026-04-10 20:03:46 +00:00
|
|
|
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);
|
|
|
|
|
|
2026-02-17 09:05:22 +00:00
|
|
|
return (
|
|
|
|
|
<div className="relative min-h-screen bg-white">
|
|
|
|
|
<FloatingMenuNews />
|
2026-02-19 05:35:31 +00:00
|
|
|
<Suspense fallback={null}>
|
2026-04-10 20:03:46 +00:00
|
|
|
<NewsAndServicesHeader
|
|
|
|
|
featured={featured}
|
|
|
|
|
defaultSearch={q ?? ""}
|
|
|
|
|
/>
|
2026-02-19 05:35:31 +00:00
|
|
|
</Suspense>
|
2026-04-10 20:03:46 +00:00
|
|
|
<ContentLatest articlesByTab={latestByTab} />
|
|
|
|
|
<ContentPopular articlesByTab={popularByTab} />
|
|
|
|
|
<ContentCategory tagStats={tagStats} />
|
2026-02-17 09:05:22 +00:00
|
|
|
<Footer />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|