'use client'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { Suspense, useRef, useState } from 'react'; import useSWR from 'swr'; import { SERVICE_LABELS, SPOTIFY_LINK_PAGES, STREAMING_SERVICES, isQuietScrobbler, type ConnectionDTO, type MeDTO, type NowPlayingProvider, type TrackSearchResultDTO, type UserSummaryDTO, } from '@musicshare/shared'; import { Avatar } from '@/components/Avatar'; import { ServiceName } from '@/components/ServiceName'; import { SharingControls } from '@/components/SharingControls'; import { SupportCard } from '@/components/SupportLink'; import { api, client, fetcher, uploadFile, useMe } from '@/lib/api'; import { timeAgo } from '@musicshare/shared'; import { useDebounced } from '@/lib/useDebounced'; export default function SettingsPage() { return ( ); } function Settings() { const { me, loggedOut } = useMe(); const router = useRouter(); if (loggedOut) router.replace('/login'); if (!me) return null; return (

Settings

); } function ProfileForm({ me }: { me: MeDTO }) { const { mutate } = useMe(); const [saved, setSaved] = useState(false); const [error, setError] = useState(null); const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); const f = new FormData(e.currentTarget); const str = (k: string) => (f.get(k) as string).trim() || null; try { const updated = await api('/me', { method: 'PATCH', body: { displayName: str('displayName'), bio: str('bio'), preferredService: str('preferredService') }, }); await mutate(updated, { revalidate: false }); setError(null); setSaved(true); setTimeout(() => setSaved(false), 2000); } catch (err) { setError((err as Error).message); } }; return (

Profile