forked from UKSOURCE/ipv6
162 lines
5.5 KiB
TypeScript
162 lines
5.5 KiB
TypeScript
import { createSummitRequest } from "@/lib/summit-requests";
|
|
import type { AdminRequestRow } from "@/types/admin-submission";
|
|
import { NextResponse } from "next/server";
|
|
|
|
export const runtime = "nodejs";
|
|
|
|
const INDUSTRY_SEGMENT: Record<string, string> = {
|
|
government: "enterprise",
|
|
telecom: "tier1",
|
|
cloud: "cloud",
|
|
ai: "enterprise",
|
|
others: "enterprise",
|
|
};
|
|
|
|
function displayDateNow(): string {
|
|
return new Date()
|
|
.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" })
|
|
.toUpperCase()
|
|
.replace(/ /g, " ");
|
|
}
|
|
|
|
function newId(): string {
|
|
return `V6-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
}
|
|
|
|
type RegistrationBody = {
|
|
type: "registration";
|
|
fullName: string;
|
|
phone: string;
|
|
email: string;
|
|
company: string;
|
|
jobTitle: string;
|
|
industry: string;
|
|
industryLabel?: string;
|
|
notes: string;
|
|
};
|
|
|
|
type FeedbackBody = {
|
|
type: "feedback";
|
|
[key: string]: any;
|
|
};
|
|
|
|
function buildFeedbackNotes(b: FeedbackBody): string {
|
|
const lines = [
|
|
"Source: Event feedback",
|
|
b.overallExperience && `Overall experience: ${b.overallExperience}/5`,
|
|
b.venueFacilities && `Venue & Facilities: ${b.venueFacilities}/5`,
|
|
b.organisationProcess && `Organisation & Registration: ${b.organisationProcess}/5`,
|
|
b.mostValuableSession && `Most valuable session: ${b.mostValuableSession}`,
|
|
b.relevance && `Content relevance: ${b.relevance}`,
|
|
b.speakerRating && `Speakers/Panels rating: ${b.speakerRating}`,
|
|
b.networkingUtility && `Networking utility: ${b.networkingUtility}`,
|
|
b.futureTopics && `Future topics: ${Array.isArray(b.futureTopics) ? b.futureTopics.join(", ") : b.futureTopics}${b.futureTopics_other ? ` (Other: ${b.futureTopics_other})` : ""}`,
|
|
b.attendAgain && `Attend again in 2027: ${b.attendAgain}`,
|
|
b.recommend && `Recommend to others: ${b.recommend}`,
|
|
b.enjoyedMost && `Enjoyed most: ${b.enjoyedMost}`,
|
|
b.improvementAreas && `Improvement areas: ${b.improvementAreas}`,
|
|
b.additionalComments && `Additional comments: ${b.additionalComments}`,
|
|
b.industry && `Industry: ${Array.isArray(b.industry) ? b.industry.join(", ") : b.industry}${b.industry_other ? ` (Other: ${b.industry_other})` : ""}`,
|
|
b.role && `Role: ${Array.isArray(b.role) ? b.role.join(", ") : b.role}${b.role_other ? ` (Other: ${b.role_other})` : ""}`,
|
|
];
|
|
return lines.filter(Boolean).join("\n");
|
|
}
|
|
|
|
export async function POST(req: Request) {
|
|
let body: unknown;
|
|
try {
|
|
body = await req.json();
|
|
} catch {
|
|
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
}
|
|
|
|
if (!body || typeof body !== "object" || !("type" in body)) {
|
|
return NextResponse.json({ error: "Missing type" }, { status: 400 });
|
|
}
|
|
|
|
const t = (body as { type: string }).type;
|
|
const submittedAt = new Date().toISOString().slice(0, 10);
|
|
const displayDate = displayDateNow();
|
|
|
|
if (t === "registration") {
|
|
const b = body as RegistrationBody;
|
|
const fullName = typeof b.fullName === "string" ? b.fullName.trim() : "";
|
|
const email = typeof b.email === "string" ? b.email.trim() : "";
|
|
if (!fullName || !email) {
|
|
return NextResponse.json({ error: "Full name and email are required" }, { status: 400 });
|
|
}
|
|
|
|
const industry = typeof b.industry === "string" ? b.industry : "";
|
|
const segment = INDUSTRY_SEGMENT[industry] ?? "enterprise";
|
|
const industryLabel = typeof b.industryLabel === "string" ? b.industryLabel : industry;
|
|
const noteParts = [
|
|
typeof b.notes === "string" && b.notes.trim() ? b.notes.trim() : "",
|
|
industryLabel ? `Industry: ${industryLabel}` : "",
|
|
].filter(Boolean);
|
|
|
|
const row: AdminRequestRow = {
|
|
id: newId(),
|
|
submittedAt,
|
|
displayDate,
|
|
fullName,
|
|
jobTitle: typeof b.jobTitle === "string" ? b.jobTitle.trim() : "",
|
|
company: typeof b.company === "string" ? b.company.trim() : "",
|
|
segment,
|
|
email,
|
|
phone: typeof b.phone === "string" ? b.phone.trim() : "",
|
|
status: "pending",
|
|
notes: noteParts.join("\n"),
|
|
source: "registration",
|
|
};
|
|
|
|
try {
|
|
await createSummitRequest(row);
|
|
} catch (e: unknown) {
|
|
const code = e && typeof e === "object" && "code" in e ? (e as { code?: number }).code : undefined;
|
|
if (code === 11000) {
|
|
return NextResponse.json({ error: "Duplicate submission id" }, { status: 409 });
|
|
}
|
|
console.error(e);
|
|
return NextResponse.json({ error: "Could not save submission" }, { status: 500 });
|
|
}
|
|
return NextResponse.json({ ok: true, id: row.id });
|
|
}
|
|
|
|
if (t === "feedback") {
|
|
const b = body as FeedbackBody;
|
|
const sessionTitle =
|
|
typeof b.mostValuableSession === "string" && b.mostValuableSession
|
|
? b.mostValuableSession
|
|
: "General";
|
|
|
|
const row: AdminRequestRow = {
|
|
id: newId(),
|
|
submittedAt,
|
|
displayDate,
|
|
fullName: "Event feedback",
|
|
jobTitle: sessionTitle,
|
|
company: "—",
|
|
segment: "enterprise",
|
|
email: "—",
|
|
phone: "—",
|
|
status: "pending",
|
|
notes: buildFeedbackNotes(b),
|
|
source: "feedback",
|
|
};
|
|
|
|
try {
|
|
await createSummitRequest(row);
|
|
} catch (e: unknown) {
|
|
const code = e && typeof e === "object" && "code" in e ? (e as { code?: number }).code : undefined;
|
|
if (code === 11000) {
|
|
return NextResponse.json({ error: "Duplicate submission id" }, { status: 409 });
|
|
}
|
|
console.error(e);
|
|
return NextResponse.json({ error: "Could not save submission" }, { status: 500 });
|
|
}
|
|
return NextResponse.json({ ok: true, id: row.id });
|
|
}
|
|
|
|
return NextResponse.json({ error: "Unknown type" }, { status: 400 });
|
|
}
|