feat(admin): Sprint 6 — /admin/media gallery + theme write-through
This commit is contained in:
parent
f9c10f151c
commit
4e6867b365
3 changed files with 208 additions and 0 deletions
60
src/lib/admin/media.ts
Normal file
60
src/lib/admin/media.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
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 };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue