(Feat) Init WebSite
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
"use server";
|
||||
|
||||
export type ContactState = {
|
||||
status: "idle" | "success" | "error";
|
||||
message: string;
|
||||
fieldErrors?: Partial<Record<"name" | "email" | "subject" | "message", string>>;
|
||||
};
|
||||
|
||||
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
|
||||
export async function sendContact(
|
||||
_prev: ContactState,
|
||||
formData: FormData,
|
||||
): Promise<ContactState> {
|
||||
const name = String(formData.get("name") ?? "").trim();
|
||||
const email = String(formData.get("email") ?? "").trim();
|
||||
const subject = String(formData.get("subject") ?? "").trim();
|
||||
const message = String(formData.get("message") ?? "").trim();
|
||||
const honeypot = String(formData.get("website") ?? "");
|
||||
|
||||
if (honeypot) {
|
||||
return { status: "success", message: "Thanks for reaching out." };
|
||||
}
|
||||
|
||||
const fieldErrors: ContactState["fieldErrors"] = {};
|
||||
if (!name) fieldErrors.name = "Required.";
|
||||
if (!email || !EMAIL_RE.test(email)) fieldErrors.email = "Valid email required.";
|
||||
if (!subject) fieldErrors.subject = "Required.";
|
||||
if (!message || message.length < 10) {
|
||||
fieldErrors.message = "Tell us a bit more (10+ chars).";
|
||||
}
|
||||
|
||||
if (Object.keys(fieldErrors).length > 0) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Please fix the highlighted fields.",
|
||||
fieldErrors,
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: wire to Resend / Postmark / SendGrid to actually deliver the email.
|
||||
// For now we log so messages are visible in server logs.
|
||||
console.log("[contact]", { name, email, subject, message });
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Message sent. We'll get back to you soon.",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
"use server";
|
||||
|
||||
export type SubscribeState = {
|
||||
status: "idle" | "success" | "error";
|
||||
message: string;
|
||||
};
|
||||
|
||||
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
|
||||
export async function subscribe(
|
||||
_prev: SubscribeState,
|
||||
formData: FormData,
|
||||
): Promise<SubscribeState> {
|
||||
const email = String(formData.get("email") ?? "").trim();
|
||||
const honeypot = String(formData.get("website") ?? "");
|
||||
|
||||
if (honeypot) {
|
||||
return { status: "success", message: "Thanks — we'll keep you posted." };
|
||||
}
|
||||
|
||||
if (!email || !EMAIL_RE.test(email)) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Please enter a valid email address.",
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: wire to a real provider (Buttondown, ConvertKit, Mailchimp, Resend Audiences).
|
||||
// For now we just log the signup so you can collect addresses from server logs.
|
||||
console.log(`[newsletter] new signup: ${email}`);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Welcome to the climb. Check your inbox soon.",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user