useFeeds.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { useState, useEffect } from 'react';
  2. import { supabase } from '@/integrations/supabase/client';
  3. import { Feed } from '@/types/feed';
  4. import { useAuth } from './useAuth';
  5. import { toast } from 'sonner';
  6. export function useFeeds() {
  7. const [feeds, setFeeds] = useState<Feed[]>([]);
  8. const [loading, setLoading] = useState(true);
  9. const { user } = useAuth();
  10. const fetchFeeds = async () => {
  11. try {
  12. setLoading(true);
  13. // Fetch all feeds
  14. const { data: feedsData, error: feedsError } = await supabase
  15. .from('feeds')
  16. .select('*')
  17. .order('name');
  18. if (feedsError) {
  19. toast.error('Erreur lors du chargement des flux');
  20. console.error('Error fetching feeds:', feedsError);
  21. return;
  22. }
  23. // If user is authenticated, fetch their subscriptions
  24. let userFeedsData = null;
  25. if (user) {
  26. const { data, error } = await supabase
  27. .from('user_feeds')
  28. .select('feed_id, is_followed')
  29. .eq('user_id', user.id);
  30. if (error) {
  31. console.error('Error fetching user feeds:', error);
  32. } else {
  33. userFeedsData = data;
  34. }
  35. }
  36. // Combine feeds with user subscription status
  37. const combinedFeeds = feedsData.map(feed => ({
  38. id: feed.id,
  39. name: feed.name,
  40. url: feed.url,
  41. type: feed.type as Feed['type'],
  42. description: feed.description,
  43. category: feed.category,
  44. isFollowed: userFeedsData?.find(uf => uf.feed_id === feed.id)?.is_followed || false,
  45. lastUpdated: feed.last_updated || feed.created_at,
  46. articleCount: feed.article_count || 0,
  47. status: feed.status as Feed['status']
  48. }));
  49. setFeeds(combinedFeeds);
  50. } catch (error) {
  51. console.error('Error in fetchFeeds:', error);
  52. toast.error('Erreur lors du chargement des flux');
  53. } finally {
  54. setLoading(false);
  55. }
  56. };
  57. const toggleFollow = async (feedId: string) => {
  58. if (!user) {
  59. toast.error('Vous devez être connecté pour suivre un flux');
  60. return;
  61. }
  62. try {
  63. const feed = feeds.find(f => f.id === feedId);
  64. if (!feed) return;
  65. // Check if subscription exists
  66. const { data: existingSubscription } = await supabase
  67. .from('user_feeds')
  68. .select('*')
  69. .eq('user_id', user.id)
  70. .eq('feed_id', feedId)
  71. .single();
  72. if (existingSubscription) {
  73. // Update existing subscription
  74. const { error } = await supabase
  75. .from('user_feeds')
  76. .update({ is_followed: !feed.isFollowed })
  77. .eq('user_id', user.id)
  78. .eq('feed_id', feedId);
  79. if (error) {
  80. toast.error('Erreur lors de la mise à jour');
  81. return;
  82. }
  83. } else {
  84. // Create new subscription
  85. const { error } = await supabase
  86. .from('user_feeds')
  87. .insert({
  88. user_id: user.id,
  89. feed_id: feedId,
  90. is_followed: true
  91. });
  92. if (error) {
  93. toast.error('Erreur lors de l\'ajout');
  94. return;
  95. }
  96. }
  97. // Update local state
  98. setFeeds(prev => prev.map(f =>
  99. f.id === feedId
  100. ? { ...f, isFollowed: !f.isFollowed }
  101. : f
  102. ));
  103. toast.success(
  104. feed.isFollowed
  105. ? `Vous ne suivez plus "${feed.name}"`
  106. : `Vous suivez maintenant "${feed.name}"`
  107. );
  108. } catch (error) {
  109. console.error('Error toggling follow:', error);
  110. toast.error('Erreur lors de la mise à jour');
  111. }
  112. };
  113. useEffect(() => {
  114. fetchFeeds();
  115. }, [user]);
  116. return {
  117. feeds,
  118. loading,
  119. toggleFollow,
  120. refetch: fetchFeeds
  121. };
  122. }