Gestion de page ACF
This commit is contained in:
@@ -1,88 +1,129 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import {
|
|
||||||
Box, Typography, Button, Table, TableBody, TableCell,
|
|
||||||
TableContainer, TableHead, TableRow, Paper, TextField
|
|
||||||
} from "@mui/material";
|
|
||||||
import { Edit, ArrowBack } from "@mui/icons-material";
|
|
||||||
import api from "../api";
|
|
||||||
import { getToken } from "../auth";
|
import { getToken } from "../auth";
|
||||||
|
import { fetchPages } from "../wordpress";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Button,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Paper,
|
||||||
|
} from "@mui/material";
|
||||||
|
import { Edit, ArrowBack, Add } from "@mui/icons-material";
|
||||||
|
|
||||||
const GestionPagesACF = () => {
|
const HOME_PAGE_ID = 13; // Remplace 13 par l'ID réel de la page d'accueil
|
||||||
const [pages, setPages] = useState([]);
|
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
function GestionPagesACF() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [pages, setPages] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
// ✅ Vérifie l'authentification
|
// ✅ Vérifier l'authentification
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!getToken()) {
|
if (!getToken()) {
|
||||||
navigate("/admin/login");
|
navigate("/admin/login");
|
||||||
}
|
}
|
||||||
}, [navigate]);
|
}, [navigate]);
|
||||||
|
|
||||||
// ✅ Récupère les pages contenant des champs ACF
|
// ✅ Récupérer les pages ACF et exclure la page d'accueil
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchPages = async () => {
|
const loadPages = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await api.get("wp/v2/pages?_fields=id,title,acf");
|
const response = await fetchPages();
|
||||||
const pagesData = response.data;
|
console.log("📢 Données reçues de fetchPages() :", response);
|
||||||
|
|
||||||
// Filtrer les pages qui ont au moins un champ ACF
|
if (!Array.isArray(response)) {
|
||||||
const pagesWithACF = pagesData.filter(page => page.acf && Object.keys(page.acf).length > 0);
|
console.error(
|
||||||
|
"❌ La réponse `fetchPages()` n'est pas un tableau :",
|
||||||
|
response
|
||||||
|
);
|
||||||
|
setError("❌ Impossible de charger les pages ACF.");
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setPages(pagesWithACF);
|
// ✅ Exclure la page d'accueil
|
||||||
|
const filteredPages = response.filter(
|
||||||
|
(page) => page.id !== HOME_PAGE_ID
|
||||||
|
);
|
||||||
|
setPages(filteredPages);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Erreur chargement des pages :", error);
|
console.error("❌ Erreur chargement pages ACF :", error);
|
||||||
|
setError("Impossible de charger les pages.");
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchPages();
|
loadPages();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// ✅ Filtrage des pages par recherche
|
if (loading) return <Typography>Chargement...</Typography>;
|
||||||
const filteredPages = pages.filter(page =>
|
if (error) return <Typography color="error">{error}</Typography>;
|
||||||
page.title.rendered.toLowerCase().includes(searchTerm.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ padding: "40px 20px" }}>
|
<Box sx={{ padding: "40px 20px", mt: 6 }}>
|
||||||
{/* ✅ En-tête */}
|
<Box
|
||||||
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 4, mt:5 }}>
|
sx={{
|
||||||
<Button startIcon={<ArrowBack />} variant="outlined" color="secondary" onClick={() => navigate("/admin/dashboard")}>
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
mb: 4,
|
||||||
|
mt: 5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
startIcon={<ArrowBack />}
|
||||||
|
variant="outlined"
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => navigate("/admin/dashboard")}
|
||||||
|
>
|
||||||
Retour au Dashboard
|
Retour au Dashboard
|
||||||
</Button>
|
</Button>
|
||||||
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", flexGrow: 1 }}>
|
<Typography
|
||||||
Gestion des Pages ACF
|
variant="h4"
|
||||||
|
sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}
|
||||||
|
>
|
||||||
|
📄 Gestion des Pages
|
||||||
</Typography>
|
</Typography>
|
||||||
|
<Button
|
||||||
|
startIcon={<Add />}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() =>
|
||||||
|
window.open("https://it.sveitl.synology.me/", "_blank")
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Ticket
|
||||||
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* ✅ Recherche */}
|
|
||||||
<TextField
|
|
||||||
label="Rechercher une page..."
|
|
||||||
variant="outlined"
|
|
||||||
fullWidth
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
|
||||||
sx={{ mb: 3 }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* ✅ Tableau des pages */}
|
|
||||||
<TableContainer component={Paper}>
|
<TableContainer component={Paper}>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead sx={{ backgroundColor: "#0e467f" }}>
|
<TableHead sx={{ backgroundColor: "#0e467f" }}>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell sx={{ color: "white", fontWeight: "bold" }}>Titre</TableCell>
|
<TableCell sx={{ color: "white", fontWeight: "bold" }}>
|
||||||
<TableCell sx={{ color: "white", fontWeight: "bold", textAlign: "center" }}>Actions</TableCell>
|
Titre
|
||||||
|
</TableCell>
|
||||||
|
<TableCell
|
||||||
|
sx={{ color: "white", fontWeight: "bold", textAlign: "center" }}
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{filteredPages.length > 0 ? (
|
{pages.length > 0 ? (
|
||||||
filteredPages.map((page) => (
|
pages.map((page) => (
|
||||||
<TableRow key={page.id}>
|
<TableRow key={page.id}>
|
||||||
{/* ✅ Titre de la page */}
|
<TableCell sx={{ fontWeight: "bold" }}>
|
||||||
<TableCell sx={{ fontWeight: "bold" }}>{page.title.rendered}</TableCell>
|
{page.title.rendered}
|
||||||
|
</TableCell>
|
||||||
{/* ✅ Bouton Modifier */}
|
|
||||||
<TableCell sx={{ textAlign: "center" }}>
|
<TableCell sx={{ textAlign: "center" }}>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<Edit />}
|
startIcon={<Edit />}
|
||||||
@@ -98,7 +139,7 @@ const GestionPagesACF = () => {
|
|||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={2} sx={{ textAlign: "center", py: 2 }}>
|
<TableCell colSpan={2} sx={{ textAlign: "center", py: 2 }}>
|
||||||
Aucune page avec champs ACF trouvée.
|
Aucune page avec des champs ACF trouvée.
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)}
|
)}
|
||||||
@@ -107,6 +148,6 @@ const GestionPagesACF = () => {
|
|||||||
</TableContainer>
|
</TableContainer>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export default GestionPagesACF;
|
export default GestionPagesACF;
|
||||||
@@ -168,7 +168,7 @@ function Dashboard() {
|
|||||||
<ArticleIcon fontSize="inherit" />
|
<ArticleIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold" }}>
|
<Typography variant="h6" sx={{ fontWeight: "bold" }}>
|
||||||
Gérer les Pages ACF
|
Gérer les Pages
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ function EditPageACF() {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [successMessage, setSuccessMessage] = useState("");
|
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
|
// ✅ Vérifier l'authentification
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -31,26 +38,30 @@ function EditPageACF() {
|
|||||||
// ✅ Récupérer les champs ACF des pages
|
// ✅ Récupérer les champs ACF des pages
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchPage = async () => {
|
const fetchPage = async () => {
|
||||||
try {
|
console.log("📢 Récupération de la page avec ID :", id);
|
||||||
const pageData = await getPageById(id);
|
|
||||||
console.log("📢 Données ACF reçues :", JSON.stringify(pageData.acf, null, 2));
|
|
||||||
|
|
||||||
if (!pageData.acf || Object.keys(pageData.acf).length === 0) {
|
if (!id) {
|
||||||
setError("❌ Aucun champ ACF disponible pour cette page.");
|
setError("❌ L'ID de la page est invalide !");
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setAcfFields({
|
|
||||||
...pageData.acf,
|
|
||||||
faq_list: Array.isArray(pageData.acf?.faq_list) ? pageData.acf.faq_list : [],
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("❌ Erreur chargement des champs ACF :", error);
|
|
||||||
setError("⚠ Impossible de charger les champs ACF.");
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pageData = await getPageById(id);
|
||||||
|
|
||||||
|
if (!pageData || !pageData.acf) {
|
||||||
|
setError("❌ Impossible de charger 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();
|
fetchPage();
|
||||||
@@ -113,13 +124,15 @@ function EditPageACF() {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
backgroundImage: "url('https://source.unsplash.com/1600x900/?technology')",
|
backgroundImage:
|
||||||
|
"url('https://source.unsplash.com/1600x900/?technology')",
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
backgroundPosition: "center",
|
backgroundPosition: "center",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Container maxWidth="sm">
|
<Container maxWidth="sm">
|
||||||
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3 }}>
|
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, mt:10 }}>
|
||||||
<Button
|
<Button
|
||||||
startIcon={<ArrowBack />}
|
startIcon={<ArrowBack />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
@@ -130,47 +143,137 @@ function EditPageACF() {
|
|||||||
Retour à la gestion des pages
|
Retour à la gestion des pages
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}>
|
<Typography
|
||||||
Modifier les Champs ACF
|
variant="h4"
|
||||||
|
sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}
|
||||||
|
>
|
||||||
|
Modifier les Champs
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{error && <Typography textAlign="center" color="error" sx={{ mb: 2 }}>{error}</Typography>}
|
{error && (
|
||||||
{successMessage && <Typography sx={{ color: "green", textAlign: "center", mb: 2 }}>{successMessage}</Typography>}
|
<Typography textAlign="center" color="error" sx={{ mb: 2 }}>
|
||||||
|
{error}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{successMessage && (
|
||||||
|
<Typography sx={{ color: "green", textAlign: "center", mb: 2 }}>
|
||||||
|
{successMessage}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
|
||||||
<form onSubmit={handleUpdateACF}>
|
<form onSubmit={handleUpdateACF}>
|
||||||
{/* ✅ Affichage dynamique des champs ACF */}
|
{/* ✅ Affichage dynamique des champs ACF */}
|
||||||
{Object.keys(acfFields).map((field) => {
|
{Object.keys(acfFields).map((field) => {
|
||||||
const value = acfFields[field];
|
const value = acfFields[field];
|
||||||
|
|
||||||
if (typeof value === "object" && !Array.isArray(value)) {
|
// ✅ 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 (
|
return (
|
||||||
<Box key={field} sx={{ mb: 3 }}>
|
<Box key="faq_list" sx={{ mb: 3 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
|
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
|
||||||
{field.replace(/_/g, " ")}
|
FAQ
|
||||||
</Typography>
|
</Typography>
|
||||||
{Object.keys(value).map((subField) => (
|
{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
|
<TextField
|
||||||
key={subField}
|
label="Question"
|
||||||
label={subField.replace(/_/g, " ")}
|
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
value={value[subField] || ""}
|
value={item.question || ""}
|
||||||
onChange={(e) =>
|
onChange={(e) => {
|
||||||
handleFieldChange(field, { ...value, [subField]: e.target.value })
|
const updatedArray = [...faqData];
|
||||||
}
|
updatedArray[index].question = e.target.value;
|
||||||
|
setAcfFields({
|
||||||
|
...acfFields,
|
||||||
|
faq: { ...acfFields.faq, faq_list: updatedArray },
|
||||||
|
});
|
||||||
|
}}
|
||||||
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
|
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
|
||||||
/>
|
/>
|
||||||
))}
|
<TextField
|
||||||
</Box>
|
label="Réponse"
|
||||||
);
|
fullWidth
|
||||||
} else if (Array.isArray(value)) {
|
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 (
|
return (
|
||||||
<Box key={field} sx={{ mb: 3 }}>
|
<Box key={field} sx={{ mb: 3 }}>
|
||||||
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
|
<Typography variant="h6" sx={{ fontWeight: "bold", mb: 1 }}>
|
||||||
{field.replace(/_/g, " ")}
|
{field.replace(/_/g, " ")}
|
||||||
</Typography>
|
</Typography>
|
||||||
{value.map((item, index) => (
|
{value.map((item, index) => (
|
||||||
<Box key={index} sx={{ border: "1px solid #ccc", padding: 2, borderRadius: 2, mb: 2 }}>
|
<Box
|
||||||
|
key={index}
|
||||||
|
sx={{
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
padding: 2,
|
||||||
|
borderRadius: 2,
|
||||||
|
mb: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{Object.keys(item).map((subField) => (
|
{Object.keys(item).map((subField) => (
|
||||||
<TextField
|
<TextField
|
||||||
key={subField}
|
key={subField}
|
||||||
@@ -181,29 +284,62 @@ function EditPageACF() {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const updatedArray = [...value];
|
const updatedArray = [...value];
|
||||||
updatedArray[index][subField] = e.target.value;
|
updatedArray[index][subField] = e.target.value;
|
||||||
setAcfFields({ ...acfFields, [field]: updatedArray });
|
setAcfFields({
|
||||||
|
...acfFields,
|
||||||
|
[field]: updatedArray,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
mb: 1,
|
||||||
|
backgroundColor: "#fff",
|
||||||
|
borderRadius: "5px",
|
||||||
}}
|
}}
|
||||||
sx={{ mb: 1, backgroundColor: "#fff", borderRadius: "5px" }}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Button startIcon={<Delete />} variant="outlined" color="error" onClick={() => deleteFAQ(index)}>
|
|
||||||
Supprimer cette entrée
|
|
||||||
</Button>
|
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
<Button startIcon={<Add />} variant="contained" color="primary" onClick={addFAQ} sx={{ mb: 2 }}>
|
<Button
|
||||||
|
startIcon={<Add />}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setAcfFields({
|
||||||
|
...acfFields,
|
||||||
|
[field]: [...value, {}], // ✅ Ajoute un objet vide
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
sx={{ mb: 2 }}
|
||||||
|
>
|
||||||
Ajouter une entrée
|
Ajouter une entrée
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<TextField key={field} label={field.replace(/_/g, " ")} fullWidth variant="outlined" value={value || ""} onChange={(e) => handleFieldChange(field, e.target.value)} sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ Gérer les champs simples
|
||||||
|
return (
|
||||||
|
<TextField
|
||||||
|
key={field}
|
||||||
|
label={field.replace(/_/g, " ")}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
value={value || ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setAcfFields({ ...acfFields, [field]: e.target.value })
|
||||||
|
}
|
||||||
|
sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<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
|
Enregistrer les modifications
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -219,13 +219,19 @@ export async function updateHomePageACF(pageId, newData) {
|
|||||||
* @returns {Promise<Object>} - Données de la page avec ACF
|
* @returns {Promise<Object>} - Données de la page avec ACF
|
||||||
*/
|
*/
|
||||||
export async function getPageById(pageId) {
|
export async function getPageById(pageId) {
|
||||||
|
if (!pageId) {
|
||||||
|
console.error("❌ Erreur : l'ID de la page est `undefined` !");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${API_URL}/pages/${pageId}?_fields=id,title,acf`);
|
const response = await axios.get(
|
||||||
console.log("📢 Données de la page récupérées :", response.data);
|
`https://preprod.octopusdesign.fr/api-octopus/server/wp-json/wp/v2/pages/${pageId}?_fields=id,title,acf`
|
||||||
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Erreur récupération page :", error.response?.data || error.message);
|
console.error("❌ Erreur récupération page :", error);
|
||||||
throw error;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,3 +268,29 @@ export async function updatePageACF(pageId, acfData) {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 🔹 Récupère la liste des pages WordPress ayant des champs ACF
|
||||||
|
* @returns {Promise<Array>} - Liste des pages
|
||||||
|
*/
|
||||||
|
export async function fetchPages() {
|
||||||
|
try {
|
||||||
|
const response = await fetch("https://preprod.octopusdesign.fr/api-octopus/server/wp-json/wp/v2/pages?_fields=id,title");
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("❌ Erreur lors de la récupération des pages WordPress.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!data || typeof data !== "object" || !Array.isArray(data)) {
|
||||||
|
console.error("❌ Données invalides reçues :", data);
|
||||||
|
return []; // ✅ Retourne un tableau vide pour éviter toute erreur
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("❌ Erreur `fetchPages()` :", error);
|
||||||
|
return []; // ✅ Retourne un tableau vide en cas d'erreur pour éviter le plantage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user