import React, { useState, useEffect } from "react"; import Navbar from "../components/Navigation/Navbar"; import AuthModal from "../components/Auth/AuthModal"; import { useAuthModal } from "../hooks/useAuthModal"; import { useAuth } from "../context/AuthContext"; import { useParams } from "react-router-dom"; import ListItem from "../components/Layout/ListItem"; import { useFollow } from "../hooks/useFollow"; import { useNavigate } from "react-router-dom"; import Button, { EditButton } from "../components/Input/Button"; import DynamicPageContent from "../components/Layout/DynamicPageContent"; interface UserProfileData { id: number; username: string; bio: string; followerCount: number; isPartnered: boolean; isLive: boolean; currentStreamTitle?: string; currentStreamCategory?: string; currentStreamViewers?: number; currentStreamStartTime?: string; currentStreamThumbnail?: string; } const UserPage: React.FC = () => { const [userPageVariant, setUserPageVariant] = useState< "personal" | "streamer" | "user" | "admin" >("user"); const [profileData, setProfileData] = useState(); const { isFollowing, checkFollowStatus, followUser, unfollowUser } = useFollow(); const { showAuthModal, setShowAuthModal } = useAuthModal(); const { username: loggedInUsername } = useAuth(); const { username } = useParams(); const navigate = useNavigate(); const bgColors = { personal: "", streamer: "bg-gradient-radial from-[#ff00f1] via-[#0400ff] to-[#ff0000]", // offline streamer user: "bg-gradient-radial from-[#ff00f1] via-[#0400ff] to-[#ff00f1]", admin: "bg-gradient-to-r from-[rgb(255,0,0)] via-transparent to-[rgb(0,0,255)]", }; useEffect(() => { // Fetch user profile data fetch(`/api/user/${username}`) .then((res) => res.json()) .then((data) => { setProfileData({ id: data.user_id, username: data.username, bio: data.bio || "This user hasn't written a bio yet.", followerCount: data.num_followers || 0, isPartnered: data.isPartnered || false, isLive: data.is_live, currentStreamTitle: "", currentStreamCategory: "", currentStreamViewers: 0, currentStreamThumbnail: "", }); if (data.is_live) { // Fetch stream data for this streamer fetch(`/api/streams/${data.user_id}/data`) .then((res) => res.json()) .then((streamData) => { setProfileData((prevData) => { if (!prevData) return prevData; return { ...prevData, currentStreamTitle: streamData.title, currentStreamCategory: streamData.category_id, currentStreamViewers: streamData.num_viewers, currentStreamStartTime: streamData.start_time, currentStreamThumbnail: streamData.thumbnail || `/images/category_thumbnails/${streamData.category_name .toLowerCase() .replace(/ /g, "_")}.webp`, }; }); let variant: "user" | "streamer" | "personal" | "admin"; if (username === loggedInUsername) variant = "personal"; else if (streamData.title) variant = "streamer"; // else if (data.isAdmin) variant = "admin"; else variant = "user"; setUserPageVariant(variant); }) .catch((err) => console.error("Error fetching stream data:", err)); } }) .catch((err) => { console.error("Error fetching profile data:", err); navigate("/404"); }); // Check if the *logged-in* user is following this user if (loggedInUsername && username) checkFollowStatus(username); }, [username]); if (!profileData) { return (
Loading...
); } return (
{/* Profile Section - TOP */}
{/* Border Overlay (Always on Top) */}
{/* Background Box */}
{/* Profile Picture */}
{`${profileData.username}'s
{/* Username - Now Directly Below PFP */}

{profileData.username}

{/* Follower Count */} {userPageVariant === "streamer" && ( <>
{profileData.followerCount.toLocaleString()} followers {profileData.isPartnered && ( Partner )}
{/* (Un)Follow Button */} {!isFollowing ? ( ) : ( )} )}
{/* User Type (e.g., "USER") */} {userPageVariant.toUpperCase()}

About {profileData.username}

{profileData.bio}

{/* Content Section */}
{userPageVariant === "streamer" && ( <> {/* ↓↓ Current Stream ↓↓ */} {profileData.isLive && (

Currently Live!

{ navigate(`/${profileData.username}`); }} />
)} {/* ↓↓ VODS ↓↓ */}

Past Broadcasts

No past broadcasts found
)}
e.currentTarget.style.boxShadow = "var(--follow-shadow)"} onMouseLeave={(e) => e.currentTarget.style.boxShadow = "none"} >

Following www

{showAuthModal && setShowAuthModal(false)} />}
); }; export default UserPage;