@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* The marketing site is a static bundle. Both forms post to sitesvc, which owns
|
||||
* the contact mailer and the signup flow; the control plane is not involved.
|
||||
*
|
||||
* The base URL is baked in at build time. Contact falls back to composing an
|
||||
* email when sitesvc is not configured, so it never silently swallows what
|
||||
* someone typed. Signup has no fallback: an account cannot be created over
|
||||
* mailto, so the form says so rather than pretending.
|
||||
*/
|
||||
|
||||
const SITE_API = (process.env.NEXT_PUBLIC_SITE_API ?? "").replace(/\/$/, "");
|
||||
const FALLBACK_ADDRESS = process.env.NEXT_PUBLIC_CONTACT_EMAIL ?? "support@hostxtra.co.uk";
|
||||
|
||||
export type SubmitState = "idle" | "sending" | "sent" | "error";
|
||||
|
||||
export type SubmitResult = {
|
||||
state: SubmitState;
|
||||
/** Message to show when the submission was refused. */
|
||||
message?: string;
|
||||
/** Per-field messages, keyed by field name. */
|
||||
fields?: Record<string, string>;
|
||||
};
|
||||
|
||||
type FieldProblem = { field: string; message: string };
|
||||
|
||||
async function post(url: string, payload: unknown): Promise<SubmitResult> {
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
if (res.ok) return { state: "sent" };
|
||||
|
||||
const data = await res.json().catch(() => null);
|
||||
const problems: FieldProblem[] = data?.fields ?? [];
|
||||
|
||||
return {
|
||||
state: "error",
|
||||
message: data?.error ?? "That did not go through. Try again in a moment.",
|
||||
fields: Object.fromEntries(problems.map((p) => [p.field, p.message])),
|
||||
};
|
||||
} catch {
|
||||
return { state: "error", message: "We could not reach the server. Check your connection and try again." };
|
||||
}
|
||||
}
|
||||
|
||||
export async function submitContact(fields: {
|
||||
name: string;
|
||||
email: string;
|
||||
servers: string;
|
||||
topic: string;
|
||||
message: string;
|
||||
website: string;
|
||||
}): Promise<SubmitResult> {
|
||||
if (!SITE_API) {
|
||||
const body = [
|
||||
`Name: ${fields.name}`,
|
||||
`Email: ${fields.email}`,
|
||||
`Servers: ${fields.servers}`,
|
||||
`Topic: ${fields.topic}`,
|
||||
"",
|
||||
fields.message,
|
||||
].join("\n");
|
||||
window.location.href = `mailto:${FALLBACK_ADDRESS}?subject=${encodeURIComponent(
|
||||
`Vantage enquiry — ${fields.topic}`
|
||||
)}&body=${encodeURIComponent(body)}`;
|
||||
return { state: "sent" };
|
||||
}
|
||||
return post(`${SITE_API}/api/contact`, fields);
|
||||
}
|
||||
|
||||
export async function submitSignup(fields: {
|
||||
org_name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
website: string;
|
||||
}): Promise<SubmitResult> {
|
||||
if (!SITE_API) {
|
||||
return {
|
||||
state: "error",
|
||||
message: `Signup is not available from here yet. Email ${FALLBACK_ADDRESS} and we will set you up.`,
|
||||
};
|
||||
}
|
||||
return post(`${SITE_API}/api/signup`, fields);
|
||||
}
|
||||
Reference in New Issue
Block a user