Kontaktformular: Anfragen über die Kontakt-API, damit WEBklar per Mail davon erfährt
Bisher schrieb das Formular als Gast direkt in Appwrite, und niemand las die Einträge. Jetzt geht es an POST /api/contact (webklar-webclaw-contact-api): die API speichert in Appwrite und meldet jede Anfrage sofort an support@webklar.com, Antworten gehen an die Absenderadresse. - src/lib/contact.ts ersetzt src/lib/appwrite.ts, kein Appwrite-SDK mehr im Bundle - Honeypot-Feld "website" (unsichtbar, nicht per Tab erreichbar) - maxLength passend zu den Grenzen der API (120/200/200/4000) - eigener Hinweis bei 429 (zu viele Anfragen) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
795c79d393
commit
cbc149f9f8
6 files changed
+181
-63
No files matched your search
+28
-6
@@ -1,5 +1,6 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { usePageMeta } from "@/hooks/use-page-meta";
|
||||
import { CONTACT_LIMITS, ContactSendError, sendContactMessage } from "@/lib/contact";
|
||||
import "./unterseiten.css";
|
||||
|
||||
type Rueckmeldung = { art: "erfolg" | "fehler"; titel: string; text: string };
|
||||
@@ -18,6 +19,7 @@ const Contact = () => {
|
||||
email: "",
|
||||
company: "",
|
||||
message: "",
|
||||
website: "",
|
||||
});
|
||||
|
||||
const handleChange = (
|
||||
@@ -35,20 +37,21 @@ const Contact = () => {
|
||||
setIsSubmitting(true);
|
||||
setRueckmeldung(null);
|
||||
try {
|
||||
// Das Appwrite-SDK wird erst beim Absenden geladen (Spezifikation 9.7)
|
||||
const { createContactDocument } = await import("@/lib/appwrite");
|
||||
await createContactDocument(formData);
|
||||
await sendContactMessage(formData);
|
||||
setRueckmeldung({
|
||||
art: "erfolg",
|
||||
titel: "Nachricht gesendet.",
|
||||
text: "Wir melden uns spätestens am nächsten Werktag bei Ihnen.",
|
||||
});
|
||||
setFormData({ name: "", email: "", company: "", message: "" });
|
||||
} catch {
|
||||
setFormData({ name: "", email: "", company: "", message: "", website: "" });
|
||||
} catch (fehler) {
|
||||
setRueckmeldung({
|
||||
art: "fehler",
|
||||
titel: "Die Nachricht konnte nicht gesendet werden.",
|
||||
text: "Bitte versuchen Sie es noch einmal oder schreiben Sie uns direkt per E-Mail.",
|
||||
text:
|
||||
fehler instanceof ContactSendError && fehler.tooMany
|
||||
? "Es kamen gerade zu viele Anfragen. Bitte versuchen Sie es in ein paar Minuten noch einmal oder schreiben Sie uns direkt per E-Mail."
|
||||
: "Bitte versuchen Sie es noch einmal oder schreiben Sie uns direkt per E-Mail.",
|
||||
});
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
@@ -83,6 +86,7 @@ const Contact = () => {
|
||||
type="text"
|
||||
required
|
||||
autoComplete="name"
|
||||
maxLength={CONTACT_LIMITS.name}
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
placeholder="Ihr Name"
|
||||
@@ -96,6 +100,7 @@ const Contact = () => {
|
||||
type="email"
|
||||
required
|
||||
autoComplete="email"
|
||||
maxLength={CONTACT_LIMITS.email}
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
placeholder="ihre@email.de"
|
||||
@@ -112,6 +117,7 @@ const Contact = () => {
|
||||
name="company"
|
||||
type="text"
|
||||
autoComplete="organization"
|
||||
maxLength={CONTACT_LIMITS.company}
|
||||
value={formData.company}
|
||||
onChange={handleChange}
|
||||
placeholder="Name Ihres Betriebs"
|
||||
@@ -124,12 +130,28 @@ const Contact = () => {
|
||||
id="message"
|
||||
name="message"
|
||||
required
|
||||
maxLength={CONTACT_LIMITS.message}
|
||||
value={formData.message}
|
||||
onChange={handleChange}
|
||||
placeholder="z. B. neue Website, Online-Shop, Web-App oder Automatisierung …"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Honeypot gegen Bots: für Menschen unsichtbar und nicht erreichbar, die Kontakt-API verwirft
|
||||
Anfragen, in denen es ausgefüllt ist */}
|
||||
<div className="wk-visually-hidden" aria-hidden="true">
|
||||
<label htmlFor="website">Website (bitte leer lassen)</label>
|
||||
<input
|
||||
id="website"
|
||||
name="website"
|
||||
type="text"
|
||||
tabIndex={-1}
|
||||
autoComplete="off"
|
||||
value={formData.website}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="wk-form__senden">
|
||||
<button type="submit" className="wk-btn wk-btn--primary" aria-disabled={isSubmitting}>
|
||||
{isSubmitting ? "Wird gesendet …" : "Nachricht senden"}
|
||||
|
||||
Reference in new issue
Block a user