Files
Octopus-React-Wp/frontend/src/components/Pages/Contact.jsx
T
2025-01-08 22:19:50 +01:00

508 lines
15 KiB
React
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect, lazy, Suspense } from "react";
import {
Box,
TextField,
Typography,
Button,
Grid,
Checkbox,
FormControlLabel,
Snackbar,
Alert,
CircularProgress,
Card,
CardContent,
Modal,
Fade,
Backdrop,
} from "@mui/material";
import SEO from "../SEO";
import api from "../../api";
import Faq from "../Faq";
const FAQ = lazy(() => import('../Faq'));
const Contact = () => {
const [metaTitle, setMetaTitle] = useState("Contactez-nous");
const [metaDescription, setMetaDescription] = useState(
"Contactez notre équipe pour plus d'informations."
);
const [formData, setFormData] = useState({
name: "",
email: "",
subject: "",
message: "",
consent: false,
});
const [errors, setErrors] = useState({});
const [loading, setLoading] = useState(false);
const [successMessage, setSuccessMessage] = useState(false);
const [openLightbox, setOpenLightbox] = useState(false);
const [showFAQ, setShowFAQ] = useState(false); // État pour afficher/masquer la FAQ
const handleToggleFAQ = () => {
setShowFAQ((prev) => !prev);
};
useEffect(() => {
const fetchSEOData = async () => {
try {
const response = await api.get(
"wp/v2/pages/116?_fields=acf,rank_math_title,rank_math_description"
);
const { rank_math_title, rank_math_description } = response.data;
setMetaTitle(rank_math_title || "Contactez-nous");
setMetaDescription(rank_math_description || "Contactez notre équipe.");
} catch (error) {
console.error(
"Erreur lors de la récupération des données SEO :",
error
);
}
};
fetchSEOData();
}, []);
const validate = () => {
const newErrors = {};
if (!formData.name) newErrors.name = "Le nom est requis.";
if (!formData.email || !/\S+@\S+\.\S+/.test(formData.email))
newErrors.email = "Une adresse e-mail valide est requise.";
if (!formData.subject) newErrors.subject = "Le sujet est requis.";
if (!formData.message) newErrors.message = "Le message est requis.";
if (!formData.consent)
newErrors.consent =
"Vous devez accepter la politique de confidentialité.";
return newErrors;
};
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData({
...formData,
[name]: type === "checkbox" ? checked : value,
});
};
const handleSubmit = async (e) => {
e.preventDefault();
const validationErrors = validate();
setErrors(validationErrors);
if (Object.keys(validationErrors).length === 0) {
setLoading(true);
try {
const response = await fetch(
"https://votre-site.com/wp-json/custom/v1/contact",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
}
);
if (response.ok) {
setSuccessMessage(true);
setFormData({
name: "",
email: "",
subject: "",
message: "",
consent: false,
});
} else {
const errorData = await response.json();
throw new Error(errorData.message || "Une erreur est survenue.");
}
} catch (error) {
alert(error.message);
} finally {
setLoading(false);
}
}
};
const handleOpenLightbox = () => {
setOpenLightbox(true);
};
const handleCloseLightbox = () => {
setOpenLightbox(false);
};
return (
<Box>
{/* SEO */}
<SEO title={metaTitle} description={metaDescription} />
{/* Section Attention */}
<Box
sx={{
backgroundImage: `url('https://via.placeholder.com/1920x800')`,
backgroundSize: "cover",
backgroundPosition: "center",
minHeight: "50vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
textAlign: "center",
color: "white",
padding: "20px",
}}
>
<Box>
<Typography
variant="h1"
sx={{
color: "#000",
fontWeight: "bold",
fontSize: { xs: "2rem", md: "3rem", lg: "4rem" },
mb: 2,
}}
>
Contactez-nous
</Typography>
<Typography
variant="body2"
sx={{
color: "#000",
fontSize: { xs: "1rem", md: "1rem" },
maxWidth: "600px",
mx: "auto",
}}
>
Notre bureau détude technique est, par essence, spécialisé.
Vous pouvez donc faire appel à nous pour un diagnostic ponctuel portant sur tel ou tel équipement ou ouvrage du bâtiment
(structures, chaufferie, ascenseur).<br></br> <br></br>
Une question? Une demande particulière? Remplissez le formulaire
ci-dessous ou consultez nos coordonnées.
</Typography>
</Box>
</Box>
{/* Section Coordonnées et Horaires */}
<Box sx={{ padding: "40px 20px", backgroundColor: "#f9f9f9" }}>
<Grid container spacing={4}>
{/* Coordonnées */}
<Grid item xs={12} md={6}>
<Card
sx={{
boxShadow: 2,
borderRadius: 2,
padding: "20px",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
height: "80%",
}}
>
<Box>
<Typography
variant="h2"
sx={{
fontSize: { xs: "2rem", md: "2rem", lg: "3rem" },
fontWeight: "bold",
color: "#0e467f",
mb: 2,
}}
>
Nos coordonnées
</Typography>
<Typography variant="body1">
<strong>Adresse :</strong>67 Bd Winston Churchill, Le Mans,
France
</Typography>
<Typography variant="body1">
<strong>Téléphone :</strong> 02.43.85.09.01
</Typography>
<Typography variant="body1">
<strong>Email :</strong> contact@be-in3.com
</Typography>
</Box>
<Box
onClick={handleOpenLightbox}
sx={{
position: "relative",
cursor: "pointer",
width: "120px",
height: "120px",
borderRadius: "8px",
overflow: "hidden",
boxShadow: 3,
"&:hover": {
transform: "scale(1.10)",
boxShadow: 4,
transition: "transform 0.3s, box-shadow 0.3s",
},
"&:hover::before": {
content: '"Cliquez pour agrandir"',
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
backgroundColor: "rgba(0, 0, 0, 0.7)",
color: "white",
padding: "5px 10px",
borderRadius: "4px",
fontSize: "12px",
},
}}
>
<img
src="https://picsum.photos/id/442/300.webp"
alt="Carte"
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
</Box>
</Card>
</Grid>
{/* Horaires */}
<Grid item xs={12} md={6}>
<Card
sx={{
boxShadow: 2,
borderRadius: 2,
padding: "20px",
backgroundColor: "#fff",
height: "80%",
}}
>
<CardContent>
<Typography
variant="h2"
sx={{
fontSize: { xs: "2rem", md: "2rem", lg: "3rem" },
fontWeight: "bold",
color: "#0e467f",
mb: 2,
textAlign: "left",
}}
>
Horaires d'ouverture
</Typography>
<Typography variant="body1">
<strong>Lundi - Mardi :</strong> 9h00 - 16h00
</Typography>
<Typography variant="body1">
<strong>Mercredi :</strong> 09h00 - 12h00
</Typography>
<Typography variant="body1">
<strong>Jeudi - Vendredi :</strong> 09h00 - 17h00
</Typography>
<Typography variant="body1">
<strong>Samedi - Dimanche :</strong> Fermé
</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
</Box>
{/* Lightbox */}
<Modal
open={openLightbox}
onClose={handleCloseLightbox}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{ timeout: 500 }}
>
<Fade in={openLightbox}>
<Box
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: "90%",
maxWidth: "800px",
backgroundColor: "white",
boxShadow: 24,
borderRadius: 2,
overflow: "hidden",
}}
>
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2670.1862696285393!2d0.22040227623964043!3d47.990787261369235!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47e28ec5f984044d%3A0xa3a21789f4a4eaa6!2sIN3%20Int%C3%A9grale%20Ing%C3%A9nierie%20Internationale%20Bureau%20D&#39;%C3%A9tudes%20Ing%C3%A9nieries%20Ma%C3%AEtrise%20d&#39;oeuvre!5e0!3m2!1sfr!2sfr!4v1736328111099!5m2!1sfr!2sfr%22%20width=%22600%22%20height=%22450%22%20style=%22border:0;%22%20allowfullscreen=%22%22%20loading=%22lazy%22%20referrerpolicy=%22no-referrer-when-downgrade%22"
width="100%"
height="400"
title="Carte interactive"
style={{ border: 0 }}
allowFullScreen=""
loading="lazy"
/>
</Box>
</Fade>
</Modal>
{/* Section Action */}
<Box
sx={{
backgroundColor: "#0e467f",
color: "white",
textAlign: "center",
padding: "40px 20px",
}}
>
<Typography
variant="h2"
sx={{
fontSize: { xs: "2rem", md: "2rem", lg: "3rem" }, // Responsive
fontWeight: "bold",
mb: 2,
fontSize: { xs: "1.5rem", md: "2rem" },
}}
>
Besoin d'une assistance immédiate?
</Typography>
<Button
onClick={handleToggleFAQ}
variant="contained"
sx={{
textTransform: "none",
fontWeight: "bold",
backgroundColor: "#00bcd4",
"&:hover": { backgroundColor: "#0288d1" },
}}
>
{showFAQ ? "Masquer la FAQ" : "Afficher la FAQ"}
</Button>
</Box>
{/* Section FAQ */}
<Suspense fallback={<div>Chargement...</div>}>
<Faq showFAQ={showFAQ} />
</Suspense>
{/* Formulaire de contact */}
<Box
sx={{
maxWidth: "800px",
margin: "auto",
padding: "40px",
boxShadow: 3,
borderRadius: 2,
backgroundColor: "#fff",
mt: 4,
}}
>
<Typography
variant="h2"
sx={{
mb: 4,
textAlign: "center",
fontWeight: "bold",
color: "#0e467f",
}}
>
Formulaire de contact
</Typography>
<form onSubmit={handleSubmit} noValidate>
<TextField
label="Nom"
name="name"
value={formData.name}
onChange={handleChange}
error={Boolean(errors.name)}
helperText={errors.name}
fullWidth
margin="normal"
variant="outlined"
/>
<TextField
label="E-mail"
name="email"
value={formData.email}
onChange={handleChange}
error={Boolean(errors.email)}
helperText={errors.email}
fullWidth
margin="normal"
variant="outlined"
/>
<TextField
label="Sujet"
name="subject"
value={formData.subject}
onChange={handleChange}
error={Boolean(errors.subject)}
helperText={errors.subject}
fullWidth
margin="normal"
variant="outlined"
/>
<TextField
label="Message"
name="message"
value={formData.message}
onChange={handleChange}
error={Boolean(errors.message)}
helperText={errors.message}
fullWidth
margin="normal"
variant="outlined"
multiline
rows={4}
/>
<FormControlLabel
control={
<Checkbox
name="consent"
checked={formData.consent}
onChange={handleChange}
/>
}
label="J'accepte la politique de confidentialité."
sx={{ mt: 2, color: errors.consent ? "red" : "inherit" }}
/>
{errors.consent && (
<Typography variant="caption" color="error">
{errors.consent}
</Typography>
)}
<Box sx={{ textAlign: "center", mt: 3 }}>
<Button
type="submit"
variant="contained"
color="primary"
size="large"
disabled={loading}
sx={{
textTransform: "none",
fontWeight: "bold",
px: 5,
}}
>
{loading ? (
<CircularProgress size={24} sx={{ color: "#fff" }} />
) : (
"Envoyer"
)}
</Button>
</Box>
</form>
<Snackbar
open={successMessage}
autoHideDuration={6000}
onClose={() => setSuccessMessage(false)}
>
<Alert onClose={() => setSuccessMessage(false)} severity="success">
Message envoyé avec succès!
</Alert>
</Snackbar>
</Box>
</Box>
);
};
export default Contact;