useArticles.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { useState, useEffect } from 'react';
  2. import { supabase } from '@/integrations/supabase/client';
  3. import { useAuth } from './useAuth';
  4. import { NewsItem } from '@/types/news';
  5. import { toast } from 'sonner';
  6. export function useArticles() {
  7. const [articles, setArticles] = useState<NewsItem[]>([]);
  8. const [loading, setLoading] = useState(true);
  9. const { user } = useAuth();
  10. const fetchArticles = async () => {
  11. try {
  12. setLoading(true);
  13. if (user) {
  14. // For authenticated users, fetch articles from their followed feeds
  15. const { data: userFeeds, error: userFeedsError } = await supabase
  16. .from('user_feeds')
  17. .select(`
  18. feed_id,
  19. feeds!inner(*)
  20. `)
  21. .eq('user_id', user.id)
  22. .eq('is_followed', true);
  23. if (userFeedsError) {
  24. console.error('Error fetching user feeds:', userFeedsError);
  25. toast.error('Erreur lors du chargement de vos flux');
  26. return;
  27. }
  28. // For now, we'll use mock data but filter by followed feeds
  29. // In a real app, you'd have an articles table linked to feeds
  30. const followedFeedNames = userFeeds?.map(uf => uf.feeds.name) || [];
  31. // Import mock data and filter by followed feeds
  32. const { newsItems } = await import('@/data/mockNews');
  33. const filteredArticles = newsItems.filter(article =>
  34. followedFeedNames.some(feedName =>
  35. article.source.toLowerCase().includes(feedName.toLowerCase()) ||
  36. feedName.toLowerCase().includes(article.source.toLowerCase())
  37. )
  38. );
  39. setArticles(filteredArticles);
  40. } else {
  41. // For visitors, show all recent articles
  42. const { newsItems } = await import('@/data/mockNews');
  43. setArticles(newsItems);
  44. }
  45. } catch (error) {
  46. console.error('Error in fetchArticles:', error);
  47. toast.error('Erreur lors du chargement des articles');
  48. } finally {
  49. setLoading(false);
  50. }
  51. };
  52. const togglePin = (id: string) => {
  53. setArticles(prev => prev.map(item =>
  54. item.id === id ? { ...item, isPinned: !item.isPinned } : item
  55. ));
  56. toast.success("Article épinglé mis à jour");
  57. };
  58. const markAsRead = (id: string) => {
  59. setArticles(prev => prev.map(item =>
  60. item.id === id ? { ...item, isRead: true } : item
  61. ));
  62. };
  63. const deleteArticle = (id: string) => {
  64. setArticles(prev => prev.filter(item => item.id !== id));
  65. toast.success("Article supprimé");
  66. };
  67. useEffect(() => {
  68. fetchArticles();
  69. }, [user]);
  70. return {
  71. articles,
  72. loading,
  73. togglePin,
  74. markAsRead,
  75. deleteArticle,
  76. refetch: fetchArticles
  77. };
  78. }