Files

52 lines
2.3 KiB
TypeScript

"use client";
import { useState } from "react";
import { submitContactMessage } from "@/app/[locale]/contact/actions";
type ContactFormProps = {
labels: {
name: string;
email: string;
message: string;
submit: string;
sending: string;
success: string;
savedWarning: string;
invalid: string;
rateLimit: string;
};
};
export default function ContactForm({ labels }: ContactFormProps) {
const [status, setStatus] = useState<{ type: "success" | "warning" | "error"; message: string } | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
setStatus(null);
setIsSubmitting(true);
const form = event.currentTarget;
const result = await submitContactMessage(Object.fromEntries(new FormData(form).entries()));
setIsSubmitting(false);
if (result.error) {
setStatus({ type: "error", message: result.error === "rate-limit" ? labels.rateLimit : labels.invalid });
return;
}
form.reset();
setStatus({ type: result.warning ? "warning" : "success", message: result.warning ? labels.savedWarning : labels.success });
}
return (
<form onSubmit={handleSubmit} className="card contact-form space-y-4" noValidate>
<div className="grid gap-4 sm:grid-cols-2">
<label className="space-y-2"><span>{labels.name}</span><input name="name" required maxLength={100} autoComplete="name" /></label>
<label className="space-y-2"><span>{labels.email}</span><input name="email" type="email" required maxLength={254} autoComplete="email" /></label>
</div>
<label className="space-y-2"><span>{labels.message}</span><textarea name="message" required minLength={10} maxLength={5000} rows={6} /></label>
<label aria-hidden="true" className="absolute -left-[9999px] h-px w-px overflow-hidden"><span>Website</span><input name="website" tabIndex={-1} autoComplete="off" /></label>
<button type="submit" disabled={isSubmitting}>{isSubmitting ? labels.sending : labels.submit}</button>
{status ? <p role={status.type === "error" ? "alert" : "status"} className={status.type === "error" ? "text-sm text-destructive" : "text-sm text-muted-foreground"}>{status.message}</p> : null}
</form>
);
}