Add Next.js web app
Feed with live updates and pinning, profiles with follow/pin, featured song picker, settings for all music services, and account deletion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import type { UserSummaryDTO } from '@musicshare/shared';
|
||||
import { fetcher } from '@/lib/api';
|
||||
import { useDebounced } from '@/lib/useDebounced';
|
||||
import { Avatar } from './Avatar';
|
||||
|
||||
export function UserSearch() {
|
||||
const [q, setQ] = useState('');
|
||||
const debounced = useDebounced(q.trim(), 250);
|
||||
const { data } = useSWR<UserSummaryDTO[]>(
|
||||
debounced.length >= 2 ? `/users/search?q=${encodeURIComponent(debounced)}` : null,
|
||||
fetcher,
|
||||
);
|
||||
return (
|
||||
<div className="search">
|
||||
<input placeholder="Find friends by username" value={q} onChange={(e) => setQ(e.target.value)} />
|
||||
{data && debounced.length >= 2 && (
|
||||
<ul className="search-results">
|
||||
{data.length === 0 && <li className="muted">No one found</li>}
|
||||
{data.map((u) => (
|
||||
<li key={u.id}>
|
||||
<Link href={`/u/${u.username}`} className="user-chip">
|
||||
<Avatar user={u} size={28} />
|
||||
<span>{u.displayName ?? u.username}</span>
|
||||
<span className="muted">@{u.username}</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user