diff --git a/web/src/components/input/InputWithTags.tsx b/web/src/components/input/InputWithTags.tsx index 608043152..0d85b3323 100644 --- a/web/src/components/input/InputWithTags.tsx +++ b/web/src/components/input/InputWithTags.tsx @@ -2,10 +2,9 @@ import { useState, useRef, useEffect, useMemo, useCallback } from "react"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { LuX, LuFilter, LuImage } from "react-icons/lu"; -import { SearchFilter, SearchSource } from "@/types/search"; +import { FilterType, SearchFilter, SearchSource } from "@/types/search"; import { DropdownMenuSeparator } from "../ui/dropdown-menu"; - -type FilterType = keyof SearchFilter; +import useSuggestions from "@/hooks/use-suggestions"; const convertMMDDYYToTimestamp = (dateString: string): number => { const match = dateString.match(/^(\d{2})(\d{2})(\d{2})$/); @@ -16,63 +15,6 @@ const convertMMDDYYToTimestamp = (dateString: string): number => { return date.getTime(); }; -// Custom hook for managing suggestions -const useSuggestions = ( - filters: SearchFilter, - allSuggestions: { [K in keyof SearchFilter]: string[] }, - searchHistory: string[], -) => { - const [suggestions, setSuggestions] = useState([]); - const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1); - - const updateSuggestions = useCallback( - (value: string, currentFilterType: FilterType | null) => { - if (currentFilterType && currentFilterType in allSuggestions) { - const filterValue = value.split(":").pop() || ""; - const currentFilterValues = filters[currentFilterType] || []; - setSuggestions( - allSuggestions[currentFilterType]?.filter( - (item) => - item.toLowerCase().startsWith(filterValue.toLowerCase()) && - !(currentFilterValues as (string | number)[]).includes(item), - ) ?? [], - ); - } else { - const availableFilters = Object.keys(allSuggestions).filter( - (filter) => { - const filterKey = filter as FilterType; - const filterValues = filters[filterKey]; - const suggestionValues = allSuggestions[filterKey]; - - if (!filterValues) return true; - if ( - Array.isArray(filterValues) && - Array.isArray(suggestionValues) - ) { - return filterValues.length < suggestionValues.length; - } - return false; - }, - ); - setSuggestions([ - ...searchHistory, - ...availableFilters, - "before", - "after", - ]); - } - }, - [filters, allSuggestions, searchHistory], - ); - - return { - suggestions, - selectedSuggestionIndex, - setSelectedSuggestionIndex, - updateSuggestions, - }; -}; - type InputWithTagsProps = { filters: SearchFilter; setFilters: (filter: SearchFilter) => void; diff --git a/web/src/hooks/use-suggestions.ts b/web/src/hooks/use-suggestions.ts new file mode 100644 index 000000000..91cf0080d --- /dev/null +++ b/web/src/hooks/use-suggestions.ts @@ -0,0 +1,66 @@ +import { FilterType, SearchFilter } from "@/types/search"; +import { useCallback, useState } from "react"; + +// Custom hook for managing suggestions +export type UseSuggestionsType = ( + filters: SearchFilter, + allSuggestions: { [K in keyof SearchFilter]: string[] }, + searchHistory: string[], +) => ReturnType; + +// Define and export the useSuggestions hook +export default function useSuggestions( + filters: SearchFilter, + allSuggestions: { [K in keyof SearchFilter]: string[] }, + searchHistory: string[], +) { + const [suggestions, setSuggestions] = useState([]); + const [selectedSuggestionIndex, setSelectedSuggestionIndex] = useState(-1); + + const updateSuggestions = useCallback( + (value: string, currentFilterType: FilterType | null) => { + if (currentFilterType && currentFilterType in allSuggestions) { + const filterValue = value.split(":").pop() || ""; + const currentFilterValues = filters[currentFilterType] || []; + setSuggestions( + allSuggestions[currentFilterType]?.filter( + (item) => + item.toLowerCase().startsWith(filterValue.toLowerCase()) && + !(currentFilterValues as (string | number)[]).includes(item), + ) ?? [], + ); + } else { + const availableFilters = Object.keys(allSuggestions).filter( + (filter) => { + const filterKey = filter as FilterType; + const filterValues = filters[filterKey]; + const suggestionValues = allSuggestions[filterKey]; + + if (!filterValues) return true; + if ( + Array.isArray(filterValues) && + Array.isArray(suggestionValues) + ) { + return filterValues.length < suggestionValues.length; + } + return false; + }, + ); + setSuggestions([ + ...searchHistory, + ...availableFilters, + "before", + "after", + ]); + } + }, + [filters, allSuggestions, searchHistory], + ); + + return { + suggestions, + selectedSuggestionIndex, + setSelectedSuggestionIndex, + updateSuggestions, + }; +} diff --git a/web/src/types/search.ts b/web/src/types/search.ts index 9aaf35849..63daf445d 100644 --- a/web/src/types/search.ts +++ b/web/src/types/search.ts @@ -55,3 +55,4 @@ export type SearchQueryParams = { }; export type SearchQuery = [string, SearchQueryParams] | null; +export type FilterType = keyof SearchFilter; \ No newline at end of file