165 lines
6.2 KiB
React
165 lines
6.2 KiB
React
// ✅ Importations nécessaires
|
|
import React, { useState, useEffect } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import {
|
|
Box, Typography, Button, Table, TableBody, TableCell,
|
|
TableContainer, TableHead, TableRow, Paper, TextField, Avatar
|
|
} from "@mui/material";
|
|
import { Add, ArrowBack, Edit, Delete } from "@mui/icons-material";
|
|
import api from "../../api";
|
|
import { getToken } from "../../auth";
|
|
import { deletePost } from "../../wordpress";
|
|
|
|
const GestionArticles = () => {
|
|
const [posts, setPosts] = useState([]);
|
|
const [searchTerm, setSearchTerm] = useState("");
|
|
const navigate = useNavigate();
|
|
|
|
// ✅ Vérifier si l'utilisateur est connecté
|
|
useEffect(() => {
|
|
if (!getToken()) {
|
|
navigate("/admin/login");
|
|
}
|
|
}, [navigate]);
|
|
|
|
// ✅ Récupérer les articles et leurs images associées
|
|
useEffect(() => {
|
|
const fetchPosts = async () => {
|
|
try {
|
|
const response = await api.get("wp/v2/posts?_fields=id,title,excerpt,featured_media");
|
|
const postsData = response.data;
|
|
|
|
const postsWithImages = await Promise.all(
|
|
postsData.map(async (post) => {
|
|
if (post.featured_media) {
|
|
try {
|
|
const mediaResponse = await api.get(`wp/v2/media/${post.featured_media}`);
|
|
return { ...post, image: mediaResponse.data.source_url, imageId: post.featured_media };
|
|
} catch (error) {
|
|
console.error(`❌ Erreur chargement image article ${post.id}:`, error);
|
|
return { ...post, image: null, imageId: null };
|
|
}
|
|
}
|
|
return { ...post, image: null, imageId: null };
|
|
})
|
|
);
|
|
|
|
setPosts(postsWithImages);
|
|
} catch (error) {
|
|
console.error("❌ Erreur chargement des articles :", error);
|
|
}
|
|
};
|
|
|
|
fetchPosts();
|
|
}, []);
|
|
|
|
// ✅ Supprimer un article et son image associée
|
|
const handleDeletePost = async (postId, imageId) => {
|
|
if (window.confirm("Es-tu sûr de vouloir supprimer cet article ?")) {
|
|
try {
|
|
await deletePost(postId, imageId); // ✅ Appel de la fonction deletePost
|
|
setPosts(posts.filter((post) => post.id !== postId)); // ✅ Met à jour la liste après suppression
|
|
alert("✅ Article supprimé avec succès !");
|
|
} catch (error) {
|
|
console.error("❌ Erreur suppression article :", error);
|
|
alert("⚠ Erreur : impossible de supprimer l'article.");
|
|
}
|
|
}
|
|
};
|
|
|
|
// ✅ Filtrage des articles
|
|
const filteredPosts = posts.filter((post) =>
|
|
post.title.rendered.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
post.excerpt.rendered.replace(/(<([^>]+)>)/gi, "").replace(/ /g, " ").toLowerCase().includes(searchTerm.toLowerCase())
|
|
);
|
|
|
|
return (
|
|
<Box sx={{ padding: "40px 20px" }}>
|
|
{/* ✅ En-tête avec retour et création */}
|
|
<Box sx={{ 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
|
|
</Button>
|
|
<Typography variant="h4" sx={{ fontWeight: "bold", textAlign: "center", flexGrow: 1 }}>
|
|
Gestion des Articles
|
|
</Typography>
|
|
<Button startIcon={<Add />} variant="contained" color="primary" onClick={() => navigate("/admin/create-post")}>
|
|
Créer un article
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* ✅ Recherche */}
|
|
<TextField
|
|
label="Rechercher un article..."
|
|
variant="outlined"
|
|
fullWidth
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
sx={{ mb: 3 }}
|
|
/>
|
|
|
|
{/* ✅ Tableau des articles */}
|
|
<TableContainer component={Paper}>
|
|
<Table>
|
|
<TableHead sx={{ backgroundColor: "#0e467f" }}>
|
|
<TableRow>
|
|
<TableCell sx={{ color: "white", fontWeight: "bold" }}>Image</TableCell>
|
|
<TableCell sx={{ color: "white", fontWeight: "bold" }}>Titre</TableCell>
|
|
<TableCell sx={{ color: "white", fontWeight: "bold" }}>Résumé</TableCell>
|
|
<TableCell sx={{ color: "white", fontWeight: "bold", textAlign: "center" }}>Actions</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
<TableBody>
|
|
{filteredPosts.length > 0 ? (
|
|
filteredPosts.map((post) => (
|
|
<TableRow key={post.id}>
|
|
{/* ✅ Image en vedette */}
|
|
<TableCell>
|
|
<Avatar
|
|
src={post.image || "https://via.placeholder.com/100"}
|
|
variant="rounded"
|
|
sx={{ width: 80, height: 80 }}
|
|
/>
|
|
</TableCell>
|
|
{/* ✅ Titre de l'article */}
|
|
<TableCell sx={{ fontWeight: "bold" }}>{post.title.rendered}</TableCell>
|
|
{/* ✅ Résumé avec 100 caractères max */}
|
|
<TableCell>
|
|
{post.excerpt.rendered.replace(/(<([^>]+)>)/gi, "").replace(/ /g, " ").substring(0, 100)}...
|
|
</TableCell>
|
|
{/* ✅ Boutons Modifier et Supprimer */}
|
|
<TableCell sx={{ textAlign: "center" }}>
|
|
<Button startIcon={<Edit />}
|
|
variant="outlined"
|
|
color="warning"
|
|
sx={{ mr: 1 }}
|
|
onClick={() => navigate(`/admin/edit-post/${post.id}`)}
|
|
>
|
|
Modifier
|
|
</Button>
|
|
<Button
|
|
startIcon={<Delete />}
|
|
variant="outlined"
|
|
color="error"
|
|
onClick={() => handleDeletePost(post.id, post.imageId)}
|
|
>
|
|
Supprimer
|
|
</Button>
|
|
</TableCell>
|
|
</TableRow>
|
|
))
|
|
) : (
|
|
<TableRow>
|
|
<TableCell colSpan={4} sx={{ textAlign: "center", py: 2 }}>
|
|
Aucun article trouvé.
|
|
</TableCell>
|
|
</TableRow>
|
|
)}
|
|
</TableBody>
|
|
</Table>
|
|
</TableContainer>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default GestionArticles; |