import { TopicProps } from '@junwon/centum' import { Button, Input, Text, XStack, YStack, isWeb } from '@my/ui' import { ChevronRight, Search, X, Plus } from '@tamagui/lucide-icons' import { debounce } from 'lodash' import { useCallback, useEffect, useState } from 'react' import { StyleSheet } from 'react-native' import usePageOpener from '../../utils/catalog/usePageOpener' const linkColor = '#06CAEB' async function searchCatalogForTopics(database, searchQuery: string): Promise { if (searchQuery.length < 1) { return [] } const reformulatedSearchQuery = `"${searchQuery.replace(/"/g, '\\"').replace(/ /g, '+')}":*` const { data, error } = await database .from('topics') .select('*') .textSearch('text_search_vector', reformulatedSearchQuery) .eq('allowed_in_site', true) .eq('disallowed_in_site', false) .limit(10) if (error) { console.error('Error searching topics:', error) return [] } return data } const SearchResultItem = ({ topic, database, insertDataAfterIndex, handleEndEditing, }: { topic: TopicProps database: any insertDataAfterIndex: Function handleEndEditing: Function }) => { const { openTopicPage } = usePageOpener() const title = topic.topic const subtitle = topic.is_presentable ? topic.intro : 'Ask Santana' const searchResultItemStyle = { overflow: 'hidden', textOverflow: 'ellipsis', ellipsizeMode: 'tail', whiteSpace: 'nowrap', letterSpacing: 0.3, } const titleFont = isWeb ? { fontFamily: 'Spline+Sans', fontWeight: 400 } : { fontFamily: 'SplineSansRegular' } const subtitleFont = isWeb ? { fontFamily: 'Spline+Sans', fontWeight: 300 } : { fontFamily: 'SplineSansLight' } const openTopic = () => { openTopicPage(topic.topic) handleEndEditing() } return ( {title} {subtitle} {topic.is_presentable ? ( ) : ( )} ) } const styles = StyleSheet.create({ searchBarFont: isWeb ? { fontFamily: 'Spline+Sans', fontWeight: '300', } : { fontFamily: 'SplineSansLight', }, input: { letterSpacing: 0.3, flex: 1, textDecorationLine: 'none', }, }) export const SearchBar = ({ database, insertDataAfterIndex }) => { const [searchQuery, setSearchQuery] = useState('') const [isFocused, setIsFocused] = useState(false) const [searchResults, setSearchResults] = useState([]) const handleSearchChange = (query: string) => { setSearchQuery(query) debouncedSearch(query) } const debouncedSearch = useCallback( debounce(async (query: string) => { const results = await searchCatalogForTopics(database, query) setSearchResults(results) }, 300), [database] ) const handleSearchSubmit = () => { setIsFocused(false) } const handleEndEditing = () => { setSearchQuery('') setSearchResults([]) setIsFocused(false) } useEffect(() => { return () => { debouncedSearch.cancel() } }, [debouncedSearch]) return ( setIsFocused(true)} onBlur={() => { if (searchQuery.length === 0) { setIsFocused(false) } }} style={[styles.searchBarFont, styles.input]} fontSize="$5" transform={[{ scaleX: 1.03 }, { scaleY: 0.95 }]} height="$6" borderWidth={0} backgroundColor="$colorTransparent" caretColor="$gray8" focusVisibleStyle={{ outlineWidth: 0 }} enterKeyHint="search" /> {searchQuery.length > 0 && ( {!searchResults.some( (result) => result.topic.toLowerCase() === searchQuery.toLowerCase() ) && ( )} {searchResults.map((result, index) => ( ))} )} ) }