feat: add master classes section with registration system
- New master classes section on landing page with upcoming events grid - Admin CRUD for master classes (image, slots, trainer, style, cost, location) - User signup modal (name + Instagram required, Telegram optional) - Admin registration management: view, add, edit, delete with quick-contact links - Customizable success message for signup confirmation - Auto-filter past events, Russian date formatting, duration auto-calculation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
52
src/app/api/admin/mc-registrations/route.ts
Normal file
52
src/app/api/admin/mc-registrations/route.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getMcRegistrations, addMcRegistration, updateMcRegistration, deleteMcRegistration } from "@/lib/db";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const title = request.nextUrl.searchParams.get("title");
|
||||
if (!title) {
|
||||
return NextResponse.json({ error: "title parameter is required" }, { status: 400 });
|
||||
}
|
||||
const registrations = getMcRegistrations(title);
|
||||
return NextResponse.json(registrations);
|
||||
}
|
||||
|
||||
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 {
|
||||
return NextResponse.json({ error: "Internal error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function PUT(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
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 {
|
||||
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 });
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { getSection, setSection, SECTION_KEYS } from "@/lib/db";
|
||||
import { siteContent } from "@/data/content";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
type Params = { params: Promise<{ key: string }> };
|
||||
@@ -10,9 +11,16 @@ export async function GET(_request: NextRequest, { params }: Params) {
|
||||
return NextResponse.json({ error: "Invalid section key" }, { status: 400 });
|
||||
}
|
||||
|
||||
const data = getSection(key);
|
||||
let data = getSection(key);
|
||||
if (!data) {
|
||||
return NextResponse.json({ error: "Section not found" }, { status: 404 });
|
||||
// Auto-seed from fallback content if section doesn't exist yet
|
||||
const fallback = (siteContent as unknown as Record<string, unknown>)[key];
|
||||
if (fallback) {
|
||||
setSection(key, fallback);
|
||||
data = fallback;
|
||||
} else {
|
||||
return NextResponse.json({ error: "Section not found" }, { status: 404 });
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(data);
|
||||
|
||||
Reference in New Issue
Block a user