52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { readBody } from "h3";
|
|
import { prisma } from "../utils/prisma";
|
|
import { getAuthContext } from "../utils/auth";
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const auth = await getAuthContext(event);
|
|
const body = await readBody<{
|
|
title?: string;
|
|
start?: string;
|
|
end?: string;
|
|
contact?: string;
|
|
note?: string;
|
|
status?: string;
|
|
}>(event);
|
|
|
|
const title = (body?.title ?? "").trim();
|
|
const start = body?.start ? new Date(body.start) : null;
|
|
const end = body?.end ? new Date(body.end) : null;
|
|
if (!title) throw createError({ statusCode: 400, statusMessage: "title is required" });
|
|
if (!start || Number.isNaN(start.getTime())) throw createError({ statusCode: 400, statusMessage: "start is invalid" });
|
|
|
|
const contactName = (body?.contact ?? "").trim();
|
|
const contact = contactName
|
|
? await prisma.contact.findFirst({ where: { teamId: auth.teamId, name: contactName }, select: { id: true, name: true } })
|
|
: null;
|
|
|
|
const created = await prisma.calendarEvent.create({
|
|
data: {
|
|
teamId: auth.teamId,
|
|
contactId: contact?.id ?? null,
|
|
title,
|
|
startsAt: start,
|
|
endsAt: end && !Number.isNaN(end.getTime()) ? end : null,
|
|
note: (body?.note ?? "").trim() || null,
|
|
status: (body?.status ?? "").trim() || null,
|
|
},
|
|
include: { contact: { select: { name: true } } },
|
|
});
|
|
|
|
return {
|
|
item: {
|
|
id: created.id,
|
|
title: created.title,
|
|
start: created.startsAt.toISOString(),
|
|
end: (created.endsAt ?? created.startsAt).toISOString(),
|
|
contact: created.contact?.name ?? "",
|
|
note: created.note ?? "",
|
|
},
|
|
};
|
|
});
|
|
|