Files
twotalesanimation 0fbe856dce Initial commit
2026-05-19 22:20:29 +02:00

103 lines
2.7 KiB
TypeScript

"use server";
import { auth } from "@/auth";
import { db } from "@/lib/db";
import { revalidatePath } from "next/cache";
import { z } from "zod";
import type { AnnotationDrawingData } from "@/types";
const saveAnnotationSchema = z.object({
versionId: z.string().cuid(),
commentId: z.string().cuid().optional(),
frameNumber: z.number().int().min(0),
drawingData: z.object({
shapes: z.array(z.any()),
canvasWidth: z.number(),
canvasHeight: z.number(),
version: z.literal("1.0"),
}),
color: z.string().default("#ef4444"),
});
export async function saveAnnotation(data: z.infer<typeof saveAnnotationSchema>) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const parsed = saveAnnotationSchema.parse(data);
const annotation = await db.annotation.create({
data: {
versionId: parsed.versionId,
commentId: parsed.commentId,
authorId: session.user.id,
frameNumber: parsed.frameNumber,
drawingData: parsed.drawingData as any,
color: parsed.color,
},
});
revalidatePath(`/review/${parsed.versionId}`);
return { success: true, annotation };
}
export async function getAnnotationsForVersion(versionId: string) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
return db.annotation.findMany({
where: { versionId, isVisible: true },
include: {
author: { select: { id: true, name: true, image: true } },
},
orderBy: { frameNumber: "asc" },
});
}
export async function getAnnotationsForFrame(
versionId: string,
frameNumber: number
) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
return db.annotation.findMany({
where: { versionId, frameNumber, isVisible: true },
include: {
author: { select: { id: true, name: true, image: true } },
},
});
}
export async function toggleAnnotationVisibility(
annotationId: string,
visible: boolean
) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
await db.annotation.update({
where: { id: annotationId },
data: { isVisible: visible },
});
return { success: true };
}
export async function deleteAnnotation(annotationId: string) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const annotation = await db.annotation.findUnique({
where: { id: annotationId },
});
if (!annotation) throw new Error("Annotation not found");
if (annotation.authorId !== session.user.id && session.user.role !== "ADMIN") {
throw new Error("Unauthorized");
}
await db.annotation.delete({ where: { id: annotationId } });
revalidatePath(`/review/${annotation.versionId}`);
return { success: true };
}