diff --git a/backend/config.php b/backend/config.php new file mode 100644 index 0000000..05369cf --- /dev/null +++ b/backend/config.php @@ -0,0 +1,7 @@ + 'dev@andre-kempf.com', + 'from_email' => 'noreply@andre-kempf.com', + 'app_name' => 'Portfolio Contact', +]; \ No newline at end of file diff --git a/backend/sendMail.php b/backend/sendMail.php new file mode 100644 index 0000000..d18a452 --- /dev/null +++ b/backend/sendMail.php @@ -0,0 +1,67 @@ +website)) { + http_response_code(200); + echo json_encode(["status" => "success"]); + exit; + } + + // 2. Sanitize inputs & set fallbacks + $email = filter_var($params->email ?? '', FILTER_VALIDATE_EMAIL); + $name = htmlspecialchars(trim($params->name ?? 'Anonymous'), ENT_QUOTES, 'UTF-8'); + $text = htmlspecialchars(trim($params->message ?? ''), ENT_QUOTES, 'UTF-8'); + + // Validate required fields + if (!$email || empty($text)) { + http_response_code(400); + echo json_encode(["status" => "error", "message" => "Invalid input"]); + exit; + } + + // 3. Render template + $emailBody = renderEmailTemplate($name, $email, $text, $params->message ?? ''); + $subject = "{$config['app_name']}: $name"; + + // 4. Set headers + $headers = [ + 'MIME-Version: 1.0', + 'Content-type: text/html; charset=utf-8', + "From: {$config['from_email']}", + "Reply-To: $email" + ]; + + // Send email + $success = mail($config['recipient_email'], $subject, $emailBody, implode("\n", $headers)); + + if ($success) { + http_response_code(200); + echo json_encode(["status" => "success"]); + } else { + http_response_code(500); + echo json_encode(["status" => "error"]); + } + break; + + default: // Reject any other HTTP method + header("Allow: POST", true, 405); + exit; +} \ No newline at end of file diff --git a/backend/templates/emailTemplate.php b/backend/templates/emailTemplate.php new file mode 100644 index 0000000..7f31a0c --- /dev/null +++ b/backend/templates/emailTemplate.php @@ -0,0 +1,35 @@ + +
+
+ // Portfolio Contact Message +

New message from $name

+
+ +
+
+ From: $name ($email) +
+
{$formattedText}
+
+ +
+ + ➜ Quick Reply + +
+
+ + "; +} \ No newline at end of file diff --git a/sendMail.php b/sendMail.php deleted file mode 100644 index 57cb3d8..0000000 --- a/sendMail.php +++ /dev/null @@ -1,43 +0,0 @@ -website)) { - http_response_code(200); - exit; - } - - // Extract values - $email = $params->email; - $name = $params->name; - $message = $params->message; - - $recipient = 'dev@andre-kempf.com'; - $subject = "Contact Form <$email>"; - $message = "From: $name
Email: $email

$message"; - - $headers = array(); - $headers[] = 'MIME-Version: 1.0'; - $headers[] = 'Content-type: text/html; charset=utf-8'; - $headers[] = "From: noreply@andre-kempf.com"; - - mail($recipient, $subject, $message, implode("\r\n", $headers)); - break; - - default: // Reject non-POST or OPTIONS requests. - header("Allow: POST", true, 405); - exit; -} \ No newline at end of file diff --git a/src/components/Contact.tsx b/src/components/Contact.tsx index 7160259..92c41f5 100644 --- a/src/components/Contact.tsx +++ b/src/components/Contact.tsx @@ -34,13 +34,16 @@ export default function Contact() { setError(false); try { - const response = await fetch("https://andre-kempf.com/sendMail.php", { - method: "POST", - headers: { - "Content-Type": "application/json", + const response = await fetch( + "https://andre-kempf.com/backend/sendMail.php", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ name, email, message, honeypot }), }, - body: JSON.stringify({ name, email, message, honeypot }), - }); + ); if (response.ok) { setSubmitted(true);