'use client'; import { motion } from 'motion/react'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import { useState } from 'react'; import useSWR from 'swr'; import { profileUrl, type ProfileDTO } from '@musicshare/shared'; import { Avatar } from '@/components/Avatar'; import { NowPlayingCard } from '@/components/NowPlayingCard'; import { ProfileMenu } from '@/components/ProfileMenu'; import { QrCode } from '@/components/QrCode'; import { RecentPlays } from '@/components/RecentPlays'; import { TrackCard } from '@/components/TrackCard'; import { api, fetcher, useMe } from '@/lib/api'; import { useRealtime } from '@/lib/useRealtime'; export function ProfileClient() { const { username } = useParams<{ username: string }>(); const { me } = useMe(); const { data: profile, error, mutate } = useSWR(`/users/${username}`, fetcher); const [busy, setBusy] = useState(false); const [showQr, setShowQr] = useState(false); // Live updates arrive for people you follow (and yourself) useRealtime(Boolean(me), (msg) => { if (msg.type === 'now_playing' && profile && msg.data.user.id === profile.user.id) { // A new track moves the previous one into "Recently played", so refetch; otherwise patch in place. const newTrack = msg.data.track.id !== profile.nowPlaying?.track.id; mutate({ ...profile, nowPlaying: msg.data }, { revalidate: newTrack }); } }); if (error) return

User not found.

; if (!profile) return null; const togglePin = async () => { setBusy(true); try { await api(`/users/${username}/pin`, { method: profile.isPinned ? 'DELETE' : 'PUT', body: profile.isPinned ? undefined : {} }); await mutate(); } catch (err) { alert((err as Error).message); } setBusy(false); }; const toggleFollow = async () => { setBusy(true); await api(`/users/${username}/follow`, { method: profile.isFollowing ? 'DELETE' : 'POST', body: {} }); await mutate(); setBusy(false); }; const { user } = profile; const preferred = me?.preferredService; return (

{user.displayName ?? user.username}

@{user.username} {profile.followsYou && !profile.isSelf && Follows you}
{profile.followerCount} {profile.followerCount === 1 ? 'follower' : 'followers'} {profile.followingCount} following
{user.bio &&

{user.bio}

} {profile.isSelf ? (
Edit profile
) : me ? (
{profile.isFollowing && ( )} {!profile.isBlocked && ( )} mutate()} />
) : ( Sign up to follow )}
{profile.isBlocked && (

You blocked @{user.username}. They can't see your profile or what you play, and you won't see theirs. Unblock them from the ⋯ menu.

)} {profile.isSelf && showQr && (

Friends scan this in the musicshare app (or their camera) to open your profile.

)} {profile.featured && (

Featured song

{profile.featured.comment &&
{profile.featured.comment}
}
)} {profile.nowPlaying ? ( ) : (

Nothing playing right now.

)}
); }