- Changed API and Keycloak URLs in `.env` and `.env.development`. - Updated `vite.config.js` to reflect new allowed hosts. - Refactored components to use `useContent` context instead of individual contexts for blogs, companies, and projects. - Improved error handling in `App` component with `AppError`. - Added FPS monitoring to `ParticlesBackground` component for developer mode. - Removed unused contexts and adjusted related imports. - Enhanced styling for various components and added new styles for FPS monitor. - Cleaned up SVG files by removing unnecessary attributes.
149 lines
3.9 KiB
JavaScript
149 lines
3.9 KiB
JavaScript
import { useState, useRef } from "react";
|
|
import axios from "axios";
|
|
import CheckIcon from "../../icons/CheckIcon";
|
|
import Turnstile from "./Turnstile";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { useContent } from "../../contexts/ContentContext";
|
|
import LoadingIcon from "../../icons/LoadingIcon.jsx";
|
|
import { useEffect } from "react";
|
|
const apiUrl = import.meta.env.VITE_API_URL;
|
|
const turnstileKey = import.meta.env.VITE_TURNSTILE_KEY;
|
|
|
|
const ContactForm = () => {
|
|
const navigate = useNavigate();
|
|
const { settings } = useContent();
|
|
const turnstileRef = useRef(null); // Ref for Turnstile
|
|
|
|
const [formData, setFormData] = useState({
|
|
name: "",
|
|
email: "",
|
|
message: "",
|
|
});
|
|
|
|
const [token, setToken] = useState("");
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
const [loadTurnstile, setLoadTurnstile] = useState(false);
|
|
|
|
const handleChange = (e) => {
|
|
setFormData({
|
|
...formData,
|
|
[e.target.name]: e.target.value,
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (turnstileKey && turnstileKey != "") {
|
|
setTimeout(() => {
|
|
setLoadTurnstile(true);
|
|
}, 500);
|
|
}
|
|
}, []);
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
|
|
if (!token) {
|
|
alert("Please complete the CAPTCHA");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
// Send formData + token to your backend using axios
|
|
const response = await axios.post(`${apiUrl}/contact`, {
|
|
...formData,
|
|
token,
|
|
});
|
|
console.log(settings);
|
|
navigate(`/${settings.redirects.contactFormComplete}`);
|
|
console.log("Form submitted:", response.data);
|
|
} catch (error) {
|
|
console.error("Error submitting form:", error);
|
|
const errorData = error.response.data;
|
|
setError(errorData);
|
|
if (errorData.code.startsWith("captcha-")) {
|
|
turnstileRef.current.reset();
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="tb-contact-form-wrapper">
|
|
<form onSubmit={handleSubmit} className="tb-form">
|
|
<div className="tb-form-input-wrapper">
|
|
<input
|
|
id="name"
|
|
type="text"
|
|
name="name"
|
|
value={formData.name}
|
|
onChange={handleChange}
|
|
required
|
|
className="tb-form-input"
|
|
placeholder="Your Name"
|
|
disabled={loading}
|
|
autoComplete="name"
|
|
/>
|
|
</div>
|
|
|
|
<div className="tb-form-input-wrapper">
|
|
<input
|
|
id="email"
|
|
type="email"
|
|
name="email"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
required
|
|
className="tb-form-input"
|
|
placeholder="Email"
|
|
disabled={loading}
|
|
autoComplete="email"
|
|
/>
|
|
</div>
|
|
|
|
<div className="tb-form-input-wrapper">
|
|
<textarea
|
|
id="message"
|
|
name="message"
|
|
value={formData.message}
|
|
onChange={handleChange}
|
|
required
|
|
rows="5"
|
|
className="tb-form-input"
|
|
placeholder="Write your message here..."
|
|
disabled={loading}
|
|
autoComplete="message"
|
|
></textarea>
|
|
</div>
|
|
|
|
{/* Cloudflare Turnstile */}
|
|
{loadTurnstile == true && (
|
|
<Turnstile
|
|
siteKey={turnstileKey}
|
|
theme="light"
|
|
ref={turnstileRef}
|
|
onVerify={(token) => setToken(token)}
|
|
/>
|
|
)}
|
|
|
|
<div className="tb-form-actions">
|
|
<button
|
|
type="submit"
|
|
className={"tb-button"}
|
|
style={{ marginTop: 0 }}
|
|
disabled={loading}
|
|
>
|
|
{loading ? <LoadingIcon /> : <CheckIcon />}
|
|
Send Message
|
|
</button>
|
|
{error && <p className="tb-form-error">{error.message}</p>}
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ContactForm;
|