- Header: throttle scroll handler via requestAnimationFrame (was firing 60+/sec)
- Auth: use crypto.timingSafeEqual for password and token signature comparison
- A11y: add role="dialog", aria-modal, aria-label to all modals (SignupModal, NewsModal, TeamProfile lightbox)
- A11y: add aria-label to close buttons, menu toggle (with aria-expanded), floating CTA
- A11y: add aria-label to MC Instagram buttons
- Error logging: add console.error with route names to all API catch blocks (admin + public)
- Fix open-day-register error leak (was returning raw DB error to client)
- Fix MasterClasses key={index} → key={item.title}
- Delete 3 unused modal components (BookingModal, MasterClassSignupModal, OpenDaySignupModal) — replaced by unified SignupModal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import {
|
|
getOpenDayEvents,
|
|
getOpenDayEvent,
|
|
createOpenDayEvent,
|
|
updateOpenDayEvent,
|
|
deleteOpenDayEvent,
|
|
} from "@/lib/db";
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const idStr = request.nextUrl.searchParams.get("id");
|
|
if (idStr) {
|
|
const id = parseInt(idStr, 10);
|
|
if (isNaN(id)) return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
const event = getOpenDayEvent(id);
|
|
if (!event) return NextResponse.json({ error: "Not found" }, { status: 404 });
|
|
return NextResponse.json(event);
|
|
}
|
|
return NextResponse.json(getOpenDayEvents());
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
if (!body.date || typeof body.date !== "string") {
|
|
return NextResponse.json({ error: "date is required" }, { status: 400 });
|
|
}
|
|
const id = createOpenDayEvent(body);
|
|
return NextResponse.json({ ok: true, id });
|
|
} catch (err) {
|
|
console.error("[admin/open-day] error:", err);
|
|
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function PUT(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
if (!body.id) return NextResponse.json({ error: "id is required" }, { status: 400 });
|
|
const { id, ...data } = body;
|
|
updateOpenDayEvent(id, data);
|
|
return NextResponse.json({ ok: true });
|
|
} catch (err) {
|
|
console.error("[admin/open-day] error:", err);
|
|
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function DELETE(request: NextRequest) {
|
|
const idStr = request.nextUrl.searchParams.get("id");
|
|
if (!idStr) return NextResponse.json({ error: "id is required" }, { status: 400 });
|
|
const id = parseInt(idStr, 10);
|
|
if (isNaN(id)) return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
deleteOpenDayEvent(id);
|
|
return NextResponse.json({ ok: true });
|
|
}
|