import { useState, useMemo, useEffect } from 'react'; import { categories } from '@/data/mockNews'; import { useRealArticles } from '@/hooks/useRealArticles'; import { useAuth } from '@/hooks/useAuth'; import { useIsMobile } from '@/hooks/use-mobile'; import { NewsItem } from '@/types/news'; import Header from '@/components/Header'; import CategoryFilter from '@/components/CategoryFilter'; import NewsCard from '@/components/NewsCard'; import AddFeedModal from '@/components/AddFeedModal'; import ArticleModal from '@/components/ArticleModal'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PaginationEllipsis } from '@/components/ui/pagination'; import { RefreshCw, Filter, Rss, Plus } from 'lucide-react'; import { toast } from 'sonner'; import { Link, useNavigate } from 'react-router-dom'; const ARTICLES_PER_PAGE = 20; const Index = () => { const { user } = useAuth(); const navigate = useNavigate(); const [dateFilter, setDateFilter] = useState<'today' | 'yesterday' | null>(null); const [showFollowedOnly, setShowFollowedOnly] = useState(!!user); const [showDiscoveryMode, setShowDiscoveryMode] = useState(false); const [showReadArticles, setShowReadArticles] = useState(false); // Handle view mode changes (followed, discovery, all) const handleViewModeChange = (mode: 'followed' | 'discovery' | 'all') => { switch (mode) { case 'followed': setShowFollowedOnly(true); setShowDiscoveryMode(false); break; case 'discovery': setShowFollowedOnly(false); setShowDiscoveryMode(true); setDateFilter(null); break; case 'all': setShowFollowedOnly(false); setShowDiscoveryMode(false); setDateFilter(null); break; } }; const { articles, loading, togglePin, markAsRead, deleteArticle, refetch } = useRealArticles(dateFilter, showFollowedOnly, showReadArticles, showDiscoveryMode); const isMobile = useIsMobile(); const [selectedCategory, setSelectedCategory] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [showFilters, setShowFilters] = useState(true); const [isAddFeedModalOpen, setIsAddFeedModalOpen] = useState(false); const [selectedArticle, setSelectedArticle] = useState(null); const [isArticleModalOpen, setIsArticleModalOpen] = useState(false); const [currentPage, setCurrentPage] = useState(1); console.log('🏠 Index page - Articles count:', articles.length, 'Loading:', loading, 'User:', !!user); const filteredNews = useMemo(() => { let filtered = articles; if (selectedCategory) { const category = categories.find(c => c.id === selectedCategory); if (category) { filtered = filtered.filter(item => item.category === category.type); } } if (searchQuery) { filtered = filtered.filter(item => item.title.toLowerCase().includes(searchQuery.toLowerCase()) || item.description.toLowerCase().includes(searchQuery.toLowerCase()) || item.source.toLowerCase().includes(searchQuery.toLowerCase())); } return filtered.sort((a, b) => { if (a.isPinned && !b.isPinned) return -1; if (!a.isPinned && b.isPinned) return 1; return new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime(); }); }, [articles, selectedCategory, searchQuery]); // Separate pinned and regular articles const pinnedArticles = useMemo(() => { return filteredNews.filter(article => article.isPinned); }, [filteredNews]); const regularArticles = useMemo(() => { return filteredNews.filter(article => !article.isPinned); }, [filteredNews]); // Pagination logic const totalPages = Math.ceil(regularArticles.length / ARTICLES_PER_PAGE); const paginatedArticles = useMemo(() => { const startIndex = (currentPage - 1) * ARTICLES_PER_PAGE; return regularArticles.slice(startIndex, startIndex + ARTICLES_PER_PAGE); }, [regularArticles, currentPage]); // Reset page when filters change useEffect(() => { setCurrentPage(1); }, [selectedCategory, searchQuery, dateFilter, showFollowedOnly, showDiscoveryMode, showReadArticles]); const pinnedCount = articles.filter(item => item.isPinned).length; const unreadCount = articles.filter(item => !item.isRead).length; // Update document title with unread count useEffect(() => { const baseTitle = 'Feeds.Duhaz.fr'; if (unreadCount > 0) { document.title = `(${unreadCount}) ${baseTitle}`; } else { document.title = baseTitle; } }, [unreadCount]); // Auto-refresh articles every 5 minutes, paused when article modal is open const REFRESH_INTERVAL = 5 * 60 * 1000; // 5 minutes useEffect(() => { if (isArticleModalOpen) { return; } const intervalId = setInterval(() => { refetch(); }, REFRESH_INTERVAL); return () => { clearInterval(intervalId); }; }, [isArticleModalOpen, refetch]); const handleRefresh = () => { refetch(); toast.success("Flux actualisés"); }; const handleAddFeed = (feedData: any) => { console.log('Nouveau flux ajouté:', feedData); toast.success(`Flux "${feedData.name}" ajouté avec succès!`); }; const handleOpenArticle = (article: NewsItem) => { setSelectedArticle(article); setIsArticleModalOpen(true); }; const handleCloseArticleModal = () => { setIsArticleModalOpen(false); setSelectedArticle(null); }; const handleSourceClick = (feedId: string, feedName: string) => { navigate(`/feed/${feedId}`); }; if (loading) { return

Chargement des articles...

; } return
{/* Message pour les utilisateurs non connectés */} {!user && (

Vous consultez les articles en mode visiteur. Connectez-vous pour gérer vos flux et marquer vos articles préférés.

)} {/* Message pour les utilisateurs connectés sans articles suivis */} {user && articles.length === 0 && (

Vous ne suivez aucun flux RSS pour le moment. Ajoutez des flux pour commencer Ă  voir des articles.

)}
{/* Sidebar - Desktop only */} {!isMobile && (

Statistiques

Articles non lus {unreadCount}
Articles totaux {articles.length}
{user &&
Épinglés {pinnedCount}
}
)} {/* Main content */}

