/* eslint-disable @next/next/no-img-element */ "use client"; import { useMemo, useState } from "react"; type ProfileHeaderProps = { displayName: string; username: string; bio: string | null; avatarUrl: string | null; }; export function ProfileHeader({ displayName, username, bio, avatarUrl }: ProfileHeaderProps) { const [avatarFailed, setAvatarFailed] = useState(false); const initials = useMemo(() => { const words = displayName.trim().split(/\s+/).filter(Boolean); if (words.length >= 2) { return `${words[0]?.[0] ?? ""}${words[1]?.[0] ?? ""}`.toUpperCase(); } if (words.length === 1) { return (words[0]?.[0] ?? username[0] ?? "?").toUpperCase(); } return (username[0] ?? "?").toUpperCase(); }, [displayName, username]); const normalizedAvatarUrl = avatarUrl?.trim() ?? ""; const hasValidAvatarUrl = useMemo(() => { if (!normalizedAvatarUrl) { return false; } try { const url = new URL(normalizedAvatarUrl); if (url.protocol !== "http:" && url.protocol !== "https:") { return false; } // Reject placeholder-like values such as "https://..." if (!url.hostname || url.hostname === "..." || !url.hostname.includes(".")) { return false; } return true; } catch { return false; } }, [normalizedAvatarUrl]); const shouldShowAvatar = hasValidAvatarUrl && !avatarFailed; return (
{shouldShowAvatar ? ( {`${displayName} setAvatarFailed(true)} /> ) : (
{initials}
)}

{displayName}

@{username}

{bio ?

{bio}

: null}
); }