From 9466c701c731630b57377602863c840ce80f34ae Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sat, 27 Sep 2025 21:44:20 +0000 Subject: [PATCH] Create Network page with public profile, recommendations, follow button cgen-7112ecc6a7664fcfbcd9d6c52efc10ac --- client/pages/Network.tsx | 151 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 client/pages/Network.tsx diff --git a/client/pages/Network.tsx b/client/pages/Network.tsx new file mode 100644 index 00000000..ba0b2572 --- /dev/null +++ b/client/pages/Network.tsx @@ -0,0 +1,151 @@ +import Layout from "@/components/Layout"; +import { useAuth } from "@/contexts/AuthContext"; +import { useEffect, useMemo, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import LoadingScreen from "@/components/LoadingScreen"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import { aethexSocialService } from "@/lib/aethex-social-service"; +import { UserPlus, UserCheck } from "lucide-react"; + +export default function Network() { + const { user, profile, loading } = useAuth(); + const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(true); + const [recommended, setRecommended] = useState([]); + const [following, setFollowing] = useState([]); + + useEffect(() => { + if (!loading && !user) { + navigate("/login", { replace: true }); + return; + } + if (!user) return; + + const load = async () => { + setIsLoading(true); + try { + const recs = await aethexSocialService.listRecommended(user.id, 12); + setRecommended(recs); + const flw = await aethexSocialService.getFollowing(user.id); + setFollowing(flw); + } finally { + setIsLoading(false); + } + }; + load(); + }, [user, loading, navigate]); + + const isFollowing = (id: string) => following.includes(id); + + const toggleFollow = async (targetId: string) => { + if (!user) return; + if (isFollowing(targetId)) { + await aethexSocialService.unfollowUser(user.id, targetId); + setFollowing((s) => s.filter((x) => x !== targetId)); + } else { + await aethexSocialService.followUser(user.id, targetId); + setFollowing((s) => Array.from(new Set([...s, targetId]))); + } + }; + + if (loading || isLoading) { + return ; + } + + if (!user) return null; + + return ( + +
+
+ {/* Public Profile */} +
+ + +
+ + + {profile?.full_name?.[0] || user.email?.[0]?.toUpperCase()} + +
+

{profile?.full_name || user.email?.split("@")[0]}

+

{profile?.role || "Member"}

+
+ Level {profile?.level || 1} + {(profile as any)?.experience_level || "beginner"} +
+
+
+ {profile?.bio && ( +

{profile.bio}

+ )} +
+ + +
+
+
+ + + + Recommendations + People who align with your interests + + + {recommended.slice(0, 3).map((r) => ( +
+
+ {(r.full_name || r.username || "U")[0]} +
+
{r.full_name || r.username}
+
{r.bio?.slice(0, 40) || "Member"}
+
+
+ +
+ ))} + {recommended.length === 0 && ( +
No recommendations yet.
+ )} +
+
+
+ + {/* Discover People */} +
+ + + Discover People + Connect with creators, clients, and members + + + {recommended.map((r) => ( +
+
+ {(r.full_name || r.username || "U")[0]} +
+
{r.full_name || r.username}
+
{r.bio?.slice(0, 80) || "Member"}
+
+
+ +
+ ))} + {recommended.length === 0 && ( +
No people found yet.
+ )} +
+
+
+
+
+
+ ); +}