Files
musicshare/apps/web/src/components/UserSearch.tsx
T
chrisandClaude Opus 5.5 864ab88627 New look: slate-indigo panels, pink accent, Poppins, and a gradient card for your song
Inspired by a dashboard design the user shared.
- App: new palette and fonts, borderless rounded panels with soft shadows, a pink-to-blue
  gradient card for your own song (text and controls switch to white on it), flat cards for
  friends, a 'Hi Chris, welcome back' header, an outline bell, and a pink pill on the active tab.
- Website: the same look, plus a wide-screen layout with a sidebar, the page in a rounded panel,
  and a right column with your profile, recent activity and recent plays. Phones keep the top
  bar and bottom tabs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
2026-10-15 15:01:20 -04:00

38 lines
1.3 KiB
TypeScript

'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({ placeholder = 'Find friends by username' }: { placeholder?: string }) {
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={placeholder} aria-label="Search people" 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>
);
}