gestion accueil MAJ avec gestion photo hero

This commit is contained in:
sebvtl728
2025-02-02 22:20:15 +01:00
parent 6eaa0fcf64
commit f25b0fa6e4
@@ -1,168 +1,224 @@
import React, { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { updateHomePageACF, uploadImage } from "../../wordpress";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Box, Button, TextField, Typography, Snackbar, Alert, Paper, Card, CardMedia } from "@mui/material"; import { updateHomePageACF, uploadImage } from "../../wordpress";
import api from "../../api"; import { getToken } from "../../auth";
import {
const PAGE_ID = 13; // ID de la page d'accueil Typography,
TextField,
Button,
Container,
Paper,
Box,
CircularProgress,
} from "@mui/material";
const GestionPageAccueil = () => { const GestionPageAccueil = () => {
const [heroTitle, setHeroTitle] = useState(""); const navigate = useNavigate();
const [heroText, setHeroText] = useState(""); const [heroTitle, setHeroTitle] = useState("");
const [heroImage, setHeroImage] = useState(null); const [heroText, setHeroText] = useState("");
const [heroImageId, setHeroImageId] = useState(null); const [heroImage, setHeroImage] = useState(null);
const [message, setMessage] = useState({ type: "", text: "" }); const [loading, setLoading] = useState(true);
const navigate = useNavigate(); // 🔥 Gestion de la navigation const [error, setError] = useState(null);
const [successMessage, setSuccessMessage] = useState("");
// ✅ Charger les données ACF existantes // ✅ Vérification de l'authentification (Redirection si non connecté)
useEffect(() => { useEffect(() => {
const fetchPageData = async () => { if (!getToken()) {
try { navigate("/admin/login");
const response = await api.get(`wp/v2/pages/${PAGE_ID}?_fields=acf`); }
const acfData = response.data.acf; }, [navigate]);
if (acfData) { // ✅ Chargement des données ACF depuis WordPress
setHeroTitle(acfData.hero_title || ""); useEffect(() => {
setHeroText(acfData.hero_text || ""); const fetchPageData = async () => {
try {
const response = await fetch(
"https://preprod.octopusdesign.fr/api-octopus/server/wp-json/wp/v2/pages/13?_fields=acf",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (acfData.img_hero) { if (!response.ok) {
setHeroImageId(acfData.img_hero); throw new Error("Erreur de chargement des données");
const imageResponse = await api.get(`wp/v2/media/${acfData.img_hero}`);
setHeroImage(imageResponse.data.source_url);
}
}
} catch (error) {
console.error("❌ Erreur chargement ACF :", error);
setMessage({ type: "error", text: "Erreur lors du chargement des données." });
}
};
fetchPageData();
}, []);
// ✅ Sauvegarde des données ACF
const handleSave = async () => {
try {
const formData = {
acf: {
hero_title: heroTitle,
hero_text: heroText,
img_hero: heroImageId || null, // ✅ Mise à jour avec l'ID de l'image
}
};
console.log("📢 Envoi des nouvelles données ACF :", formData);
await updateHomePageACF(PAGE_ID, formData);
setMessage({ type: "success", text: "✅ Mise à jour réussie !" });
// ✅ 🔥 Redirection vers le Dashboard après 1.5 sec
setTimeout(() => {
navigate("/admin/dashboard");
}, 1500);
} catch (error) {
console.error("❌ Erreur mise à jour ACF :", error);
setMessage({ type: "error", text: "❌ Échec de la mise à jour. Vérifie les permissions WordPress." });
} }
const data = await response.json();
setHeroTitle(data.acf?.hero_title || "");
setHeroText(data.acf?.hero_text || "");
// ✅ Récupération de l'image Hero
if (data.acf?.img_hero) {
const mediaResponse = await fetch(
`https://preprod.octopusdesign.fr/api-octopus/server/wp-json/wp/v2/media/${data.acf.img_hero}`
);
const mediaData = await mediaResponse.json();
setHeroImage(mediaData.source_url);
}
setLoading(false);
} catch (error) {
console.error("❌ Erreur chargement ACF :", error);
setError("Impossible de charger les données.");
setLoading(false);
}
}; };
// ✅ Gestion de l'upload d'image fetchPageData();
const handleImageUpload = async (event) => { }, []);
const file = event.target.files[0];
if (!file) return;
try { // ✅ Mise à jour des champs ACF
const imageId = await uploadImage(file); const handleSave = async () => {
setHeroImageId(imageId); try {
const newData = {
hero_title: heroTitle,
hero_text: heroText,
};
const imageResponse = await api.get(`wp/v2/media/${imageId}`); console.log("📢 Données envoyées pour mise à jour ACF :", newData);
setHeroImage(imageResponse.data.source_url); await updateHomePageACF(13, newData);
setMessage({ type: "success", text: "✅ Image uploadée avec succès !" }); setSuccessMessage("✅ Modifications enregistrées avec succès !");
} catch (error) { setTimeout(() => setSuccessMessage(""), 3000);
console.error("❌ Erreur lors de l'upload de l'image :", error); } catch (error) {
setMessage({ type: "error", text: "❌ Échec de l'upload de l'image." }); console.error("❌ Erreur mise à jour :", error);
} setError("⚠ Impossible de mettre à jour les champs ACF.");
}; }
};
return ( // ✅ Gérer le téléversement dune nouvelle image Hero
<Box sx={{ padding: "40px", maxWidth: "700px", margin: "auto", mt: 5 }}> const handleImageUpload = async (event) => {
<Paper sx={{ padding: "30px", borderRadius: "10px", boxShadow: 3 }}> const file = event.target.files[0];
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", mb: 3 }}> if (file) {
🏠 Gestion de la Page d'Accueil try {
const imageId = await uploadImage(file);
setHeroImage(URL.createObjectURL(file)); // Affichage immédiat
await updateHomePageACF(13, { img_hero: imageId });
setSuccessMessage("✅ Image mise à jour !");
} catch (error) {
console.error("❌ Erreur lors de l'upload :", error);
setError("❌ Échec de l'upload de l'image.");
}
}
};
return (
<Container maxWidth="md" sx={{ mt: 16, mb:5 }}>
<Paper elevation={6} sx={{ padding: 4, borderRadius: 3, backgroundColor: "#f8f9fa" }}>
{/* ✅ En-tête */}
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", mb: 3, color: "#0e467f" }}>
🏠 Gestion de la Page d'Accueil
</Typography>
{/* ✅ Affichage du statut de chargement */}
{loading ? (
<Box display="flex" justifyContent="center" alignItems="center">
<CircularProgress />
</Box>
) : error ? (
<Typography textAlign="center" color="error">
{error}
</Typography>
) : (
<>
{/* ✅ Message de succès */}
{successMessage && (
<Box
sx={{
backgroundColor: "#d4edda",
color: "#155724",
padding: "12px",
borderRadius: "8px",
marginBottom: "16px",
textAlign: "center",
boxShadow: "0px 2px 10px rgba(0,0,0,0.1)",
}}
>
<Typography variant="body1" fontWeight="bold">
{successMessage}
</Typography> </Typography>
</Box>
)}
{message.text && ( {/* ✅ Affichage de l'image actuelle */}
<Snackbar open autoHideDuration={3000} onClose={() => setMessage({ type: "", text: "" })}> {heroImage && (
<Alert severity={message.type} sx={{ width: '100%' }}> <Box sx={{ textAlign: "center", mb: 2 }}>
{message.text} <img
</Alert> src={heroImage}
</Snackbar> alt="Hero"
)} style={{
width: "100%",
{/* ✅ Aperçu de l'image actuelle */} maxHeight: "250px",
{heroImage && ( objectFit: "cover",
<Card sx={{ mb: 3, boxShadow: 3 }}> borderRadius: "8px",
<CardMedia }}
component="img"
height="200"
image={heroImage}
alt="Image actuelle du héros"
sx={{ objectFit: "cover" }}
/>
</Card>
)}
{/* ✅ Bouton pour modifier l'image */}
<Button variant="outlined" component="label" fullWidth sx={{ mb: 3 }}>
Modifier l'image
<input type="file" hidden onChange={handleImageUpload} />
</Button>
<TextField
label="Titre Héros"
fullWidth
margin="normal"
variant="outlined"
value={heroTitle}
onChange={(e) => setHeroTitle(e.target.value)}
sx={{ "& .MuiInputBase-input": { fontSize: "1.2rem" } }}
/> />
</Box>
)}
<TextField {/* ✅ Bouton pour changer l'image */}
label="Texte Héros" <Button variant="contained" component="label" fullWidth sx={{ mb: 2 }}>
fullWidth 📸 Modifier l'Image Hero
margin="normal" <input type="file" hidden onChange={handleImageUpload} />
variant="outlined" </Button>
value={heroText}
onChange={(e) => setHeroText(e.target.value)}
multiline
rows={3}
sx={{ "& .MuiInputBase-input": { fontSize: "1rem" } }}
/>
<Button {/* ✅ Formulaire de modification */}
variant="contained" <TextField
color="primary" label="Titre Héros"
fullWidth fullWidth
sx={{ mt: 3, fontSize: "1.1rem", fontWeight: "bold" }} variant="outlined"
onClick={handleSave} value={heroTitle}
> onChange={(e) => setHeroTitle(e.target.value)}
💾 Enregistrer les modifications sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }}
</Button> />
{/* ✅ Bouton retour Dashboard */} <TextField
<Button label="Texte Héros"
variant="outlined" fullWidth
color="secondary" variant="outlined"
fullWidth value={heroText}
sx={{ mt: 2, fontSize: "1rem", fontWeight: "bold" }} onChange={(e) => setHeroText(e.target.value)}
onClick={() => navigate("/admin/dashboard")} sx={{ mb: 2, backgroundColor: "#fff", borderRadius: "5px" }}
> multiline
Retour au Dashboard rows={3}
</Button> />
</Paper>
</Box> {/* ✅ Bouton d'enregistrement */}
); <Button
variant="contained"
color="primary"
fullWidth
sx={{
mt: 3,
fontSize: "1.1rem",
fontWeight: "bold",
color:"#ffffff",
backgroundColor: "#0e467f",
"&:hover": { backgroundColor: "#093a6b" },
}}
onClick={handleSave}
>
💾 Enregistrer les modifications
</Button>
{/* ✅ Bouton retour au Dashboard */}
<Button
variant="outlined"
color="secondary"
fullWidth
sx={{ mt: 2, fontSize: "1rem", fontWeight: "bold", borderColor: "#0e467f", color: "#0e467f" }}
onClick={() => navigate("/admin/dashboard")}
>
Retour au Dashboard
</Button>
</>
)}
</Paper>
</Container>
);
}; };
export default GestionPageAccueil; export default GestionPageAccueil;