123 lines
4.0 KiB
TypeScript
123 lines
4.0 KiB
TypeScript
//import { Link } from "expo-router";
|
|
import {
|
|
FlatList,
|
|
Image,
|
|
SafeAreaView,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} from "react-native";
|
|
// import images from "@/constants/images";
|
|
import icons from "@/constants/icons";
|
|
import Search from "@/components/Search";
|
|
import { useGlobalContext } from "@/lib/globalProvider";
|
|
import { Card, FeaturedCard } from "@/components/Cards";
|
|
import Filters from "@/components/Filters";
|
|
// import { cars, featuredCars } from "@/constants/data";
|
|
import { router } from 'expo-router';
|
|
import { useEffect, useState } from "react";
|
|
import { getCars, getFeaturedCars } from "@/lib/database";
|
|
|
|
export default function Index() {
|
|
const { user } = useGlobalContext();
|
|
const [cars, setCars] = 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(() => {
|
|
fetchCars();
|
|
getFeaturedCars().then(setFeaturedCars);
|
|
}, []);
|
|
|
|
const handleSearch = async (query: string) => {
|
|
await fetchCars(query);
|
|
};
|
|
|
|
return (
|
|
<SafeAreaView className={"bg-white h-full"}>
|
|
<FlatList
|
|
data={cars}
|
|
renderItem={({ item }) => <Card data={item} />}
|
|
keyExtractor={(item) => item.$id}
|
|
numColumns={2}
|
|
ListHeaderComponent={
|
|
<View>
|
|
{/* User Info */}
|
|
<View className="px-5 pt-5 flex-row items-center justify-between">
|
|
<View>
|
|
<Text className="text-2xl font-bold">Welcome back,</Text>
|
|
<Text className="text-lg text-gray-500">{user?.name}</Text>
|
|
</View>
|
|
<TouchableOpacity>
|
|
<Image
|
|
source={{ uri: user?.avatar }}
|
|
className="w-12 h-12 rounded-full"
|
|
/>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
{/* Search */}
|
|
<View className="px-5 mt-5">
|
|
<Search onSearch={handleSearch} />
|
|
</View>
|
|
|
|
{/* Featured Section */}
|
|
<View className={"my-5"}>
|
|
<View className={"flex flex-row items-center justify-between"}>
|
|
<Text className={"capitalize font-bold text-base"}>featured</Text>
|
|
<TouchableOpacity>
|
|
<Text className={"capitalize text-base text-blue-500"}>see all</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<FlatList
|
|
data={featuredCars}
|
|
renderItem={({ item }) => <FeaturedCard data={item} />}
|
|
keyExtractor={(item) => item.$id}
|
|
horizontal={true}
|
|
bounces={false}
|
|
showsHorizontalScrollIndicator={false}
|
|
contentContainerClassName={"flex gap-3 mt-5"}
|
|
/>
|
|
</View>
|
|
|
|
{/* Latest Cars Section */}
|
|
<View className={"flex flex-row items-center justify-between"}>
|
|
<Text className={"capitalize font-bold text-base"}>latest cars</Text>
|
|
<TouchableOpacity>
|
|
<Text className={"capitalize font-bold"}>see all</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<Filters />
|
|
</View>
|
|
}
|
|
contentContainerClassName={"pb-32"}
|
|
columnWrapperClassName={"flex flex-row gap-5 px-5"}
|
|
showsVerticalScrollIndicator={false}
|
|
refreshing={isLoading}
|
|
onRefresh={() => fetchCars()}
|
|
/>
|
|
{/* Add Car Button */}
|
|
<TouchableOpacity
|
|
onPress={() => router.push('/cars/new')}
|
|
className="absolute bottom-8 right-8 bg-blue-500 rounded-full p-4 shadow-lg"
|
|
>
|
|
<View className="bg-white rounded-full p-2 mb-14">
|
|
<Image source={icons.bed} className="size-6" tintColor="black" />
|
|
</View>
|
|
</TouchableOpacity>
|
|
</SafeAreaView>
|
|
);
|
|
}
|