├── .expo-shared
└── assets.json
├── .gitignore
├── App.tsx
├── README.md
├── app.json
├── app
├── hooks.ts
├── slices
│ └── navigationSlice.ts
└── store.ts
├── assets
├── adaptive-icon.png
├── favicon.png
├── icon.png
├── screenshots
│ ├── Screenshot_1634302767.jpg
│ ├── Screenshot_1634302842.jpg
│ ├── Screenshot_1634302884.jpg
│ ├── ezgif-7-2d01dc3b82b1.gif
│ └── logo.png
└── splash.png
├── babel.config.js
├── components
├── HomeNavigation.tsx
├── Map.tsx
├── MapScreenNavigation.tsx
├── NavFavorites.tsx
├── NavOptions.tsx
├── NavigateCard.tsx
└── RideOptionsCard.tsx
├── env.d.ts
├── package-lock.json
├── package.json
├── screens
├── EatsScreen.tsx
├── HomeScreen.tsx
└── MapScreen.tsx
└── tsconfig.json
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | npm-debug.*
4 | *.jks
5 | *.p8
6 | *.p12
7 | *.key
8 | *.mobileprovision
9 | *.orig.*
10 | web-build/
11 |
12 | # macOS
13 | .DS_Store
14 |
15 | .env
16 |
--------------------------------------------------------------------------------
/App.tsx:
--------------------------------------------------------------------------------
1 | import "intl";
2 | import "intl/locale-data/jsonp/en";
3 |
4 | import { KeyboardAvoidingView, Platform } from "react-native";
5 |
6 | import HomeNavigation from "./components/HomeNavigation";
7 | import { NavigationContainer } from "@react-navigation/native";
8 | import { Provider } from "react-redux";
9 | import React from "react";
10 | import { SafeAreaProvider } from "react-native-safe-area-context";
11 | import { store } from "./app/store";
12 |
13 | export default function App() {
14 | return (
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native Uber Clone
2 |
3 | A cross-platform Uber clone app built with React Native, Expo
4 |
5 | ## Demo
6 |
7 |
8 |
9 | ## Features
10 |
11 | - Cross platform (Web, iOS, Android)
12 | - Pick origin and destination
13 | - Pick ride type (UberX, Uber XL, Uber LUX)
14 | - Show fare and travel distance
15 | - Show travel time
16 |
17 | ## Run Locally
18 |
19 | Clone the project
20 |
21 | ```bash
22 | git clone https://github.com/emmanuelchucks/react-native-uber-clone.git
23 | ```
24 |
25 | Go to the project directory
26 |
27 | ```bash
28 | cd react-native-uber-clone
29 | ```
30 |
31 | Install dependencies
32 |
33 | ```bash
34 | npm install
35 | ```
36 |
37 | Start the server
38 |
39 | ```bash
40 | npm start
41 | ```
42 |
43 | ## Screenshots
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "UberClone",
4 | "slug": "UberClone",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "splash": {
9 | "image": "./assets/splash.png",
10 | "resizeMode": "contain",
11 | "backgroundColor": "#ffffff"
12 | },
13 | "updates": {
14 | "fallbackToCacheTimeout": 0
15 | },
16 | "assetBundlePatterns": [
17 | "**/*"
18 | ],
19 | "ios": {
20 | "supportsTablet": true
21 | },
22 | "android": {
23 | "adaptiveIcon": {
24 | "foregroundImage": "./assets/adaptive-icon.png",
25 | "backgroundColor": "#FFFFFF"
26 | }
27 | },
28 | "web": {
29 | "favicon": "./assets/favicon.png"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/hooks.ts:
--------------------------------------------------------------------------------
1 | import type { AppDispatch, RootState } from "./store";
2 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
3 |
4 | export const useAppDispatch = () => useDispatch();
5 | export const useAppSelector: TypedUseSelectorHook = useSelector;
6 |
--------------------------------------------------------------------------------
/app/slices/navigationSlice.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | import { Point } from "react-native-google-places-autocomplete";
4 | import { RootState } from "../../app/store";
5 |
6 | type DistanceMatrix = {
7 | distance: {
8 | text: string;
9 | value: number;
10 | };
11 | duration: {
12 | text: string;
13 | value: number;
14 | };
15 | status: string;
16 | };
17 |
18 | type NavigationState = {
19 | origin: { location: Point | undefined; description: string } | null;
20 | destination: { location: Point | undefined; description: string } | null;
21 | travelTimeInfo: DistanceMatrix | null;
22 | };
23 |
24 | const initialState: NavigationState = {
25 | origin: null,
26 | destination: null,
27 | travelTimeInfo: null,
28 | };
29 |
30 | export const navigationSlice = createSlice({
31 | name: "navigation",
32 | initialState,
33 | reducers: {
34 | setOrigin: (state, action: PayloadAction) => {
35 | state.origin = action.payload;
36 | },
37 | setDestination: (
38 | state,
39 | action: PayloadAction
40 | ) => {
41 | state.destination = action.payload;
42 | },
43 | setTravelTimeInfo: (state, action: PayloadAction) => {
44 | state.travelTimeInfo = action.payload;
45 | },
46 | },
47 | });
48 |
49 | export const { setOrigin, setDestination, setTravelTimeInfo } =
50 | navigationSlice.actions;
51 |
52 | export const selectOrigin = (state: RootState) => state.navigation.origin;
53 | export const selectDestination = (state: RootState) =>
54 | state.navigation.destination;
55 | export const selectTravelTimeInfo = (state: RootState) =>
56 | state.navigation.travelTimeInfo;
57 |
58 | export default navigationSlice.reducer;
59 |
--------------------------------------------------------------------------------
/app/store.ts:
--------------------------------------------------------------------------------
1 | import { configureStore } from "@reduxjs/toolkit";
2 | import navigationReducer from "./slices/navigationSlice";
3 |
4 | export const store = configureStore({
5 | reducer: { navigation: navigationReducer },
6 | });
7 |
8 | export type RootState = ReturnType;
9 | export type AppDispatch = typeof store.dispatch;
10 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/favicon.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/icon.png
--------------------------------------------------------------------------------
/assets/screenshots/Screenshot_1634302767.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/screenshots/Screenshot_1634302767.jpg
--------------------------------------------------------------------------------
/assets/screenshots/Screenshot_1634302842.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/screenshots/Screenshot_1634302842.jpg
--------------------------------------------------------------------------------
/assets/screenshots/Screenshot_1634302884.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/screenshots/Screenshot_1634302884.jpg
--------------------------------------------------------------------------------
/assets/screenshots/ezgif-7-2d01dc3b82b1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/screenshots/ezgif-7-2d01dc3b82b1.gif
--------------------------------------------------------------------------------
/assets/screenshots/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/screenshots/logo.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/emmanuelchucks/react-native-uber-clone/af032325f5536a9351900b7393b26de0c5d9b186/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: ["babel-preset-expo"],
5 | plugins: [
6 | [
7 | "module:react-native-dotenv",
8 | {
9 | moduleName: "@env",
10 | path: ".env",
11 | },
12 | ],
13 | ],
14 | };
15 | };
16 |
--------------------------------------------------------------------------------
/components/HomeNavigation.tsx:
--------------------------------------------------------------------------------
1 | import EatsScreen from "../screens/EatsScreen";
2 | import HomeScreen from "../screens/HomeScreen";
3 | import MapScreen from "../screens/MapScreen";
4 | import React from "react";
5 | import { createNativeStackNavigator } from "@react-navigation/native-stack";
6 |
7 | export type StackList = {
8 | HomeScreen: undefined;
9 | MapScreen: undefined;
10 | EatsScreen: undefined;
11 | };
12 |
13 | const Stack = createNativeStackNavigator();
14 |
15 | const HomeNavigation = () => {
16 | return (
17 |
18 |
25 |
32 |
39 |
40 | );
41 | };
42 |
43 | export default HomeNavigation;
44 |
--------------------------------------------------------------------------------
/components/Map.tsx:
--------------------------------------------------------------------------------
1 | import MapView, { Marker } from "react-native-maps";
2 | import React, { useEffect, useRef } from "react";
3 | import {
4 | selectDestination,
5 | selectOrigin,
6 | setTravelTimeInfo,
7 | } from "../app/slices/navigationSlice";
8 | import { useDispatch, useSelector } from "react-redux";
9 |
10 | import { GOOGLE_MAPS_API_KEY } from "@env";
11 | import MapViewDirections from "react-native-maps-directions";
12 | import tailwind from "tailwind-react-native-classnames";
13 |
14 | const Map = () => {
15 | const dispatch = useDispatch();
16 | const origin = useSelector(selectOrigin);
17 | const destination = useSelector(selectDestination);
18 | const mapRef = useRef(null);
19 |
20 | useEffect(() => {
21 | if (!origin || !destination) return;
22 |
23 | mapRef.current?.fitToSuppliedMarkers(["origin", "destination"], {
24 | edgePadding: { top: 50, right: 50, bottom: 50, left: 50 },
25 | });
26 | }, [origin, destination]);
27 |
28 | useEffect(() => {
29 | if (!origin || !destination) return;
30 |
31 | const getTravelTime = async () => {
32 | const url = `https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=${origin.description}&destinations=${destination.description}&key=${GOOGLE_MAPS_API_KEY}`;
33 | const response = await fetch(url);
34 | const data = await response.json();
35 | dispatch(setTravelTimeInfo(data.rows[0].elements[0]));
36 | };
37 |
38 | getTravelTime();
39 | }, [origin, destination, GOOGLE_MAPS_API_KEY]);
40 |
41 | return (
42 |
53 | {origin && destination && (
54 |
62 | )}
63 |
64 | {origin?.location && (
65 |
74 | )}
75 |
76 | {destination?.location && (
77 |
86 | )}
87 |
88 | );
89 | };
90 |
91 | export default Map;
92 |
--------------------------------------------------------------------------------
/components/MapScreenNavigation.tsx:
--------------------------------------------------------------------------------
1 | import NavigateCard from "./NavigateCard";
2 | import React from "react";
3 | import RideOptionsCard from "./RideOptionsCard";
4 | import { createNativeStackNavigator } from "@react-navigation/native-stack";
5 |
6 | export type StackList = {
7 | NavigateCard: undefined;
8 | RideOptionsCard: undefined;
9 | };
10 |
11 | const Stack = createNativeStackNavigator();
12 |
13 | const MapScreenNavigation = () => {
14 | return (
15 |
16 | {/* */}
23 |
30 |
37 |
38 | );
39 | };
40 |
41 | export default MapScreenNavigation;
42 |
--------------------------------------------------------------------------------
/components/NavFavorites.tsx:
--------------------------------------------------------------------------------
1 | import { FlatList, Text, TouchableOpacity, View } from "react-native";
2 | import {
3 | selectOrigin,
4 | setDestination,
5 | setOrigin,
6 | } from "../app/slices/navigationSlice";
7 | import { useDispatch, useSelector } from "react-redux";
8 |
9 | import { HomeScreenProp } from "./NavOptions";
10 | import { Icon } from "react-native-elements";
11 | import { Point } from "react-native-google-places-autocomplete";
12 | import React from "react";
13 | import tailwind from "tailwind-react-native-classnames";
14 | import { useNavigation } from "@react-navigation/native";
15 |
16 | const NavFavorites = ({ shouldSetOrigin }: { shouldSetOrigin?: boolean }) => {
17 | const dispatch = useDispatch();
18 | const origin = useSelector(selectOrigin);
19 | const navigation = useNavigation();
20 |
21 | return (
22 | shouldSetOrigin || origin?.location !== item.location
26 | )}
27 | keyExtractor={(item) => item.id}
28 | ItemSeparatorComponent={() => (
29 |
37 | )}
38 | renderItem={({ item: { name, icon, location, description } }) => (
39 | {
42 | if (shouldSetOrigin) {
43 | dispatch(
44 | setOrigin({
45 | location,
46 | description,
47 | })
48 | );
49 | navigation.navigate("MapScreen");
50 | } else {
51 | dispatch(
52 | setDestination({
53 | location,
54 | description,
55 | })
56 | );
57 | }
58 | }}
59 | >
60 |
67 |
68 | {name}
69 | {description}
70 |
71 |
72 | )}
73 | />
74 | );
75 | };
76 |
77 | type FavoritesData = {
78 | id: string;
79 | name: string;
80 | icon: string;
81 | location: Point;
82 | description: string;
83 | }[];
84 |
85 | const favoritesData: FavoritesData = [
86 | {
87 | id: "234",
88 | icon: "home",
89 | name: "Home",
90 | location: { lat: 5.4945, lng: -0.4118 },
91 | description: "Jordan Gospel Centre, Land of Grace",
92 | },
93 | {
94 | id: "567",
95 | icon: "briefcase",
96 | name: "Work",
97 | location: { lat: 5.5497, lng: -0.3522 },
98 | description: "Finger Bites Kitchen, Mile 11",
99 | },
100 | ];
101 |
102 | export default NavFavorites;
103 |
--------------------------------------------------------------------------------
/components/NavOptions.tsx:
--------------------------------------------------------------------------------
1 | import { FlatList, Image, Text, TouchableOpacity, View } from "react-native";
2 |
3 | import { Icon } from "react-native-elements";
4 | import { NativeStackNavigationProp } from "@react-navigation/native-stack";
5 | import React from "react";
6 | import { StackList } from "./HomeNavigation";
7 | import { selectOrigin } from "../app/slices/navigationSlice";
8 | import tailwind from "tailwind-react-native-classnames";
9 | import { useNavigation } from "@react-navigation/native";
10 | import { useSelector } from "react-redux";
11 |
12 | const NavOptions = () => {
13 | const navigation = useNavigation();
14 | const origin = useSelector(selectOrigin);
15 |
16 | return (
17 | item.id}
21 | renderItem={({ item }) => (
22 | navigation.navigate(item.screen)}
25 | style={tailwind`pr-2 pl-6 pt-4 pb-8 bg-gray-200 mr-2 mb-5 w-40 rounded-md`}
26 | >
27 |
28 |
32 | {item.title}
33 |
39 |
40 |
41 | )}
42 | />
43 | );
44 | };
45 |
46 | type NavData = {
47 | id: string;
48 | title: string;
49 | image: string;
50 | screen: keyof StackList;
51 | }[];
52 |
53 | export const navData: NavData = [
54 | {
55 | id: "123",
56 | title: "Get a ride",
57 | image: "https://links.papareact.com/3pn",
58 | screen: "MapScreen",
59 | },
60 | {
61 | id: "456",
62 | title: "Order Food",
63 | image: "https://links.papareact.com/28w",
64 | screen: "EatsScreen",
65 | },
66 | ];
67 |
68 | export type HomeScreenProp = NativeStackNavigationProp;
69 |
70 | export default NavOptions;
71 |
--------------------------------------------------------------------------------
/components/NavigateCard.tsx:
--------------------------------------------------------------------------------
1 | import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
2 |
3 | import { GOOGLE_MAPS_API_KEY } from "@env";
4 | import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
5 | import { Icon } from "react-native-elements";
6 | import { NativeStackNavigationProp } from "@react-navigation/native-stack";
7 | import NavFavorites from "./NavFavorites";
8 | import React from "react";
9 | import { SafeAreaView } from "react-native-safe-area-context";
10 | import { StackList } from "./MapScreenNavigation";
11 | import { setDestination } from "../app/slices/navigationSlice";
12 | import tailwind from "tailwind-react-native-classnames";
13 | import { useDispatch } from "react-redux";
14 | import { useNavigation } from "@react-navigation/native";
15 |
16 | const NavigateCard = () => {
17 | const dispatch = useDispatch();
18 | const navigation = useNavigation();
19 |
20 | return (
21 |
22 |
23 |
24 | Good morning, Papi
25 |
26 |
27 | {
39 | dispatch(
40 | setDestination({
41 | location: details?.geometry.location,
42 | description: data.description,
43 | })
44 | );
45 | navigation.navigate("RideOptionsCard");
46 | }}
47 | />
48 |
49 |
50 |
51 |
52 |
53 |
56 | navigation.navigate("RideOptionsCard")}
59 | >
60 |
61 | Rides
62 |
63 |
66 |
72 | Eats
73 |
74 |
75 |
76 | );
77 | };
78 |
79 | const toInputBoxStyles = StyleSheet.create({
80 | container: {
81 | backgroundColor: "white",
82 | paddingTop: 20,
83 | flex: 0,
84 | },
85 | textInput: {
86 | backgroundColor: "#DDDDDF",
87 | borderRadius: 0,
88 | fontSize: 18,
89 | },
90 | textInputContainer: {
91 | paddingHorizontal: 20,
92 | paddingBottom: 0,
93 | },
94 | });
95 |
96 | type NavigateCardProp = NativeStackNavigationProp;
97 |
98 | export default NavigateCard;
99 |
--------------------------------------------------------------------------------
/components/RideOptionsCard.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | FlatList,
3 | Image,
4 | Platform,
5 | Text,
6 | TouchableOpacity,
7 | View,
8 | } from "react-native";
9 | import React, { useState } from "react";
10 |
11 | import { Icon } from "react-native-elements";
12 | import { SafeAreaView } from "react-native-safe-area-context";
13 | import { selectTravelTimeInfo } from "../app/slices/navigationSlice";
14 | import tailwind from "tailwind-react-native-classnames";
15 | import { useNavigation } from "@react-navigation/native";
16 | import { useSelector } from "react-redux";
17 |
18 | const RideOptionsCard = () => {
19 | const navigation = useNavigation();
20 | const [selected, setSelected] = useState(null);
21 | const travelTimeInformation = useSelector(selectTravelTimeInfo);
22 |
23 | return (
24 |
25 |
26 | navigation.goBack()}
28 | style={tailwind`absolute top-1 left-0 px-5 rounded-full`}
29 | >
30 |
34 |
35 |
36 | Select a Ride - {travelTimeInformation?.distance.text}
37 |
38 |
39 | item.id}
42 | renderItem={({ item: { id, title, multiplier, image }, item }) => (
43 | setSelected(item)}
45 | style={tailwind.style(
46 | `flex-row justify-between items-center px-6`,
47 | id === selected?.id && "bg-gray-200"
48 | )}
49 | >
50 |
60 |
61 | {title}
62 | {travelTimeInformation?.duration.text}
63 |
64 |
65 | {new Intl.NumberFormat("ee-gh", {
66 | currency: "GHS",
67 | style: "currency",
68 | }).format(
69 | ((travelTimeInformation?.duration.value || 0) *
70 | SURGE_CHARGE_RATE *
71 | multiplier) /
72 | 100
73 | )}
74 |
75 |
76 | )}
77 | />
78 |
79 |
86 |
87 | Choose {selected?.title}
88 |
89 |
90 |
91 |
92 | );
93 | };
94 |
95 | type RidesData = {
96 | id: string;
97 | title: string;
98 | multiplier: number;
99 | image: string;
100 | }[];
101 |
102 | const ridesData: RidesData = [
103 | {
104 | id: "Uber-X-123",
105 | title: "UberX",
106 | multiplier: 1,
107 | image: "https://links.papareact.com/3pn",
108 | },
109 | {
110 | id: "Uber-XL-456",
111 | title: "Uber XL",
112 | multiplier: 1.2,
113 | image: "https://links.papareact.com/5w8",
114 | },
115 | {
116 | id: "Uber-LUX-789",
117 | title: "Uber LUX",
118 | multiplier: 1.75,
119 | image: "https://links.papareact.com/7pf",
120 | },
121 | ];
122 |
123 | const SURGE_CHARGE_RATE = 1.5;
124 |
125 | export default RideOptionsCard;
126 |
--------------------------------------------------------------------------------
/env.d.ts:
--------------------------------------------------------------------------------
1 | declare module "@env" {
2 | export const GOOGLE_MAPS_API_KEY: string;
3 | }
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "@react-navigation/native": "^6.0.4",
12 | "@react-navigation/native-stack": "^6.2.2",
13 | "@reduxjs/toolkit": "^1.6.1",
14 | "expo": "~42.0.1",
15 | "expo-status-bar": "~1.0.4",
16 | "intl": "^1.2.5",
17 | "react": "16.13.1",
18 | "react-dom": "16.13.1",
19 | "react-native": "0.63.4",
20 | "react-native-dotenv": "^3.2.0",
21 | "react-native-elements": "^3.4.2",
22 | "react-native-google-places-autocomplete": "^2.4.1",
23 | "react-native-maps": "0.28.0",
24 | "react-native-maps-directions": "^1.8.0",
25 | "react-native-safe-area-context": "3.2.0",
26 | "react-native-screens": "~3.4.0",
27 | "react-native-vector-icons": "^8.1.0",
28 | "react-native-web": "~0.13.12",
29 | "react-redux": "^7.2.5",
30 | "tailwind-react-native-classnames": "^1.5.1"
31 | },
32 | "devDependencies": {
33 | "@babel/core": "~7.9.0",
34 | "@types/react": "~16.9.35",
35 | "@types/react-native": "~0.63.2",
36 | "typescript": "~4.0.0"
37 | },
38 | "private": true
39 | }
40 |
--------------------------------------------------------------------------------
/screens/EatsScreen.tsx:
--------------------------------------------------------------------------------
1 | import { Image, Text, View } from "react-native";
2 |
3 | import React from "react";
4 | import { SafeAreaView } from "react-native-safe-area-context";
5 | import { navData } from "../components/NavOptions";
6 |
7 | const EatsScreen = () => {
8 | return (
9 |
12 |
13 |
17 |
18 |
19 | Not yet implemented...
20 |
21 |
22 | );
23 | };
24 |
25 | export default EatsScreen;
26 |
--------------------------------------------------------------------------------
/screens/HomeScreen.tsx:
--------------------------------------------------------------------------------
1 | import { Image, View } from "react-native";
2 | import { setDestination, setOrigin } from "../app/slices/navigationSlice";
3 |
4 | import { GOOGLE_MAPS_API_KEY } from "@env";
5 | import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
6 | import NavFavorites from "../components/NavFavorites";
7 | import NavOptions from "../components/NavOptions";
8 | import React from "react";
9 | import { SafeAreaView } from "react-native-safe-area-context";
10 | import tailwind from "tailwind-react-native-classnames";
11 | import { useDispatch } from "react-redux";
12 |
13 | const HomeScreen = () => {
14 | const dispatch = useDispatch();
15 |
16 | return (
17 |
18 |
19 |
25 | {
33 | dispatch(
34 | setOrigin({
35 | location: details?.geometry.location,
36 | description: data.description,
37 | })
38 | );
39 | dispatch(setDestination(null));
40 | }}
41 | query={{
42 | key: GOOGLE_MAPS_API_KEY,
43 | language: "en",
44 | }}
45 | styles={{
46 | container: {
47 | flex: 0,
48 | },
49 | }}
50 | />
51 |
52 |
53 |
54 |
55 | );
56 | };
57 |
58 | export default HomeScreen;
59 |
--------------------------------------------------------------------------------
/screens/MapScreen.tsx:
--------------------------------------------------------------------------------
1 | import { TouchableOpacity, View } from "react-native";
2 |
3 | import { HomeScreenProp } from "../components/NavOptions";
4 | import { Icon } from "react-native-elements";
5 | import Map from "../components/Map";
6 | import MapScreenNavigation from "../components/MapScreenNavigation";
7 | import React from "react";
8 | import tailwind from "tailwind-react-native-classnames";
9 | import { useNavigation } from "@react-navigation/native";
10 |
11 | const MapScreen = () => {
12 | const navigation = useNavigation();
13 |
14 | return (
15 |
16 | navigation.navigate("HomeScreen")}
18 | style={tailwind`bg-gray-50 absolute top-8 left-4 z-50 p-3 rounded-full shadow-lg`}
19 | >
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | );
30 | };
31 |
32 | export default MapScreen;
33 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------