diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ab3d870..29f1bf4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -76,7 +76,6 @@ function App() { }> } /> } /> - } /> } /> diff --git a/frontend/src/pages/FollowUsers.tsx b/frontend/src/pages/FollowUsers.tsx new file mode 100644 index 0000000..9ed7009 --- /dev/null +++ b/frontend/src/pages/FollowUsers.tsx @@ -0,0 +1,101 @@ +import React, { useEffect, useState } from "react"; +import { useAuth } from "../context/AuthContext"; +import { useNavigate } from "react-router-dom"; +import DynamicPageContent from "../components/Layout/DynamicPageContent"; +import { useFollow } from "../hooks/useFollow"; +import { useAuthModal } from "../hooks/useAuthModal"; +import FollowUserButton from "../components/Input/FollowUserButton"; + +interface Streamer { + user_id: number; + username: string; +} + +interface FollowingStreamerProps { + extraClasses?: string; +} + +const FollowUsers: React.FC = ({ extraClasses = "" }) => { + const navigate = useNavigate(); + const { isLoggedIn } = useAuth(); + const [followedStreamers, setFollowedStreamers] = useState([]); + const [followingStatus, setFollowingStatus] = useState<{ [key: number]: boolean }>({}); // Store follow status for each streamer + + const { isFollowing, checkFollowStatus, followUser, unfollowUser } = + useFollow(); + + useEffect(() => { + const fetchFollowedStreamers = async () => { + try { + const response = await fetch("/api/user/following"); + if (!response.ok) throw new Error("Failed to fetch followed streamers"); + const data = await response.json(); + setFollowedStreamers(data); + + const updatedStatus: { [key: number]: boolean } = {}; + for (const streamer of data || []) { + const status = await checkFollowStatus(streamer.username); + updatedStatus[streamer.user_id] = Boolean(status); + } + setFollowingStatus(updatedStatus); + + console.log("Fetched Follow Status:", updatedStatus); // Log the status + } catch (error) { + console.error("Error fetching followed streamers:", error); + } + }; + + if (isLoggedIn) { + fetchFollowedStreamers(); + } + }, [isLoggedIn]); + + + const handleFollowToggle = async (userId: number) => { + const isCurrentlyFollowing = followingStatus[userId]; + + if (isCurrentlyFollowing) { + await unfollowUser(userId); + } else { + await followUser(userId); + } + + // Update local state for this specific streamer + setFollowingStatus((prev) => ({ + ...prev, + [userId]: !isCurrentlyFollowing, // Toggle based on previous state + })); + }; + + return ( + + + + ); +}; + +export default FollowUsers; \ No newline at end of file diff --git a/frontend/src/pages/Following.tsx b/frontend/src/pages/Following.tsx index 6566110..8b779b0 100644 --- a/frontend/src/pages/Following.tsx +++ b/frontend/src/pages/Following.tsx @@ -1,71 +1,79 @@ import React, { useEffect, useState } from "react"; import { useAuth } from "../context/AuthContext"; -import { useNavigate } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import DynamicPageContent from "../components/Layout/DynamicPageContent"; import { useFollow } from "../hooks/useFollow"; -import { useAuthModal } from "../hooks/useAuthModal"; import FollowUserButton from "../components/Input/FollowUserButton"; interface Streamer { - user_id: number; - username: string; + user_id: number; + username: string; } -interface FollowingStreamerProps { +interface Category { + category_id: number; + category_name: string; +} + +interface FollowingProps { extraClasses?: string; } -const Following: React.FC = ({ extraClasses = "" }) => { +const Following: React.FC = ({ extraClasses = "" }) => { const navigate = useNavigate(); const { isLoggedIn } = useAuth(); const [followedStreamers, setFollowedStreamers] = useState([]); - const [followingStatus, setFollowingStatus] = useState<{ [key: number]: boolean }>({}); // Store follow status for each streamer + const [followedCategories, setFollowedCategories] = useState([]); + const [followingStatus, setFollowingStatus] = useState<{ [key: number]: boolean }>({}); - const { isFollowing, checkFollowStatus, followUser, unfollowUser } = - useFollow(); + const { checkFollowStatus, followUser, unfollowUser } = useFollow(); + + const location = useLocation(); + const queryParams = new URLSearchParams(location.search); + const initialTab = queryParams.get("tab") === "streamers" ? "streamers" : "categories"; + + const [activeTab, setActiveTab] = useState<"categories" | "streamers">(initialTab); + //const [followingStatus, setFollowingStatus] = useState>({}); useEffect(() => { - const fetchFollowedStreamers = async () => { + const newTab = queryParams.get("tab") as "categories" | "streamers"; + if (newTab) { + setActiveTab(newTab); + } + }, [location.search]); + + useEffect(() => { + const fetchFollowedContent = async () => { try { const response = await fetch("/api/user/following"); - if (!response.ok) throw new Error("Failed to fetch followed streamers"); - const data = await response.json(); - setFollowedStreamers(data); + if (!response.ok) throw new Error("Failed to fetch followed content"); + const data = await response.json(); + if (!Array.isArray(data.streams) || !Array.isArray(data.categories)) { + throw new Error("API response structure is incorrect"); + } + + setFollowedStreamers(data.streams); + setFollowedCategories(data.categories); + + // Fetch follow status for streamers const updatedStatus: { [key: number]: boolean } = {}; - for (const streamer of data || []) { + for (const streamer of data.streams) { const status = await checkFollowStatus(streamer.username); updatedStatus[streamer.user_id] = Boolean(status); } setFollowingStatus(updatedStatus); - - console.log("Fetched Follow Status:", updatedStatus); // Log the status } catch (error) { - console.error("Error fetching followed streamers:", error); + console.error("Error fetching followed content:", error); + setFollowedStreamers([]); + setFollowedCategories([]); } }; - if (isLoggedIn) { - fetchFollowedStreamers(); - } - }, [isLoggedIn]); - - - const handleFollowToggle = async (userId: number) => { - const isCurrentlyFollowing = followingStatus[userId]; - - if (isCurrentlyFollowing) { - await unfollowUser(userId); - } else { - await followUser(userId); + if (isLoggedIn) { + fetchFollowedContent(); } - - // Update local state for this specific streamer - setFollowingStatus((prev) => ({ - ...prev, - [userId]: !isCurrentlyFollowing, // Toggle based on previous state - })); - }; + }, [isLoggedIn]); return ( @@ -73,28 +81,33 @@ const Following: React.FC = ({ extraClasses = "" }) => { id="sidebar" className={`top-0 left-0 w-screen h-screen overflow-x-hidden flex flex-col bg-[var(--sideBar-bg)] text-[var(--sideBar-text)] text-center overflow-y-auto scrollbar-hide transition-all duration-500 ease-in-out ${extraClasses}`} > -
- {followedStreamers.map((streamer: any) => ( -
navigate(`/user/${streamer.username}`)}*/ - > - {streamer.username} - -
- ))} -
+ {activeTab === "streamers" && ( +
+ {followedStreamers.map((streamer: any) => ( +
navigate(`/user/${streamer.username}`)}*/ + > + {streamer.username} + +
+ ))} +
+ )} -
+ + + + ); }; diff --git a/frontend/src/pages/UserPage.tsx b/frontend/src/pages/UserPage.tsx index 4bd80dc..f97a394 100644 --- a/frontend/src/pages/UserPage.tsx +++ b/frontend/src/pages/UserPage.tsx @@ -82,13 +82,13 @@ const UserPage: React.FC = () => { const handleNavigation = (path: string) => { if (profilePicture === initialProfilePicture.current) { - // Variable hasn't changed - use React Router navigation - navigate(path); + // Variable hasn't changed - use React Router navigation + navigate(path); } else { - // Variable has changed - use full page reload - window.location.href = path; + // Variable has changed - use full page reload + window.location.href = path; } - }; + }; // Store initial profile picture to know if it changes later useEffect(() => { @@ -138,8 +138,7 @@ const UserPage: React.FC = () => { {/* Profile Picture */}
@@ -269,7 +268,7 @@ const UserPage: React.FC = () => { onMouseEnter={(e) => (e.currentTarget.style.boxShadow = "var(--follow-shadow)")} onMouseLeave={(e) => (e.currentTarget.style.boxShadow = "none")} > -
@@ -289,7 +288,7 @@ const UserPage: React.FC = () => { onMouseEnter={(e) => (e.currentTarget.style.boxShadow = "var(--follow-shadow)")} onMouseLeave={(e) => (e.currentTarget.style.boxShadow = "none")} > - +