find ride and book ride page ui created
This commit is contained in:
committed by
GitHub
parent
78ba198a1f
commit
0b2a3ee944
@@ -4,6 +4,9 @@ const RootLayout = () => {
|
|||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
|
<Stack.Screen name="find-ride" options={{ headerShown: false }} />
|
||||||
|
<Stack.Screen name="confirm-ride" options={{ headerShown: false }} />
|
||||||
|
{/* <Stack.Screen name="book-ride" options={{ headerShown: false }} /> */}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { FlatList, View } from "react-native";
|
||||||
|
|
||||||
|
import { DriverCard } from "@/components/driver-card";
|
||||||
|
import { RideLayout } from "@/components/ride-layout";
|
||||||
|
import { CustomButton } from "@/components/custom-button";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { useDriverStore } from "@/store";
|
||||||
|
|
||||||
|
const ConfirmRide = () => {
|
||||||
|
const { drivers, selectedDriver, setSelectedDriver } = useDriverStore();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<RideLayout title="Choose a Driver" snapPoints={["65%", "85%"]}>
|
||||||
|
<FlatList
|
||||||
|
data={drivers}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<DriverCard
|
||||||
|
item={item}
|
||||||
|
selected={selectedDriver ?? 0}
|
||||||
|
setSelected={() => setSelectedDriver(item.id)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
ListFooterComponent={() => (
|
||||||
|
<View className="mx-5 mt-10">
|
||||||
|
<CustomButton
|
||||||
|
title="Select Ride"
|
||||||
|
onPress={() => router.replace("/(root)/book-ride")}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</RideLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConfirmRide;
|
||||||
@@ -1,10 +1,51 @@
|
|||||||
|
import { CustomButton } from "@/components/custom-button";
|
||||||
|
import { GoogleTextInput } from "@/components/google-text-input";
|
||||||
|
import { RideLayout } from "@/components/ride-layout";
|
||||||
|
import { icons } from "@/constants";
|
||||||
|
import { useLocationStore } from "@/store";
|
||||||
|
import { router } from "expo-router";
|
||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
const FindRide = () => {
|
const FindRide = () => {
|
||||||
|
const {
|
||||||
|
userAddress,
|
||||||
|
destinationAddress,
|
||||||
|
setDestinationLocation,
|
||||||
|
setUserLocation,
|
||||||
|
} = useLocationStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<RideLayout title="Ride" snapPoints={["85%"]}>
|
||||||
<Text>Find Ride</Text>
|
<View className="my-3">
|
||||||
|
<Text className="text-lg font-JakartaSemiBold mb-3">From</Text>
|
||||||
|
|
||||||
|
<GoogleTextInput
|
||||||
|
icon={icons.target}
|
||||||
|
initialLocation={userAddress ?? ""}
|
||||||
|
containerStyles="bg-neutral-100"
|
||||||
|
textInputBackgroundColor="#F5F5F5"
|
||||||
|
handlePress={setUserLocation}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<View className="my-3">
|
||||||
|
<Text className="text-lg font-JakartaSemiBold mb-3">To</Text>
|
||||||
|
|
||||||
|
<GoogleTextInput
|
||||||
|
icon={icons.map}
|
||||||
|
initialLocation={destinationAddress ?? ""}
|
||||||
|
containerStyles="bg-neutral-100"
|
||||||
|
textInputBackgroundColor="transparent"
|
||||||
|
handlePress={setDestinationLocation}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<CustomButton
|
||||||
|
title="Find now"
|
||||||
|
onPress={() => router.replace("/(root)/confirm-ride")}
|
||||||
|
className="mt-5"
|
||||||
|
/>
|
||||||
|
</RideLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { Image, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
|
import { icons } from "@/constants";
|
||||||
|
import { formatTime } from "@/lib/utils";
|
||||||
|
import { DriverCardProps } from "@/types/type";
|
||||||
|
|
||||||
|
export const DriverCard = ({
|
||||||
|
item,
|
||||||
|
selected,
|
||||||
|
setSelected,
|
||||||
|
}: DriverCardProps) => {
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={setSelected}
|
||||||
|
className={`${
|
||||||
|
selected === item.id ? "bg-general-600" : "bg-white"
|
||||||
|
} flex flex-row items-center justify-between py-5 px-3 rounded-xl`}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
source={{ uri: item.profile_image_url }}
|
||||||
|
alt="Driver Avatar"
|
||||||
|
className="w-14 h-14 rounded-full"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View className="flex-1 flex flex-col items-start justify-center mx-3">
|
||||||
|
<View className="flex flex-row items-center justify-start mb-1">
|
||||||
|
<Text className="text-lg font-JakartaRegular">{item.title}</Text>
|
||||||
|
|
||||||
|
<View className="flex flex-row items-center space-x-1 ml-2">
|
||||||
|
<Image source={icons.star} alt="Star" className="w-3.5 h-3.5" />
|
||||||
|
<Text className="text-sm font-JakartaRegular">4</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="flex flex-row items-center justify-start">
|
||||||
|
<View className="flex flex-row items-center">
|
||||||
|
<Image source={icons.dollar} alt="Dollar" className="w-4 h-4" />
|
||||||
|
<Text className="text-sm font-JakartaRegular ml-1">
|
||||||
|
${item.price}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text className="text-sm font-JakartaRegular text-general-800 mx-1">
|
||||||
|
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="text-sm font-JakartaRegular text-general-800">
|
||||||
|
{formatTime(item.time!)}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="text-sm font-JakartaRegular text-general-800 mx-1">
|
||||||
|
|
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text className="text-sm font-JakartaRegular text-general-800">
|
||||||
|
{item.car_seats} seats
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
source={{ uri: item.car_image_url }}
|
||||||
|
alt="Car"
|
||||||
|
className="h-14 w-14"
|
||||||
|
resizeMode="contain"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { View, Image } from "react-native";
|
import { View, Image, TouchableOpacity } from "react-native";
|
||||||
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
|
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
|
||||||
|
|
||||||
import { icons } from "@/constants";
|
import { icons } from "@/constants";
|
||||||
@@ -64,13 +64,22 @@ export const GoogleTextInput = ({
|
|||||||
language: "en",
|
language: "en",
|
||||||
}}
|
}}
|
||||||
renderLeftButton={() => (
|
renderLeftButton={() => (
|
||||||
<View className="justify-center items-center w-6 h-6">
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
handlePress({
|
||||||
|
latitude: 26.8467,
|
||||||
|
longitude: 80.9462,
|
||||||
|
address: "Lucknow, Uttar Pradesh",
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="justify-center items-center w-6 h-6"
|
||||||
|
>
|
||||||
<Image
|
<Image
|
||||||
source={icon ? icon : icons.search}
|
source={icon ? icon : icons.search}
|
||||||
className="w-6 h-6"
|
className="w-6 h-6"
|
||||||
resizeMode="contain"
|
resizeMode="contain"
|
||||||
/>
|
/>
|
||||||
</View>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
textInputProps={{
|
textInputProps={{
|
||||||
placeholderTextColor: "gray",
|
placeholderTextColor: "gray",
|
||||||
|
|||||||
+26
-4
@@ -8,7 +8,7 @@ import { icons } from "@/constants";
|
|||||||
|
|
||||||
const drivers = [
|
const drivers = [
|
||||||
{
|
{
|
||||||
id: "1",
|
id: 1,
|
||||||
driver_id: 1,
|
driver_id: 1,
|
||||||
first_name: "James",
|
first_name: "James",
|
||||||
last_name: "Wilson",
|
last_name: "Wilson",
|
||||||
@@ -18,9 +18,14 @@ const drivers = [
|
|||||||
"https://ucarecdn.com/a2dc52b2-8bf7-4e49-9a36-3ffb5229ed02/-/preview/465x466/",
|
"https://ucarecdn.com/a2dc52b2-8bf7-4e49-9a36-3ffb5229ed02/-/preview/465x466/",
|
||||||
car_seats: 4,
|
car_seats: 4,
|
||||||
rating: 4.8,
|
rating: 4.8,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
title: "",
|
||||||
|
price: "45",
|
||||||
|
time: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2",
|
id: 2,
|
||||||
driver_id: 2,
|
driver_id: 2,
|
||||||
first_name: "David",
|
first_name: "David",
|
||||||
last_name: "Brown",
|
last_name: "Brown",
|
||||||
@@ -30,9 +35,14 @@ const drivers = [
|
|||||||
"https://ucarecdn.com/a3872f80-c094-409c-82f8-c9ff38429327/-/preview/930x932/",
|
"https://ucarecdn.com/a3872f80-c094-409c-82f8-c9ff38429327/-/preview/930x932/",
|
||||||
car_seats: 5,
|
car_seats: 5,
|
||||||
rating: 4.6,
|
rating: 4.6,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
title: "",
|
||||||
|
price: "45",
|
||||||
|
time: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "3",
|
id: 3,
|
||||||
driver_id: 3,
|
driver_id: 3,
|
||||||
first_name: "Michael",
|
first_name: "Michael",
|
||||||
last_name: "Johnson",
|
last_name: "Johnson",
|
||||||
@@ -42,9 +52,14 @@ const drivers = [
|
|||||||
"https://ucarecdn.com/289764fb-55b6-4427-b1d1-f655987b4a14/-/preview/930x932/",
|
"https://ucarecdn.com/289764fb-55b6-4427-b1d1-f655987b4a14/-/preview/930x932/",
|
||||||
car_seats: 4,
|
car_seats: 4,
|
||||||
rating: 4.7,
|
rating: 4.7,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
title: "",
|
||||||
|
price: "45",
|
||||||
|
time: 5,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "4",
|
id: 4,
|
||||||
driver_id: 4,
|
driver_id: 4,
|
||||||
first_name: "Robert",
|
first_name: "Robert",
|
||||||
last_name: "Green",
|
last_name: "Green",
|
||||||
@@ -54,6 +69,11 @@ const drivers = [
|
|||||||
"https://ucarecdn.com/b6fb3b55-7676-4ff3-8484-fb115e268d32/-/preview/930x932/",
|
"https://ucarecdn.com/b6fb3b55-7676-4ff3-8484-fb115e268d32/-/preview/930x932/",
|
||||||
car_seats: 4,
|
car_seats: 4,
|
||||||
rating: 4.9,
|
rating: 4.9,
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
title: "",
|
||||||
|
price: "45",
|
||||||
|
time: 5,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -76,6 +96,8 @@ export const Map = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Array.isArray(drivers)) {
|
if (Array.isArray(drivers)) {
|
||||||
|
setDrivers(drivers);
|
||||||
|
|
||||||
if (!userLatitude || !userLongitude) return;
|
if (!userLatitude || !userLongitude) return;
|
||||||
|
|
||||||
const newMarkers = generateMarkersFromData({
|
const newMarkers = generateMarkersFromData({
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import BottomSheet, { BottomSheetView } from "@gorhom/bottom-sheet";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import { useRef, type PropsWithChildren } from "react";
|
||||||
|
import { Image, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||||
|
|
||||||
|
import { icons } from "@/constants";
|
||||||
|
|
||||||
|
import { Map } from "./map";
|
||||||
|
|
||||||
|
type RideLayoutProps = {
|
||||||
|
title?: string;
|
||||||
|
snapPoints?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const RideLayout = ({
|
||||||
|
title = "Go Back",
|
||||||
|
snapPoints,
|
||||||
|
children,
|
||||||
|
}: PropsWithChildren<RideLayoutProps>) => {
|
||||||
|
const bottomSheetRef = useRef<BottomSheet>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GestureHandlerRootView>
|
||||||
|
<View className="flex-1 bg-white">
|
||||||
|
<View className="flex flex-col h-screen bg-blue-500">
|
||||||
|
<View className="flex flex-row absolute z-10 top-16 items-center justify-start px-5">
|
||||||
|
<TouchableOpacity onPress={() => router.back()}>
|
||||||
|
<View className="w-10 h-10 bg-white rounded-full items-center justify-center">
|
||||||
|
<Image
|
||||||
|
source={icons.backArrow}
|
||||||
|
resizeMode="contain"
|
||||||
|
className="w-6 h-6"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<Text className="text-xl font-JakartaSemiBold ml-5">{title}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Map />
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<BottomSheet
|
||||||
|
keyboardBehavior="extend"
|
||||||
|
ref={bottomSheetRef}
|
||||||
|
snapPoints={snapPoints ?? ["40%", "85%"]}
|
||||||
|
index={0}
|
||||||
|
>
|
||||||
|
<BottomSheetView
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
padding: 20,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</BottomSheetView>
|
||||||
|
</BottomSheet>
|
||||||
|
</View>
|
||||||
|
</GestureHandlerRootView>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user