Files
shop-server/server/src/routes/api/catalog-slider.js
T
2026-05-26 12:10:38 +05:00

112 lines
3.8 KiB
JavaScript

import { prisma } from '../../lib/prisma.js'
const MAX_SLIDES = 20
export async function registerCatalogSliderRoutes(fastify) {
fastify.get('/api/catalog-slider', async (request, reply) => {
try {
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,
textColor: s.textColor,
})),
}
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось загрузить слайдер' })
}
})
fastify.get('/api/admin/catalog-slider', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
try {
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,
textColor: s.textColor,
})),
}
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось загрузить слайдер' })
}
})
fastify.put('/api/admin/catalog-slider', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => {
try {
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)
const textColor = String(row?.textColor || '#ffffff').trim()
normalized.push({ galleryImageId, caption, textColor, 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,
textColor: n.textColor,
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,
textColor: s.textColor,
})),
}
} catch (err) {
request.log.error(err)
return reply.code(500).send({ error: 'Не удалось обновить слайдер' })
}
})
}