The signup form now posts instance_name, matching sitesvc. Also restores site/next-env.d.ts. Its /// <reference> directives had been stripped, which removed the Next.js type environment and failed the build with "Cannot find name 'Promise'". Same cause as the agent's missing build constraint.
68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
/*
|
|
* 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) {
|
|
return {
|
|
state: "error",
|
|
message: `The contact form is not connected yet. Email ${FALLBACK_ADDRESS} directly.`,
|
|
};
|
|
}
|
|
return post(`${SITE_API}/api/contact`, fields);
|
|
}
|
|
|
|
export async function submitSignup(fields: { instance_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);
|
|
}
|