From 067dcc6a90d7dc5742114f5a4f63549db6c1f5f3 Mon Sep 17 00:00:00 2001 From: EvanLin3141 Date: Thu, 27 Feb 2025 17:20:13 +0000 Subject: [PATCH] Update: FollowedCategories page now have separate buttons --- .../src/components/Input/FollowButton.tsx | 58 ++++++++++ frontend/src/pages/FollowedCategories.tsx | 102 +++++++++--------- 2 files changed, 108 insertions(+), 52 deletions(-) create mode 100644 frontend/src/components/Input/FollowButton.tsx diff --git a/frontend/src/components/Input/FollowButton.tsx b/frontend/src/components/Input/FollowButton.tsx new file mode 100644 index 0000000..6ae3293 --- /dev/null +++ b/frontend/src/components/Input/FollowButton.tsx @@ -0,0 +1,58 @@ +import React, { useEffect, useState } from "react"; +import { CircleMinus, CirclePlus } from "lucide-react"; +import { useCategoryFollow } from "../../hooks/useCategoryFollow"; + +interface FollowButtonProps { + category: { + category_id: number; + category_name: string; + isFollowing: boolean; + }; +} + +const FollowButton: React.FC = ({ category }) => { + const [isFollowing, setIsFollowing] = useState(category.isFollowing); + const [isLoading, setIsLoading] = useState(false); + const { followCategory, unfollowCategory } = useCategoryFollow(); + + useEffect(() => { + setIsFollowing(category.isFollowing); + }, [category.isFollowing]); + + const handleClick = async (e: React.MouseEvent) => { + e.stopPropagation(); + setIsLoading(true); + + try { + if (isFollowing) { + await unfollowCategory(category.category_name); + setIsFollowing(false); + } else { + await followCategory(category.category_name); + setIsFollowing(true); + } + } catch (error) { + console.error("Error toggling follow state:", error); + } + + setIsLoading(false); + }; + + return ( + + ); +}; + +export default FollowButton; diff --git a/frontend/src/pages/FollowedCategories.tsx b/frontend/src/pages/FollowedCategories.tsx index 00334cb..3d50110 100644 --- a/frontend/src/pages/FollowedCategories.tsx +++ b/frontend/src/pages/FollowedCategories.tsx @@ -7,12 +7,12 @@ import { fetchContentOnScroll } from "../hooks/fetchContentOnScroll"; import { useCategoryFollow } from "../hooks/useCategoryFollow"; import { ListItemProps as StreamData } from "../components/Layout/ListItem"; import LoadingScreen from "../components/Layout/LoadingScreen"; +import FollowButton from "../components/Input/FollowButton"; interface Category { isFollowing: boolean; category_id: number; category_name: string; - isLoading?: boolean; } interface FollowedCategoryProps { @@ -30,9 +30,37 @@ const FollowedCategories: React.FC = ({ extraClasses = "" if (categoryName) checkCategoryFollowStatus(categoryName); }, [categoryName]); - const toggleFollow = async (categoryId: number, categoryName: string, currentFollowState: boolean) => { + + useEffect(() => { + if (!isLoggedIn) return; + + const fetchFollowedCategories = async () => { + try { + const response = await fetch("/api/categories/following"); + if (!response.ok) throw new Error("Failed to fetch followed categories"); + const data = await response.json(); + setFollowedCategories(data); + } catch (error) { + console.error("Error fetching followed categories:", error); + } + }; + + fetchFollowedCategories(); + }, [isLoggedIn]); + + useEffect(() => { + toggleFollow; + }) + + const toggleFollow = async (categoryId: number, categoryName: string) => { + // Find the current category state from followedCategories + const category = followedCategories.find(cat => cat.category_id === categoryId); + if (!category) return; + + const currentFollowState = category.isFollowing; // Use the actual state instead of isCategoryFollowing + try { - // Set local loading state per category + // Set local state per category (independent button states) setFollowedCategories(prevCategories => prevCategories.map(cat => cat.category_id === categoryId ? { ...cat, isLoading: true } : cat @@ -45,7 +73,7 @@ const FollowedCategories: React.FC = ({ extraClasses = "" await followCategory(categoryName); } - // Toggle only the clicked button state + // Update only the clicked category setFollowedCategories(prevCategories => prevCategories.map(cat => cat.category_id === categoryId @@ -65,23 +93,6 @@ const FollowedCategories: React.FC = ({ extraClasses = "" } }; - useEffect(() => { - if (!isLoggedIn) return; - - const fetchFollowedCategories = async () => { - try { - const response = await fetch("/api/categories/following"); - if (!response.ok) throw new Error("Failed to fetch followed categories"); - const data = await response.json(); - setFollowedCategories(data); - } catch (error) { - console.error("Error fetching followed categories:", error); - } - }; - - fetchFollowedCategories(); - }, [isLoggedIn]); - return (
= ({ extraClasses = "" > {/* Followed Categories */}
- {followedCategories.map((category: Category) => ( -
navigate(`/category/${category.category_name}`)} - > - - - {category.category_name} -
- {category.category_name} + + {category.category_name} +
+ {category.category_name} +
-
- ))} + ); + })} +