comicbox/pages/api/submit-page-bubbles.ts
2022-07-25 18:31:20 +01:00

96 lines
2.9 KiB
TypeScript

import { ComicBubble, Prisma } from '@prisma/client';
import { NextApiRequest, NextApiResponse } from 'next';
import { unstable_getServerSession } from 'next-auth';
import { z } from 'zod';
import { prisma } from '../../src/db';
import { authOptions } from './auth/[...nextauth]';
const PageBubblesSchema = z.object({
bubbles: z.array(
z.object({
area: z.object({
x: z.number(),
y: z.number(),
width: z.number(),
height: z.number(),
}),
character: z.number(),
index: z.number(),
text: z.string(),
})
),
comicId: z.number(),
pageId: z.number(),
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'PUT')
return res.status(405).json({ error: 'method not allowed' });
const session = await unstable_getServerSession(req, res, authOptions);
if (!session)
return res.status(401).json({ error: 'authentication required' });
const data = PageBubblesSchema.parse(req.body);
const page = await prisma.comicPage.findFirst({
where: {
comicId: data.comicId,
id: data.pageId,
},
});
if (!page) return res.status(404).json({ error: 'not found' });
const existingCharacters: number[] = [];
const ops: Prisma.Prisma__ComicBubbleClient<ComicBubble>[] = [];
for (const bubble of data.bubbles) {
if (!existingCharacters.includes(bubble.character)) {
const char = await prisma.comicCharacter.findFirst({
where: {
id: bubble.character,
},
});
if (!char) {
return res.status(400).json({ message: 'bad request' });
}
}
const op = prisma.comicBubble.upsert({
where: {
comicId_pageId_idx: {
comicId: data.comicId,
pageId: data.pageId,
idx: bubble.index,
},
},
update: {
areaX: bubble.area.x,
areaY: bubble.area.y,
areaWidth: bubble.area.width,
areaHeight: bubble.area.height,
characterId: bubble.character,
content: bubble.text,
},
create: {
comicId: data.comicId,
pageId: data.pageId,
idx: bubble.index,
areaX: bubble.area.x,
areaY: bubble.area.y,
areaWidth: bubble.area.width,
areaHeight: bubble.area.height,
characterId: bubble.character,
content: bubble.text,
},
});
ops.push(op);
}
await prisma.$transaction(ops);
res.status(201).json({});
}