52 lines
2.3 KiB
TypeScript
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>
|
|
);
|
|
}
|