fix: profile bio
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* ProfileHeader — Instagram-style centered header used at the top of
|
||||
* /u/me and /u/[handle]. Avatar, display name, @handle, a single stat
|
||||
* line, and an action row.
|
||||
* ProfileHeader — the header at the top of /u/me and /u/[handle].
|
||||
*
|
||||
* Layout is two stacked blocks:
|
||||
* 1. An identity ROW — avatar on the left, with display name, @handle, and
|
||||
* the posts/followers/following stat line stacked to its right.
|
||||
* 2. Full-width rows beneath it — the bio, then the action row. Both span the
|
||||
* avatar's width too, so a 200-character bio gets the whole column rather
|
||||
* than the narrow gutter beside the avatar.
|
||||
*
|
||||
* The action row hosts:
|
||||
* • "Edit profile" link — only on the owner's own profile (via the
|
||||
@@ -122,61 +127,80 @@ export function ProfileHeader({
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="flex flex-col items-center text-center gap-4 pt-4 pb-6 sm:pt-6 sm:pb-8">
|
||||
{/* Avatar, with Śrīla Prabhupāda's portrait tucked into the lower-right
|
||||
for his direct disciples (verification-tick placement). */}
|
||||
<div className="relative">
|
||||
<UserAvatar
|
||||
src={avatarURL}
|
||||
name={name}
|
||||
className="size-24 sm:size-28"
|
||||
textClassName="text-3xl"
|
||||
interactive
|
||||
onClick={avatarURL ? () => setZoomOpen(true) : undefined}
|
||||
ariaLabel={`View ${name}'s profile picture`}
|
||||
/>
|
||||
{isDirectDisciple ? (
|
||||
<DiscipleBadge className="absolute -bottom-0.5 -right-0.5" />
|
||||
) : null}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-1">
|
||||
<h1 className="font-(family-name:--font-title) font-semibold text-xl sm:text-2xl text-foreground leading-tight">
|
||||
{name}
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">@{handle}</p>
|
||||
<header className="flex flex-col gap-4 pt-4 pb-6 sm:pt-6 sm:pb-8">
|
||||
{/* Identity row — avatar on the left, name + handle + stats stacked to
|
||||
its right. The bio and action row sit below at full width, so long
|
||||
prose gets the whole column instead of a narrow gutter. */}
|
||||
<div className="flex items-center gap-4 sm:gap-6">
|
||||
{/* Avatar, with Śrīla Prabhupāda's portrait tucked into the
|
||||
lower-right for his direct disciples (verification-tick
|
||||
placement). */}
|
||||
<div className="relative shrink-0">
|
||||
<UserAvatar
|
||||
src={avatarURL}
|
||||
name={name}
|
||||
className="size-20 sm:size-28"
|
||||
textClassName="text-3xl"
|
||||
interactive
|
||||
onClick={avatarURL ? () => setZoomOpen(true) : undefined}
|
||||
ariaLabel={`View ${name}'s profile picture`}
|
||||
/>
|
||||
{isDirectDisciple ? (
|
||||
<DiscipleBadge className="absolute -bottom-0.5 -right-0.5" />
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{/* Stat line: posts · followers · following */}
|
||||
<div className="flex items-center justify-center gap-5 sm:gap-7 pt-1 my-4">
|
||||
{typeof postCount === "number" ? (
|
||||
<Stat n={postCount} label={postCount === 1 ? "post" : "posts"} />
|
||||
) : null}
|
||||
{showCounts ? (
|
||||
<>
|
||||
<Stat
|
||||
n={followers}
|
||||
label="followers"
|
||||
onClick={
|
||||
interactiveCounts
|
||||
? () => setFollowList("followers")
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
<Stat
|
||||
n={following}
|
||||
label="following"
|
||||
onClick={
|
||||
interactiveCounts
|
||||
? () => setFollowList("following")
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
{/* min-w-0 lets the long-name truncation actually kick in — without
|
||||
it the flex child refuses to shrink below its content width. */}
|
||||
<div className="min-w-0 flex-1">
|
||||
<h1 className="font-(family-name:--font-title) font-semibold text-xl sm:text-2xl text-foreground leading-tight truncate">
|
||||
{name}
|
||||
</h1>
|
||||
<p className="mt-0.5 text-sm text-muted-foreground truncate">
|
||||
@{handle}
|
||||
</p>
|
||||
|
||||
{/* Stat line: posts · followers · following */}
|
||||
<div className="mt-3 flex items-center gap-5 sm:gap-7">
|
||||
{typeof postCount === "number" ? (
|
||||
<Stat n={postCount} label={postCount === 1 ? "post" : "posts"} />
|
||||
) : null}
|
||||
{showCounts ? (
|
||||
<>
|
||||
<Stat
|
||||
n={followers}
|
||||
label="followers"
|
||||
onClick={
|
||||
interactiveCounts
|
||||
? () => setFollowList("followers")
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
<Stat
|
||||
n={following}
|
||||
label="following"
|
||||
onClick={
|
||||
interactiveCounts
|
||||
? () => setFollowList("following")
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bio — spans the full column beneath the avatar AND the name/stats
|
||||
block, so a 200-character bio wraps across the whole width instead
|
||||
of being squeezed into the column beside the avatar. */}
|
||||
{bio?.trim() ? (
|
||||
<MentionText
|
||||
text={bio.trim()}
|
||||
className="text-sm sm:text-[15px] leading-relaxed text-foreground"
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{showOwnerControls ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Link
|
||||
@@ -209,17 +233,6 @@ export function ProfileHeader({
|
||||
onResult={handleResult}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{/* Bio — left-aligned across the full column, unlike the centred
|
||||
identity block above it. Prose reads badly centred once it wraps
|
||||
past one line, and `self-stretch` overrides the header's
|
||||
`items-center` so it spans edge to edge. */}
|
||||
{bio?.trim() ? (
|
||||
<MentionText
|
||||
text={bio.trim()}
|
||||
className="self-stretch text-left text-sm sm:text-[15px] leading-relaxed text-foreground"
|
||||
/>
|
||||
) : null}
|
||||
</header>
|
||||
{avatarURL ? (
|
||||
<AvatarZoomModal
|
||||
|
||||
Reference in New Issue
Block a user