diff --git a/app/services/cataloguemate_scraper.py b/app/services/cataloguemate_scraper.py index 3b41ad0..c43e89e 100644 --- a/app/services/cataloguemate_scraper.py +++ b/app/services/cataloguemate_scraper.py @@ -278,7 +278,8 @@ async def scrape_enseigne(enseigne: Enseigne, db: Session) -> ScrapingLog: date_debut=datetime.now(), # Todo: extract real dates date_fin=datetime.now() + timedelta(days=14), image_couverture_url=pages[0]['image_url'], - content_hash=content_hash + content_hash=content_hash, + nombre_pages=len(pages) # Set actual page count ) db.add(new_cat) db.commit() diff --git a/frontend/src/components/dashboard/CatalogueAdmin.jsx b/frontend/src/components/dashboard/CatalogueAdmin.jsx index 61858e3..a64e4ab 100644 --- a/frontend/src/components/dashboard/CatalogueAdmin.jsx +++ b/frontend/src/components/dashboard/CatalogueAdmin.jsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { toast } from 'sonner'; -import { Loader2, Play, Clock, CheckCircle2, XCircle, AlertCircle } from 'lucide-react'; +import { Loader2, Play, Clock, CheckCircle2, XCircle, AlertCircle, Trash2 } from 'lucide-react'; import { useAuth } from '../../hooks/use-auth'; const API_BASE = '/api/catalogues/admin'; @@ -77,6 +77,30 @@ export default function CatalogueAdmin() { } }; + const triggerPurge = async () => { + if (!confirm('Êtes-vous sûr de vouloir purger les catalogues expirés depuis plus de 3 mois ?')) { + return; + } + + setLoading(true); + try { + const response = await axios.post(`${API_BASE}/purge`, null, { + headers: getAuthHeaders() + }); + + toast.success(response.data.message); + toast.info(`${response.data.deleted_count} catalogue(s) supprimé(s)`); + + // Reload data + await Promise.all([loadStats(), loadLogs()]); + } catch (error) { + console.error('Error triggering purge:', error); + toast.error('Erreur lors de la purge'); + } finally { + setLoading(false); + } + }; + const getStatusIcon = (status) => { switch (status) { case 'success': @@ -97,9 +121,28 @@ export default function CatalogueAdmin() { return (
-
-

Administration Catalogues

-

Gérer le scraping des catalogues Bonial

+
+
+

Administration Catalogues

+

Gérer le scraping des catalogues Cataloguemate

+
+
{/* Stats Cards */} diff --git a/frontend/src/pages/Catalogues.jsx b/frontend/src/pages/Catalogues.jsx index f171ca6..b7a240b 100644 --- a/frontend/src/pages/Catalogues.jsx +++ b/frontend/src/pages/Catalogues.jsx @@ -1,7 +1,8 @@ import React, { useEffect, useState } from 'react'; import { toast } from 'sonner'; -import { Loader2, Calendar, BookOpen, Search, ChevronRight, Eye } from 'lucide-react'; +import { Loader2, Calendar, BookOpen, Search, ChevronRight, Eye, Trash2 } from 'lucide-react'; import axios from 'axios'; +import { useAuth } from '../hooks/use-auth'; const API_BASE = '/api/catalogues'; @@ -14,6 +15,7 @@ export default function Catalogues() { const [selectedCatalogue, setSelectedCatalogue] = useState(null); const [cataloguePages, setCataloguePages] = useState([]); const [searchQuery, setSearchQuery] = useState(''); + const { user, getAuthHeaders } = useAuth(); useEffect(() => { loadEnseignes(); @@ -104,6 +106,26 @@ export default function Catalogues() { return now >= debut && now <= fin; }; + const deleteCatalogue = async (catalogueId, event) => { + event.stopPropagation(); // Prevent opening the catalogue + + if (!confirm('Êtes-vous sûr de vouloir supprimer ce catalogue ?')) { + return; + } + + try { + await axios.delete(`${API_BASE}/admin/${catalogueId}`, { + headers: getAuthHeaders() + }); + + toast.success('Catalogue supprimé'); + loadCatalogues(); // Reload the list + } catch (error) { + console.error('Error deleting catalogue:', error); + toast.error('Erreur lors de la suppression'); + } + }; + return (
{/* Header */} @@ -244,9 +266,20 @@ export default function Catalogues() {
{/* Pages */} -
- - {catalogue.nombre_pages} pages +
+
+ + {catalogue.nombre_pages} pages +
+ {user?.is_admin && ( + + )}