{showReadArticles ? 'Tous les articles' : (user ? 'Articles non lus' : 'Derniers articles')}

{/* Desktop Filter Toggle - keep existing logic */} {!isMobile && ( )}
{regularArticles.length === 0 && articles.length > 0 ?

Aucun article trouvé avec ces filtres

Essayez de modifier vos filtres ou votre recherche

{pinnedArticles.length > 0 && (

({pinnedArticles.length} article{pinnedArticles.length > 1 ? 's' : ''} épinglé{pinnedArticles.length > 1 ? 's' : ''} dans la sidebar)

)}
: regularArticles.length === 0 ?

Aucun article non lu disponible

{user ? 'Bravo ! Tous vos articles sont lus ou suivez des flux RSS pour voir des articles ici' : 'Aucun article public disponible pour le moment'}

{pinnedArticles.length > 0 && (

({pinnedArticles.length} article{pinnedArticles.length > 1 ? 's' : ''} épinglé{pinnedArticles.length > 1 ? 's' : ''} dans la sidebar)

)} {user &&
}
:
{paginatedArticles.map(item => )} {/* Pagination */} {totalPages > 1 && ( setCurrentPage(p => Math.max(1, p - 1))} className={currentPage === 1 ? 'pointer-events-none opacity-50' : 'cursor-pointer'} /> {Array.from({ length: totalPages }, (_, i) => i + 1) .filter(page => page === 1 || page === totalPages || Math.abs(page - currentPage) <= 1) .map((page, index, array) => ( <> {index > 0 && array[index - 1] !== page - 1 && ( )} setCurrentPage(page)} isActive={currentPage === page} className="cursor-pointer" > {page} ))} setCurrentPage(p => Math.min(totalPages, p + 1))} className={currentPage === totalPages ? 'pointer-events-none opacity-50' : 'cursor-pointer'} /> )} {/* Info pagination */} {totalPages > 1 && (

Page {currentPage} sur {totalPages} ({regularArticles.length} articles)

)}
}
{/* Modals */} {user && setIsAddFeedModalOpen(false)} onAddFeed={handleAddFeed} categories={categories} />}
; }; export default Index;