karbe/src/lib/admin/media.ts

60 lines
1.8 KiB
TypeScript

import "server-only";
import { Prisma } from "@/generated/prisma/client";
import { MediaType } from "@/generated/prisma/enums";
import { prisma } from "@/lib/prisma";
export type AdminMediaFilters = {
q?: string;
type?: MediaType;
carbetId?: string;
};
export type AdminMediaListItem = {
id: string;
type: MediaType;
s3Key: string;
s3Url: string;
sortOrder: number;
createdAt: Date;
carbet: { id: string; title: string; slug: string; status: string };
};
export async function listMediaAdmin(filters: AdminMediaFilters = {}): Promise<AdminMediaListItem[]> {
const where: Prisma.MediaWhereInput = {};
if (filters.q) {
where.OR = [
{ s3Key: { contains: filters.q, mode: "insensitive" } },
{ carbet: { title: { contains: filters.q, mode: "insensitive" } } },
{ carbet: { slug: { contains: filters.q, mode: "insensitive" } } },
];
}
if (filters.type) where.type = filters.type;
if (filters.carbetId) where.carbetId = filters.carbetId;
return prisma.media.findMany({
where,
orderBy: [{ createdAt: "desc" }],
take: 200,
select: {
id: true,
type: true,
s3Key: true,
s3Url: true,
sortOrder: true,
createdAt: true,
carbet: { select: { id: true, title: true, slug: true, status: true } },
},
});
}
export async function getMediaStats() {
const [total, photo, video, carbetsWithMedia, carbetsWithoutMedia] = await Promise.all([
prisma.media.count(),
prisma.media.count({ where: { type: MediaType.PHOTO } }),
prisma.media.count({ where: { type: MediaType.VIDEO } }),
prisma.carbet.count({ where: { media: { some: {} } } }),
prisma.carbet.count({ where: { media: { none: {} } } }),
]);
return { total, photo, video, carbetsWithMedia, carbetsWithoutMedia };
}