diff --git a/app/api/contact/route.ts b/app/api/contact/route.ts new file mode 100644 index 0000000..b1597e2 --- /dev/null +++ b/app/api/contact/route.ts @@ -0,0 +1,63 @@ +import {NextRequest, NextResponse} from "next/server"; +import nodemailer from "nodemailer"; + +export async function POST(req: NextRequest) { + const {captcha, ...data} = await req.json(); + const {name, email, company, phone, website, message} = data; + + const isDev = process.env.NODE_ENV === "development"; + const hCaptchaSecret = isDev + ? "0x0000000000000000000000000000000000000000" // hCaptcha test secret + : "ES_ff59a664dc764f92870bf2c7b4eab7c5"; + + // ✅ hCaptcha verification + const captchaRes = await fetch("https://hcaptcha.com/siteverify", { + method: "POST", + headers: {"Content-Type": "application/x-www-form-urlencoded"}, + body: `response=${captcha}&secret=${hCaptchaSecret}`, + }); + + const captchaResult = await captchaRes.json(); + if (!captchaResult.success) { + return NextResponse.json({success: false, error: "CAPTCHA-Verifizierung fehlgeschlagen."}, {status: 403}); + } + + // ✅ Send mail with Ethereal (for dev) or real SMTP later + const testAccount = await nodemailer.createTestAccount(); + const transporter = nodemailer.createTransport({ + host: testAccount.smtp.host, + port: testAccount.smtp.port, + secure: testAccount.smtp.secure, + auth: { + user: testAccount.user, + pass: testAccount.pass, + }, + }); + + const mailToMe = { + from: email, + to: "thatsaphorn@outlook.de", + subject: "Neue Nachricht vom Kontaktformular", + html: ` +

Name: ${name}

+

E-Mail: ${email}

+

Firma: ${company || "—"}

+

Telefon: ${phone || "—"}

+

Webseite: ${website || "—"}

+

Nachricht:

+

${message}

+ `, + }; + + try { + const info = await transporter.sendMail(mailToMe); + + return NextResponse.json({ + success: true, + previewUrl: nodemailer.getTestMessageUrl(info), + }); + } catch (err) { + console.error("Mail send error:", err); + return NextResponse.json({success: false, error: "Mailversand fehlgeschlagen."}, {status: 500}); + } +} diff --git a/components/Contact/Section/ContactFormSection.tsx b/components/Contact/Section/ContactFormSection.tsx index 18a19b2..15b336e 100644 --- a/components/Contact/Section/ContactFormSection.tsx +++ b/components/Contact/Section/ContactFormSection.tsx @@ -1,12 +1,68 @@ 'use client'; -import React from "react"; +import React, {useState} from "react"; import {motion} from "framer-motion"; import {useThemeColors} from "@/utils/useThemeColors"; +import HCaptcha from "@hcaptcha/react-hcaptcha"; const ContactFormSection = () => { const colors = useThemeColors(); + const [form, setForm] = useState({ + name: "", + email: "", + company: "", + phone: "", + website: "", + message: "", + }); + + const [captchaToken, setCaptchaToken] = useState(""); + const [submitted, setSubmitted] = useState(false); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + const isDev = process.env.NODE_ENV === "development"; + const hCaptchaSiteKey = isDev + ? "10000000-ffff-ffff-ffff-000000000001" // hCaptcha test sitekey + : "ES_ff59a664dc764f92870bf2c7b4eab7c5"; + + const handleChange = (e: React.ChangeEvent) => { + setForm({...form, [e.target.name]: e.target.value}); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setError(""); + + if (!captchaToken) { + setError("Bitte löse das CAPTCHA, um fortzufahren."); + setLoading(false); + return; + } + + try { + const res = await fetch("/api/contact", { + method: "POST", + headers: {"Content-Type": "application/json"}, + body: JSON.stringify({...form, captcha: captchaToken}), + }); + + if (res.ok) { + setSubmitted(true); + setForm({name: "", email: "", company: "", phone: "", website: "", message: ""}); + } else { + const resJson = await res.json(); + setError(resJson?.error || "Ein Fehler ist aufgetreten. Bitte versuche es später erneut."); + } + } catch (err) { + setError("Serverfehler. Bitte versuche es später erneut."); + } + + setLoading(false); + }; + return (
{ Wir freuen uns über dein Interesse und melden uns schnellstmöglich bei dir zurück. -
-
+ {submitted ? ( +
✅ Deine Nachricht wurde erfolgreich + gesendet!
+ ) : ( + +
+ {[ + { + label: "Dein Name *", + name: "name", + type: "text", + required: true, + placeholder: "Max Mustermann" + }, + { + label: "Deine E-Mail *", + name: "email", + type: "email", + required: true, + placeholder: "max@example.com" + }, + { + label: "Firmenname (optional)", + name: "company", + type: "text", + required: false, + placeholder: "Mustermann GmbH" + }, + { + label: "Telefonnummer (optional)", + name: "phone", + type: "tel", + required: false, + placeholder: "+49 123 456789" + }, + { + label: "Webseite (optional)", + name: "website", + type: "url", + required: false, + placeholder: "https://..." + }, + ].map((field, index) => ( + + + + + ))} +
+ - { - - + + {error && ( +
+ ❌ {error} +
+ )} + - - + - - - - - - - - - - -
- - - -