UI: подсказки ников при приглашении игрока в группу

При вводе в поле приглашения («Список игроков») под инпутом всплывают
до 3 подходящих игроков — аватар + ник, в стилистике строк топов.
Клик подставляет ник в поле (приглашение отправляется кнопкой/Enter),
уже состоящие в группе не предлагаются.

Детали: компонент PlayerSuggestions (выбор по mousedown — до blur
инпута), хук useUserSearch с дебаунсом 250 мс и keepPreviousData,
классы .suggest-* в духе .notif-panel/.lb-row. В поиске общего списка
подсказки не нужны — таблица уже фильтруется вживую при вводе.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 02:30:55 +03:00
co-authored by Claude Fable 5
parent e5b7420bae
commit ddbcd74058
5 changed files with 147 additions and 8 deletions
+30
View File
@@ -0,0 +1,30 @@
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { api, unwrap } from "../api/client";
import { qk } from "../api/queryKeys";
/** Значение с задержкой: не дёргаем поиск на каждый введённый символ. */
function useDebounced<T>(value: T, ms = 250): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const t = setTimeout(() => setDebounced(value), ms);
return () => clearTimeout(t);
}, [value, ms]);
return debounced;
}
/** Подсказки по нику среди всех активных игроков (GET /api/users/search). */
export function useUserSearch(q: string, limit = 3) {
const dq = useDebounced(q.trim());
return useQuery({
queryKey: qk.userSearch(dq, limit),
enabled: dq.length > 0,
// Список не мигает пустым между буквами; при пустом q данные остаются —
// видимость выпадашки родитель гейтит по q, а не по data.
placeholderData: keepPreviousData,
staleTime: 30_000,
queryFn: async () =>
unwrap(await api.GET("/api/users/search", { params: { query: { q: dq, limit } } })),
});
}