add upload and search implemented

This commit is contained in:
dimitar 2025-02-12 09:07:21 +01:00
parent f3007d6419
commit 3aeffb3585
3 changed files with 71 additions and 23 deletions

View File

@ -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<any[]>([]);
const [featuredCars, setFeaturedCars] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
const fetchCars = async (query?: string) => {
try {
const [allCars, featured] = await Promise.all([
getCars(),
getFeaturedCars()
]);
setCars(allCars);
setFeaturedCars(featured);
setIsLoading(true);
const fetchedCars = await getCars(query);
setCars(fetchedCars);
} catch (error) {
console.error('Error fetching data:', error);
console.error('Error fetching cars:', error);
} finally {
setIsLoading(false);
}
};
fetchData();
useEffect(() => {
fetchCars();
getFeaturedCars().then(setFeaturedCars);
}, []);
const handleSearch = async (query: string) => {
await fetchCars(query);
};
return (
<SafeAreaView className={"bg-white h-full"}>
<FlatList
@ -65,7 +70,7 @@ export default function Index() {
{/* Search */}
<View className="px-5 mt-5">
<Search />
<Search onSearch={handleSearch} />
</View>
{/* 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 */}
<TouchableOpacity

View File

@ -1,8 +1,35 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { View, TextInput, TouchableOpacity, Image } from 'react-native';
import icons from '@/constants/icons';
const Search = () => {
interface Props {
onSearch: (query: string) => void;
}
export function useDebounce<T>(value: T, delay: number = 500): T {
const [debouncedValue, setDebouncedValue] = useState<T>(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 (
<View className="flex-row items-center bg-gray-100 rounded-full px-4 py-2">
<Image source={icons.search} className="w-5 h-5 mr-2" />
@ -10,12 +37,17 @@ const Search = () => {
placeholder="Search cars..."
className="flex-1"
placeholderTextColor="#666"
value={searchQuery}
onChangeText={setSearchQuery}
/>
<TouchableOpacity>
<Image source={icons.filter} className="w-5 h-5" />
{searchQuery ? (
<TouchableOpacity onPress={() => setSearchQuery('')}>
<Image source={icons.backArrow} className="w-5 h-5" />
</TouchableOpacity>
) : null}
</View>
);
};
export default Search;

View File

@ -37,12 +37,21 @@ export async function createCar(carData: Omit<Car, 'id' | 'createdAt'>) {
}
}
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) {