Gestion de page ACF maj

This commit is contained in:
sebvtl728 2025-02-11 00:38:29 +01:00
parent 038dd3498a
commit 7df66f13df
2 changed files with 138 additions and 238 deletions

View File

@ -20,13 +20,6 @@ function EditPageACF() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [successMessage, setSuccessMessage] = useState("");
const deleteFAQItem = (index) => {
const updatedArray = acfFields.faq?.faq_list.filter((_, i) => i !== index);
setAcfFields({
...acfFields,
faq: { ...acfFields.faq, faq_list: updatedArray },
});
};
// Vérifier l'authentification
useEffect(() => {
@ -35,7 +28,7 @@ function EditPageACF() {
}
}, [navigate]);
// Récupérer les champs ACF des pages
// Récupérer les champs ACF de la page
useEffect(() => {
const fetchPage = async () => {
console.log("📢 Récupération de la page avec ID :", id);
@ -46,22 +39,21 @@ function EditPageACF() {
return;
}
const pageData = await getPageById(id);
try {
const pageData = await getPageById(id);
if (!pageData || !pageData.acf) {
setError("❌ Impossible de charger les champs ACF.");
if (!pageData || !pageData.acf) {
setError("❌ Impossible de charger les champs ACF.");
setLoading(false);
return;
}
setAcfFields(pageData.acf);
setLoading(false);
} catch (error) {
setError("⚠ Impossible de récupérer les champs ACF.");
setLoading(false);
return;
}
setAcfFields({
...pageData.acf,
faq_list: Array.isArray(pageData.acf?.faq?.faq_list)
? pageData.acf.faq.faq_list
: [], // On s'assure d'avoir un tableau vide si ce n'est pas défini
});
setLoading(false);
};
fetchPage();
@ -71,13 +63,8 @@ function EditPageACF() {
const handleUpdateACF = async (e) => {
e.preventDefault();
const updatedACF = {
...acfFields,
faq_list: Array.isArray(acfFields?.faq_list) ? acfFields.faq_list : [],
};
try {
await updatePageACF(id, updatedACF);
await updatePageACF(id, acfFields);
setSuccessMessage("✅ Modifications enregistrées !");
setTimeout(() => navigate("/admin/pages-acf"), 2000);
} catch (error) {
@ -86,7 +73,7 @@ function EditPageACF() {
}
};
// Gérer la modification des champs ACF (y compris objets et tableaux)
// Gérer la modification des champs ACF
const handleFieldChange = (field, value) => {
setAcfFields((prevFields) => ({
...prevFields,
@ -94,25 +81,36 @@ function EditPageACF() {
}));
};
// Ajouter, modifier et supprimer des entrées de FAQ
// Gérer la FAQ : ajouter, modifier et supprimer des entrées
const handleFAQChange = (index, field, value) => {
const updatedFAQ = [...acfFields.faq_list];
const updatedFAQ = [...(acfFields.faq?.faq_list || [])];
updatedFAQ[index][field] = value;
setAcfFields({ ...acfFields, faq_list: updatedFAQ });
setAcfFields({
...acfFields,
faq: { ...acfFields.faq, faq_list: updatedFAQ },
});
};
const addFAQ = () => {
setAcfFields({
...acfFields,
faq_list: [...acfFields.faq_list, { question: "", answer: "" }],
faq: {
...acfFields.faq,
faq_list: [...(acfFields.faq?.faq_list || []), { question: "", answer: "" }],
},
});
};
const deleteFAQ = (index) => {
setAcfFields({
...acfFields,
faq_list: acfFields.faq_list.filter((_, i) => i !== index),
});
const updatedFAQList = acfFields.faq.faq_list.filter((_, i) => i !== index);
const updatedACF = { ...acfFields, faq: { ...acfFields.faq, faq_list: updatedFAQList } };
// Si la FAQ devient vide, on la supprime entièrement pour éviter l'affichage
if (updatedFAQList.length === 0) {
delete updatedACF.faq.faq_list;
}
setAcfFields(updatedACF);
};
if (loading) return <Typography>Chargement...</Typography>;
@ -124,15 +122,13 @@ function EditPageACF() {
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundImage:
"url('https://source.unsplash.com/1600x900/?technology')",
backgroundImage: "url('https://source.unsplash.com/1600x900/?technology')",
backgroundSize: "cover",
backgroundPosition: "center",
}}
>
<Container maxWidth="sm">
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, mt:10 }}>
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, mt: 10 }}>
<Button
startIcon={<ArrowBack />}
variant="outlined"
@ -143,203 +139,82 @@ function EditPageACF() {
Retour à la gestion des pages
</Button>
<Typography
variant="h4"
sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}
>
Modifier les Champs
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}>
Modifier la Page
</Typography>
{error && (
<Typography textAlign="center" color="error" sx={{ mb: 2 }}>
{error}
</Typography>
)}
{successMessage && (
<Typography sx={{ color: "green", textAlign: "center", mb: 2 }}>
{successMessage}
</Typography>
)}
{error && <Typography textAlign="center" color="error" sx={{ mb: 2 }}>{error}</Typography>}
{successMessage && <Typography sx={{ color: "green", textAlign: "center", mb: 2 }}>{successMessage}</Typography>}
<form onSubmit={handleUpdateACF}>
{/* ✅ Affichage dynamique des champs ACF */}
{Object.keys(acfFields).map((field) => {
const value = acfFields[field];
// Si c'est un objet (comme `faq`), afficher ses sous-champs
if (field === "faq") {
return null; // On ne veut pas afficher `faq` en tant que champ texte
}
if (field === "faq_list" && Array.isArray(value)) {
const faqData = acfFields.faq?.faq_list || [];
return (
<Box key="faq_list" sx={{ mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
FAQ
</Typography>
{faqData.map((item, index) => (
<Box
key={index}
sx={{
border: "1px solid #ccc",
padding: 2,
borderRadius: 2,
mb: 2,
position: "relative", // Permet d'aligner le bouton en haut à droite
}}
>
<TextField
label="Question"
fullWidth
variant="outlined"
value={item.question || ""}
onChange={(e) => {
const updatedArray = [...faqData];
updatedArray[index].question = e.target.value;
setAcfFields({
...acfFields,
faq: { ...acfFields.faq, faq_list: updatedArray },
});
}}
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
/>
<TextField
label="Réponse"
fullWidth
variant="outlined"
multiline
rows={3}
value={item.answer || ""}
onChange={(e) => {
const updatedArray = [...faqData];
updatedArray[index].answer = e.target.value;
setAcfFields({
...acfFields,
faq: { ...acfFields.faq, faq_list: updatedArray },
});
}}
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
/>
<Button
startIcon={<Delete />}
variant="outlined"
color="error"
onClick={() => deleteFAQItem(index)}
sx={{
position: "absolute",
top: 10,
right: 10,
}}
>
Supprimer
</Button>
</Box>
))}
<Button
startIcon={<Add />}
variant="contained"
color="primary"
onClick={() => {
setAcfFields({
...acfFields,
faq: {
...acfFields.faq,
faq_list: [...faqData, { question: "", answer: "" }],
},
});
}}
sx={{ mb: 2 }}
>
Ajouter une question
</Button>
</Box>
);
}
// Si c'est un tableau (comme `faq_list`), afficher chaque élément
if (Array.isArray(value)) {
return (
<Box key={field} sx={{ mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
{field.replace(/_/g, " ")}
</Typography>
{value.map((item, index) => (
<Box
key={index}
sx={{
border: "1px solid #ccc",
padding: 2,
borderRadius: 2,
mb: 2,
}}
>
{Object.keys(item).map((subField) => (
<TextField
key={subField}
label={subField.replace(/_/g, " ")}
fullWidth
variant="outlined"
value={item[subField] || ""}
onChange={(e) => {
const updatedArray = [...value];
updatedArray[index][subField] = e.target.value;
setAcfFields({
...acfFields,
[field]: updatedArray,
});
}}
sx={{
mb: 1,
backgroundColor: "#fff",
borderRadius: "5px",
}}
/>
))}
</Box>
))}
<Button
startIcon={<Add />}
variant="contained"
color="primary"
onClick={() => {
setAcfFields({
...acfFields,
[field]: [...value, {}], // Ajoute un objet vide
});
}}
sx={{ mb: 2 }}
>
Ajouter une entrée
</Button>
</Box>
);
}
// Gérer les champs simples
return (
{/* ✅ Affichage dynamique des champs ACF sauf la FAQ */}
<Paper>
{Object.keys(acfFields)
.filter((field) => field !== "faq" && field !== "faq_list") // 🔥 On exclut la FAQ et faq_list
.map((field) => (
<TextField
key={field}
label={field.replace(/_/g, " ")}
fullWidth
variant="outlined"
value={value || ""}
onChange={(e) =>
setAcfFields({ ...acfFields, [field]: e.target.value })
}
value={acfFields[field] || ""}
onChange={(e) => handleFieldChange(field, e.target.value)}
sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }}
/>
);
})}
))}
</Paper>
{/* ✅ Gestion de la FAQ uniquement si elle est définie */}
{acfFields.faq?.faq_list && acfFields.faq.faq_list.length > 0 && (
<Box sx={{ mb: 3 }}>
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>FAQ</Typography>
{acfFields.faq.faq_list.map((item, index) => (
<Box
key={index}
sx={{
border: "1px solid #ccc",
padding: 2,
borderRadius: 2,
mb: 2,
position: "relative",
}}
>
<TextField
label="Question"
fullWidth
variant="outlined"
value={item.question || ""}
onChange={(e) => handleFAQChange(index, "question", e.target.value)}
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
/>
<TextField
label="Réponse"
fullWidth
variant="outlined"
multiline
rows={3}
value={item.answer || ""}
onChange={(e) => handleFAQChange(index, "answer", e.target.value)}
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
/>
<Button
startIcon={<Delete />}
variant="outlined"
color="error"
onClick={() => deleteFAQ(index)}
sx={{ position: "absolute", top: 10, right: 10 }}
>
Supprimer
</Button>
</Box>
))}
<Button startIcon={<Add />} variant="contained" color="primary" onClick={addFAQ} sx={{ mb: 2 }}>
Ajouter une question
</Button>
</Box>
)}
<Button
type="submit"
variant="contained"
color="primary"
fullWidth
startIcon={<Save />}
sx={{ mt: 3 }}
>
<Button type="submit" variant="contained" color="primary" fullWidth startIcon={<Save />} sx={{ mt: 3 }}>
Enregistrer les modifications
</Button>
</form>
@ -349,4 +224,4 @@ function EditPageACF() {
);
}
export default EditPageACF;
export default EditPageACF;

View File

@ -1,40 +1,65 @@
import React from "react";
import React, { useState, useEffect } from "react";
import ServicePageTemplate from "../ServicePageTemplate";
import { getPageById } from "../../wordpress";
const ServiceQuatre = () => {
const [acfData, setAcfData] = useState(null);
const [loading, setLoading] = useState(true);
const pageId = 590; // 🔥 Remplace par l'ID réel de la page WordPress
useEffect(() => {
const fetchACFData = async () => {
try {
const pageData = await getPageById(pageId);
setAcfData(pageData.acf);
} catch (error) {
console.error("❌ Erreur récupération des champs ACF :", error);
} finally {
setLoading(false);
}
};
fetchACFData();
}, []);
// Affichage du chargement en attendant les données ACF
if (loading) {
return <p>Chargement...</p>;
}
const ServiceUn = () => {
const serviceDetails = {
// Hero
title: 'Titre héros', // Modifiable individuellement
subtitle: 'Description, héros', // Modifiable individuellement
title: acfData?.title || "Titre héros !", // Modifiable individuellement
subtitle: acfData?.sub_title || "Description, héros", // Modifiable individuellement
image: "https://picsum.photos/id/1021/1920/1080.webp",
image: "https://picsum.photos/id/1021/1920/1080.webp",
ctaText: "En savoir plus",
ctaLink: "/contact",
// section 1
interestTitle: 'Titre interet', // Modifiable individuellement
description: 'Description interet', // Modifiable individuellement
interestTitle: acfData?.interest_Title || "Titre interet", // Modifiable individuellement
description: "Description interet", // Modifiable individuellement
// section 2
desirTitle: 'Titre', // Modifiable individuellement
desirTitle: "Titre", // Modifiable individuellement
features: [
{
title: "Titre",
description: "Description.",
modalText:"Description Modal.",
modalText: "Description Modal.",
modalImage: "https://picsum.photos/id/300/800/400.webp",
},
{
title: "Titre",
description: "Description.",
modalText:"Description Modal.",
modalText: "Description Modal.",
modalImage: "https://picsum.photos/id/301/800/400.webp",
},
{
title: "Titre",
description: "Description.",
modalText:"Description Modal.",
modalText: "Description Modal.",
modalImage: "https://picsum.photos/id/302/800/400.webp",
},
],
@ -56,4 +81,4 @@ const ServiceUn = () => {
return <ServicePageTemplate {...serviceDetails} />;
};
export default ServiceUn;
export default ServiceQuatre;