Files
schulos/src/app/api/announcements/[id]/read/route.ts
T
Mustafa Cetin 490bd0650f Round 22: Exam Calendar, Tablet Grading, Student Achievements, Notification Center, Announcements, Styling
- Exam Calendar View: Teacher exam planning with calendar integration
  - Teachers create/modify exams, admin full CRUD, students read-only
  - CalendarEvent integration, 2-week warning, AI test availability badge
  - Monthly/weekly calendar view, list view, statistics

- Tablet Grading View: Stylus annotation and AI grading audit
  - HTML5 Canvas with PointerEvent pressure sensitivity
  - Tool palette: pen, highlighter, eraser, text, stamp
  - Quick grade buttons (German 1-6 scale)
  - AI grading audit with detailed feedback and suggestions

- Student Achievements View: Badges, XP, leaderboard
  - Badge collection grid with category filters
  - Level/XP system with progress bars
  - Leaderboard with opt-in
  - Daily/weekly challenges

- Student Study Planner View: Pomodoro timer, weekly schedule
  - Pomodoro timer with focus score
  - Weekly study schedule with drag-and-drop
  - AI study recommendations
  - Session history and statistics

- Notification Center View: Categories, filters, bulk actions
  - 6 categories, 4 priority levels
  - Real-time polling (10 seconds)
  - Preferences with quiet hours
  - Statistics charts

- School Announcements View: CRUD, read receipts
  - 6 announcement types with gradient headers
  - Pin-to-top, read receipts, target audience
  - Admin/teacher create, students/parents view

- Bug fixes: AnnouncementRead model user relation, User API schoolId field
- i18n: 200+ new keys, breadcrumb navigation fixes
- Styling: Gradient headers, animations, hover effects across all new views
2026-07-29 22:56:40 +00:00

70 lines
1.7 KiB
TypeScript

// CompetenceTrack — Announcement Read Receipt API
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { getSession } from '@/lib/auth';
export async function POST(
_request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const session = await getSession();
if (!session?.user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
// Verify announcement exists
const announcement = await db.announcement.findUnique({
where: { id, deletedAt: null },
});
if (!announcement) {
return NextResponse.json({ error: 'Announcement not found' }, { status: 404 });
}
// Upsert read receipt
const readReceipt = await db.announcementRead.upsert({
where: {
announcementId_userId: {
announcementId: id,
userId: session.user.id,
},
},
update: {
readAt: new Date(),
},
create: {
announcementId: id,
userId: session.user.id,
},
});
return NextResponse.json({ readReceipt });
}
export async function GET(
_request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const session = await getSession();
if (!session?.user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
// Get all read receipts for this announcement
const reads = await db.announcementRead.findMany({
where: { announcementId: id },
include: {
user: {
select: { id: true, firstName: true, lastName: true },
},
},
orderBy: { readAt: 'desc' },
});
return NextResponse.json({ reads, totalReads: reads.length });
}