- Puzzle-Kontext: Hördle #, Genre/Special, Titel werden jetzt angezeigt - API erweitert: puzzleNumber wird berechnet, special-Informationen inkludiert - Badge für neue Kommentare: zeigt Anzahl ungelesener Kommentare - Verbesserte Kommentar-Anzeige mit vollständigem Rätsel-Kontext - UI-Anpassungen: nur Badge für neue Kommentare, keine übermäßige Hervorhebung
140 lines
4.6 KiB
TypeScript
140 lines
4.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { requireStaffAuth } from '@/lib/auth';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
export async function GET(request: NextRequest) {
|
|
// Require curator authentication
|
|
const { error, context } = await requireStaffAuth(request);
|
|
if (error || !context) {
|
|
return error!;
|
|
}
|
|
|
|
// Only curators can view comments (not admins directly)
|
|
if (context.role !== 'curator') {
|
|
return NextResponse.json(
|
|
{ error: 'Only curators can view comments' },
|
|
{ status: 403 }
|
|
);
|
|
}
|
|
|
|
try {
|
|
const curatorId = context.curator.id;
|
|
|
|
// Get all non-archived comments for this curator, ordered by creation date (newest first)
|
|
const comments = await prisma.curatorCommentRecipient.findMany({
|
|
where: {
|
|
curatorId: curatorId,
|
|
archived: false
|
|
},
|
|
include: {
|
|
comment: {
|
|
include: {
|
|
puzzle: {
|
|
include: {
|
|
song: {
|
|
select: {
|
|
title: true,
|
|
artist: true
|
|
}
|
|
},
|
|
genre: {
|
|
select: {
|
|
id: true,
|
|
name: true
|
|
}
|
|
},
|
|
special: {
|
|
select: {
|
|
id: true,
|
|
name: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
orderBy: {
|
|
comment: {
|
|
createdAt: 'desc'
|
|
}
|
|
}
|
|
});
|
|
|
|
// Format the response with puzzle context
|
|
const formattedComments = await Promise.all(comments.map(async (recipient) => {
|
|
const puzzle = recipient.comment.puzzle;
|
|
|
|
// Calculate puzzle number
|
|
let puzzleNumber = 0;
|
|
if (puzzle.specialId) {
|
|
// Special puzzle
|
|
puzzleNumber = await prisma.dailyPuzzle.count({
|
|
where: {
|
|
specialId: puzzle.specialId,
|
|
date: {
|
|
lte: puzzle.date
|
|
}
|
|
}
|
|
});
|
|
} else if (puzzle.genreId) {
|
|
// Genre puzzle
|
|
puzzleNumber = await prisma.dailyPuzzle.count({
|
|
where: {
|
|
genreId: puzzle.genreId,
|
|
date: {
|
|
lte: puzzle.date
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
// Global puzzle
|
|
puzzleNumber = await prisma.dailyPuzzle.count({
|
|
where: {
|
|
genreId: null,
|
|
specialId: null,
|
|
date: {
|
|
lte: puzzle.date
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return {
|
|
id: recipient.comment.id,
|
|
message: recipient.comment.message,
|
|
createdAt: recipient.comment.createdAt,
|
|
readAt: recipient.readAt,
|
|
puzzle: {
|
|
id: puzzle.id,
|
|
date: puzzle.date,
|
|
puzzleNumber: puzzleNumber,
|
|
song: {
|
|
title: puzzle.song.title,
|
|
artist: puzzle.song.artist
|
|
},
|
|
genre: puzzle.genre ? {
|
|
id: puzzle.genre.id,
|
|
name: puzzle.genre.name
|
|
} : null,
|
|
special: puzzle.special ? {
|
|
id: puzzle.special.id,
|
|
name: puzzle.special.name
|
|
} : null
|
|
}
|
|
};
|
|
}));
|
|
|
|
return NextResponse.json(formattedComments);
|
|
} catch (error) {
|
|
console.error('Error fetching curator comments:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Internal Server Error' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|