b906216317
- DB migration v12: add status column to mc_registrations and open_day_bookings - MC and Open Day tabs now have full status workflow (new → contacted → confirmed/declined) - Filter tabs with counts, status badges, action buttons matching group bookings - Extract shared components (_shared.tsx): FilterTabs, StatusBadge, StatusActions, BookingCard, ContactLinks - Split monolith into _McRegistrationsTab.tsx, _OpenDayBookingsTab.tsx, _shared.tsx Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
81 lines
3.1 KiB
TypeScript
81 lines
3.1 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { getMcRegistrations, getAllMcRegistrations, addMcRegistration, updateMcRegistration, toggleMcNotification, deleteMcRegistration, setMcRegistrationStatus } from "@/lib/db";
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const title = request.nextUrl.searchParams.get("title");
|
|
if (title) {
|
|
return NextResponse.json(getMcRegistrations(title));
|
|
}
|
|
// No title = return all registrations
|
|
return NextResponse.json(getAllMcRegistrations());
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const { masterClassTitle, name, instagram, telegram } = body;
|
|
if (!masterClassTitle || !name || !instagram) {
|
|
return NextResponse.json({ error: "masterClassTitle, name, instagram are required" }, { status: 400 });
|
|
}
|
|
const id = addMcRegistration(masterClassTitle.trim(), name.trim(), instagram.trim(), telegram?.trim() || undefined);
|
|
return NextResponse.json({ ok: true, id });
|
|
} catch (err) {
|
|
console.error("[admin/mc-registrations] error:", err);
|
|
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
|
}
|
|
}
|
|
|
|
export async function PUT(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
|
|
// Set booking status
|
|
if (body.action === "set-status") {
|
|
const { id, status } = body;
|
|
if (!id || !status) return NextResponse.json({ error: "id, status required" }, { status: 400 });
|
|
if (!["new", "contacted", "confirmed", "declined"].includes(status)) {
|
|
return NextResponse.json({ error: "Invalid status" }, { status: 400 });
|
|
}
|
|
setMcRegistrationStatus(id, status);
|
|
return NextResponse.json({ ok: true });
|
|
}
|
|
|
|
// Toggle notification status
|
|
if (body.action === "toggle-notify") {
|
|
const { id, field, value } = body;
|
|
if (!id || !field || typeof value !== "boolean") {
|
|
return NextResponse.json({ error: "id, field, value are required" }, { status: 400 });
|
|
}
|
|
if (field !== "notified_confirm" && field !== "notified_reminder") {
|
|
return NextResponse.json({ error: "Invalid field" }, { status: 400 });
|
|
}
|
|
toggleMcNotification(id, field, value);
|
|
return NextResponse.json({ ok: true });
|
|
}
|
|
|
|
// Regular update
|
|
const { id, name, instagram, telegram } = body;
|
|
if (!id || !name || !instagram) {
|
|
return NextResponse.json({ error: "id, name, instagram are required" }, { status: 400 });
|
|
}
|
|
updateMcRegistration(id, name.trim(), instagram.trim(), telegram?.trim() || undefined);
|
|
return NextResponse.json({ ok: true });
|
|
} catch (err) {
|
|
console.error("[admin/mc-registrations] 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 parameter is required" }, { status: 400 });
|
|
}
|
|
const id = parseInt(idStr, 10);
|
|
if (isNaN(id)) {
|
|
return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
}
|
|
deleteMcRegistration(id);
|
|
return NextResponse.json({ ok: true });
|
|
}
|