From dde10b49ad9e7227b1f81fb43f658f2e6e158b99 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Mon, 16 Feb 2026 19:56:02 +0100 Subject: [PATCH] added feed to frontpage --- backend/api/views.py | 4 + frontend/src/pages/CategoryList.tsx | 157 +++++++++++++++++++++------- 2 files changed, 125 insertions(+), 36 deletions(-) diff --git a/backend/api/views.py b/backend/api/views.py index c6d1729..d8df648 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -180,9 +180,13 @@ class UserViewSet(viewsets.ModelViewSet): ratings = user.ratings.select_related('flavor', 'flavor__category').exclude(flavor__category__slug='packs-and-other').order_by('-score') return Response({ + 'id': user.id, 'username': user.username, 'theme': user.theme, 'avatar': request.build_absolute_uri(user.avatar.url) if user.avatar else None, + 'following_count': user.following.count(), + 'followers_count': user.followers.count(), + 'is_following': request.user.following.filter(pk=user.pk).exists() if request.user.is_authenticated else False, 'ratings': RatingSerializer(ratings, many=True, context={'request': request}).data }) diff --git a/frontend/src/pages/CategoryList.tsx b/frontend/src/pages/CategoryList.tsx index 7be09f2..8ce0b26 100644 --- a/frontend/src/pages/CategoryList.tsx +++ b/frontend/src/pages/CategoryList.tsx @@ -57,11 +57,13 @@ const CategoryList: React.FC = () => { const [topFlavors, setTopFlavors] = useState([]); const [recentReviews, setRecentReviews] = useState([]); const [allFlavors, setAllFlavors] = useState([]); + const [feedRatings, setFeedRatings] = useState([]); const [loading, setLoading] = useState(true); const [activeIndex, setActiveIndex] = useState(0); const location = useLocation(); const query = new URLSearchParams(location.search).get('q') || ''; + const isLoggedIn = !!localStorage.getItem('token'); useEffect(() => { const fetchData = async () => { @@ -72,14 +74,26 @@ const CategoryList: React.FC = () => { const res = await api.get(`flavors/?search=${encodeURIComponent(query)}`); setAllFlavors(Array.isArray(res.data) ? res.data : (res.data.results || [])); } else { - const [catRes, topRes, recentRes] = await Promise.all([ + const requests: any[] = [ api.get('categories/'), api.get('flavors/top/'), api.get('ratings/recent/') - ]); - setCategories(Array.isArray(catRes.data) ? catRes.data : (catRes.data.results || [])); - setTopFlavors(Array.isArray(topRes.data) ? topRes.data : (topRes.data.results || [])); - setRecentReviews(Array.isArray(recentRes.data) ? recentRes.data : (recentRes.data.results || [])); + ]; + + if (isLoggedIn) { + requests.push(api.get('ratings/feed/')); + } + + const results = await Promise.all(requests); + + setCategories(Array.isArray(results[0].data) ? results[0].data : (results[0].data.results || [])); + setTopFlavors(Array.isArray(results[1].data) ? results[1].data : (results[1].data.results || [])); + setRecentReviews(Array.isArray(results[2].data) ? results[2].data : (results[2].data.results || [])); + + if (isLoggedIn && results[3]) { + const feedData = Array.isArray(results[3].data) ? results[3].data : (results[3].data.results || []); + setFeedRatings(feedData.slice(0, 6)); // Show top 6 on home + } } } catch (err) { console.error(err); @@ -88,7 +102,7 @@ const CategoryList: React.FC = () => { } }; fetchData(); - }, [query]); + }, [query, isLoggedIn]); // Auto-rotate useEffect(() => { @@ -187,38 +201,109 @@ const CategoryList: React.FC = () => { return ( - {/* Hero Section */} - theme.palette.mode === 'dark' - ? 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' - : 'linear-gradient(135deg, #fdf6f7 0%, #f8e1e5 100%)', - textAlign: 'center', - borderBottom: '1px solid rgba(255,255,255,0.1)', - width: '100%', - boxSizing: 'border-box', - overflow: 'hidden' - }} - > - - The Ultimate Holy Archive - - - Browse every flavor ever released, discover new favorites, and share your ratings with the community. - - - - + ? 'linear-gradient(180deg, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 100%)' + : 'linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0) 100%)', + borderBottom: '1px solid', + borderColor: 'divider', + mb: 8 + }}> + + + + Community Activity + Latest reviews from people you follow + + + + + {feedRatings.length === 0 ? ( + + Your feed is a bit quiet + Follow more users to see their activity here! + + + ) : ( + + {feedRatings.map(rating => ( + + + + + + {!rating.user_avatar && rating.user.charAt(0).toUpperCase()} + + {rating.user} + + rated + + + + + + + {rating.flavor_name} + + + + + {rating.score}/10 + + + + + + ))} + + )} + - + ) : ( + theme.palette.mode === 'dark' + ? 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' + : 'linear-gradient(135deg, #fdf6f7 0%, #f8e1e5 100%)', + textAlign: 'center', + borderBottom: '1px solid rgba(255,255,255,0.1)', + width: '100%', + boxSizing: 'border-box', + overflow: 'hidden' + }} + > + + The Ultimate Holy Archive + + + Browse every flavor ever released, discover new favorites, and share your ratings with the community. + + + + + + + )}