From 3aeffb35851f43522d5940db45715a3040b07c45 Mon Sep 17 00:00:00 2001 From: dimitar Date: Wed, 12 Feb 2025 09:07:21 +0100 Subject: [PATCH] add upload and search implemented --- app/(root)/(tabs)/index.tsx | 39 ++++++++++++++++++++-------------- components/Search.tsx | 42 ++++++++++++++++++++++++++++++++----- lib/database.ts | 13 ++++++++++-- 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/app/(root)/(tabs)/index.tsx b/app/(root)/(tabs)/index.tsx index 3eaaf0f..dca2842 100644 --- a/app/(root)/(tabs)/index.tsx +++ b/app/(root)/(tabs)/index.tsx @@ -19,27 +19,32 @@ import { useEffect, useState } from "react"; import { getCars, getFeaturedCars } from "@/lib/database"; export default function Index() { - const { user, refetch } = useGlobalContext(); + const { user } = useGlobalContext(); const [cars, setCars] = useState([]); const [featuredCars, setFeaturedCars] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + const fetchCars = async (query?: string) => { + try { + setIsLoading(true); + const fetchedCars = await getCars(query); + setCars(fetchedCars); + } catch (error) { + console.error('Error fetching cars:', error); + } finally { + setIsLoading(false); + } + }; useEffect(() => { - const fetchData = async () => { - try { - const [allCars, featured] = await Promise.all([ - getCars(), - getFeaturedCars() - ]); - setCars(allCars); - setFeaturedCars(featured); - } catch (error) { - console.error('Error fetching data:', error); - } - }; - - fetchData(); + fetchCars(); + getFeaturedCars().then(setFeaturedCars); }, []); + const handleSearch = async (query: string) => { + await fetchCars(query); + }; + return ( - + {/* Featured Section */} @@ -100,6 +105,8 @@ export default function Index() { contentContainerClassName={"pb-32"} columnWrapperClassName={"flex flex-row gap-5 px-5"} showsVerticalScrollIndicator={false} + refreshing={isLoading} + onRefresh={() => fetchCars()} /> {/* Add Car Button */} { +interface Props { + onSearch: (query: string) => void; +} + +export function useDebounce(value: T, delay: number = 500): T { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const timer = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(timer); + }; + }, [value, delay]); + + return debouncedValue; +} + +const Search = ({ onSearch }: Props) => { + const [searchQuery, setSearchQuery] = useState(''); + const debouncedQuery = useDebounce(searchQuery); + + React.useEffect(() => { + onSearch(debouncedQuery); + }, [debouncedQuery]); + return ( @@ -10,12 +37,17 @@ const Search = () => { placeholder="Search cars..." className="flex-1" placeholderTextColor="#666" + value={searchQuery} + onChangeText={setSearchQuery} /> - - - + {searchQuery ? ( + setSearchQuery('')}> + + + ) : null} ); }; + export default Search; diff --git a/lib/database.ts b/lib/database.ts index 0262eea..fb6a919 100644 --- a/lib/database.ts +++ b/lib/database.ts @@ -37,12 +37,21 @@ export async function createCar(carData: Omit) { } } -export async function getCars() { +export async function getCars(searchQuery?: string) { try { + const queries = [Query.orderDesc('$createdAt')]; + + if (searchQuery) { + const searchTerm = searchQuery.toLowerCase(); + queries.push( + Query.search('title', searchTerm) + ); + } + const response = await databases.listDocuments( config.databaseId!, config.carId!, - [Query.orderDesc('$createdAt')] + queries ); return response.documents; } catch (error) {