Gestion de page ACF maj
This commit is contained in:
parent
038dd3498a
commit
7df66f13df
@ -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;
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user