100 lines
3.1 KiB
JavaScript
100 lines
3.1 KiB
JavaScript
import { prisma } from '../../lib/prisma.js'
|
|
|
|
const MAX_SLIDES = 20
|
|
|
|
export async function registerCatalogSliderRoutes(fastify) {
|
|
fastify.get('/api/catalog-slider', async () => {
|
|
const slides = await prisma.catalogSliderSlide.findMany({
|
|
orderBy: { sortOrder: 'asc' },
|
|
include: { galleryImage: true },
|
|
})
|
|
return {
|
|
slides: slides.map((s) => ({
|
|
id: s.id,
|
|
url: s.galleryImage.url,
|
|
caption: s.caption,
|
|
})),
|
|
}
|
|
})
|
|
|
|
fastify.get(
|
|
'/api/admin/catalog-slider',
|
|
{ preHandler: [fastify.verifyAdmin] },
|
|
async () => {
|
|
const slides = await prisma.catalogSliderSlide.findMany({
|
|
orderBy: { sortOrder: 'asc' },
|
|
include: { galleryImage: true },
|
|
})
|
|
return {
|
|
slides: slides.map((s) => ({
|
|
id: s.id,
|
|
galleryImageId: s.galleryImageId,
|
|
url: s.galleryImage.url,
|
|
caption: s.caption,
|
|
})),
|
|
}
|
|
},
|
|
)
|
|
|
|
fastify.put(
|
|
'/api/admin/catalog-slider',
|
|
{ preHandler: [fastify.verifyAdmin] },
|
|
async (request, reply) => {
|
|
const body = request.body ?? {}
|
|
const rawSlides = body.slides
|
|
if (!Array.isArray(rawSlides)) {
|
|
return reply.code(400).send({ error: 'Ожидается slides: массив' })
|
|
}
|
|
if (rawSlides.length > MAX_SLIDES) {
|
|
return reply.code(400).send({ error: `Не более ${MAX_SLIDES} слайдов` })
|
|
}
|
|
|
|
const seenGalleryIds = new Set()
|
|
const normalized = []
|
|
for (let i = 0; i < rawSlides.length; i++) {
|
|
const row = rawSlides[i]
|
|
const galleryImageId = String(row?.galleryImageId ?? '').trim()
|
|
if (!galleryImageId) {
|
|
return reply.code(400).send({ error: `Слайд ${i + 1}: укажите galleryImageId` })
|
|
}
|
|
if (seenGalleryIds.has(galleryImageId)) {
|
|
return reply.code(400).send({ error: 'Одно изображение нельзя добавить дважды' })
|
|
}
|
|
seenGalleryIds.add(galleryImageId)
|
|
const img = await prisma.galleryImage.findUnique({ where: { id: galleryImageId } })
|
|
if (!img) {
|
|
return reply.code(400).send({ error: `Изображение не найдено: ${galleryImageId}` })
|
|
}
|
|
const caption = row?.caption == null ? '' : String(row.caption).slice(0, 500)
|
|
normalized.push({ galleryImageId, caption, sortOrder: i })
|
|
}
|
|
|
|
await prisma.$transaction(async (tx) => {
|
|
await tx.catalogSliderSlide.deleteMany({})
|
|
for (const n of normalized) {
|
|
await tx.catalogSliderSlide.create({
|
|
data: {
|
|
sortOrder: n.sortOrder,
|
|
caption: n.caption,
|
|
galleryImageId: n.galleryImageId,
|
|
},
|
|
})
|
|
}
|
|
})
|
|
|
|
const slides = await prisma.catalogSliderSlide.findMany({
|
|
orderBy: { sortOrder: 'asc' },
|
|
include: { galleryImage: true },
|
|
})
|
|
return {
|
|
slides: slides.map((s) => ({
|
|
id: s.id,
|
|
galleryImageId: s.galleryImageId,
|
|
url: s.galleryImage.url,
|
|
caption: s.caption,
|
|
})),
|
|
}
|
|
},
|
|
)
|
|
}
|