Files
comparaison/src/app/actions/comparison.ts

116 lines
3.0 KiB
TypeScript

"use server";
import { db } from "@/lib/db";
import { comparisons, comparisonItems } from "@/lib/db/schema";
import type { ComparisonData } from "@/lib/types";
import { eq, desc, and } from "drizzle-orm";
import { createId } from "@paralleldrive/cuid2";
export async function createComparison(formData: FormData) {
const query = formData.get("query") as string;
const itemsRaw = formData.get("items") as string;
if (!query || !itemsRaw) {
return { error: "Query and items are required" };
}
const items: string[] = JSON.parse(itemsRaw);
if (!Array.isArray(items) || items.length < 2) {
return { error: "At least 2 items are required" };
}
const id = createId();
const title =
(formData.get("title") as string) ||
`Comparing ${items.join(" vs ")}`;
const slug =
title
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-|-$/g, "")
.slice(0, 200) + `-${id.slice(-6)}`;
await db.insert(comparisons).values({
id,
userId: "system",
title,
query,
slug,
status: "researching",
});
return { id, slug };
}
export async function getComparison(
slug: string
): Promise<ComparisonData | null> {
const result = await db
.select()
.from(comparisons)
.where(eq(comparisons.slug, slug))
.limit(1);
if (!result.length) return null;
const comparison = result[0];
const items = await db
.select()
.from(comparisonItems)
.where(eq(comparisonItems.comparisonId, comparison.id))
.orderBy(comparisonItems.order);
return {
id: comparison.id,
userId: comparison.userId || "",
title: comparison.title,
query: comparison.query || "",
slug: comparison.slug,
status: comparison.status as ComparisonData["status"],
summary: comparison.summary || "",
items: items.map((item) => ({
name: item.name,
description: item.description || "",
overallScore:
(item.scores as Record<string, unknown>)?.overallScore as number ?? 0,
dimensions:
(item.scores as Record<string, unknown>)?.dimensions as Record<
string,
{ score: number; summary: string; details: string; pros?: string[]; cons?: string[] }
> ?? {},
pros: item.pros || [],
cons: item.cons || [],
})),
dimensions:
(comparison.overallData as Record<string, unknown>)?.dimensions as string[] ??
[],
tags: comparison.tags || [],
isPublic: comparison.isPublic ?? false,
viewCount: comparison.viewCount ?? 0,
createdAt: comparison.createdAt.toISOString(),
updatedAt: comparison.updatedAt.toISOString(),
};
}
export async function getUserComparisons(userId: string) {
return db
.select()
.from(comparisons)
.where(eq(comparisons.userId, userId))
.orderBy(desc(comparisons.createdAt));
}
export async function getPublicComparisons(limit = 20) {
return db
.select()
.from(comparisons)
.where(
and(
eq(comparisons.isPublic, true),
eq(comparisons.status, "completed")
)
)
.orderBy(desc(comparisons.createdAt))
.limit(limit);
}