import "server-only"; import { and, asc, count, desc, eq, like, or, sql } from "drizzle-orm"; import { db, WebsiteArticles } from "@/lib/db"; export async function loadNewsArchive( options: { search?: string; page?: number; order?: string } = {}, ) { const search = (typeof options.search === "string" ? options.search : "") .trim() .slice(0, 191); const order = options.order === "oldest" ? "oldest" : "newest"; const publishedAt = sql`COALESCE(${WebsiteArticles.publishAt}, ${WebsiteArticles.createdAt})`.mapWith( WebsiteArticles.createdAt, ); const where = and( eq(WebsiteArticles.status, "published"), or( sql`${WebsiteArticles.publishAt} IS NULL`, sql`${WebsiteArticles.publishAt} <= NOW()`, ), search ? or( like(WebsiteArticles.title, `%${search}%`), like(WebsiteArticles.shortStory, `%${search}%`), ) : undefined, ); const totals = await db .select({ value: count() }) .from(WebsiteArticles) .where(where); const total = Number(totals[0]?.value ?? 0); const perPage = 24; const lastPage = Math.max(1, Math.ceil(total / perPage)); const page = Math.min( lastPage, Number.isFinite(options.page) ? Math.max(1, Math.trunc(options.page ?? 1)) : 1, ); const sort = order === "oldest" ? asc : desc; const rows = await db .select({ slug: WebsiteArticles.slug, title: WebsiteArticles.title, shortStory: WebsiteArticles.shortStory, image: WebsiteArticles.image, createdAt: publishedAt, }) .from(WebsiteArticles) .where(where) .orderBy(sort(publishedAt), sort(WebsiteArticles.id)) .limit(perPage) .offset((page - 1) * perPage); return { rows, total, page, perPage, lastPage, search, order }; }