feat: add followers/following list

This commit is contained in:
gosangam
2026-06-09 13:20:44 +05:30
parent ef6e280524
commit e36afdd1a5
5 changed files with 380 additions and 8 deletions
+57 -8
View File
@@ -34,6 +34,10 @@ import { Settings, X } from "lucide-react";
import { cn } from "@/lib/utils";
import type { RelationshipResult, RelationshipState } from "@/lib/social";
import { ProfileActions } from "@/components/profile/profile-actions";
import {
FollowListDrawer,
type FollowMode,
} from "@/components/profile/follow-list-drawer";
export function ProfileHeader({
avatarURL,
@@ -85,6 +89,9 @@ export function ProfileHeader({
const [following, setFollowing] = useState(followingCount ?? 0);
const [rel, setRel] = useState<RelationshipState | null>(relationship ?? null);
// Which follow list (if any) is open in the drawer.
const [followList, setFollowList] = useState<FollowMode | null>(null);
const handleResult = (r: RelationshipResult) => {
setRel(r.relationship);
setFollowers(r.follower_count);
@@ -116,8 +123,16 @@ export function ProfileHeader({
) : null}
{showCounts ? (
<>
<Stat n={followers} label="followers" />
<Stat n={following} label="following" />
<Stat
n={followers}
label="followers"
onClick={() => setFollowList("followers")}
/>
<Stat
n={following}
label="following"
onClick={() => setFollowList("following")}
/>
</>
) : null}
</div>
@@ -164,17 +179,51 @@ export function ProfileHeader({
onClose={() => setZoomOpen(false)}
/>
) : null}
{showCounts ? (
<FollowListDrawer
open={followList !== null}
mode={followList ?? "followers"}
handle={handle}
onClose={() => setFollowList(null)}
/>
) : null}
</>
);
}
/** One inline profile stat — bold count over a muted label. */
function Stat({ n, label }: { n: number; label: string }) {
return (
<div className="flex flex-col items-center leading-tight">
<span className="font-semibold text-lg text-foreground tabular-nums">{n}</span>
/** One inline profile stat — bold count over a muted label. Renders as a
* button (opening the follow list) when `onClick` is provided, else a plain
* div (e.g. the posts count). */
function Stat({
n,
label,
onClick,
}: {
n: number;
label: string;
onClick?: () => void;
}) {
const inner = (
<>
<span className="font-semibold text-lg text-foreground tabular-nums">
{n}
</span>
<span className="text-sm text-muted-foreground">{label}</span>
</div>
</>
);
if (!onClick) {
return (
<div className="flex flex-col items-center leading-tight">{inner}</div>
);
}
return (
<button
type="button"
onClick={onClick}
className="flex flex-col items-center leading-tight rounded-md px-2 -mx-1 py-0.5 transition-colors hover:bg-muted/60 outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
{inner}
</button>
);
}