import { gql, useQuery } from '@apollo/client'; import { useMemo, useState } from 'react'; import { SearchConfigType } from '../../../interfaces/search/interface'; import { AnyEntity, UnknownType, } from '../../../interfaces/entities/generic.interface'; import { debounce } from '../../../modules/utils/debounce'; export const SEARCH_PEOPLE_QUERY = gql` query SearchPeopleQuery($where: PersonWhereInput, $limit: Int) { searchResults: findManyPerson(where: $where, take: $limit) { id phone email city firstname lastname createdAt } } `; export const SEARCH_USER_QUERY = gql` query SearchUserQuery($where: UserWhereInput, $limit: Int) { searchResults: findManyUser(where: $where, take: $limit) { id email displayName } } `; // TODO: remove this query export const EMPTY_QUERY = gql` query EmptyQuery { searchResults: findManyUser { id } } `; export const SEARCH_COMPANY_QUERY = gql` query SearchCompanyQuery($where: CompanyWhereInput, $limit: Int) { searchResults: findManyCompany(where: $where, take: $limit) { id name domainName } } `; export type SearchResultsType = { results: { render: (value: T) => string; value: T; }[]; loading: boolean; }; export const useSearch = (): [ SearchResultsType, React.Dispatch>, React.Dispatch | null>>, string, ] => { const [searchConfig, setSearchConfig] = useState | null>( null, ); const [searchInput, setSearchInput] = useState(''); const debouncedsetSearchInput = useMemo( () => debounce(setSearchInput, 50), [], ); const where = useMemo(() => { return ( searchConfig && searchConfig.template && searchConfig.template(searchInput) ); }, [searchConfig, searchInput]); const searchQueryResults = useQuery(searchConfig?.query || EMPTY_QUERY, { variables: { where, limit: 5, }, skip: !searchConfig, }); const searchResults = useMemo<{ results: { render: (value: T) => string; value: any }[]; loading: boolean; }>(() => { if (searchConfig == null) { return { loading: false, results: [], }; } if (searchQueryResults.loading) { return { loading: true, results: [], }; } return { loading: false, // TODO: add proper typing results: searchQueryResults?.data?.searchResults?.map( searchConfig.resultMapper, ), }; }, [searchConfig, searchQueryResults]); return [searchResults, debouncedsetSearchInput, setSearchConfig, searchInput]; };