forked from UKSOURCE/ipv6
Adding UI of FeedBack, Registration, Admin console
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
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";
|
||||
eventRating: string;
|
||||
venueSatisfaction: string;
|
||||
session: string;
|
||||
sessionLabel?: string;
|
||||
speakerRating: string;
|
||||
improve2027: string;
|
||||
comments: string;
|
||||
ipv6Readiness: string;
|
||||
challenge: string;
|
||||
challengeLabel?: string;
|
||||
introductions: string;
|
||||
collaboration: string[];
|
||||
collaborationLabels?: string[];
|
||||
venueRating: string;
|
||||
};
|
||||
|
||||
function buildFeedbackNotes(b: FeedbackBody): string {
|
||||
const collab =
|
||||
b.collaborationLabels?.length ? b.collaborationLabels.join(", ") : b.collaboration.join(", ") || "—";
|
||||
const lines = [
|
||||
"Source: Event feedback",
|
||||
b.eventRating && `Overall event rating: ${b.eventRating}/5`,
|
||||
b.venueSatisfaction && `Venue & logistics satisfaction: ${b.venueSatisfaction}/5`,
|
||||
(b.sessionLabel || b.session) && `Most valuable session: ${b.sessionLabel || b.session || "—"}`,
|
||||
b.speakerRating && `Keynote rating: ${b.speakerRating}/5`,
|
||||
b.ipv6Readiness && `IPv6 readiness: ${b.ipv6Readiness}/5`,
|
||||
(b.challengeLabel || b.challenge) &&
|
||||
`Infrastructure challenge: ${b.challengeLabel || b.challenge || "—"}`,
|
||||
b.introductions && `Speaker / company introductions: ${b.introductions}`,
|
||||
`Collaboration interests: ${collab}`,
|
||||
b.venueRating && `Venue rating (HCMC): ${b.venueRating}/5`,
|
||||
b.improve2027 && `Improve for 2027: ${b.improve2027}`,
|
||||
b.comments && `Comments: ${b.comments}`,
|
||||
];
|
||||
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.sessionLabel === "string" && b.sessionLabel
|
||||
? b.sessionLabel
|
||||
: typeof b.session === "string" && b.session
|
||||
? b.session
|
||||
: "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 });
|
||||
}
|
||||
Reference in New Issue
Block a user