Refactor evaluation and admin pages to use server actions for data fetching, enhancing performance and simplifying state management. Update README to reflect API route changes and remove deprecated API endpoints for users and evaluations.
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m7s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m7s
This commit is contained in:
137
src/lib/server-data.ts
Normal file
137
src/lib/server-data.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { auth } from "@/auth";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { canAccessEvaluation } from "@/lib/evaluation-access";
|
||||
|
||||
export async function getEvaluations(options?: { status?: string; templateId?: string }) {
|
||||
const session = await auth();
|
||||
if (!session?.user) return null;
|
||||
|
||||
const isAdmin = session.user.role === "admin";
|
||||
const userId = session.user.id;
|
||||
|
||||
const evaluations = await prisma.evaluation.findMany({
|
||||
where: {
|
||||
...(options?.status && { status: options.status }),
|
||||
...(options?.templateId && { templateId: options.templateId }),
|
||||
...(!isAdmin && {
|
||||
OR: [
|
||||
{ evaluatorId: userId },
|
||||
{ sharedWith: { some: { userId } } },
|
||||
{ isPublic: true },
|
||||
],
|
||||
}),
|
||||
},
|
||||
include: {
|
||||
template: { include: { dimensions: { orderBy: { orderIndex: "asc" } } } },
|
||||
dimensionScores: { include: { dimension: true } },
|
||||
},
|
||||
orderBy: { evaluationDate: "desc" },
|
||||
});
|
||||
|
||||
return evaluations.map((e) => ({
|
||||
...e,
|
||||
evaluationDate: e.evaluationDate.toISOString(),
|
||||
}));
|
||||
}
|
||||
|
||||
export async function getEvaluation(id: string) {
|
||||
const session = await auth();
|
||||
if (!session?.user) return null;
|
||||
|
||||
const evaluation = await prisma.evaluation.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
template: {
|
||||
include: {
|
||||
dimensions: { orderBy: { orderIndex: "asc" } },
|
||||
},
|
||||
},
|
||||
dimensionScores: { include: { dimension: true } },
|
||||
sharedWith: { include: { user: { select: { id: true, email: true, name: true } } } },
|
||||
},
|
||||
});
|
||||
|
||||
if (!evaluation) return null;
|
||||
|
||||
const hasAccess = await canAccessEvaluation(
|
||||
id,
|
||||
session.user.id,
|
||||
session.user.role === "admin",
|
||||
true
|
||||
);
|
||||
if (!hasAccess) return null;
|
||||
|
||||
const templateId = evaluation.templateId;
|
||||
const dimsRaw = evaluation.template
|
||||
? ((await prisma.$queryRaw(
|
||||
Prisma.sql`SELECT id, slug, title, rubric, "orderIndex", "suggestedQuestions" FROM "TemplateDimension" WHERE "templateId" = ${templateId} ORDER BY "orderIndex" ASC`
|
||||
)) as { id: string; slug: string; title: string; rubric: string; orderIndex: number; suggestedQuestions: string | null }[])
|
||||
: [];
|
||||
|
||||
const dimMap = new Map(dimsRaw.map((d) => [d.id, d]));
|
||||
|
||||
return {
|
||||
...evaluation,
|
||||
evaluationDate: evaluation.evaluationDate.toISOString(),
|
||||
template: evaluation.template
|
||||
? {
|
||||
...evaluation.template,
|
||||
dimensions: evaluation.template.dimensions.map((d) => {
|
||||
const raw = dimMap.get(d.id);
|
||||
return {
|
||||
...d,
|
||||
suggestedQuestions: raw?.suggestedQuestions ?? d.suggestedQuestions,
|
||||
};
|
||||
}),
|
||||
}
|
||||
: null,
|
||||
dimensionScores: evaluation.dimensionScores.map((ds) => ({
|
||||
...ds,
|
||||
dimension: ds.dimension
|
||||
? {
|
||||
...ds.dimension,
|
||||
suggestedQuestions: dimMap.get(ds.dimension.id)?.suggestedQuestions ?? ds.dimension.suggestedQuestions,
|
||||
}
|
||||
: null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export async function getTemplates() {
|
||||
const templates = await prisma.template.findMany({
|
||||
include: {
|
||||
dimensions: { orderBy: { orderIndex: "asc" } },
|
||||
},
|
||||
});
|
||||
const dimsRaw = (await prisma.$queryRaw(
|
||||
Prisma.sql`SELECT id, "templateId", slug, title, rubric, "orderIndex", "suggestedQuestions" FROM "TemplateDimension" ORDER BY "templateId", "orderIndex"`
|
||||
)) as { id: string; templateId: string; slug: string; title: string; rubric: string; orderIndex: number; suggestedQuestions: string | null }[];
|
||||
const dimMap = new Map(dimsRaw.map((d) => [d.id, d]));
|
||||
return templates.map((t) => ({
|
||||
...t,
|
||||
dimensions: t.dimensions.map((d) => ({
|
||||
...d,
|
||||
suggestedQuestions: dimMap.get(d.id)?.suggestedQuestions ?? d.suggestedQuestions,
|
||||
})),
|
||||
}));
|
||||
}
|
||||
|
||||
export async function getUsers() {
|
||||
const session = await auth();
|
||||
if (!session?.user) return null;
|
||||
return prisma.user.findMany({
|
||||
orderBy: { email: "asc" },
|
||||
select: { id: true, email: true, name: true },
|
||||
});
|
||||
}
|
||||
|
||||
export async function getAdminUsers() {
|
||||
const session = await auth();
|
||||
if (session?.user?.role !== "admin") return null;
|
||||
const users = await prisma.user.findMany({
|
||||
orderBy: { createdAt: "desc" },
|
||||
select: { id: true, email: true, name: true, role: true, createdAt: true },
|
||||
});
|
||||
return users.map((u) => ({ ...u, createdAt: u.createdAt.toISOString() }));
|
||||
}
|
||||
Reference in New Issue
Block a user