add upload and search implemented
This commit is contained in:
parent
f3007d6419
commit
3aeffb3585
@ -19,27 +19,32 @@ import { useEffect, useState } from "react";
|
|||||||
import { getCars, getFeaturedCars } from "@/lib/database";
|
import { getCars, getFeaturedCars } from "@/lib/database";
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const { user, refetch } = useGlobalContext();
|
const { user } = useGlobalContext();
|
||||||
const [cars, setCars] = useState<any[]>([]);
|
const [cars, setCars] = useState<any[]>([]);
|
||||||
const [featuredCars, setFeaturedCars] = useState<any[]>([]);
|
const [featuredCars, setFeaturedCars] = useState<any[]>([]);
|
||||||
|
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(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
fetchCars();
|
||||||
try {
|
getFeaturedCars().then(setFeaturedCars);
|
||||||
const [allCars, featured] = await Promise.all([
|
|
||||||
getCars(),
|
|
||||||
getFeaturedCars()
|
|
||||||
]);
|
|
||||||
setCars(allCars);
|
|
||||||
setFeaturedCars(featured);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error fetching data:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchData();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleSearch = async (query: string) => {
|
||||||
|
await fetchCars(query);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView className={"bg-white h-full"}>
|
<SafeAreaView className={"bg-white h-full"}>
|
||||||
<FlatList
|
<FlatList
|
||||||
@ -65,7 +70,7 @@ export default function Index() {
|
|||||||
|
|
||||||
{/* Search */}
|
{/* Search */}
|
||||||
<View className="px-5 mt-5">
|
<View className="px-5 mt-5">
|
||||||
<Search />
|
<Search onSearch={handleSearch} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Featured Section */}
|
{/* Featured Section */}
|
||||||
@ -100,6 +105,8 @@ export default function Index() {
|
|||||||
contentContainerClassName={"pb-32"}
|
contentContainerClassName={"pb-32"}
|
||||||
columnWrapperClassName={"flex flex-row gap-5 px-5"}
|
columnWrapperClassName={"flex flex-row gap-5 px-5"}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
|
refreshing={isLoading}
|
||||||
|
onRefresh={() => fetchCars()}
|
||||||
/>
|
/>
|
||||||
{/* Add Car Button */}
|
{/* Add Car Button */}
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|||||||
@ -1,8 +1,35 @@
|
|||||||
import React from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { View, TextInput, TouchableOpacity, Image } from 'react-native';
|
import { View, TextInput, TouchableOpacity, Image } from 'react-native';
|
||||||
import icons from '@/constants/icons';
|
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 (
|
return (
|
||||||
<View className="flex-row items-center bg-gray-100 rounded-full px-4 py-2">
|
<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" />
|
<Image source={icons.search} className="w-5 h-5 mr-2" />
|
||||||
@ -10,12 +37,17 @@ const Search = () => {
|
|||||||
placeholder="Search cars..."
|
placeholder="Search cars..."
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
placeholderTextColor="#666"
|
placeholderTextColor="#666"
|
||||||
|
value={searchQuery}
|
||||||
|
onChangeText={setSearchQuery}
|
||||||
/>
|
/>
|
||||||
<TouchableOpacity>
|
{searchQuery ? (
|
||||||
<Image source={icons.filter} className="w-5 h-5" />
|
<TouchableOpacity onPress={() => setSearchQuery('')}>
|
||||||
</TouchableOpacity>
|
<Image source={icons.backArrow} className="w-5 h-5" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default Search;
|
export default Search;
|
||||||
|
|||||||
@ -37,12 +37,21 @@ export async function createCar(carData: Omit<Car, 'id' | 'createdAt'>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCars() {
|
export async function getCars(searchQuery?: string) {
|
||||||
try {
|
try {
|
||||||
|
const queries = [Query.orderDesc('$createdAt')];
|
||||||
|
|
||||||
|
if (searchQuery) {
|
||||||
|
const searchTerm = searchQuery.toLowerCase();
|
||||||
|
queries.push(
|
||||||
|
Query.search('title', searchTerm)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const response = await databases.listDocuments(
|
const response = await databases.listDocuments(
|
||||||
config.databaseId!,
|
config.databaseId!,
|
||||||
config.carId!,
|
config.carId!,
|
||||||
[Query.orderDesc('$createdAt')]
|
queries
|
||||||
);
|
);
|
||||||
return response.documents;
|
return response.documents;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user