import { Combobox } from "@headlessui/react"; import { useFetcher } from "@remix-run/react"; import clsx from "clsx"; import * as React from "react"; import { useTranslation } from "react-i18next"; import { useDebounce } from "react-use"; import type { UserSearchLoaderData } from "~/features/user-search/routes/u"; import { Avatar } from "./Avatar"; type UserSearchUserItem = NonNullable["users"][number]; export function UserSearch({ inputName, onChange, initialUserId, id, className, userIdsToOmit, required, }: { inputName: string; onChange?: (user: UserSearchUserItem) => void; initialUserId?: number; id?: string; className?: string; userIdsToOmit?: Set; required?: boolean; }) { const { t } = useTranslation(); const [selectedUser, setSelectedUser] = React.useState(null); const queryFetcher = useFetcher(); const initialUserFetcher = useFetcher(); const [query, setQuery] = React.useState(""); useDebounce( () => { if (!query) return; queryFetcher.load(`/u?q=${query}&limit=6`); }, 1000, [query], ); // load initial user React.useEffect(() => { if ( !initialUserId || initialUserFetcher.state !== "idle" || initialUserFetcher.data ) { return; } initialUserFetcher.load(`/u?q=${initialUserId}`); }, [initialUserId, initialUserFetcher]); React.useEffect(() => { if (!initialUserFetcher.data) return; setSelectedUser(initialUserFetcher.data.users[0]); }, [initialUserFetcher.data]); const allUsers = queryFetcher.data?.users ?? []; const users = allUsers.filter((u) => !userIdsToOmit?.has(u.id)); const noMatches = queryFetcher.data && users.length === 0; const initialSelectionIsLoading = Boolean( initialUserId && !initialUserFetcher.data, ); return (
{selectedUser && inputName ? ( ) : null} { setSelectedUser(newUser); onChange?.(newUser!); }} disabled={initialSelectionIsLoading} > setQuery(event.target.value)} displayValue={(user: UserSearchUserItem) => user?.username ?? ""} className={clsx("combobox-input", className)} data-1p-ignore data-testid={`${inputName}-combobox-input`} id={id} required={required} /> {noMatches ? (
{t("forms.errors.noSearchMatches")}{" "} 🤔
) : null} {users.map((user, i) => ( {({ active }) => (
  • {user.username}{" "} {user.plusTier ? ( +{user.plusTier} ) : null}
    {user.discordUniqueName ? (
    {user.discordUniqueName}
    ) : null}
  • )}
    ))}
    ); }