Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/driver set location #48

Open
wants to merge 13 commits into
base: dev
Choose a base branch
from
110 changes: 70 additions & 40 deletions apps/expo/src/app/driver/become-driver.tsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,124 @@
import React, { useState } from "react";
import { Image, Modal, ScrollView, Text, TouchableOpacity, View } from "react-native";
import { useRouter } from "expo-router";
import {
AntDesign,
} from "@expo/vector-icons";
Image,
LogBox,
Modal,
Text,
TouchableOpacity,
View,
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { useRouter } from "expo-router";
import { AntDesign, Ionicons } from "@expo/vector-icons";

import { api } from "~/utils/api";
import { RiderNavbar } from "~/components/Navbar/RiderNavbar";

const DriverProfile = () => {
LogBox.ignoreLogs([
"TRPCClientError: You are not a driver yet",
"Modal with 'formSheet' presentation style and 'transparent' value is not supported.",
]);

const BecomeDriver = () => {
const router = useRouter();
const [visible, setVisible] = useState(false);
const [capacity, setCapacity] = useState(1);
const utils = api.useContext();
const riderQuery = api.rider.profile.useQuery();
const becomeDriver = api.rider.becomeDriver.useMutation({
onSuccess: () => {
router.push('/driver/profile');
void utils.driver.profile.refetch();
},
});

return (
<>
<Modal
animationType="slide"
transparent={true}
visible={visible}
onRequestClose={() => {
setVisible(!visible);
}}
presentationStyle="formSheet"
transparent={true}
>
<View className="absolute bottom-0 h-1/3 w-full rounded-t-3xl bg-amber-500 px-5 py-5">
<Text className="px-2 py-2 text-xl font-bold">Passenger Capacity</Text>
<View className="flex-row justify-between mt-3">
<View className="mx-2 rounded-lg bg-white px-5 h-10 w-1/2 items-center">
<View className="absolute bottom-0 h-1/3 w-full rounded-t-3xl bg-amber-500 px-5 py-5">
<Text className="px-2 py-2 text-xl font-bold">
Passenger Capacity
</Text>
<View className="mt-3 flex-row justify-between">
<View className="mx-2 h-10 w-1/2 items-center rounded-lg bg-white px-5">
<Text className="mt-2 text-base">{capacity}</Text>
</View>
<View className="flex-row w-2/5 justify-between pr-2">
<TouchableOpacity className="bg-white justify-center items-center rounded-lg w-16" onPress={() => setCapacity(capacity<10 ? capacity+1 : capacity)}>
<View className="w-2/5 flex-row justify-between pr-2">
<TouchableOpacity
className="w-16 items-center justify-center rounded-lg bg-white"
onPress={() =>
setCapacity(capacity < 10 ? capacity + 1 : capacity)
}
>
<Text>➕</Text>
</TouchableOpacity>
<TouchableOpacity className="bg-white justify-center items-center rounded-lg w-16" onPress={() => setCapacity(capacity>1 ? capacity-1 : capacity)}>
<TouchableOpacity
className="w-16 items-center justify-center rounded-lg bg-white"
onPress={() =>
setCapacity(capacity > 1 ? capacity - 1 : capacity)
}
>
<Text>➖</Text>
</TouchableOpacity>
</View>
</View>

<View className="mt-8">
<TouchableOpacity
<TouchableOpacity
className="mx-2 my-4 w-36 flex-row items-center self-end rounded-lg bg-white px-6 py-2"
onPress={() => {
setVisible(!visible);
becomeDriver.mutate({capacity: capacity});
becomeDriver.mutate({ capacity: capacity });
}}
>
<View className="pr-2">
<AntDesign name="checkcircle" size={24} color="green" />
</View>
<Text className="font-bold">Confirm</Text>

</TouchableOpacity>
</View>
</View>
</Modal>
<View className="pb-5 pl-7 pt-20">
<Text className="text-2xl font-bold text-amber-400">Profile</Text>
</View>
<ScrollView className="mb-5">
<View className="mx-2 flex-row">
<View className="justify-center px-5 py-5">

<SafeAreaView className="h-full bg-amber-400">
<TouchableOpacity
className="ml-6 mt-6 w-10 items-center rounded-full bg-white"
onPress={() => void router.back()}
>
<Ionicons name="arrow-back" size={36} color="black" />
</TouchableOpacity>
<View className="mb-5 flex-auto">
<View className="flex-auto items-center justify-center bg-amber-400">
<Image
source={{ uri: riderQuery.data?.avatarUrl }}
className="h-24 w-24 rounded-full"
/>
</View>
<View className="flex-col justify-center pl-5">
<Text className="text-xl font-bold">{riderQuery.data?.name}</Text>
</View>
</View>
<View className="items-center">
<Text className="text-center">You are not a driver yet.{"\n"}Become driver to earn extra money!</Text>
<TouchableOpacity onPress={() => setVisible(true)}>
<View className="mt-5 h-12 w-40 bg-amber-400 rounded-xl items-center justify-center">
<Text className="text-white font-bold text-base">Become Driver</Text>
<View className="items-center">
<Text className="mt-4 text-center text-xl font-semibold">
You are not a driver yet.{"\n"}Become driver to earn extra
money!
</Text>
<TouchableOpacity
className="mt-12"
onPress={() => setVisible(true)}
>
<View className="h-12 w-40 items-center justify-center rounded-xl bg-white">
<Text className="text-base font-bold text-amber-500">
Become Driver
</Text>
</View>
</TouchableOpacity>
</View>
</TouchableOpacity>
</View>
</View>

</ScrollView>
<RiderNavbar />
</SafeAreaView>
</>
);
};

export default DriverProfile;
export default BecomeDriver;
160 changes: 156 additions & 4 deletions apps/expo/src/app/driver/home.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,166 @@
import { Text } from "react-native";
import {
ScrollView,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { type Region } from "react-native-maps";
import { SafeAreaView } from "react-native-safe-area-context";
import { Link } from "expo-router";
import { Feather } from "@expo/vector-icons";
import DateTimePicker from "@react-native-community/datetimepicker";
import { atom, useAtom } from "jotai";

import { api } from "~/utils/api";
import { DriverNavbar } from "~/components/Navbar/DriverNavbar";

export type Location = {
name: string;
longitude: number;
latitude: number;
};

export const createLocationsAtom = atom<Location[]>([]);
export const addLocationAtom = atom<Region | null>(null);
export const addLocationNameAtom = atom<string>("");

const MILLIS_PER_DAY = 1000 * 86400;
export const dateAtom = atom(new Date(Date.now() + MILLIS_PER_DAY));

const HomePage = () => {
const [locations, setLocations] = useAtom(createLocationsAtom);
const [addLocation, setAddLocation] = useAtom(addLocationAtom);
const [locationName, setLocationName] = useAtom(addLocationNameAtom);
const [date, setDate] = useAtom(dateAtom);
const addRideMutation = api.driver.create.useMutation();

const handleAddLocation = () => {
setLocations((prev) => [
...prev,
{
name: locationName,
longitude: addLocation?.longitude ?? 0,
latitude: addLocation?.latitude ?? 0,
},
]);
setLocationName("");
setAddLocation(null);
};

const handleAddRide = () => {
addRideMutation.mutate({
departAt: date,
locations,
});
};

return (
<SafeAreaView>
<Text>Home Page</Text>
<>
<SafeAreaView className="flex-auto">
<View className="mt-6 pb-5 pl-7">
<Text className="text-2xl font-bold text-amber-400">Trip</Text>
</View>

<View className="mx-4 mt-2 items-center">
<View className=" w-full items-center rounded-2xl bg-amber-100 p-4">
<Text className="mt-2 text-center text-xl font-semibold">
Create a trip !
</Text>
<TextInput
className="mt-4 h-8 w-60 rounded-2xl bg-white px-2"
placeholder="name"
value={locationName}
onChangeText={(text) => setLocationName(text)}
/>
<Link href="/driver/set-location" asChild>
<TouchableOpacity className="mt-4 h-8 w-60 justify-center rounded-2xl bg-white px-2">
{addLocation ? (
<Text>
({addLocation?.latitude.toFixed(4)},{" "}
{addLocation?.longitude.toFixed(4)})
</Text>
) : (
<View className="h-full justify-center">
<Text className="text-gray-400">Location</Text>
</View>
)}
</TouchableOpacity>
</Link>
<TouchableOpacity
className="mt-4 rounded-xl bg-amber-400 p-2"
onPress={() => handleAddLocation()}
>
<Text className="font-semibold">Add a location</Text>
</TouchableOpacity>
</View>
</View>

<View className="mx-4 mt-4 flex-auto rounded-2xl bg-amber-100">
<View className="mt-2 items-center border-b border-b-amber-400 p-1">
<View className="h-10 w-56 flex-row items-center justify-center rounded-xl">
<Text className=" text-lg font-semibold">Depart Time</Text>
<DateTimePicker
className="text-sm"
testID="dateTimePicker"
mode="datetime"
value={date}
onChange={(_, selectedDate) => {
const currentDate = selectedDate || date;
setDate(currentDate);
}}
display="default"
/>
</View>
</View>
<ScrollView className="">
<View className="items-center gap-2 py-4">
{locations.map((location, id) => (
<View className="flex-row items-center gap-2">
<View
key={location.name}
className="w-56 flex-row rounded-lg bg-white p-2"
>
<View className="px-1">
<Text className="text-lg">{id + 1}.</Text>
</View>
<View>
<Text className="text-lg font-semibold">
{location.name}
</Text>
<Text className="text-base">
({location.latitude.toFixed(4)},{" "}
{location.longitude.toFixed(4)})
</Text>
</View>
</View>
<TouchableOpacity
onPress={() =>
setLocations((prev) => {
const newLocations = [...prev];
newLocations.splice(id, 1);
return newLocations;
})
}
>
<Feather name="minus-circle" size={24} color="black" />
</TouchableOpacity>
</View>
))}
</View>
</ScrollView>
</View>
<TouchableOpacity
className="mx-4 mt-2 rounded-xl bg-amber-400"
onPress={() => handleAddRide()}
>
<Text className="p-2 text-center text-base font-semibold">
Add ride
</Text>
</TouchableOpacity>
</SafeAreaView>
<DriverNavbar />
</SafeAreaView>
</>
);
};

Expand Down
29 changes: 24 additions & 5 deletions apps/expo/src/app/driver/profile.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { Image, ScrollView, Text, TouchableOpacity, View } from "react-native";
import { Link, useRouter } from "expo-router";
import { SafeAreaView } from "react-native-safe-area-context";
import { Link } from "expo-router";
import {
Feather,
FontAwesome5,
Expand All @@ -15,26 +16,44 @@ import { DriverNavbar } from "~/components/Navbar/DriverNavbar";
import { RatingStars } from "~/components/RatingStars";
import { useObjectState } from "~/hooks/useObjectState";
import SignOut from "~/screens/auth/SignOut";
import BecomeDriver from "./become-driver";

type ModalTypes = "Bio" | "Rules" | "Capacity" | "none";

const DriverProfile = () => {
const ProfilePage = () => {
const [visibleModal, setVisibleModal] = useState<ModalTypes>("none");
const [profile, updateProfile] = useObjectState({
bio: "",
rules: "",
capacity: "",
});
const router = useRouter();

const profileQuery = api.driver.profile.useQuery(undefined, {
onSuccess: (data) => {
updateProfile({ ...data, capacity: data.capacity.toString() });
},
onError: (err) => {
console.log("here is an error", err);
},
retry(failureCount, error) {
if (error.data?.code === "UNAUTHORIZED") return false;
return failureCount < 2;
},
});

if (profileQuery.isLoading) {
return (
<SafeAreaView className="h-full items-center justify-center">
<Image
source={{ uri: "https://hackmd.io/_uploads/H1uca9p8h.gif" }}
style={{ width: 400, height: 300 }}
/>
</SafeAreaView>
);
}

if (profileQuery.data == null) {
router.push("/driver/become-driver");
return <BecomeDriver />;
}

return (
Expand Down Expand Up @@ -158,4 +177,4 @@ const DriverProfile = () => {
);
};

export default DriverProfile;
export default ProfilePage;
Loading