the form should showcase red labels if i leave the fields empty for each individual field. but here when i click submit the form submitted successfully pop up shows and and the entire form clears up even when the entire form was empty . I feel the captcha is causing the issue with the overall logic but how do i fix that.
import React, { useState,useEffect,useRef } from 'react';
import { Headings } from '../../components';
import './Contact.css';
import { useTranslation } from 'react-i18next';
import axios from 'axios';
import { Toast } from 'react-bootstrap';
const Contact = () => {
const { t } = useTranslation();
const [captchaText, setCaptchaText] = useState('');
const [userInput, setUserInput] = useState('');
const canvasRef = useRef(null);
const [showToast, setShowToast] = useState(false);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
initializeCaptcha(ctx);
}, []);
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
companyName: '',
phoneNumber: '',
message: '',
solutionType: '',
agreeToCommunications: false,
agreeToStoreData: false
});
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const generateRandomChar = (min, max) =>
String.fromCharCode(Math.floor
(Math.random() * (max - min + 1) + min));
const generateCaptchaText = () => {
let captcha = '';
for (let i = 0; i < 2; i++) {
captcha += generateRandomChar(65, 90);
captcha += generateRandomChar(97, 122);
captcha += generateRandomChar(48, 57);
}
return captcha.split('').sort(
() => Math.random() - 0.5).join('');
};
const drawCaptchaOnCanvas = (ctx, captcha) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const textColors = ['rgb(0,0,0)', 'rgb(130,130,130)'];
const letterSpace = 150 / captcha.length;
for (let i = 0; i < captcha.length; i++) {
const xInitialSpace = 25;
ctx.font = '20px Roboto Mono';
ctx.fillStyle = textColors[Math.floor(
Math.random() * 2)];
ctx.fillText(
captcha[i],
xInitialSpace + i * letterSpace,
// Randomize Y position slightly
Math.floor(Math.random() * 16 + 25),
100
);
}
};
const initializeCaptcha = (ctx) => {
setUserInput('');
const newCaptcha = generateCaptchaText();
setCaptchaText(newCaptcha);
drawCaptchaOnCanvas(ctx, newCaptcha);
};
const handleUserInputChange = (e) => {
setUserInput(e.target.value);
};
const handleCaptchaSubmit = () => {
if (userInput === captchaText) {
setShowToast(true);
// Clear form fields after successful submission
;
} else {
alert('Incorrect Captcha');
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
initializeCaptcha(ctx);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
// Send form data to backend API
const response = await axios.post('https://orelse.ai/api/contact', formData);
console.log('Form submission successful:', response.data);
} catch (error) {
console.error('Form submission error:', error);
}
};
const handlePhoneChange = (value) => {
setFormData({ ...formData, phoneNumber: value });
};
return (
<div className="section-padding" id="contact">
<Headings title={t("Contact Us")} text={t("Let's Discuss the Best Solution for You")} />
<div className="contact-divider" style={{display:'flex'}}>
<div className="col-md-4" style={{padding:'60px' ,backgroundColor:'#f3f3f3' }}>
<h1 className='title'>Invest in nature</h1>
<p>Questions or requests for orelse? Our team is here to help. Tell us a little about your needs to be directed to the appropriate team.</p>
</div>
<div className="col-md-8">
<div className="contact" >
<div className="row">
<div className="formdetails">
<form onSubmit={handleSubmit}>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ display: 'flex', marginBottom: '20px' }}>
<input
className="form-control"
type="text"
placeholder={t("First Name")}
name="firstName"
value={formData.firstName}
onChange={handleChange}
required
/>
</div>
<div style={{ display: 'flex', marginBottom: '20px' }}>
<input
className="form-control"
type="text"
placeholder={t("Last Name")}
name="lastName"
value={formData.lastName}
onChange={handleChange}
required
/>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ display: 'flex', marginBottom: '20px' }}>
<input
className="form-control"
type="email"
placeholder={t("Email")}
name="email"
value={formData.email}
onChange={handleChange}
required
/>
</div>
<div style={{ display: 'flex', marginBottom: '20px' }}>
<input
className="form-control"
type="text"
placeholder={t("Company Name")}
name="companyName"
value={formData.companyName}
onChange={handleChange}
required
/>
</div>
</div>
<div style={{ display: 'flex', marginBottom: '20px' }}>
<input
className="form-control"
type="tel"
placeholder={t("Phone Number")}
name="phoneNumber"
value={formData.phoneNumber}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="Textarea1">{t("Message*")}</label>
<textarea
className="form-control"
id="Textareamessage"
rows="3"
name="message"
value={formData.message}
onChange={handleChange}
required
></textarea>
</div>
<div className="form-group">
<label htmlFor="solutionType">{t("Select Solution Type")}</label>
<select
className="form-control"
id="solutionType"
name="solutionType"
value={formData.solutionType}
onChange={handleChange}
>
<option value="">{t("Select Solution Type")}</option>
<option value="Measuring my emissions">{t("Measuring my emissions")}</option>
<option value="Sourcing sustainable grain">{t("Sourcing sustainable grain")}</option>
<option value="Creating a custom sustainable program">{t("Creating a custom sustainable program")}</option>
<option value="Purchasing carbon offsets">{t("Purchasing carbon offsets")}</option>
<option value="Transaction tooling">{t("Transaction tooling")}</option>
<option value="Scientific Collaboration">{t("Scientific Collaboration")}</option>
<option value="MRV Engine">{t("MRV Engine")}</option>
</select>
</div>
<div className="form-group checkbox-group">
<input
type="checkbox"
id="checkbox"
name="agreeToCommunications"
checked={formData.agreeToCommunications}
onChange={() => setFormData({ ...formData, agreeToCommunications: !formData.agreeToCommunications })}
/>
<label htmlFor="checkbox">{t("I agree to receive other communications from orelse Solutions")}</label>
</div>
<div className="form-group checkbox-group">
<input
type="checkbox"
id="checkbox2"
name="agreeToStoreData"
checked={formData.agreeToStoreData}
onChange={() => setFormData({ ...formData, agreeToStoreData: !formData.agreeToStoreData })}
/>
<label htmlFor="checkbox2">{t("I agree to orelse to store and process my personal data")}</label>
</div>
<div>
<label style={{ marginTop:'20px',minWidth: '130px' }}>{t("Captcha Verification")}</label>
<div className="container-captcha">
<div className="wrapper-captcha">
<canvas ref={canvasRef}
width="200"
height="70">
</canvas>
<button id="reload-button" onClick={
() => initializeCaptcha(
canvasRef.current.getContext('2d'))}>
Reload
</button>
</div>
<input
className="form-control"
type="text"
id="user-input"
placeholder="Enter the text in the image"
value={userInput}
onChange={handleUserInputChange}/>
</div>
</div>
<button type="submit" className="btn-orelse-contact" onClick={handleCaptchaSubmit}> {t("Submit")}</button>
</form>
<Toast
show={showToast}
onClose={() => setShowToast(false)}
delay={5000}
autohide
position="top-end" // Position the toast on the top right corner
>
<Toast.Header>
<strong className="mr-auto">Success</strong>
</Toast.Header>
<Toast.Body>Form submitted successfully!</Toast.Body>
</Toast>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default Contact;
I also tried validating individual fields where i checked if that particular field was empty string and if yes show the error but it still wont work