feat(web): add public portfolio rendering and media streaming

This commit is contained in:
2026-02-12 21:43:53 +01:00
parent 1fddb6d858
commit 958f3ad723
15 changed files with 888 additions and 9 deletions

View File

@@ -9,6 +9,14 @@ import {
import { db } from "./client"
type PublicArtworkGroupType = "gallery" | "album" | "category" | "tag"
type ListPublishedArtworksInput = {
groupType?: PublicArtworkGroupType
groupSlug?: string
limit?: number
}
export async function listMediaAssets(limit = 24) {
return db.mediaAsset.findMany({
orderBy: { updatedAt: "desc" },
@@ -280,3 +288,251 @@ export async function getMediaFoundationSummary() {
tags,
}
}
export async function listPublishedPortfolioGroups() {
const [galleries, albums, categories, tags] = await Promise.all([
db.gallery.findMany({
where: {
isVisible: true,
},
orderBy: [{ sortOrder: "asc" }, { name: "asc" }],
select: {
id: true,
name: true,
slug: true,
},
}),
db.album.findMany({
where: {
isVisible: true,
},
orderBy: [{ sortOrder: "asc" }, { name: "asc" }],
select: {
id: true,
name: true,
slug: true,
},
}),
db.category.findMany({
where: {
isVisible: true,
},
orderBy: [{ sortOrder: "asc" }, { name: "asc" }],
select: {
id: true,
name: true,
slug: true,
},
}),
db.tag.findMany({
orderBy: [{ name: "asc" }],
select: {
id: true,
name: true,
slug: true,
},
}),
])
return {
galleries,
albums,
categories,
tags,
}
}
export async function listPublishedArtworks(input: ListPublishedArtworksInput = {}) {
const take = input.limit ?? 36
const where: Record<string, unknown> = {
isPublished: true,
}
if (input.groupType && input.groupSlug) {
if (input.groupType === "gallery") {
where.galleryLinks = {
some: {
gallery: {
slug: input.groupSlug,
isVisible: true,
},
},
}
} else if (input.groupType === "album") {
where.albumLinks = {
some: {
album: {
slug: input.groupSlug,
isVisible: true,
},
},
}
} else if (input.groupType === "category") {
where.categoryLinks = {
some: {
category: {
slug: input.groupSlug,
isVisible: true,
},
},
}
} else if (input.groupType === "tag") {
where.tagLinks = {
some: {
tag: {
slug: input.groupSlug,
},
},
}
}
}
return db.artwork.findMany({
where,
orderBy: [{ updatedAt: "desc" }],
take,
include: {
renditions: {
where: {
mediaAsset: {
isPublished: true,
},
},
include: {
mediaAsset: {
select: {
id: true,
title: true,
altText: true,
mimeType: true,
width: true,
height: true,
},
},
},
},
galleryLinks: {
include: {
gallery: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
albumLinks: {
include: {
album: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
categoryLinks: {
include: {
category: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
tagLinks: {
include: {
tag: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
},
})
}
export async function getPublishedArtworkBySlug(slug: string) {
return db.artwork.findFirst({
where: {
slug,
isPublished: true,
},
include: {
renditions: {
where: {
mediaAsset: {
isPublished: true,
},
},
include: {
mediaAsset: {
select: {
id: true,
title: true,
altText: true,
mimeType: true,
width: true,
height: true,
source: true,
author: true,
copyright: true,
tags: true,
},
},
},
},
galleryLinks: {
include: {
gallery: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
albumLinks: {
include: {
album: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
categoryLinks: {
include: {
category: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
tagLinks: {
include: {
tag: {
select: {
id: true,
name: true,
slug: true,
},
},
},
},
},
})
}