176 lines
6.0 KiB
TypeScript
176 lines
6.0 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import {
|
|
View,
|
|
StyleSheet,
|
|
StatusBar as RNStatusBar,
|
|
ScrollView,
|
|
} from 'react-native'
|
|
import { StatusBar } from 'expo-status-bar'
|
|
import { SafeAreaView } from 'react-native-safe-area-context'
|
|
import { useRouter, useLocalSearchParams } from 'expo-router'
|
|
|
|
import SearchResultsGrid from '@/components/SearchResultsGrid'
|
|
import SearchBar from '@/components/SearchBar'
|
|
import LoadingState from '@/components/LoadingState'
|
|
import ErrorState from '@/components/ErrorState'
|
|
import PaginationLoader from '@/components/PaginationLoader'
|
|
import { useTemplates, useSearchHistory } from '@/hooks'
|
|
|
|
export default function SearchResultsScreen() {
|
|
const router = useRouter()
|
|
const params = useLocalSearchParams()
|
|
const [searchText, setSearchText] = useState((params.q as string) || '')
|
|
|
|
const { templates, loading, loadingMore, error, execute, refetch, loadMore, hasMore } = useTemplates()
|
|
const { addToHistory } = useSearchHistory()
|
|
|
|
useEffect(() => {
|
|
if (params.q && typeof params.q === 'string') {
|
|
const query = params.q.trim()
|
|
setSearchText(query)
|
|
if (query) {
|
|
execute({ search: query, limit: 20, sortBy: 'createdAt', sortOrder: 'desc', page: 1 })
|
|
addToHistory(query)
|
|
}
|
|
}
|
|
}, [params.q, execute, addToHistory])
|
|
|
|
const handleRefresh = async () => {
|
|
if (searchText) {
|
|
await refetch()
|
|
}
|
|
}
|
|
|
|
const handleLoadMore = () => {
|
|
if (hasMore && !loadingMore) {
|
|
loadMore()
|
|
}
|
|
}
|
|
|
|
const searchResults = templates.map(template => ({
|
|
id: template.id,
|
|
title: template.title || template.titleEn || '',
|
|
image: { uri: template.previewUrl || template.coverImageUrl || '' },
|
|
previewUrl: template.previewUrl,
|
|
coverImageUrl: template.coverImageUrl,
|
|
aspectRatio: template.aspectRatio ? parseFloat(template.aspectRatio as string) : undefined,
|
|
}))
|
|
|
|
if (loading) {
|
|
return (
|
|
<SafeAreaView style={styles.container} edges={['top']}>
|
|
<StatusBar style="light" />
|
|
<RNStatusBar barStyle="light-content" />
|
|
<SearchBar
|
|
searchText={searchText}
|
|
onSearchTextChange={setSearchText}
|
|
onSearch={(text) => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: text, focus: 'true' },
|
|
})
|
|
}}
|
|
onBack={() => router.back()}
|
|
readOnly={true}
|
|
onInputPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: searchText, focus: 'true' },
|
|
})
|
|
}}
|
|
onClearPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: '', focus: 'true' },
|
|
})
|
|
}}
|
|
marginBottom={12}
|
|
/>
|
|
<LoadingState />
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<SafeAreaView style={styles.container} edges={['top']}>
|
|
<StatusBar style="light" />
|
|
<RNStatusBar barStyle="light-content" />
|
|
<SearchBar
|
|
searchText={searchText}
|
|
onSearchTextChange={setSearchText}
|
|
onSearch={(text) => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: text, focus: 'true' },
|
|
})
|
|
}}
|
|
onBack={() => router.back()}
|
|
readOnly={true}
|
|
onInputPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: searchText, focus: 'true' },
|
|
})
|
|
}}
|
|
onClearPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: '', focus: 'true' },
|
|
})
|
|
}}
|
|
marginBottom={12}
|
|
/>
|
|
<ErrorState message={error.message} onRetry={refetch} />
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<SafeAreaView style={styles.container} edges={['top']}>
|
|
<StatusBar style="light" />
|
|
<RNStatusBar barStyle="light-content" />
|
|
|
|
<SearchBar
|
|
searchText={searchText}
|
|
onSearchTextChange={setSearchText}
|
|
onSearch={(text) => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: text, focus: 'true' },
|
|
})
|
|
}}
|
|
onBack={() => router.back()}
|
|
readOnly={true}
|
|
onInputPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: searchText, focus: 'true' },
|
|
})
|
|
}}
|
|
onClearPress={() => {
|
|
router.push({
|
|
pathname: '/searchTemplate',
|
|
params: { q: '', focus: 'true' },
|
|
})
|
|
}}
|
|
marginBottom={12}
|
|
/>
|
|
|
|
<SearchResultsGrid
|
|
results={searchResults}
|
|
loading={false}
|
|
onEndReached={handleLoadMore}
|
|
ListFooterComponent={loadingMore ? <PaginationLoader /> : null}
|
|
/>
|
|
</SafeAreaView>
|
|
)
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#090A0B',
|
|
},
|
|
})
|