├── .expo-shared
└── assets.json
├── .gitignore
├── App.js
├── app.json
├── assets
├── icon.png
└── splash.png
├── babel.config.js
├── package-lock.json
├── package.json
└── src
├── api
└── WebService.js
├── components
├── Buttons
│ ├── AddRemoveButton.js
│ └── AppButton.js
├── Cards
│ ├── CartItem.js
│ ├── FoodCard.js
│ ├── OfferCard.js
│ ├── OrderCard.js
│ └── Restaurant.js
├── CategoryItem.js
├── FoodCartMedium.js
├── InputFields
│ ├── SearchBar.js
│ └── UserLogin.js
├── Listview
│ ├── CartListView.js
│ ├── OrderListView.js
│ └── ProductListView.js
├── Overlay.js
└── TopCategoryList.js
├── dataStore
├── createAppContext.js
├── reducer.js
└── userAccessContext.js
├── images
├── account_icon.png
├── account_n_icon.png
├── arrow_icon.png
├── back_arrow.png
├── best_restaurent_1.jpg
├── best_restaurent_2.jpg
├── burger.jpg
├── burger_icon.jpg
├── cart_icon.png
├── cart_n_icon.png
├── coffee.jpeg
├── cusin_1.jpg
├── cusin_2.jpg
├── cusin_3.jpg
├── hambar.png
├── home.png
├── home_focused.png
├── home_icon.png
├── home_n_icon.png
├── lunch.jpg
├── offer.jpg
├── offer_icon.png
├── offer_n_icon.png
├── orders.png
├── pizza.jpg
├── search.png
└── starIcon.png
├── screens
├── AuthCheckScreen.js
├── foods
│ ├── FoodDetails.js
│ ├── RestaurantDetails.js
│ └── TopRestaurants.js
├── home
│ ├── HomeScreen.js
│ ├── OffersScreen.js
│ └── SearchScreen.js
├── shoping
│ ├── CartScreen.js
│ ├── OrderDetails.js
│ ├── OrderScreen.js
│ └── PaymentScreen.js
└── user
│ ├── AccountScreen.js
│ ├── SigninScreen.js
│ └── SignupScreen.js
└── utils
├── ActionTypes.js
├── AppConst.js
└── NavigationRef.js
/.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 | web-report/
12 |
13 | # macOS
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createAppContainer, createSwitchNavigator } from 'react-navigation';
3 | import { createStackNavigator } from 'react-navigation-stack';
4 | import { createBottomTabNavigator } from 'react-navigation-tabs';
5 | import { Image, StyleSheet } from 'react-native';
6 | import { Provider as UserProvider } from './src/dataStore/userAccessContext';
7 |
8 | /**
9 | *
10 | * Screens
11 | *
12 | **/
13 |
14 | import AuthCheckScreen from './src/screens/AuthCheckScreen';
15 | import AccountScreen from './src/screens/user/AccountScreen';
16 | import CartScreen from './src/screens/shoping/CartScreen';
17 | import HomeScreen from './src/screens/home/HomeScreen';
18 | import OfferScreen from './src/screens/home/OffersScreen';
19 | import SearchScreen from './src/screens/home/SearchScreen';
20 | import SigninScreen from './src/screens/user/SigninScreen';
21 | import SignupScreen from './src/screens/user/SignupScreen';
22 | import { setNavigator } from './src/utils/NavigationRef';
23 | import OrderScreen from './src/screens/shoping/OrderScreen';
24 | import OrderDetailScreen from './src/screens/shoping/OrderDetails';
25 | import PaymentScreen from './src/screens/shoping/PaymentScreen';
26 | import FoodDetails from './src/screens/foods/FoodDetails';
27 | import RestaurantDetailScreen from './src/screens/foods/RestaurantDetails';
28 |
29 | const switchNavigator = createSwitchNavigator({
30 | authCheck: AuthCheckScreen,
31 | homeStack: createBottomTabNavigator({
32 | Home: {
33 | screen: createStackNavigator({
34 | TopProducts: HomeScreen,
35 | Search: SearchScreen,
36 | ProductDetail: FoodDetails,
37 | RestaurantDetail: RestaurantDetailScreen,
38 | }),
39 | navigationOptions: {
40 | tabBarOptions: {
41 | activeTintColor: '#f15b5d',
42 | },
43 | tabBarIcon: ({ focused, tintColor }) => {
44 | let icon =
45 | focused == true
46 | ? require('./src/images/home_icon.png')
47 | : require('./src/images/home_n_icon.png');
48 | return ;
49 | },
50 | },
51 | },
52 | Offer: {
53 | screen: OfferScreen,
54 | navigationOptions: {
55 | tabBarOptions: {
56 | activeTintColor: '#f15b5d',
57 | },
58 | tabBarIcon: ({ focused, tintColor }) => {
59 | let icon =
60 | focused == true
61 | ? require('./src/images/offer_icon.png')
62 | : require('./src/images/offer_n_icon.png');
63 | return ;
64 | },
65 | },
66 | },
67 | Cart: {
68 | screen: createStackNavigator({
69 | Shoping: CartScreen,
70 | Order: OrderScreen,
71 | Payment: PaymentScreen,
72 | OrderDetails: OrderDetailScreen,
73 | }),
74 | navigationOptions: {
75 | tabBarOptions: {
76 | activeTintColor: '#f15b5d',
77 | },
78 | tabBarIcon: ({ focused, tintColor }) => {
79 | let icon =
80 | focused == true
81 | ? require('./src/images/cart_icon.png')
82 | : require('./src/images/cart_n_icon.png');
83 | return ;
84 | },
85 | },
86 | },
87 | Account: {
88 | screen: AccountScreen,
89 | navigationOptions: {
90 | tabBarOptions: {
91 | activeTintColor: '#f15b5d',
92 | },
93 | tabBarIcon: ({ focused, tintColor }) => {
94 | let img =
95 | focused == true
96 | ? require('./src/images/account_icon.png')
97 | : require('./src/images/account_n_icon.png');
98 | return ;
99 | },
100 | },
101 | },
102 | }),
103 | loginStack: {
104 | screen: createStackNavigator({
105 | Signin: SigninScreen,
106 | Signup: SignupScreen,
107 | }),
108 | navigationOptions: {
109 | tabBarIcon: ({ focused, tintColor }) => {
110 | let icon =
111 | focused == true
112 | ? require('./src/images/account_icon.png')
113 | : require('./src/images/account_n_icon.png');
114 | return ;
115 | },
116 | },
117 | },
118 | });
119 |
120 | const styles = StyleSheet.create({
121 | tabIcon: {
122 | width: 30,
123 | height: 30,
124 | },
125 | });
126 |
127 | const App = createAppContainer(switchNavigator);
128 |
129 | export default () => {
130 | return (
131 |
132 | {
134 | setNavigator(navigator);
135 | }}
136 | />
137 |
138 | );
139 | };
140 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "React_Native_Food_Delivery_App",
4 | "slug": "React_Native_Food_Delivery_App",
5 | "platforms": [
6 | "ios",
7 | "android",
8 | "web"
9 | ],
10 | "version": "1.0.0",
11 | "orientation": "portrait",
12 | "icon": "./assets/icon.png",
13 | "splash": {
14 | "image": "./assets/splash.png",
15 | "resizeMode": "contain",
16 | "backgroundColor": "#ffffff"
17 | },
18 | "updates": {
19 | "fallbackToCacheTimeout": 0
20 | },
21 | "assetBundlePatterns": [
22 | "**/*"
23 | ],
24 | "ios": {
25 | "supportsTablet": true
26 | },
27 | "description": "Online Food Order Application built using React Native",
28 | "githubUrl": "https://github.com/codergogoi/React_Native_Food_Order_App"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/assets/icon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/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-native-community/masked-view": "0.1.6",
12 | "axios": "^0.19.2",
13 | "expo": "^37.0.0",
14 | "moment": "^2.25.3",
15 | "react": "16.9.0",
16 | "react-dom": "16.9.0",
17 | "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
18 | "react-native-elements": "^1.2.7",
19 | "react-native-gesture-handler": "~1.6.0",
20 | "react-native-maps": "0.26.1",
21 | "react-native-raw-bottom-sheet": "^2.2.0",
22 | "react-native-reanimated": "~1.7.0",
23 | "react-native-safe-area-context": "0.7.3",
24 | "react-native-screens": "~2.2.0",
25 | "react-native-web": "^0.11.7",
26 | "react-navigation": "^4.3.7",
27 | "react-navigation-stack": "^2.3.11",
28 | "react-navigation-tabs": "^2.8.11"
29 | },
30 | "devDependencies": {
31 | "babel-preset-expo": "^8.1.0",
32 | "@babel/core": "^7.8.6"
33 | },
34 | "private": true
35 | }
36 |
--------------------------------------------------------------------------------
/src/api/WebService.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export default axios.create({
4 | baseURL: "https://online-foods.herokuapp.com/",
5 | });
6 |
--------------------------------------------------------------------------------
/src/components/Buttons/AddRemoveButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet } from "react-native";
3 | import { Button } from "react-native-elements";
4 |
5 | const AddRemoveButton = ({ title, onTap, width = 32 }) => {
6 | return (
7 |
14 | );
15 | };
16 |
17 | const styles = StyleSheet.create({
18 | titleStyle: {
19 | fontSize: 20,
20 | fontWeight: "600",
21 | color: "#f15b5d",
22 | },
23 |
24 | button: {
25 | width: 50,
26 | height: 50,
27 | borderColor: "#f15b5d",
28 | borderWidth: 0.3,
29 | alignSelf: "center",
30 | borderRadius: 5,
31 | },
32 | });
33 |
34 | export default AddRemoveButton;
35 |
--------------------------------------------------------------------------------
/src/components/Buttons/AppButton.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet } from "react-native";
3 | import { Button } from "react-native-elements";
4 |
5 | const AppButton = ({ title, onTap, width = 300, height = 40 }) => {
6 | return (
7 |
14 | );
15 | };
16 |
17 | const styles = StyleSheet.create({
18 | titleStyle: {
19 | fontSize: 16,
20 | fontWeight: "300",
21 | color: "white",
22 | },
23 |
24 | button: {
25 | width: 300,
26 | height: 40,
27 | backgroundColor: "#f15b5d",
28 | alignSelf: "center",
29 | borderRadius: 30,
30 | },
31 | });
32 |
33 | export default AppButton;
34 |
--------------------------------------------------------------------------------
/src/components/Cards/CartItem.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | Image,
6 | TouchableOpacity,
7 | Dimensions,
8 | } from "react-native";
9 |
10 | import { Text, Badge, Button } from "react-native-elements";
11 |
12 | import ButtonAddRemove from "../Buttons/AddRemoveButton";
13 |
14 | const CartItem = ({ data, onAddItem, onRemoveItem }) => {
15 | const { food, qty } = data.item;
16 | const { name, category, description, price } = food;
17 |
18 | let currentQty = qty;
19 |
20 | return (
21 |
22 |
23 | {name}
24 |
25 | {category.toString().toUpperCase()}
26 |
27 | {description}
28 |
29 |
30 | ₹{price}
31 |
32 | onAddItem(food, --currentQty)}
35 | />
36 |
37 |
41 | {currentQty}
42 |
43 | onRemoveItem(food, ++currentQty)}
46 | />
47 |
48 |
49 |
50 | );
51 | };
52 |
53 | const styles = StyleSheet.create({
54 | root: {
55 | flex: 1,
56 | height: "100%",
57 | display: "flex",
58 | flexDirection: "column",
59 | justifyContent: "flex-start",
60 | alignItems: "center",
61 | margin: 10,
62 | },
63 | smallCard: {
64 | flex: 1,
65 | minHeight: 100,
66 | display: "flex",
67 | flexDirection: "row",
68 | justifyContent: "flex-start",
69 | backgroundColor: "white",
70 | borderColor: "#E5E5E5",
71 | borderWidth: 1,
72 | padding: 10,
73 | borderRadius: 10,
74 | margin: 10,
75 | },
76 |
77 | title: {
78 | fontSize: 22,
79 | fontWeight: "300",
80 | display: "flex",
81 | justifyContent: "center",
82 | alignItems: "center",
83 | },
84 | resturentTitle: {
85 | fontSize: 16,
86 | fontWeight: "600",
87 | marginTop: 4,
88 | marginBottom: 4,
89 | display: "flex",
90 | color: "#565555",
91 | },
92 | foodDescription: {
93 | fontSize: 16,
94 | fontWeight: "300",
95 | display: "flex",
96 | color: "#565555",
97 | },
98 | price: {
99 | fontSize: 18,
100 | fontWeight: "600",
101 | display: "flex",
102 | color: "#EA5656",
103 | alignSelf: "center",
104 | },
105 | foodImageSmall: {
106 | borderRadius: 10,
107 | height: 99,
108 | width: 99,
109 | justifyContent: "flex-start",
110 | alignItems: "center",
111 | backgroundColor: "#581845",
112 | alignSelf: "center",
113 | },
114 | rating: {
115 | alignSelf: "flex-start",
116 | },
117 | productInfo: {
118 | flex: 9,
119 | justifyContent: "space-around",
120 | },
121 |
122 | priceView: {
123 | flex: 3,
124 | justifyContent: "space-around",
125 | alignItems: "flex-start",
126 | },
127 | countView: {
128 | display: "flex",
129 | flexDirection: "row",
130 | justifyContent: "center",
131 | alignItems: "center",
132 | width: "100%",
133 | flex: 8,
134 | },
135 | badge: {
136 | backgroundColor: "green",
137 | },
138 | //Button
139 | btnAddRemove: {
140 | borderColor: "#f15b5d",
141 | borderRadius: 5,
142 | borderWidth: 0.5,
143 | },
144 | btnTitleStyle: {
145 | color: "#f15b5d",
146 | },
147 | });
148 |
149 | export default CartItem;
150 |
--------------------------------------------------------------------------------
/src/components/Cards/FoodCard.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | Image,
6 | TouchableOpacity,
7 | Dimensions,
8 | } from "react-native";
9 |
10 | import { Text, Rating } from "react-native-elements";
11 | import AppButton from "../Buttons/AppButton";
12 | import ButtonAddRemove from "../Buttons/AddRemoveButton";
13 |
14 | import { urlImage } from "../../utils/AppConst";
15 |
16 | const deviceWidth = Math.round(Dimensions.get("window").width);
17 |
18 | const FoodCard = ({
19 | size,
20 | data,
21 | onSelect,
22 | disable = false,
23 | onAddToCart,
24 | canAdd = true,
25 | didAddRemove,
26 | cartItems,
27 | }) => {
28 | const { item } = data;
29 |
30 | const { _id, name, images, description, price, readyTime, category } = item;
31 |
32 | let isAdded = false;
33 | let currentQty = 1;
34 |
35 | let image = urlImage(images[0]);
36 |
37 | const didAddItem = () => {
38 | onAddToCart();
39 | };
40 |
41 | const didRemoveItem = () => {};
42 |
43 | const mediumCard = () => {
44 | return (
45 |
46 | onSelect(item)}>
47 |
48 |
49 | {name}
50 |
51 | );
52 | };
53 |
54 | const smallCard = () => {
55 | return (
56 | onSelect(item)}
59 | disabled={disable}
60 | >
61 |
62 |
63 | {name}
64 |
65 | {category.toString().toUpperCase()}
66 |
67 |
74 |
75 |
76 | ₹{price}
77 | {cartItems !== undefined &&
78 | cartItems.map((item) => {
79 | if (item.food._id.toString() === _id.toString()) {
80 | isAdded = true;
81 | currentQty = item.qty;
82 | }
83 | })}
84 | {canAdd && !isAdded && (
85 | onAddToCart(data.item)}
89 | />
90 | )}
91 |
92 | {isAdded && (
93 |
94 | didAddRemove(item, --currentQty)}
97 | />
98 |
99 |
103 | {currentQty}
104 |
105 | didAddRemove(item, ++currentQty)}
108 | />
109 |
110 | )}
111 |
112 |
113 | );
114 | };
115 |
116 | switch (size) {
117 | case "small": // wide card
118 | return smallCard();
119 | case "medium": // medium card
120 | return mediumCard();
121 | default:
122 | return mediumCard();
123 | }
124 | };
125 |
126 | const styles = StyleSheet.create({
127 | root: {
128 | flex: 1,
129 | height: "100%",
130 | display: "flex",
131 | flexDirection: "column",
132 | justifyContent: "flex-start",
133 | alignItems: "center",
134 | margin: 10,
135 | },
136 | foodImage: {
137 | borderRadius: 20,
138 | height: 220,
139 | width: deviceWidth - 30,
140 | backgroundColor: "red",
141 | justifyContent: "center",
142 | alignItems: "center",
143 | alignContent: "center",
144 | backgroundColor: "#581845",
145 | },
146 | title: {
147 | fontSize: 14,
148 | fontWeight: "500",
149 | width: "100%",
150 | display: "flex",
151 | justifyContent: "center",
152 | alignItems: "center",
153 | textAlign: "center",
154 | marginTop: 10,
155 | color: "#636363",
156 | },
157 | countView: {
158 | display: "flex",
159 | flexDirection: "row",
160 | justifyContent: "center",
161 | alignItems: "center",
162 | flex: 8,
163 | },
164 | });
165 |
166 | const smallStyles = StyleSheet.create({
167 | smallCard: {
168 | flex: 1,
169 | height: 100,
170 | display: "flex",
171 | flexDirection: "row",
172 | justifyContent: "flex-start",
173 | backgroundColor: "white",
174 | borderColor: "#E5E5E5",
175 | borderWidth: 1,
176 | borderRadius: 10,
177 | margin: 10,
178 | },
179 |
180 | title: {
181 | fontSize: 16,
182 | fontWeight: "500",
183 | display: "flex",
184 | justifyContent: "center",
185 | alignItems: "center",
186 | },
187 | resturentTitle: {
188 | fontSize: 16,
189 | display: "flex",
190 | color: "#565555",
191 | },
192 | price: {
193 | fontSize: 18,
194 | fontWeight: "400",
195 | display: "flex",
196 | color: "#EA5656",
197 | },
198 | foodImageSmall: {
199 | borderRadius: 10,
200 | height: 99,
201 | width: 99,
202 | justifyContent: "flex-start",
203 | alignItems: "center",
204 | backgroundColor: "#581845",
205 | alignSelf: "center",
206 | },
207 | rating: {
208 | alignSelf: "flex-start",
209 | },
210 | productInfo: {
211 | flex: 1,
212 | padding: 5,
213 | justifyContent: "space-around",
214 | },
215 | shopView: {
216 | justifyContent: "space-around",
217 | padding: 10,
218 | alignItems: "center",
219 | },
220 | productSize: {
221 | fontSize: 20,
222 | fontWeight: "600",
223 | color: "#848484",
224 | },
225 | });
226 |
227 | export default FoodCard;
228 |
--------------------------------------------------------------------------------
/src/components/Cards/OfferCard.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | Image,
6 | TouchableOpacity,
7 | Dimensions,
8 | } from "react-native";
9 |
10 | import { Text, Rating } from "react-native-elements";
11 |
12 | const deviceWidth = Math.round(Dimensions.get("window").width);
13 |
14 | const OfferCard = ({ data, onSelect }) => {
15 | const { name, image, description, price } = data.item;
16 |
17 | return (
18 | onSelect(data)}
21 | >
22 |
23 |
24 | {name}
25 | Western Foods
26 |
33 | $ 2.99
34 |
35 |
36 | );
37 | };
38 |
39 | const styles = StyleSheet.create({
40 | root: {
41 | flex: 1,
42 | height: "100%",
43 | display: "flex",
44 | flexDirection: "column",
45 | justifyContent: "flex-start",
46 | alignItems: "center",
47 | margin: 10,
48 | },
49 | foodImage: {
50 | borderRadius: 20,
51 | height: 250,
52 | width: deviceWidth - 40,
53 | backgroundColor: "red",
54 | justifyContent: "center",
55 | alignItems: "center",
56 | alignContent: "center",
57 | backgroundColor: "#581845",
58 | },
59 | title: {
60 | fontSize: 14,
61 | fontWeight: "500",
62 | width: "100%",
63 | display: "flex",
64 | justifyContent: "center",
65 | alignItems: "center",
66 | textAlign: "center",
67 | marginTop: 10,
68 | color: "#636363",
69 | },
70 | });
71 |
72 | const smallStyles = StyleSheet.create({
73 | smallCard: {
74 | flex: 1,
75 | height: 100,
76 | display: "flex",
77 | flexDirection: "row",
78 | justifyContent: "flex-start",
79 | backgroundColor: "white",
80 | borderColor: "#E5E5E5",
81 | borderWidth: 1,
82 | borderRadius: 10,
83 | margin: 10,
84 | },
85 |
86 | title: {
87 | fontSize: 22,
88 | fontWeight: "600",
89 | display: "flex",
90 | justifyContent: "center",
91 | alignItems: "center",
92 | },
93 | resturentTitle: {
94 | fontSize: 18,
95 | fontWeight: "400",
96 | display: "flex",
97 | color: "#565555",
98 | },
99 | price: {
100 | fontSize: 18,
101 | fontWeight: "400",
102 | display: "flex",
103 | color: "#EA5656",
104 | },
105 | foodImageSmall: {
106 | borderRadius: 10,
107 | height: 99,
108 | width: 99,
109 | justifyContent: "flex-start",
110 | alignItems: "center",
111 | backgroundColor: "#581845",
112 | alignSelf: "center",
113 | },
114 | rating: {
115 | alignSelf: "flex-start",
116 | },
117 | productInfo: {
118 | flex: 1,
119 | padding: 5,
120 | justifyContent: "space-around",
121 | },
122 | });
123 |
124 | export default OfferCard;
125 |
--------------------------------------------------------------------------------
/src/components/Cards/OrderCard.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | View,
4 | StyleSheet,
5 | Image,
6 | TouchableOpacity,
7 | Dimensions,
8 | } from 'react-native';
9 |
10 | import { Text, Rating } from 'react-native-elements';
11 | import moment from 'moment';
12 | import WaitingIcon from '../../images/orders.png';
13 | import AppButton from '../Buttons/AppButton';
14 |
15 | const deviceWidth = Math.round(Dimensions.get('window').width);
16 |
17 | const OrderCard = ({ data, onSelect, onCancel }) => {
18 | const {
19 | orderID,
20 | totalAmount,
21 | orderDate,
22 | paidThrough,
23 | orderStatus,
24 | items,
25 | } = data.item;
26 |
27 | const checkCancelOption = (orderDate) => {
28 | let date = moment(orderDate);
29 | var now = moment();
30 |
31 | if (now < date) {
32 | return (
33 |
42 | Delivered
43 |
44 | );
45 | } else {
46 | return (
47 |
53 | );
54 | }
55 | };
56 |
57 | return (
58 | onSelect(data)}
61 | >
62 |
63 |
70 | Order ID: {orderID}
71 |
72 | {moment(orderDate).format('MMM Do, h:mm a')}
73 |
74 | ₹{totalAmount}
75 |
76 |
84 | {checkCancelOption(orderDate)}
85 |
86 |
87 |
88 |
89 | );
90 | };
91 |
92 | const smallStyles = StyleSheet.create({
93 | smallCard: {
94 | flex: 1,
95 | height: 100,
96 | display: 'flex',
97 | flexDirection: 'row',
98 | justifyContent: 'flex-start',
99 | backgroundColor: 'white',
100 | borderColor: '#E5E5E5',
101 | borderWidth: 1,
102 | borderRadius: 10,
103 | margin: 10,
104 | },
105 |
106 | title: {
107 | fontSize: 22,
108 | display: 'flex',
109 | justifyContent: 'center',
110 | alignItems: 'center',
111 | },
112 | orderDateTitle: {
113 | marginTop: 5,
114 | fontSize: 18,
115 | fontWeight: '400',
116 | display: 'flex',
117 | color: '#565555',
118 | },
119 | price: {
120 | fontSize: 25,
121 | fontWeight: '600',
122 | display: 'flex',
123 | color: '#EA5656',
124 | marginTop: 5,
125 | },
126 | statusOnGoing: {
127 | height: 60,
128 | width: 60,
129 | justifyContent: 'flex-start',
130 | alignItems: 'center',
131 | alignSelf: 'center',
132 | },
133 | statusCompleted: {
134 | height: 80,
135 | width: 80,
136 | justifyContent: 'flex-start',
137 | alignItems: 'center',
138 | alignSelf: 'center',
139 | },
140 |
141 | rating: {
142 | alignSelf: 'flex-start',
143 | },
144 | productInfo: {
145 | display: 'flex',
146 | flex: 1,
147 | justifyContent: 'space-around',
148 | flexDirection: 'row',
149 | alignItems: 'center',
150 | },
151 | });
152 |
153 | export default OrderCard;
154 |
--------------------------------------------------------------------------------
/src/components/Cards/Restaurant.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | TouchableOpacity,
6 | Dimensions,
7 | Image,
8 | } from "react-native";
9 |
10 | import { Text, Rating } from "react-native-elements";
11 | import AppButton from "../Buttons/AppButton";
12 |
13 | import { urlImage } from "../../utils/AppConst";
14 |
15 | const deviceWidth = Math.round(Dimensions.get("window").width);
16 |
17 | const Restaurant = ({ size, data, onSelect, disable = false }) => {
18 | const { name, images, address, foodType } = data.item;
19 |
20 | let image = urlImage(images[0]);
21 |
22 | const mediumCard = () => {
23 | return (
24 |
25 | onSelect(data)}>
26 |
27 |
28 |
29 | );
30 | };
31 |
32 | const smallCard = () => {
33 | return (
34 | onSelect(data)}
37 | disabled={disable}
38 | >
39 |
40 |
41 | {name}
42 | Western Foods
43 |
50 | {price}
51 |
52 |
53 | Large
54 |
55 |
56 |
57 | );
58 | };
59 |
60 | switch (size) {
61 | case "small": // wide card
62 | return smallCard();
63 | case "medium": // medium card
64 | return mediumCard();
65 | default:
66 | return mediumCard();
67 | }
68 | };
69 |
70 | const styles = StyleSheet.create({
71 | root: {
72 | flex: 1,
73 | height: "100%",
74 | display: "flex",
75 | flexDirection: "column",
76 | justifyContent: "flex-start",
77 | alignItems: "center",
78 | margin: 10,
79 | },
80 | foodImage: {
81 | borderRadius: 20,
82 | height: 220,
83 | width: deviceWidth - 30,
84 | justifyContent: "center",
85 | alignItems: "center",
86 | alignContent: "center",
87 | },
88 | title: {
89 | fontSize: 14,
90 | fontWeight: "500",
91 | width: "100%",
92 | display: "flex",
93 | justifyContent: "center",
94 | alignItems: "center",
95 | textAlign: "center",
96 | marginTop: 10,
97 | color: "#636363",
98 | },
99 | });
100 |
101 | const smallStyles = StyleSheet.create({
102 | smallCard: {
103 | flex: 1,
104 | height: 100,
105 | display: "flex",
106 | flexDirection: "row",
107 | justifyContent: "flex-start",
108 | backgroundColor: "white",
109 | borderColor: "#E5E5E5",
110 | borderWidth: 1,
111 | borderRadius: 10,
112 | margin: 10,
113 | },
114 |
115 | title: {
116 | fontSize: 22,
117 | fontWeight: "600",
118 | display: "flex",
119 | justifyContent: "center",
120 | alignItems: "center",
121 | },
122 | resturentTitle: {
123 | fontSize: 18,
124 | fontWeight: "400",
125 | display: "flex",
126 | color: "#565555",
127 | },
128 | price: {
129 | fontSize: 18,
130 | fontWeight: "400",
131 | display: "flex",
132 | color: "#EA5656",
133 | },
134 | foodImageSmall: {
135 | borderRadius: 10,
136 | height: 99,
137 | width: 99,
138 | justifyContent: "flex-start",
139 | alignItems: "center",
140 | backgroundColor: "#581845",
141 | alignSelf: "center",
142 | },
143 | rating: {
144 | alignSelf: "flex-start",
145 | },
146 | productInfo: {
147 | flex: 1,
148 | padding: 5,
149 | justifyContent: "space-around",
150 | },
151 | shopView: {
152 | justifyContent: "space-between",
153 | padding: 10,
154 | alignItems: "center",
155 | },
156 | productSize: {
157 | fontSize: 20,
158 | fontWeight: "600",
159 | color: "#848484",
160 | },
161 | });
162 |
163 | export default Restaurant;
164 |
--------------------------------------------------------------------------------
/src/components/CategoryItem.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, Image, TouchableOpacity } from "react-native";
3 |
4 | import BurgerIcon from "../images/burger_icon.jpg";
5 |
6 | const CategoryItem = ({ data }) => {
7 | const { name, image } = data.item;
8 |
9 | return (
10 |
11 |
12 |
13 |
14 | {name}
15 |
16 | );
17 | };
18 |
19 | const styles = StyleSheet.create({
20 | root: {
21 | flex: 1,
22 | height: "100%",
23 | display: "flex",
24 | flexDirection: "column",
25 | justifyContent: "flex-start",
26 | alignItems: "center",
27 | margin: 10,
28 | },
29 | foodImage: {
30 | borderRadius: 20,
31 | height: 100,
32 | width: 100,
33 | backgroundColor: "red",
34 | justifyContent: "center",
35 | alignItems: "center",
36 | alignContent: "center",
37 | backgroundColor: "#581845",
38 | },
39 | title: {
40 | fontSize: 14,
41 | fontWeight: "500",
42 | width: "100%",
43 | display: "flex",
44 | justifyContent: "center",
45 | alignItems: "center",
46 | textAlign: "center",
47 | marginTop: 10,
48 | color: "#636363",
49 | },
50 | });
51 |
52 | export default CategoryItem;
53 |
--------------------------------------------------------------------------------
/src/components/FoodCartMedium.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | Image,
7 | TouchableOpacity,
8 | Dimensions,
9 | } from "react-native";
10 |
11 | const deviceWidth = Math.round(Dimensions.get("window").width);
12 |
13 | const Product = ({ data, onSelect }) => {
14 | const { name, image, description, price } = data.item;
15 |
16 | return (
17 |
18 | onSelect(data)}>
19 |
20 |
21 | {name}
22 |
23 | );
24 | };
25 |
26 | const styles = StyleSheet.create({
27 | root: {
28 | flex: 1,
29 | height: "100%",
30 | display: "flex",
31 | flexDirection: "column",
32 | justifyContent: "flex-start",
33 | alignItems: "center",
34 | margin: 10,
35 | },
36 | foodImage: {
37 | borderRadius: 20,
38 | height: 250,
39 | width: deviceWidth - 40,
40 | backgroundColor: "red",
41 | justifyContent: "center",
42 | alignItems: "center",
43 | alignContent: "center",
44 | backgroundColor: "#581845",
45 | },
46 | title: {
47 | fontSize: 14,
48 | fontWeight: "500",
49 | width: "100%",
50 | display: "flex",
51 | justifyContent: "center",
52 | alignItems: "center",
53 | textAlign: "center",
54 | marginTop: 10,
55 | color: "#636363",
56 | },
57 | });
58 |
59 | export default Product;
60 |
--------------------------------------------------------------------------------
/src/components/InputFields/SearchBar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { navigate } from "../../utils/NavigationRef";
3 | import { View, StyleSheet, Image, TextInput } from "react-native";
4 | import SearchIcon from "../../images/search.png";
5 |
6 | const SearchBar = ({ didTouch, isHome, onTextChange, onEndEditing }) => {
7 | return (
8 |
9 |
10 |
11 |
20 |
21 |
22 | );
23 | };
24 |
25 | const styles = StyleSheet.create({
26 | root: {
27 | flex: 1,
28 | height: 60,
29 | display: "flex",
30 | flexDirection: "row",
31 | justifyContent: "space-between",
32 | alignContent: "center",
33 | alignItems: "center",
34 | paddingLeft: 20,
35 | paddingRight: 20,
36 | },
37 | searchBar: {
38 | flex: 1,
39 | height: 42,
40 | display: "flex",
41 | flexDirection: "row",
42 | justifyContent: "space-between",
43 | backgroundColor: "#ededed",
44 | alignItems: "center",
45 | borderRadius: 20,
46 | paddingLeft: 10,
47 | paddingRight: 10,
48 | borderColor: "#E5E5E5",
49 | borderWidth: 2,
50 | },
51 |
52 | searchIcon: {
53 | width: 25,
54 | height: 25,
55 | },
56 | searchTextField: {
57 | marginLeft: 5,
58 | flex: 9,
59 | display: "flex",
60 | fontSize: 20,
61 | height: 42,
62 | },
63 | });
64 |
65 | export default SearchBar;
66 |
--------------------------------------------------------------------------------
/src/components/InputFields/UserLogin.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { View, StyleSheet, Alert } from "react-native";
3 | import { Input, Button } from "react-native-elements";
4 | import AppButton from "../Buttons/AppButton";
5 | import { navigate } from "../../utils/NavigationRef";
6 |
7 | const Spacer = ({ children }) => {
8 | return {children};
9 | };
10 |
11 | const UserLogin = ({ onSubmit, route, linkText, title, isSignup = false }) => {
12 | const [email, setEmail] = useState("");
13 | const [password, setPassword] = useState("");
14 | const [firstName, setFirstName] = useState("");
15 | const [lastName, setLastName] = useState("");
16 |
17 | const addSignUpFields = () => {
18 | if (isSignup) {
19 | return (
20 |
21 |
22 |
28 |
29 |
30 |
31 |
37 |
38 |
39 | );
40 | }
41 | };
42 |
43 | return (
44 |
45 |
46 |
52 |
53 |
54 |
61 |
62 | {addSignUpFields()}
63 |
64 | onSubmit({ email, password, firstName, lastName })}
68 | />
69 |
70 |
77 |
78 | );
79 | };
80 |
81 | const styles = StyleSheet.create({
82 | txtInputView: {
83 | marginTop: 10,
84 | marginBottom: 10,
85 | },
86 | spacer: {
87 | margin: 10,
88 | marginTop: 20,
89 | marginBottom: 20,
90 | },
91 | titleStyle: {
92 | fontSize: 18,
93 | fontWeight: "400",
94 | color: "#f15b5d",
95 | },
96 | });
97 |
98 | export default UserLogin;
99 |
--------------------------------------------------------------------------------
/src/components/Listview/CartListView.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, FlatList } from "react-native";
3 |
4 | import CartItem from "../Cards/CartItem";
5 |
6 | const CartListView = ({ onAddItem, onRemoveItem, cartItems }) => {
7 | return (
8 | (
12 |
18 | )}
19 | keyExtractor={(item) => item._id}
20 | />
21 | );
22 | };
23 |
24 | export default CartListView;
25 |
--------------------------------------------------------------------------------
/src/components/Listview/OrderListView.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, FlatList } from "react-native";
3 | import OrderCard from "../Cards/OrderCard";
4 | import FoodCard from "../Cards/FoodCard";
5 |
6 | const OrderListView = ({
7 | orders,
8 | size,
9 | horizontal,
10 | didSelectItem,
11 | onCancel,
12 | disable,
13 | details,
14 | }) => {
15 | return (
16 |
22 | details ? (
23 |
30 | ) : (
31 | didSelectItem(item)}
37 | onCancel={() => onCancel(item)}
38 | />
39 | )
40 | }
41 | keyExtractor={(item) => item._id}
42 | />
43 | );
44 | };
45 |
46 | export default OrderListView;
47 |
--------------------------------------------------------------------------------
/src/components/Listview/ProductListView.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, FlatList } from "react-native";
3 | import FoodCard from "../Cards/FoodCard";
4 |
5 | const ProductListView = ({
6 | foods,
7 | size,
8 | horizontal,
9 | didSelectItem,
10 | didAddToCart,
11 | didAddRemove,
12 | cartItems,
13 | disable,
14 | }) => {
15 | return (
16 | (
22 |
32 | )}
33 | keyExtractor={(item) => item._id}
34 | />
35 | );
36 | };
37 |
38 | export default ProductListView;
39 |
--------------------------------------------------------------------------------
/src/components/Overlay.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from 'react';
2 | import {
3 | Dimensions,
4 | View,
5 | LayoutAnimation,
6 | UIManager,
7 | Animated,
8 | Easing,
9 | Text,
10 | } from 'react-native';
11 |
12 | const Overlay = ({ isShow = false }) => {
13 | const fadeAnim = useRef(new Animated.Value(0)).current;
14 |
15 | useEffect(() => {
16 | Animated.loop(
17 | Animated.sequence([
18 | Animated.timing(fadeAnim, {
19 | toValue: 1,
20 | duration: 500,
21 | }),
22 | Animated.timing(fadeAnim, {
23 | toValue: 0,
24 | duration: 500,
25 | }),
26 | ]),
27 | {
28 | iterations: 100,
29 | }
30 | ).start();
31 | }, []);
32 |
33 | if (isShow) {
34 | return (
35 |
47 |
56 |
57 | Loading Please Wait...
58 |
59 |
60 |
61 | );
62 | } else {
63 | return null;
64 | }
65 | };
66 |
67 | export default Overlay;
68 |
--------------------------------------------------------------------------------
/src/components/TopCategoryList.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, FlatList } from "react-native";
3 | import CategoryItem from "./CategoryItem";
4 | import OfferIcon from "../images/offer.jpg";
5 | import BurgerIcon from "../images/burger.jpg";
6 | import PizzaIcon from "../images/pizza.jpg";
7 | import CoffeeIcon from "../images/coffee.jpeg";
8 | import LunchIcon from "../images/lunch.jpg";
9 |
10 | const categories = [
11 | { id: 1, name: "Offers", image: OfferIcon },
12 | { id: 2, name: "Burgers", image: BurgerIcon },
13 | { id: 3, name: "Pizzas", image: PizzaIcon },
14 | { id: 4, name: "Coffee", image: CoffeeIcon },
15 | { id: 5, name: "Meals", image: LunchIcon },
16 | ];
17 |
18 | const TopCategory = () => {
19 | onSelect = (item) => {
20 | console.log("Selected Item is", item);
21 | };
22 |
23 | return (
24 | }
29 | keyExtractor={(item) => item.id}
30 | />
31 | );
32 | };
33 |
34 | export default TopCategory;
35 |
--------------------------------------------------------------------------------
/src/dataStore/createAppContext.js:
--------------------------------------------------------------------------------
1 | import React, { useReducer } from "react";
2 |
3 | export default (reducer, actions, defaultValue) => {
4 | const Context = React.createContext();
5 |
6 | const Provider = ({ children }) => {
7 | const [state, dispatch] = useReducer(reducer, defaultValue);
8 | const boundActions = {};
9 | for (let key in actions) {
10 | boundActions[key] = actions[key](dispatch);
11 | }
12 |
13 | return (
14 |
15 | {children}
16 |
17 | );
18 | };
19 |
20 | return { Context, Provider };
21 | };
22 |
--------------------------------------------------------------------------------
/src/dataStore/reducer.js:
--------------------------------------------------------------------------------
1 | import { AsyncStorage } from "react-native";
2 | import aType from "../utils/ActionTypes";
3 |
4 | /**
5 | * Reducer
6 | */
7 | const userReducer = (state, action) => {
8 | console.log(action);
9 |
10 | switch (action.type) {
11 | case aType.LOGIN:
12 | saveToken(action.payload);
13 | return { ...state, token: action.payload };
14 | case aType.LOGOUT:
15 | clearStorage();
16 | return { token: null, msg: null, state };
17 | case aType.ALL_FOODS:
18 | return { ...state, foods: action.payload };
19 | case aType.TOP_RESTAURANTS:
20 | return {
21 | ...state,
22 | restaurants: action.payload,
23 | };
24 | case aType.VIEW_CART:
25 | return {
26 | ...state,
27 | cartItems: action.payload,
28 | };
29 | case aType.VIEW_ORDER:
30 | return {
31 | ...state,
32 | orders: action.payload,
33 | };
34 | case aType.ORDER_DETAILS:
35 | return {
36 | ...state,
37 | orderItems: action.payload,
38 | };
39 | case aType.CREATE_ORDER:
40 | return {
41 | ...state,
42 | cartItems: [],
43 | orders: action.payload,
44 | };
45 |
46 | case aType.ERROR:
47 | return {
48 | ...state,
49 | msg: action.payload,
50 | };
51 | case aType.DISSMISS:
52 | return {
53 | ...state,
54 | msg: null,
55 | };
56 | default:
57 | return state;
58 | }
59 | };
60 |
61 | const saveToken = async (token) => {
62 | await AsyncStorage.setItem("token", `Bearer ${token}`);
63 | };
64 |
65 | const clearStorage = async () => {
66 | await AsyncStorage.clear();
67 | };
68 |
69 | export default userReducer;
70 |
--------------------------------------------------------------------------------
/src/dataStore/userAccessContext.js:
--------------------------------------------------------------------------------
1 | import { AsyncStorage } from "react-native";
2 | import { navigate } from "../utils/NavigationRef";
3 | import createAppContext from "./createAppContext";
4 | import API from "../api/WebService";
5 | import aType from "../utils/ActionTypes";
6 | import userReducer from "./reducer";
7 |
8 | /**
9 | * User Actions
10 | */
11 |
12 | const onCheckAvailability = (dispatch) => async () => {
13 | try {
14 | const response = await API.get("/food");
15 | dispatch({ type: aType.ALL_FOODS, payload: response.data });
16 | } catch {
17 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
18 | }
19 | };
20 |
21 | const fetchTopRestaurants = (dispatch) => async () => {
22 | try {
23 | const response = await API.get("/food/top/restaurants");
24 | dispatch({ type: aType.TOP_RESTAURANTS, payload: response.data });
25 | } catch {
26 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
27 | }
28 | };
29 |
30 | const onViewCart = (dispatch) => () => {
31 | API.get("/user/cart")
32 | .then((response) => {
33 | dispatch({ type: aType.VIEW_CART, payload: response.data });
34 | })
35 | .catch((err) => {
36 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
37 | });
38 | };
39 |
40 | const onAddToCart = (dispatch) => (item, qty) => {
41 | console.log(item);
42 |
43 | if (qty !== undefined) {
44 | API.put(`/user/cart/${item._id}/${qty}`)
45 | .then((response) => {
46 | console.log(response);
47 | dispatch({ type: aType.VIEW_CART, payload: response.data });
48 | })
49 | .catch((err) => {
50 | dispatch({ type: aType.ERROR, payload: "Data Not found" + err });
51 | });
52 | } else {
53 | API.post("/user/cart/" + item._id)
54 | .then((response) => {
55 | console.log(response);
56 | dispatch({ type: aType.VIEW_CART, payload: response.data });
57 | })
58 | .catch((err) => {
59 | dispatch({ type: aType.ERROR, payload: "Data Not found" + err });
60 | });
61 | }
62 | };
63 |
64 | const onCreateOrder = (dispatch) => () => {
65 | API.post("/user/add-order")
66 | .then((response) => {
67 | dispatch({ type: aType.CREATE_ORDER, payload: response.data });
68 | navigate("Order");
69 | })
70 | .catch((err) => {
71 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
72 | });
73 | };
74 |
75 | const onViewOrders = (dispatch) => () => {
76 | API.get("/user/order")
77 | .then((response) => {
78 | dispatch({ type: aType.VIEW_ORDER, payload: response.data });
79 | })
80 | .catch((err) => {
81 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
82 | });
83 | };
84 |
85 | const onViewOrderDetails = (dispatch) => ({ _id }) => {
86 | API.get("/user/order/" + _id)
87 | .then((response) => {
88 | dispatch({ type: aType.ORDER_DETAILS, payload: response.data });
89 | navigate("OrderDetails");
90 | })
91 | .catch((err) => {
92 | dispatch({ type: aType.ERROR, payload: "Data Not found" });
93 | });
94 | };
95 |
96 | const onSignup = (dispatch) => async ({
97 | email,
98 | password,
99 | firstName,
100 | lastName,
101 | }) => {
102 | API.post("user/signup", {
103 | email,
104 | password,
105 | firstName,
106 | lastName,
107 | })
108 | .then((response) => {
109 | configureAPI({ token: `Bearer ${response.data}` });
110 | dispatch({ type: aType.LOGIN, payload: response.data });
111 | navigate("homeStack");
112 | })
113 | .catch((err) => {
114 | dispatch({
115 | type: aType.ERROR,
116 | payload: "Login Fail with provided Email ID and Password",
117 | });
118 | });
119 | };
120 |
121 | const onSignin = (dispatch) => async ({ email, password }) => {
122 | API.post("user/login", {
123 | email,
124 | password,
125 | })
126 | .then((response) => {
127 | configureAPI({ token: `Bearer ${response.data}` });
128 | dispatch({ type: aType.LOGIN, payload: response.data });
129 | navigate("homeStack");
130 | })
131 | .catch((err) => {
132 | dispatch({
133 | type: aType.ERROR,
134 | payload: "Login Fail with provided Email ID and Password",
135 | });
136 | });
137 | };
138 |
139 | const configureAPI = ({ token }) => {
140 | API.defaults.headers.common["Authorization"] = token;
141 | };
142 |
143 | const onCheckLogin = (dispatch) => async () => {
144 | const token = await AsyncStorage.getItem("token");
145 | if (token) {
146 | dispatch({ type: aType.LOGIN, payload: token });
147 | navigate("homeStack");
148 | configureAPI({ token });
149 | } else {
150 | navigate("loginStack");
151 | }
152 | };
153 |
154 | const onGetProfile = (dispatch) => async () => {
155 | try {
156 | } catch {}
157 | };
158 |
159 | const onLogout = (dispatch) => () => {
160 | navigate("loginStack");
161 | dispatch({ type: aType.LOGOUT });
162 | };
163 | const onDissmiss = (dispatch) => () => {
164 | dispatch({ type: aType.DISSMISS });
165 | };
166 |
167 | /**
168 | * Export Methods with Create Context
169 | */
170 | export const { Provider, Context } = createAppContext(
171 | userReducer,
172 | {
173 | onCheckAvailability,
174 | onCheckLogin,
175 | onSignup,
176 | onSignin,
177 | onLogout,
178 | fetchTopRestaurants,
179 | onAddToCart,
180 | onViewCart,
181 | onCreateOrder,
182 | onViewOrders,
183 | onViewOrderDetails,
184 | onDissmiss,
185 | },
186 | { accessToken: null, msg: null }
187 | );
188 |
--------------------------------------------------------------------------------
/src/images/account_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/account_icon.png
--------------------------------------------------------------------------------
/src/images/account_n_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/account_n_icon.png
--------------------------------------------------------------------------------
/src/images/arrow_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/arrow_icon.png
--------------------------------------------------------------------------------
/src/images/back_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/back_arrow.png
--------------------------------------------------------------------------------
/src/images/best_restaurent_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/best_restaurent_1.jpg
--------------------------------------------------------------------------------
/src/images/best_restaurent_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/best_restaurent_2.jpg
--------------------------------------------------------------------------------
/src/images/burger.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/burger.jpg
--------------------------------------------------------------------------------
/src/images/burger_icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/burger_icon.jpg
--------------------------------------------------------------------------------
/src/images/cart_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/cart_icon.png
--------------------------------------------------------------------------------
/src/images/cart_n_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/cart_n_icon.png
--------------------------------------------------------------------------------
/src/images/coffee.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/coffee.jpeg
--------------------------------------------------------------------------------
/src/images/cusin_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/cusin_1.jpg
--------------------------------------------------------------------------------
/src/images/cusin_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/cusin_2.jpg
--------------------------------------------------------------------------------
/src/images/cusin_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/cusin_3.jpg
--------------------------------------------------------------------------------
/src/images/hambar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/hambar.png
--------------------------------------------------------------------------------
/src/images/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/home.png
--------------------------------------------------------------------------------
/src/images/home_focused.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/home_focused.png
--------------------------------------------------------------------------------
/src/images/home_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/home_icon.png
--------------------------------------------------------------------------------
/src/images/home_n_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/home_n_icon.png
--------------------------------------------------------------------------------
/src/images/lunch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/lunch.jpg
--------------------------------------------------------------------------------
/src/images/offer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/offer.jpg
--------------------------------------------------------------------------------
/src/images/offer_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/offer_icon.png
--------------------------------------------------------------------------------
/src/images/offer_n_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/offer_n_icon.png
--------------------------------------------------------------------------------
/src/images/orders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/orders.png
--------------------------------------------------------------------------------
/src/images/pizza.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/pizza.jpg
--------------------------------------------------------------------------------
/src/images/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/search.png
--------------------------------------------------------------------------------
/src/images/starIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codergogoi/React_Native_Food_Order_App/2d335ea51570ea7ce72d9595e819a0289d9ec358/src/images/starIcon.png
--------------------------------------------------------------------------------
/src/screens/AuthCheckScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useContext } from "react";
2 | import { Context as UserAccessContext } from "../dataStore/userAccessContext";
3 |
4 | const AuthCheckScreen = () => {
5 | const { onCheckLogin } = useContext(UserAccessContext);
6 |
7 | useEffect(() => {
8 | onCheckLogin();
9 | }, []);
10 |
11 | return null;
12 | };
13 |
14 | export default AuthCheckScreen;
15 |
--------------------------------------------------------------------------------
/src/screens/foods/FoodDetails.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | TouchableOpacity,
6 | Image,
7 | Dimensions,
8 | ImageBackground,
9 | } from "react-native";
10 | import { SafeAreaView } from "react-navigation";
11 | import { Text, Button } from "react-native-elements";
12 | import BackIcon from "../../images/back_arrow.png";
13 | import ProductListView from "../../components/Listview/ProductListView";
14 | import { urlImage } from "../../utils/AppConst";
15 | import FoodCard from "../../components/Cards/FoodCard";
16 | import { Context as UserContext } from "../../dataStore/userAccessContext";
17 |
18 | const screenWidth = Dimensions.get("window").width;
19 |
20 | const ProductDetailScreen = ({ navigation }) => {
21 | const { state, onAddToCart } = useContext(UserContext);
22 |
23 | const { cartItems } = state;
24 | const { params } = navigation.state;
25 |
26 | const { _id, name, images, description, price } = params;
27 |
28 | let image = urlImage(images[0]);
29 |
30 | const item = { item: params };
31 |
32 | const didTapBack = () => {
33 | navigation.goBack();
34 | };
35 |
36 | const didAddToCard = (item) => {
37 | onAddToCart(item);
38 | };
39 |
40 | const didAddRemove = (item, qty) => {
41 | onAddToCart(item, qty);
42 | };
43 |
44 | return (
45 |
46 |
47 | didTapBack()}>
48 |
49 |
50 |
51 | {name}
52 |
53 |
54 |
55 |
61 |
62 |
63 | {name}
64 |
65 | {description}
66 |
67 |
68 |
69 |
70 | {}}
77 | onAddToCart={didAddToCard}
78 | didAddRemove={didAddRemove}
79 | />
80 |
81 |
82 |
83 | );
84 | };
85 |
86 | const styles = StyleSheet.create({
87 | contentView: {
88 | backgroundColor: "#F2F2F2",
89 | flex: 1,
90 | justifyContent: "space-between",
91 | },
92 | titleView: {
93 | flex: 1,
94 | flexDirection: "row",
95 | justifyContent: "flex-start",
96 | alignItems: "center",
97 | },
98 | listView: {
99 | flex: 11,
100 | },
101 | coverImage: {
102 | width: screenWidth,
103 | height: 300,
104 | justifyContent: "flex-end",
105 | },
106 |
107 | imgIcon: {
108 | width: 40,
109 | height: 50,
110 | },
111 | searchOptions: {
112 | display: "flex",
113 | height: 60,
114 | justifyContent: "space-around",
115 | flexDirection: "row",
116 | alignItems: "center",
117 | marginLeft: 10,
118 | },
119 | topCategory: {
120 | height: 100,
121 | backgroundColor: "green",
122 | },
123 |
124 | amountDetails: {
125 | flexDirection: "row",
126 | justifyContent: "space-between",
127 | padding: 10,
128 | margin: 5,
129 | },
130 | foodTitle: {
131 | color: "white",
132 | fontWeight: "700",
133 | },
134 | foodInfo: {
135 | height: 120,
136 | backgroundColor: "rgba(0,0,0,0.6)",
137 | padding: 10,
138 | },
139 | foodDetails: {
140 | fontSize: 18,
141 | color: "white",
142 | fontWeight: "400",
143 | },
144 | });
145 |
146 | ProductDetailScreen.navigationOptions = () => {
147 | return {
148 | header: null,
149 | };
150 | };
151 |
152 | export default ProductDetailScreen;
153 |
--------------------------------------------------------------------------------
/src/screens/foods/RestaurantDetails.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect } from "react";
2 | import {
3 | View,
4 | StyleSheet,
5 | TouchableOpacity,
6 | Image,
7 | Dimensions,
8 | ImageBackground,
9 | } from "react-native";
10 | import { SafeAreaView } from "react-navigation";
11 | import { Text, Button } from "react-native-elements";
12 | import BackIcon from "../../images/back_arrow.png";
13 | import ProductListView from "../../components/Listview/ProductListView";
14 | import { urlImage } from "../../utils/AppConst";
15 |
16 | import { Context as UserContext } from "../../dataStore/userAccessContext";
17 |
18 | const screenWidth = Dimensions.get("window").width;
19 |
20 | const RestaurantDetails = ({ navigation }) => {
21 | const { state, onAddToCart } = useContext(UserContext);
22 |
23 | const { cartItems } = state;
24 | const { params } = navigation.state;
25 |
26 | const {
27 | name,
28 | images,
29 | description,
30 | address,
31 | foodType,
32 | foods,
33 | pincode,
34 | } = params;
35 |
36 | const didTapBack = () => {
37 | navigation.goBack();
38 | };
39 |
40 | const didSelectItem = (item) => {
41 | console.log("Selected Item");
42 | };
43 |
44 | const didAddToCard = (item) => {
45 | onAddToCart(item);
46 | };
47 |
48 | const didAddRemove = (item, qty) => {
49 | onAddToCart(item, qty);
50 | };
51 | return (
52 |
53 |
54 | didTapBack()}>
55 |
56 |
57 |
58 | {name}
59 |
60 |
61 |
62 |
68 |
69 |
70 | {name}
71 |
72 |
80 | {address}, {pincode}
81 |
82 | {description}
83 |
84 |
85 |
94 |
95 |
96 | );
97 | };
98 |
99 | const styles = StyleSheet.create({
100 | contentView: {
101 | backgroundColor: "#F2F2F2",
102 | flex: 1,
103 | justifyContent: "space-between",
104 | },
105 | titleView: {
106 | flex: 1,
107 | flexDirection: "row",
108 | justifyContent: "flex-start",
109 | alignItems: "center",
110 | },
111 | listView: {
112 | flex: 11,
113 | },
114 | coverImage: {
115 | width: screenWidth,
116 | height: 300,
117 | justifyContent: "flex-end",
118 | },
119 |
120 | imgIcon: {
121 | width: 40,
122 | height: 50,
123 | },
124 | searchOptions: {
125 | display: "flex",
126 | height: 60,
127 | justifyContent: "space-around",
128 | flexDirection: "row",
129 | alignItems: "center",
130 | marginLeft: 10,
131 | },
132 | topCategory: {
133 | height: 100,
134 | backgroundColor: "green",
135 | },
136 |
137 | amountDetails: {
138 | flexDirection: "row",
139 | justifyContent: "space-between",
140 | padding: 10,
141 | margin: 5,
142 | },
143 | foodTitle: {
144 | color: "white",
145 | fontWeight: "700",
146 | },
147 | foodInfo: {
148 | height: 120,
149 | backgroundColor: "rgba(0,0,0,0.6)",
150 | padding: 10,
151 | },
152 | foodDetails: {
153 | fontSize: 18,
154 | color: "white",
155 | fontWeight: "400",
156 | },
157 | });
158 |
159 | RestaurantDetails.navigationOptions = () => {
160 | return {
161 | header: null,
162 | };
163 | };
164 |
165 | export default RestaurantDetails;
166 |
--------------------------------------------------------------------------------
/src/screens/foods/TopRestaurants.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, StyleSheet, FlatList } from "react-native";
3 |
4 | import Restaurant from "../../components/Cards/Restaurant";
5 |
6 | const TopRestaurants = ({
7 | restaurants,
8 | size,
9 | horizontal,
10 | didSelectItem,
11 | disable,
12 | }) => {
13 | const onSelectItem = ({ item }) => {
14 | didSelectItem(item);
15 | };
16 |
17 | return (
18 | (
24 |
30 | )}
31 | keyExtractor={(item) => item._id}
32 | />
33 | );
34 | };
35 |
36 | export default TopRestaurants;
37 |
--------------------------------------------------------------------------------
/src/screens/home/HomeScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect } from "react";
2 | import { View, StyleSheet, Image } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import SearchBar from "../../components/InputFields/SearchBar";
5 | import TopCategory from "../../components/TopCategoryList";
6 | import TopFoodList from "../../components/Listview/ProductListView";
7 | import { navigate } from "../../utils/NavigationRef";
8 | import { TouchableOpacity, ScrollView } from "react-native-gesture-handler";
9 | import HambarIcon from "../../images/hambar.png";
10 | import { Ionicons } from "@expo/vector-icons";
11 | import { Text } from "react-native-elements";
12 |
13 | //Context
14 | import { Context as UserContext } from "../../dataStore/userAccessContext";
15 | import TopRestaurants from "../foods/TopRestaurants";
16 |
17 | const HomeScreen = ({ navigation }) => {
18 | const { state, onCheckAvailability, fetchTopRestaurants } = useContext(
19 | UserContext
20 | );
21 |
22 | const { foods, restaurants } = state;
23 |
24 | /**
25 | * LifeCycle Methoda
26 | */
27 | useEffect(() => {
28 | fetchTopRestaurants();
29 | onCheckAvailability();
30 | }, []);
31 |
32 | /**
33 | * USER Actions
34 | */
35 | const didTapOptions = () => {
36 | console.log("Show Options");
37 | };
38 |
39 | const goToSearchPage = () => {
40 | navigate("Search");
41 | };
42 |
43 | const didSelectItem = (item) => {
44 | navigate("ProductDetail", item);
45 | };
46 |
47 | const didSelectRestaurant = (item) => {
48 | navigate("RestaurantDetail", item);
49 | };
50 |
51 | return (
52 |
53 |
54 |
55 | goToSearchPage()} isHome={true} />
56 | didTapOptions()}>
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Top Restaurants
65 |
66 |
67 | {restaurants == undefined ? (
68 |
77 | ) : (
78 |
84 | )}
85 |
86 |
87 |
88 | 30 Minutes Foods
89 |
90 |
91 | {foods == undefined ? (
92 |
101 | ) : (
102 |
108 | )}
109 |
110 |
111 |
112 | );
113 | };
114 |
115 | const styles = StyleSheet.create({
116 | imgIcon: {
117 | width: 50,
118 | height: 30,
119 | },
120 | searchOptions: {
121 | display: "flex",
122 | height: 60,
123 | justifyContent: "space-around",
124 | flexDirection: "row",
125 | alignItems: "center",
126 | marginRight: 10,
127 | },
128 | topCategory: {
129 | height: 100,
130 | backgroundColor: "#CACACA",
131 | },
132 | choiceView: {
133 | height: 40,
134 | marginLeft: 10,
135 | marginRight: 30,
136 | borderBottomColor: "rgba(0,0,0,0.2)",
137 | borderBottomWidth: 0.2,
138 | justifyContent: "flex-start",
139 | },
140 | choiceText: {
141 | fontWeight: "700",
142 | color: "#f15b5d",
143 | },
144 | });
145 |
146 | HomeScreen.navigationOptions = () => {
147 | return {
148 | header: null,
149 | tabBarLabel: "MyHome",
150 | tabBarIcon: ({ tintColor }) => (
151 |
152 | ),
153 | };
154 | };
155 |
156 | export default HomeScreen;
157 |
--------------------------------------------------------------------------------
/src/screens/home/OffersScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { View, StyleSheet } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text } from "react-native-elements";
5 |
6 | import FoodListView from "../../components/Listview/ProductListView";
7 |
8 | const OfferScreen = ({ navigation }) => {
9 | const onTapItem = (item) => {
10 | console.log(`Selected Item: ${item}`);
11 | };
12 |
13 | return (
14 |
18 |
19 |
20 | Available Offers
21 |
22 |
27 |
28 |
29 | );
30 | };
31 |
32 | const styles = StyleSheet.create({
33 | imgIcon: {
34 | width: 40,
35 | height: 50,
36 | },
37 | searchOptions: {
38 | display: "flex",
39 | height: 60,
40 | justifyContent: "space-around",
41 | flexDirection: "row",
42 | alignItems: "center",
43 | marginLeft: 10,
44 | },
45 | topCategory: {
46 | height: 100,
47 | backgroundColor: "green",
48 | },
49 | });
50 |
51 | OfferScreen.navigationOptions = () => {
52 | return {
53 | header: null,
54 | };
55 | };
56 |
57 | export default OfferScreen;
58 |
--------------------------------------------------------------------------------
/src/screens/home/SearchScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect, useState } from "react";
2 | import { View, StyleSheet, Text, Image } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import SearchBar from "../../components/InputFields/SearchBar";
5 | import BackIcon from "../../images/back_arrow.png";
6 | import { TouchableOpacity } from "react-native-gesture-handler";
7 | import { navigate } from "../../utils/NavigationRef";
8 | import FoodListView from "../../components/Listview/ProductListView";
9 |
10 | import { Context as UserContext } from "../../dataStore/userAccessContext";
11 |
12 | const SearchScreen = ({ navigation }) => {
13 | const { state, onCheckAvailability } = useContext(UserContext);
14 |
15 | const { foods, restaurants } = state;
16 |
17 | const [isEditing, setIsEditing] = useState(false);
18 | const [keyword, setKeyword] = useState("");
19 |
20 | const didTapBack = () => {
21 | navigation.goBack();
22 | };
23 |
24 | const onTapItem = (item) => {
25 | navigate("ProductDetail", item);
26 | };
27 |
28 | useEffect(() => {
29 | onCheckAvailability({ searchAll: true });
30 | }, []);
31 |
32 | const onTextChange = (text) => {
33 | setIsEditing(true);
34 | setKeyword(text);
35 | };
36 |
37 | const onEndEditing = () => {
38 | setIsEditing(false);
39 | };
40 |
41 | return (
42 |
43 |
44 |
45 | didTapBack()}>
46 |
47 |
48 |
49 |
50 |
51 |
52 | {
56 | return item.name.includes(keyword);
57 | })
58 | : foods
59 | }
60 | style={{ flex: 1 }}
61 | size={"small"}
62 | didSelectItem={() => {}}
63 | didAddToCart={() => {}}
64 | didAddRemove={() => {}}
65 | />
66 |
67 |
68 | );
69 | };
70 |
71 | const styles = StyleSheet.create({
72 | contentView: {
73 | backgroundColor: "#F2F2F2",
74 | flex: 1,
75 | justifyContent: "space-between",
76 | },
77 | titleView: {
78 | flex: 1,
79 | justifyContent: "center",
80 | alignItems: "center",
81 | },
82 | listView: {
83 | flex: 9,
84 | },
85 | imgIcon: {
86 | width: 40,
87 | height: 50,
88 | },
89 | searchOptions: {
90 | display: "flex",
91 | height: 60,
92 | justifyContent: "space-around",
93 | flexDirection: "row",
94 | alignItems: "center",
95 | marginLeft: 10,
96 | },
97 | topCategory: {
98 | height: 100,
99 | backgroundColor: "green",
100 | },
101 | });
102 |
103 | SearchScreen.navigationOptions = () => {
104 | return {
105 | header: null,
106 | };
107 | };
108 |
109 | export default SearchScreen;
110 |
--------------------------------------------------------------------------------
/src/screens/shoping/CartScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect, useRef } from "react";
2 | import { View, StyleSheet, Image } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text, Button } from "react-native-elements";
5 |
6 | import CartListView from "../../components/Listview/CartListView";
7 | import AppButton from "../../components/Buttons/AppButton";
8 | import { TouchableOpacity } from "react-native-gesture-handler";
9 |
10 | import { Context as UserContext } from "../../dataStore/userAccessContext";
11 | import { navigate } from "../../utils/NavigationRef";
12 | import OrderIcon from "../../images/orders.png";
13 | import PaymentTypePopup from "react-native-raw-bottom-sheet";
14 | import ArrowIcon from "../../images/arrow_icon.png";
15 |
16 | const CartScreen = ({ navigation }) => {
17 | const { state, onViewCart, onAddToCart, onCreateOrder } = useContext(
18 | UserContext
19 | );
20 |
21 | const { cartItems, orders } = state;
22 |
23 | const popupRef = useRef();
24 |
25 | useEffect(() => {
26 | console.log(orders);
27 | console.log("Goto Order Screen");
28 | }, [orders]);
29 |
30 | useEffect(() => {
31 | onViewCart();
32 | }, []);
33 |
34 | let isLoading = false;
35 |
36 | const didTapOrderNow = () => {
37 | isLoading = true;
38 | onCreateOrder();
39 | };
40 |
41 | const onAddItem = (item, qty) => {
42 | onAddToCart(item, qty);
43 | };
44 |
45 | const onRemoveItem = (item, qty) => {
46 | onAddToCart(item, qty);
47 | };
48 |
49 | const totalAmount = () => {
50 | let total = 0;
51 | if (cartItems !== undefined && cartItems.length > 0) {
52 | cartItems.map((item) => {
53 | let qty = item.qty;
54 | let price = item.food.price;
55 | total += qty * price;
56 | });
57 | }
58 |
59 | return total;
60 | };
61 |
62 | return (
63 |
64 |
65 | My Cart
66 | {
69 | navigate("Order");
70 | }}
71 | >
72 |
73 |
74 |
75 |
76 | {cartItems !== undefined && cartItems.length > 0 ? (
77 |
82 | ) : (
83 |
91 |
92 | Your Cart is Empty
93 |
94 |
95 | )}
96 |
97 | {cartItems !== undefined && cartItems.length > 0 && (
98 |
99 |
100 | Total
101 |
102 | ₹ {totalAmount()}
103 |
104 |
105 | popupRef.current.open()}
109 | />
110 |
111 | )}
112 |
130 |
138 |
139 | Total + (Delivery Charge ₹50)
140 |
141 | ₹ {totalAmount() + 50}
142 |
143 |
144 | {
146 | popupRef.current.close();
147 | didTapOrderNow();
148 | }}
149 | >
150 |
151 | Cash On Delivery
152 |
153 |
154 |
155 | {}}>
156 |
157 | Pay Through Card
158 |
159 |
160 |
161 | {}}>
162 |
163 |
166 | Change Delivery Address
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | );
175 | };
176 |
177 | const styles = StyleSheet.create({
178 | contentView: {
179 | backgroundColor: "#F2F2F2",
180 | flex: 1,
181 | justifyContent: "space-between",
182 | },
183 | titleView: {
184 | flex: 1,
185 | justifyContent: "space-between",
186 | alignItems: "center",
187 | flexDirection: "row",
188 | paddingLeft: 20,
189 | paddingRight: 20,
190 | },
191 | listView: {
192 | flex: 9,
193 | },
194 | bottomView: {
195 | flex: 2,
196 | },
197 |
198 | imgIcon: {
199 | width: 60,
200 | height: 60,
201 | },
202 | searchOptions: {
203 | display: "flex",
204 | height: 60,
205 | justifyContent: "space-around",
206 | flexDirection: "row",
207 | alignItems: "center",
208 | marginLeft: 10,
209 | },
210 | topCategory: {
211 | height: 100,
212 | backgroundColor: "green",
213 | },
214 |
215 | amountDetails: {
216 | flexDirection: "row",
217 | justifyContent: "space-between",
218 | padding: 10,
219 | margin: 5,
220 | },
221 | options: {
222 | display: "flex",
223 | height: 80,
224 | justifyContent: "space-between",
225 | alignItems: "center",
226 | flexDirection: "row",
227 | paddingLeft: 20,
228 | paddingRight: 20,
229 | borderTopColor: "#DFDFDF",
230 | borderTopWidth: 0.5,
231 | borderBottomColor: "#DFDFDF",
232 | borderBottomWidth: 0.5,
233 | },
234 | optionsText: {
235 | fontSize: 18,
236 | },
237 | icon: {
238 | width: 40,
239 | height: 40,
240 | },
241 | });
242 |
243 | CartScreen.navigationOptions = () => {
244 | return {
245 | header: null,
246 | };
247 | };
248 |
249 | export default CartScreen;
250 |
251 | /*
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 | */
261 |
--------------------------------------------------------------------------------
/src/screens/shoping/OrderDetails.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect } from "react";
2 | import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text, Button } from "react-native-elements";
5 | import OrderListView from "../../components/Listview/OrderListView";
6 | import BackIcon from "../../images/back_arrow.png";
7 | import moment from "moment";
8 |
9 | import { Context as UserContext } from "../../dataStore/userAccessContext";
10 |
11 | const OrderDetails = ({ navigation }) => {
12 | const { state } = useContext(UserContext);
13 |
14 | const { orderItems } = state;
15 |
16 | const didTapBack = () => {
17 | navigation.goBack();
18 | };
19 |
20 | return (
21 |
22 |
23 | didTapBack()}>
24 |
25 |
26 |
27 | Order ID: {orderItems.orderID}
28 |
29 |
30 |
31 |
38 |
39 | Order Date:
40 | {moment(orderItems.orderDate).format("MMM Do, h:mm a")}
41 |
42 |
43 | Order Amount: {orderItems.totalAmount}
44 |
45 | Status: {orderItems.orderStatus}
46 |
47 |
48 |
49 |
50 | );
51 | };
52 |
53 | const styles = StyleSheet.create({
54 | contentView: {
55 | backgroundColor: "#F2F2F2",
56 | flex: 1,
57 | justifyContent: "space-between",
58 | },
59 | titleView: {
60 | flex: 1,
61 | justifyContent: "center",
62 | alignItems: "center",
63 | flexDirection: "row",
64 | paddingLeft: 20,
65 | paddingRight: 20,
66 | },
67 | listView: {
68 | flex: 9,
69 | },
70 | bottomView: {
71 | flex: 2,
72 | },
73 |
74 | imgIcon: {
75 | width: 40,
76 | height: 50,
77 | },
78 | searchOptions: {
79 | display: "flex",
80 | height: 60,
81 | justifyContent: "space-around",
82 | flexDirection: "row",
83 | alignItems: "center",
84 | marginLeft: 10,
85 | },
86 | topCategory: {
87 | height: 100,
88 | backgroundColor: "green",
89 | },
90 |
91 | amountDetails: {
92 | flexDirection: "row",
93 | justifyContent: "space-between",
94 | padding: 10,
95 | margin: 5,
96 | },
97 | details: {
98 | fontSize: 20,
99 | color: "#4D4B4B",
100 | },
101 | });
102 |
103 | OrderDetails.navigationOptions = () => {
104 | return {
105 | header: null,
106 | };
107 | };
108 |
109 | export default OrderDetails;
110 |
--------------------------------------------------------------------------------
/src/screens/shoping/OrderScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect, useRef } from "react";
2 | import { View, StyleSheet, Image, TouchableOpacity } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text, Button } from "react-native-elements";
5 | import OrderListView from "../../components/Listview/OrderListView";
6 | import BackIcon from "../../images/back_arrow.png";
7 |
8 | import { Context as UserContext } from "../../dataStore/userAccessContext";
9 |
10 | const OrderScreen = ({ navigation }) => {
11 | const { state, onViewOrders, onViewOrderDetails } = useContext(UserContext);
12 |
13 | const { orders } = state;
14 |
15 | useEffect(() => {
16 | onViewOrders();
17 | }, []);
18 |
19 | const didSelect = ({ item }) => {
20 | onViewOrderDetails(item);
21 | };
22 |
23 | const onCancel = ({ item }) => {
24 | console.log(item);
25 | };
26 |
27 | const didTapBack = () => {
28 | navigation.goBack();
29 | };
30 |
31 | return (
32 |
33 |
34 | didTapBack()}>
35 |
36 |
37 |
38 | My Orders
39 |
40 |
41 | {orders !== undefined && orders.length > 0 ? (
42 |
43 |
48 |
49 | ) : (
50 |
51 |
59 |
60 | Your Order is Empty
61 |
62 |
63 |
64 | )}
65 |
66 | );
67 | };
68 |
69 | const styles = StyleSheet.create({
70 | contentView: {
71 | backgroundColor: "#F2F2F2",
72 | flex: 1,
73 | justifyContent: "space-between",
74 | },
75 | titleView: {
76 | flex: 1,
77 | justifyContent: "center",
78 | alignItems: "center",
79 | flexDirection: "row",
80 | paddingLeft: 20,
81 | paddingRight: 20,
82 | },
83 | listView: {
84 | flex: 9,
85 | },
86 | bottomView: {
87 | flex: 2,
88 | },
89 |
90 | imgIcon: {
91 | width: 40,
92 | height: 50,
93 | },
94 | searchOptions: {
95 | display: "flex",
96 | height: 60,
97 | justifyContent: "space-around",
98 | flexDirection: "row",
99 | alignItems: "center",
100 | marginLeft: 10,
101 | },
102 | topCategory: {
103 | height: 100,
104 | backgroundColor: "green",
105 | },
106 |
107 | amountDetails: {
108 | flexDirection: "row",
109 | justifyContent: "space-between",
110 | padding: 10,
111 | margin: 5,
112 | },
113 | });
114 |
115 | OrderScreen.navigationOptions = () => {
116 | return {
117 | header: null,
118 | };
119 | };
120 |
121 | export default OrderScreen;
122 |
--------------------------------------------------------------------------------
/src/screens/shoping/PaymentScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { View, StyleSheet, Image } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text, Button } from "react-native-elements";
5 |
6 | import CartListView from "../../components/Listview/CartListView";
7 | import AppButton from "../../components/Buttons/AppButton";
8 | import { TouchableOpacity } from "react-native-gesture-handler";
9 |
10 | import OrderIcon from "../../images/orders.png";
11 |
12 | const PaymentScreen = ({ navigation }) => {
13 | const onTapItem = (item) => {
14 | console.log(`Selected Item: ${item}`);
15 | };
16 |
17 | let isLoading = false;
18 |
19 | const didTapOrderNow = () => {
20 | isLoading = true;
21 | console.log("isLoading");
22 | };
23 |
24 | const didChangeItems = (item) => {
25 | console.log(`API level Operation ${JSON.stringify(item)}`);
26 | };
27 |
28 | return (
29 |
30 |
31 | My Cart
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | Total
42 | $200.00
43 |
44 |
45 |
46 |
47 | );
48 | };
49 |
50 | const styles = StyleSheet.create({
51 | contentView: {
52 | backgroundColor: "#F2F2F2",
53 | flex: 1,
54 | justifyContent: "space-between",
55 | },
56 | titleView: {
57 | flex: 1,
58 | justifyContent: "space-between",
59 | alignItems: "center",
60 | flexDirection: "row",
61 | paddingLeft: 20,
62 | paddingRight: 20,
63 | },
64 | listView: {
65 | flex: 9,
66 | },
67 | bottomView: {
68 | flex: 2,
69 | },
70 |
71 | imgIcon: {
72 | width: 60,
73 | height: 60,
74 | },
75 | searchOptions: {
76 | display: "flex",
77 | height: 60,
78 | justifyContent: "space-around",
79 | flexDirection: "row",
80 | alignItems: "center",
81 | marginLeft: 10,
82 | },
83 | topCategory: {
84 | height: 100,
85 | backgroundColor: "green",
86 | },
87 |
88 | amountDetails: {
89 | flexDirection: "row",
90 | justifyContent: "space-between",
91 | padding: 10,
92 | margin: 5,
93 | },
94 | });
95 |
96 | PaymentScreen.navigationOptions = () => {
97 | return {
98 | header: null,
99 | };
100 | };
101 |
102 | export default PaymentScreen;
103 |
--------------------------------------------------------------------------------
/src/screens/user/AccountScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useEffect } from "react";
2 | import { View, StyleSheet, ActivityIndicator, Image } from "react-native";
3 | import { SafeAreaView } from "react-navigation";
4 | import { Text, Button } from "react-native-elements";
5 | import ArrowIcon from "../../images/arrow_icon.png";
6 |
7 | import { Context as UserAccessConext } from "../../dataStore/userAccessContext";
8 | import { TouchableOpacity } from "react-native-gesture-handler";
9 | import { navigate } from "../../utils/NavigationRef";
10 |
11 | const AccountScreen = () => {
12 | const { onLogout } = useContext(UserAccessConext);
13 |
14 | return (
15 |
16 |
17 |
18 |
24 |
25 |
26 | Jayanta Gogoi
27 |
28 | codergogoi@gmail.com
29 |
30 |
31 |
32 |
33 | {/* view Orders */}
34 | navigate("Order")}>
35 |
36 | View Orders
37 |
38 |
39 |
40 | {/* View Payment Methods */}
41 | {}}>
42 |
43 | Payment Options
44 |
45 |
46 |
47 | {/* Edit Profile */}
48 | {}}>
49 |
50 | Edit Profile
51 |
52 |
53 |
54 | {/* Contact Us */}
55 | {}}>
56 |
57 | Contact Support
58 |
59 |
60 |
61 | {/* Logout */}
62 |
63 |
64 | Signout
65 |
66 |
67 |
68 |
69 |
70 | );
71 | };
72 |
73 | const styles = StyleSheet.create({
74 | contentView: {
75 | backgroundColor: "#F2F2F2",
76 | flex: 1,
77 | justifyContent: "space-between",
78 | },
79 | titleView: {
80 | flex: 2,
81 | justifyContent: "center",
82 | alignItems: "center",
83 | justifyContent: "space-between",
84 | },
85 | listView: {
86 | flex: 9,
87 | backgroundColor: "white",
88 | },
89 | bottomView: {
90 | flex: 1,
91 | },
92 | icon: {
93 | width: 40,
94 | height: 40,
95 | },
96 | imageStyle: {
97 | width: 100,
98 | height: 100,
99 | borderRadius: 50,
100 | },
101 | profileView: {
102 | margin: 10,
103 | padding: 10,
104 | flex: 1,
105 | width: "90%",
106 | flexDirection: "row",
107 | alignItems: "center",
108 | },
109 | options: {
110 | display: "flex",
111 | height: 80,
112 | justifyContent: "space-between",
113 | alignItems: "center",
114 | flexDirection: "row",
115 | paddingLeft: 20,
116 | paddingRight: 20,
117 | borderTopColor: "#DFDFDF",
118 | borderTopWidth: 0.5,
119 | borderBottomColor: "#DFDFDF",
120 | borderBottomWidth: 0.5,
121 | },
122 | optionsText: {
123 | fontSize: 18,
124 | },
125 | signoutButton: {
126 | marginTop: 7,
127 | width: 300,
128 | height: 50,
129 | backgroundColor: "#A3A2A2",
130 | alignSelf: "center",
131 | borderRadius: 30,
132 | },
133 | titleStyle: {
134 | fontSize: 18,
135 | fontWeight: "600",
136 | color: "white",
137 | marginTop: 3,
138 | },
139 | });
140 |
141 | export default AccountScreen;
142 |
--------------------------------------------------------------------------------
/src/screens/user/SigninScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState, useEffect } from 'react';
2 | import { View, StyleSheet, Alert, Dimensions } from 'react-native';
3 | import { SafeAreaView } from 'react-navigation';
4 | import { Text, Input } from 'react-native-elements';
5 | import { Context as UserContext } from '../../dataStore/userAccessContext';
6 | import UserLogin from '../../components/InputFields/UserLogin';
7 | import Overlay from '../../components/Overlay';
8 |
9 | const SigninScreen = () => {
10 | const { state, onSignin, onDissmiss } = useContext(UserContext);
11 |
12 | const { msg } = state;
13 |
14 | const [isLoading, setIsLoading] = useState(false);
15 |
16 | useEffect(() => {
17 | showAlert();
18 | setIsLoading(false);
19 | }, [msg]);
20 |
21 | const showAlert = () => {
22 | if (msg !== null) {
23 | Alert.alert(
24 | 'Login',
25 | `${msg}`,
26 | [{ text: 'Okay', onPress: () => onDissmiss }],
27 | {
28 | cancelable: false,
29 | }
30 | );
31 | }
32 | };
33 |
34 | return (
35 |
36 |
37 |
38 | Signin
39 |
40 |
41 | {
43 | setIsLoading(true);
44 | onSignin({ email, password });
45 | }}
46 | route="Signup"
47 | linkText="New User? Signup Here"
48 | title="Sign In"
49 | />
50 |
51 |
52 | Copyright@ Jayanta Gogoi 2020
53 |
54 |
55 | );
56 | };
57 |
58 | const styles = StyleSheet.create({
59 | contentView: {
60 | backgroundColor: '#F2F2F2',
61 | flex: 1,
62 | justifyContent: 'space-between',
63 | },
64 | titleView: {
65 | flex: 2,
66 | justifyContent: 'space-between',
67 | alignItems: 'center',
68 | flexDirection: 'row',
69 | paddingLeft: 20,
70 | paddingRight: 20,
71 | },
72 | listView: {
73 | paddingTop: 50,
74 | flex: 6,
75 | },
76 | bottomView: {
77 | flex: 2,
78 | alignItems: 'center',
79 | justifyContent: 'flex-end',
80 | paddingBottom: 20,
81 | },
82 | });
83 |
84 | SigninScreen.navigationOptions = () => {
85 | return {
86 | headerShown: false,
87 | };
88 | };
89 |
90 | export default SigninScreen;
91 |
--------------------------------------------------------------------------------
/src/screens/user/SignupScreen.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState, useEffect } from 'react';
2 | import { View, StyleSheet } from 'react-native';
3 | import { SafeAreaView } from 'react-navigation';
4 | import { Text, Input } from 'react-native-elements';
5 | import { Context as UserContext } from '../../dataStore/userAccessContext';
6 | import UserLogin from '../../components/InputFields/UserLogin';
7 | import Overlay from '../../components/Overlay';
8 |
9 | const SignupScreen = () => {
10 | const { state, onSignup } = useContext(UserContext);
11 | const [isLoading, setIsLoading] = useState(false);
12 |
13 | const { msg } = state;
14 |
15 | useEffect(() => {
16 | setIsLoading(false);
17 | }, [msg]);
18 |
19 | return (
20 |
21 |
22 |
23 | Signup
24 |
25 |
26 | {
29 | setIsLoading(true);
30 | onSignup({ email, password, firstName, lastName });
31 | }}
32 | route="Signin"
33 | linkText="Already Registred? Login Here"
34 | title="Sign up"
35 | />
36 |
37 |
38 | Copyright@ Jayanta Gogoi 2020
39 |
40 |
41 | );
42 | };
43 |
44 | const styles = StyleSheet.create({
45 | contentView: {
46 | backgroundColor: '#F2F2F2',
47 | flex: 1,
48 | justifyContent: 'space-between',
49 | },
50 | titleView: {
51 | flex: 2,
52 | justifyContent: 'space-between',
53 | alignItems: 'center',
54 | flexDirection: 'row',
55 | paddingLeft: 20,
56 | paddingRight: 20,
57 | },
58 | listView: {
59 | paddingTop: 50,
60 | flex: 6,
61 | },
62 | bottomView: {
63 | flex: 2,
64 | alignItems: 'center',
65 | justifyContent: 'flex-end',
66 | paddingBottom: 20,
67 | },
68 | });
69 |
70 | SignupScreen.navigationOptions = () => {
71 | return {
72 | headerShown: false,
73 | };
74 | };
75 |
76 | export default SignupScreen;
77 |
--------------------------------------------------------------------------------
/src/utils/ActionTypes.js:
--------------------------------------------------------------------------------
1 | const Action = {
2 | ERROR: "Error",
3 | LOGIN: "login",
4 | LOGOUT: "LOGOUT",
5 | SIGNUP: "signup",
6 | DISSMISS: "dismiss",
7 |
8 | ALL_FOODS: "view_all",
9 | TOP_RESTAURANTS: "top_restaurants",
10 | VIEW_CART: "view_cart",
11 | VIEW_ORDER: "view_Order",
12 | CREATE_ORDER: "create_Order",
13 | ORDER_DETAILS: "order_details",
14 | };
15 |
16 | export default Action;
17 |
--------------------------------------------------------------------------------
/src/utils/AppConst.js:
--------------------------------------------------------------------------------
1 | exports.urlImage = (img) => {
2 | return `https://online-foods.herokuapp.com/images/${img}`;
3 | };
4 |
--------------------------------------------------------------------------------
/src/utils/NavigationRef.js:
--------------------------------------------------------------------------------
1 | import { NavigationActions } from 'react-navigation';
2 |
3 | let navigator;
4 |
5 | export const setNavigator = (nav) => {
6 | navigator = nav;
7 | };
8 |
9 | export const navigate = (routeName, params) => {
10 | navigator.dispatch(NavigationActions.navigate({ routeName, params }));
11 | };
12 |
--------------------------------------------------------------------------------