GRV-Summit-Site/lib/inquiry.ts
“kirukib” 1a710aa3c6
Some checks are pending
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Waiting to run
first commit + project setup
2026-05-20 11:57:21 +03:00

276 lines
8.3 KiB
TypeScript

export const inquiryIntents = [
"general",
"exhibitor",
"sponsor",
"partnership",
"startup_referral",
"sales",
"press",
"newsletter",
] as const;
export type InquiryIntent = (typeof inquiryIntents)[number];
export type InquiryPayload = {
intent: InquiryIntent;
name: string;
email: string;
company?: string;
message: string;
phone?: string;
firstName?: string;
lastName?: string;
consent: boolean;
startupName?: string;
startupWebsite?: string;
startupSector?: string;
whyRecommend?: string;
jobTitle?: string;
companyWebsite?: string;
companyDescription?: string;
sector?: string;
productsToAdvertise?: string;
boothSize?: string;
powerRequired?: boolean;
internetRequired?: boolean;
staffCount?: string;
marketingMaterials?: string;
specialRequirements?: string;
};
function parseEmail(email: unknown) {
return typeof email === "string" ? email.trim() : "";
}
function requireConsent(consent: unknown): boolean {
return consent === true;
}
export function validateInquiry(
body: unknown
): { ok: true; data: InquiryPayload } | { ok: false; error: string } {
if (!body || typeof body !== "object") {
return { ok: false, error: "Invalid request body" };
}
const b = body as Record<string, unknown>;
const intent = b.intent as InquiryIntent;
if (!inquiryIntents.includes(intent)) {
return { ok: false, error: "Invalid intent" };
}
const email = parseEmail(b.email);
if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
return { ok: false, error: "Valid email is required" };
}
if (intent === "partnership") {
const firstName = typeof b.firstName === "string" ? b.firstName.trim() : "";
const lastName = typeof b.lastName === "string" ? b.lastName.trim() : "";
const company = typeof b.company === "string" ? b.company.trim() : "";
if (!firstName || firstName.length < 2) {
return { ok: false, error: "First name is required" };
}
if (!lastName || lastName.length < 2) {
return { ok: false, error: "Last name is required" };
}
if (!company) {
return { ok: false, error: "Company name is required" };
}
if (!requireConsent(b.consent)) {
return { ok: false, error: "You must agree to data collection to submit" };
}
return {
ok: true,
data: {
intent,
firstName,
lastName,
name: `${firstName} ${lastName}`,
email,
company,
message:
typeof b.message === "string" && b.message.trim()
? b.message.trim()
: "Partnership information request",
consent: true,
},
};
}
if (intent === "exhibitor") {
const firstName = typeof b.firstName === "string" ? b.firstName.trim() : "";
const lastName = typeof b.lastName === "string" ? b.lastName.trim() : "";
const company = typeof b.company === "string" ? b.company.trim() : "";
const phone = typeof b.phone === "string" ? b.phone.trim() : "";
const jobTitle = typeof b.jobTitle === "string" ? b.jobTitle.trim() : "";
const companyDescription =
typeof b.companyDescription === "string" ? b.companyDescription.trim() : "";
const productsToAdvertise =
typeof b.productsToAdvertise === "string" ? b.productsToAdvertise.trim() : "";
const boothSize = typeof b.boothSize === "string" ? b.boothSize.trim() : "";
const sector = typeof b.sector === "string" ? b.sector.trim() : "";
const message = typeof b.message === "string" ? b.message.trim() : "";
if (!firstName || firstName.length < 2) {
return { ok: false, error: "First name is required" };
}
if (!lastName || lastName.length < 2) {
return { ok: false, error: "Last name is required" };
}
if (!company) {
return { ok: false, error: "Company name is required" };
}
if (!phone) {
return { ok: false, error: "Phone number is required" };
}
if (!jobTitle) {
return { ok: false, error: "Job title is required" };
}
if (!sector) {
return { ok: false, error: "Industry / sector is required" };
}
if (!companyDescription || companyDescription.length < 20) {
return { ok: false, error: "Please describe your company (at least 20 characters)" };
}
if (!productsToAdvertise || productsToAdvertise.length < 20) {
return {
ok: false,
error: "Please describe the products you plan to advertise (at least 20 characters)",
};
}
if (!boothSize) {
return { ok: false, error: "Preferred booth size is required" };
}
if (!message || message.length < 10) {
return { ok: false, error: "Please describe your booth goals (at least 10 characters)" };
}
if (!requireConsent(b.consent)) {
return { ok: false, error: "You must agree to data collection to submit" };
}
return {
ok: true,
data: {
intent,
firstName,
lastName,
name: `${firstName} ${lastName}`,
email,
phone,
jobTitle,
company,
companyWebsite:
typeof b.companyWebsite === "string" ? b.companyWebsite.trim() : undefined,
companyDescription,
sector,
productsToAdvertise,
boothSize,
powerRequired: b.powerRequired === true,
internetRequired: b.internetRequired === true,
staffCount: typeof b.staffCount === "string" ? b.staffCount.trim() : undefined,
marketingMaterials:
typeof b.marketingMaterials === "string" ? b.marketingMaterials.trim() : undefined,
specialRequirements:
typeof b.specialRequirements === "string" ? b.specialRequirements.trim() : undefined,
message,
consent: true,
},
};
}
if (intent === "startup_referral") {
const name = typeof b.name === "string" ? b.name.trim() : "";
const startupName = typeof b.startupName === "string" ? b.startupName.trim() : "";
const whyRecommend = typeof b.whyRecommend === "string" ? b.whyRecommend.trim() : "";
if (!name || name.length < 2) {
return { ok: false, error: "Your name is required" };
}
if (!startupName) {
return { ok: false, error: "Startup name is required" };
}
if (!whyRecommend || whyRecommend.length < 20) {
return { ok: false, error: "Please tell us why you recommend this startup (at least 20 characters)" };
}
if (!requireConsent(b.consent)) {
return { ok: false, error: "You must agree to data collection to submit" };
}
return {
ok: true,
data: {
intent,
name,
email,
startupName,
startupWebsite:
typeof b.startupWebsite === "string" ? b.startupWebsite.trim() : undefined,
startupSector:
typeof b.startupSector === "string" ? b.startupSector.trim() : undefined,
whyRecommend,
message: whyRecommend,
consent: true,
},
};
}
if (!requireConsent(b.consent)) {
return { ok: false, error: "You must agree to data collection to submit" };
}
if (intent === "newsletter") {
const firstName = typeof b.firstName === "string" ? b.firstName.trim() : "";
const lastName = typeof b.lastName === "string" ? b.lastName.trim() : "";
const nameFromFields = `${firstName} ${lastName}`.trim();
const name = nameFromFields || (typeof b.name === "string" ? b.name.trim() : "");
if (!firstName || firstName.length < 2) {
return { ok: false, error: "First name is required" };
}
if (!lastName || lastName.length < 2) {
return { ok: false, error: "Last name is required" };
}
return {
ok: true,
data: {
intent,
firstName,
lastName,
name,
email,
message: "Newsletter signup",
consent: true,
},
};
}
const name = typeof b.name === "string" ? b.name.trim() : "";
const message = typeof b.message === "string" ? b.message.trim() : "";
if (!name || name.length < 2) {
return { ok: false, error: "Name is required" };
}
if (!message || message.length < 10) {
return { ok: false, error: "Message must be at least 10 characters" };
}
return {
ok: true,
data: {
intent,
name,
email,
message,
company: typeof b.company === "string" ? b.company.trim() : undefined,
phone: typeof b.phone === "string" ? b.phone.trim() : undefined,
consent: true,
},
};
}