77 lines
2.2 KiB
TypeScript
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 };
|
|
}
|