66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
import { db } from "@/lib/db";
|
|
import { comparisons, comparisonItems } from "@/lib/db/schema";
|
|
import { eq, and, desc, ilike, sql, inArray } from "drizzle-orm";
|
|
|
|
export async function GET(request: Request) {
|
|
const { searchParams } = new URL(request.url);
|
|
const page = Math.max(1, Number(searchParams.get("page")) || 1);
|
|
const limit = Math.min(100, Math.max(1, Number(searchParams.get("limit")) || 20));
|
|
const search = searchParams.get("search") || "";
|
|
const offset = (page - 1) * limit;
|
|
|
|
const conditions = [eq(comparisons.isPublic, true), eq(comparisons.status, "completed")];
|
|
if (search) {
|
|
conditions.push(ilike(comparisons.title, `%${search}%`));
|
|
}
|
|
|
|
const where = and(...conditions);
|
|
|
|
const [result, countResult] = await Promise.all([
|
|
db
|
|
.select()
|
|
.from(comparisons)
|
|
.where(where)
|
|
.orderBy(desc(comparisons.createdAt))
|
|
.limit(limit)
|
|
.offset(offset),
|
|
db
|
|
.select({ count: sql<number>`count(*)` })
|
|
.from(comparisons)
|
|
.where(where),
|
|
]);
|
|
|
|
const total = countResult[0].count;
|
|
|
|
const comparisonIds = result.map((c) => c.id);
|
|
const itemsMap: Record<string, string[]> = {};
|
|
|
|
if (comparisonIds.length > 0) {
|
|
const items = await db
|
|
.select({
|
|
comparisonId: comparisonItems.comparisonId,
|
|
name: comparisonItems.name,
|
|
})
|
|
.from(comparisonItems)
|
|
.where(inArray(comparisonItems.comparisonId, comparisonIds));
|
|
|
|
for (const item of items) {
|
|
if (!itemsMap[item.comparisonId]) itemsMap[item.comparisonId] = [];
|
|
itemsMap[item.comparisonId].push(item.name);
|
|
}
|
|
}
|
|
|
|
const data = result.map((c) => ({
|
|
id: c.id,
|
|
title: c.title,
|
|
summary: (c.summary || "").slice(0, 200),
|
|
slug: c.slug,
|
|
tags: c.tags || [],
|
|
items: itemsMap[c.id] || [],
|
|
viewCount: c.viewCount ?? 0,
|
|
createdAt: c.createdAt.toISOString(),
|
|
}));
|
|
|
|
return Response.json({ comparisons: data, total, page, limit });
|
|
}
|