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: 'Не удалось обновить слайдер' }) } }) }