Files
v2.app.gaertan.art/src/actions/portfolio/getPortfolioArtworksMeta.ts
2026-01-31 16:04:29 +01:00

77 lines
2.2 KiB
TypeScript

"use server";
import type { PortfolioFilters } from "@/actions/portfolio/getPortfolioArtworksPage";
import type { Prisma } from "@/generated/prisma/browser";
import { prisma } from "@/lib/prisma";
function coerceYear(y: PortfolioFilters["year"]) {
if (y === "all" || y == null) return null;
if (typeof y === "number") return Number.isFinite(y) ? y : null;
return null;
}
function normQ(q?: string | null) {
const s = (q ?? "").trim();
return s.length ? s : null;
}
export async function getPortfolioArtworksMeta(args: {
filters: PortfolioFilters;
onlyPublished?: boolean;
}): Promise<{
total: number;
years: number[];
albums: Array<{ id: string; name: string }>;
}> {
const { filters, onlyPublished = true } = args;
const year = coerceYear(filters.year);
const q = normQ(filters.q);
const albumId = filters.albumId && filters.albumId !== "all" ? filters.albumId : null;
const baseWhere: Prisma.ArtworkWhereInput = {
...(onlyPublished ? { published: true } : {}),
...(year != null ? { year } : {}),
...(albumId ? { albums: { some: { id: albumId } } } : {}),
variants: { some: { type: "thumbnail" } },
};
const where: Prisma.ArtworkWhereInput = q
? {
AND: [
baseWhere,
{
OR: [
{ name: { contains: q, mode: "insensitive" } },
{ slug: { contains: q, mode: "insensitive" } },
{ altText: { contains: q, mode: "insensitive" } },
{ tags: { some: { name: { contains: q, mode: "insensitive" } } } },
{ albums: { some: { name: { contains: q, mode: "insensitive" } } } },
],
},
],
}
: baseWhere;
const [total, yearsRaw, albums] = await Promise.all([
prisma.artwork.count({ where }),
prisma.artwork.findMany({
where: { ...(onlyPublished ? { published: true } : {}) },
distinct: ["year"],
select: { year: true },
orderBy: [{ year: "desc" }],
}),
prisma.album.findMany({
orderBy: [{ sortIndex: "asc" }, { name: "asc" }],
select: { id: true, name: true },
}),
]);
const years = yearsRaw
.map((r) => r.year)
.filter((y): y is number => typeof y === "number")
.sort((a, b) => b - a);
return { total, years, albums };
}