Browse Source

Fix: Hide read articles

When an article is marked as read, it should disappear from the view.
gpt-engineer-app[bot] 5 months ago
parent
commit
0ba2efdc15
2 changed files with 52 additions and 49 deletions
  1. 42 36
      src/hooks/useRealArticles.tsx
  2. 10 13
      src/pages/Index.tsx

+ 42 - 36
src/hooks/useRealArticles.tsx

@@ -34,12 +34,13 @@ export function useRealArticles() {
         
         if (followedFeedIds.length === 0) {
           console.log('⚠️ No followed feeds found for user');
-          // Si l'utilisateur ne suit aucun flux, on affiche les articles récents
+          // Si l'utilisateur ne suit aucun flux, on affiche les articles récents non lus
           const { data: recentArticles, error: recentError } = await supabase
             .from('articles')
             .select(`
               *,
-              feeds!inner(name, category)
+              feeds!inner(name, category),
+              user_articles(is_read, is_pinned)
             `)
             .order('published_at', { ascending: false })
             .limit(20);
@@ -52,27 +53,29 @@ export function useRealArticles() {
 
           console.log('📰 Recent articles for user with no followed feeds:', recentArticles?.length);
           
-          // Transform to NewsItem format
-          const transformedArticles: NewsItem[] = recentArticles?.map(article => ({
-            id: article.id,
-            title: article.title,
-            description: article.description || '',
-            content: article.content || '',
-            source: article.feeds.name,
-            category: article.feeds.category as NewsItem['category'],
-            publishedAt: article.published_at,
-            readTime: article.read_time || 5,
-            isPinned: false,
-            isRead: false,
-            url: article.url || undefined,
-            imageUrl: article.image_url || undefined
-          })) || [];
+          // Transform to NewsItem format and filter out read articles
+          const transformedArticles: NewsItem[] = recentArticles
+            ?.filter(article => !article.user_articles[0]?.is_read) // Filter out read articles
+            ?.map(article => ({
+              id: article.id,
+              title: article.title,
+              description: article.description || '',
+              content: article.content || '',
+              source: article.feeds.name,
+              category: article.feeds.category as NewsItem['category'],
+              publishedAt: article.published_at,
+              readTime: article.read_time || 5,
+              isPinned: article.user_articles[0]?.is_pinned || false,
+              isRead: article.user_articles[0]?.is_read || false,
+              url: article.url || undefined,
+              imageUrl: article.image_url || undefined
+            })) || [];
 
           setArticles(transformedArticles);
           return;
         }
 
-        // Fetch articles from followed feeds with user interactions
+        // Fetch articles from followed feeds with user interactions, excluding read articles
         const { data: articlesData, error: articlesError } = await supabase
           .from('articles')
           .select(`
@@ -92,21 +95,23 @@ export function useRealArticles() {
 
         console.log('📰 Articles found for followed feeds:', articlesData?.length);
 
-        // Transform to NewsItem format
-        const transformedArticles: NewsItem[] = articlesData?.map(article => ({
-          id: article.id,
-          title: article.title,
-          description: article.description || '',
-          content: article.content || '',
-          source: article.feeds.name,
-          category: article.feeds.category as NewsItem['category'],
-          publishedAt: article.published_at,
-          readTime: article.read_time || 5,
-          isPinned: article.user_articles[0]?.is_pinned || false,
-          isRead: article.user_articles[0]?.is_read || false,
-          url: article.url || undefined,
-          imageUrl: article.image_url || undefined
-        })) || [];
+        // Transform to NewsItem format and filter out read articles
+        const transformedArticles: NewsItem[] = articlesData
+          ?.filter(article => !article.user_articles[0]?.is_read) // Filter out read articles
+          ?.map(article => ({
+            id: article.id,
+            title: article.title,
+            description: article.description || '',
+            content: article.content || '',
+            source: article.feeds.name,
+            category: article.feeds.category as NewsItem['category'],
+            publishedAt: article.published_at,
+            readTime: article.read_time || 5,
+            isPinned: article.user_articles[0]?.is_pinned || false,
+            isRead: article.user_articles[0]?.is_read || false,
+            url: article.url || undefined,
+            imageUrl: article.image_url || undefined
+          })) || [];
 
         setArticles(transformedArticles);
       } else {
@@ -219,9 +224,10 @@ export function useRealArticles() {
         return;
       }
 
-      setArticles(prev => prev.map(item => 
-        item.id === articleId ? { ...item, isRead: true } : item
-      ));
+      // Remove the article from the list instead of just marking it as read
+      setArticles(prev => prev.filter(item => item.id !== articleId));
+      
+      toast.success("Article marqué comme lu et retiré de la liste");
     } catch (error) {
       console.error('Error marking as read:', error);
     }

+ 10 - 13
src/pages/Index.tsx

@@ -1,3 +1,4 @@
+
 import { useState, useMemo } from 'react';
 import { categories } from '@/data/mockNews';
 import { useRealArticles } from '@/hooks/useRealArticles';
@@ -53,7 +54,7 @@ const Index = () => {
   }, [articles, selectedCategory, searchQuery]);
 
   const pinnedCount = articles.filter(item => item.isPinned).length;
-  const unreadCount = articles.filter(item => !item.isRead).length;
+  const unreadCount = articles.length; // All displayed articles are unread now
 
   const handleRefresh = () => {
     refetch();
@@ -105,7 +106,7 @@ const Index = () => {
                 <div className="flex-1">
                   <p className="font-medium text-blue-900">Vous consultez les derniers articles publics</p>
                   <p className="text-sm text-blue-700">
-                    Connectez-vous pour voir uniquement les articles de vos flux suivis et personnaliser votre expérience.
+                    Connectez-vous pour voir uniquement les articles non lus de vos flux suivis et personnaliser votre expérience.
                   </p>
                 </div>
                 <Link to="/auth">
@@ -125,9 +126,9 @@ const Index = () => {
               <div className="flex items-center gap-3">
                 <Rss className="h-5 w-5 text-yellow-600" />
                 <div className="flex-1">
-                  <p className="font-medium text-yellow-900">Aucun article trouvé</p>
+                  <p className="font-medium text-yellow-900">Aucun article non lu trouvé</p>
                   <p className="text-sm text-yellow-700">
-                    Commencez par suivre des flux RSS pour voir vos articles ici. Vous verrez aussi quelques articles récents même sans flux suivis.
+                    Tous vos articles sont lus ! Ajoutez de nouveaux flux RSS ou actualisez pour voir de nouveaux articles.
                   </p>
                 </div>
                 <div className="flex gap-2">
@@ -151,7 +152,7 @@ const Index = () => {
           <Card className="mb-6 border-gray-200 bg-gray-50">
             <CardContent className="pt-4">
               <div className="text-xs text-gray-600">
-                <p>Debug: {articles.length} articles trouvés | Utilisateur: {user ? 'connecté' : 'visiteur'}</p>
+                <p>Debug: {articles.length} articles non lus trouvés | Utilisateur: {user ? 'connecté' : 'visiteur'}</p>
               </div>
             </CardContent>
           </Card>
@@ -172,13 +173,9 @@ const Index = () => {
               <h3 className="font-semibold text-sm">Statistiques</h3>
               <div className="space-y-2 text-sm">
                 <div className="flex justify-between">
-                  <span className="text-muted-foreground">Total articles</span>
+                  <span className="text-muted-foreground">Articles non lus</span>
                   <Badge variant="outline">{articles.length}</Badge>
                 </div>
-                <div className="flex justify-between">
-                  <span className="text-muted-foreground">Non lus</span>
-                  <Badge variant="default">{unreadCount}</Badge>
-                </div>
                 {user && (
                   <div className="flex justify-between">
                     <span className="text-muted-foreground">Épinglés</span>
@@ -194,7 +191,7 @@ const Index = () => {
             <div className="flex items-center justify-between">
               <div className="flex items-center gap-4">
                 <h2 className="text-2xl font-bold">
-                  {user ? 'Vos flux suivis' : 'Derniers articles'}
+                  {user ? 'Articles non lus' : 'Derniers articles'}
                 </h2>
                 <Badge variant="outline">
                   {filteredNews.length} article{filteredNews.length !== 1 ? 's' : ''}
@@ -234,9 +231,9 @@ const Index = () => {
             ) : filteredNews.length === 0 ? (
               <div className="text-center py-12">
                 <Rss className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
-                <p className="text-muted-foreground text-lg">Aucun article disponible</p>
+                <p className="text-muted-foreground text-lg">Aucun article non lu disponible</p>
                 <p className="text-sm text-muted-foreground mt-2 mb-4">
-                  {user ? 'Suivez des flux RSS pour voir des articles ici' : 'Aucun article public disponible pour le moment'}
+                  {user ? 'Bravo ! Tous vos articles sont lus ou suivez des flux RSS pour voir des articles ici' : 'Aucun article public disponible pour le moment'}
                 </p>
                 {user && (
                   <div className="flex gap-2 justify-center">