├── .expo └── settings.json ├── .gitignore ├── .vscode └── settings.json ├── App.js ├── __tests__ └── App-test.js ├── android ├── app │ ├── BUCK │ ├── build.gradle │ ├── build_defs.bzl │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── foodnet │ │ │ └── ReactNativeFlipper.java │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── index.android.bundle │ │ ├── java │ │ └── com │ │ │ └── foodnet │ │ │ ├── MainActivity.java │ │ │ └── MainApplication.java │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios ├── Podfile ├── Podfile.lock ├── foodnet-tvOS │ └── Info.plist ├── foodnet-tvOSTests │ └── Info.plist ├── foodnet.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── foodnet-tvOS.xcscheme │ │ └── foodnet.xcscheme ├── foodnet.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── foodnet │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── hu.lproj │ │ ├── LaunchScreen.storyboard │ │ └── LaunchScreen.strings │ ├── main.m │ └── ro.lproj │ │ ├── LaunchScreen.storyboard │ │ └── LaunchScreen.strings └── foodnetTests │ ├── Info.plist │ └── foodnetTests.m ├── metro.config.js ├── package-lock.json ├── package.json ├── src ├── assets │ ├── icons │ │ ├── Left Accessory.svg │ │ ├── Vector.svg │ │ ├── alert-circle.svg │ │ ├── alert-circle1.svg │ │ ├── back.svg │ │ ├── check-circle.svg │ │ ├── check-circle1.svg │ │ ├── clipboard.svg │ │ ├── filter.svg │ │ ├── flag.svg │ │ ├── foodnet-logo 1.svg │ │ ├── google.svg │ │ ├── help-circle.svg │ │ ├── hungary.png │ │ ├── loader.gif │ │ ├── logo-big.png │ │ ├── logo.svg │ │ ├── map-pin-grey.svg │ │ ├── map-pin.svg │ │ ├── percent.svg │ │ ├── reply_24px_outlined.svg │ │ ├── romania.png │ │ ├── search.svg │ │ ├── shopping-bag.svg │ │ ├── shopping-bag1.svg │ │ ├── star.svg │ │ ├── star2.svg │ │ ├── trash-2.svg │ │ ├── trash-5.svg │ │ ├── united-states.png │ │ └── user.svg │ ├── images │ │ ├── background.jpg │ │ ├── bg.jpg │ │ ├── loader1.gif │ │ ├── loaderimg.gif │ │ └── pizza.png │ ├── languages │ │ ├── en.json │ │ ├── hu.json │ │ └── ro.json │ ├── nodes │ │ ├── @codler.zip │ │ ├── react-native-code-input.zip │ │ ├── react-native-material-textfield.zip │ │ ├── react-native-swiper.zip │ │ └── react-native-tab-view.zip │ ├── package.json │ └── screens │ │ ├── Forgot.js │ │ └── temp.json ├── components │ ├── Athena │ │ ├── Card.js │ │ ├── Loading.js │ │ └── Picker.js │ ├── Cities.js │ ├── Dashboard │ │ ├── Featured.js │ │ ├── Filters.js │ │ ├── Result.js │ │ ├── Trendy.js │ │ └── index.js │ ├── Restaurant │ │ ├── Information.js │ │ ├── Menu.js │ │ ├── MenuS.js │ │ └── Reviews.js │ ├── Splash.js │ ├── index.js │ └── package.json ├── constants │ ├── assets.js │ ├── configs.js │ ├── package.json │ ├── regexs.js │ ├── svgs.js │ └── themes.js ├── modules │ ├── index.js │ ├── package.json │ ├── reducers │ │ ├── auth │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── types.js │ │ ├── food │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── types.js │ │ └── profile │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ └── types.js │ ├── services │ │ ├── AuthService.js │ │ ├── FoodService.js │ │ ├── ProfileService.js │ │ └── index.js │ └── stores │ │ ├── AuthStore.js │ │ └── index.js ├── navigations │ ├── DrawerNavigator.js │ ├── StackNavigators │ │ ├── AuthStackNavigator.js │ │ ├── CartStackNavigator.js │ │ ├── DeliveryStackNavigator.js │ │ ├── HomeStackNavigator.js │ │ ├── OrderStackNavigator.js │ │ └── ProfileStackNavigator.js │ ├── index.js │ └── package.json ├── screens │ ├── Athena │ │ ├── Errors.js │ │ ├── Internet.js │ │ ├── Languages.js │ │ └── Success.js │ ├── Auth │ │ ├── Cities.js │ │ ├── Forgot.js │ │ ├── Reset.js │ │ ├── SignIn.js │ │ ├── SignUp.js │ │ └── index.js │ ├── Cart │ │ ├── CartDetail.js │ │ └── CartIndex.js │ ├── Delivery │ │ ├── DeliveryAdd.js │ │ └── DeliveryList.js │ ├── Home │ │ ├── Detail.js │ │ ├── Details.js │ │ ├── Extra.js │ │ └── index.js │ ├── Order │ │ ├── OrderDetail.js │ │ ├── OrderIndex.js │ │ └── OrderSuccess.js │ ├── Profile │ │ ├── CouponCodes.js │ │ ├── ProfileDelete.js │ │ ├── ProfileEdit.js │ │ ├── ProfilePassword.js │ │ └── index.js │ ├── Review │ │ ├── ReviewAdd.js │ │ ├── ReviewDelete.js │ │ └── ReviewList.js │ ├── index.js │ └── package.json └── utils │ ├── axios.js │ ├── functions.js │ ├── i18n.js │ └── package.json └── yarn.lock /.expo/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "hostType": "lan", 3 | "lanType": "ip", 4 | "dev": true, 5 | "minify": false, 6 | "urlRandomness": null, 7 | "https": false 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | yarn-error.log 37 | 38 | # BUCK 39 | buck-out/ 40 | \.buckd/ 41 | *.keystore 42 | !debug.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # CocoaPods 59 | /ios/Pods/ 60 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "compile-hero.disable-compile-files-on-did-save-code": false 3 | } -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { LogBox } from 'react-native'; 3 | import { Provider } from 'react-redux'; 4 | import { PersistGate } from 'redux-persist/integration/react'; 5 | import { store, persistor } from '@modules'; 6 | import AppContainer from '@navigations'; 7 | import { Splash } from '@components'; 8 | 9 | import i18n from '@utils/i18n'; 10 | 11 | i18n.setI18nConfig(); 12 | LogBox.ignoreAllLogs(true); 13 | 14 | global.internet = true; 15 | 16 | export default App = () => { 17 | const [splash, setSplash] = useState(true); 18 | 19 | setTimeout(() => setSplash(false), 1000); 20 | 21 | return ( 22 | 23 | 24 | {splash ? : } 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.foodnet", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.foodnet", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/debug.keystore -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/debug/java/com/foodnet/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.foodnet; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin; 21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | public class ReactNativeFlipper { 28 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 29 | if (FlipperUtils.shouldEnableFlipper(context)) { 30 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 31 | 32 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 33 | client.addPlugin(new ReactFlipperPlugin()); 34 | client.addPlugin(new DatabasesFlipperPlugin(context)); 35 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 36 | client.addPlugin(CrashReporterPlugin.getInstance()); 37 | 38 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 39 | NetworkingModule.setCustomClientBuilder( 40 | new NetworkingModule.CustomClientBuilder() { 41 | @Override 42 | public void apply(OkHttpClient.Builder builder) { 43 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 44 | } 45 | }); 46 | client.addPlugin(networkFlipperPlugin); 47 | client.start(); 48 | 49 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 50 | // Hence we run if after all native modules have been initialized 51 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 52 | if (reactContext == null) { 53 | reactInstanceManager.addReactInstanceEventListener( 54 | new ReactInstanceManager.ReactInstanceEventListener() { 55 | @Override 56 | public void onReactContextInitialized(ReactContext reactContext) { 57 | reactInstanceManager.removeReactInstanceEventListener(this); 58 | reactContext.runOnNativeModulesQueueThread( 59 | new Runnable() { 60 | @Override 61 | public void run() { 62 | client.addPlugin(new FrescoFlipperPlugin()); 63 | } 64 | }); 65 | } 66 | }); 67 | } else { 68 | client.addPlugin(new FrescoFlipperPlugin()); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/foodnet/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.foodnet; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "foodnet"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/foodnet/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.foodnet; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.reactnativecommunity.netinfo.NetInfoPackage; 8 | import com.facebook.react.ReactInstanceManager; 9 | import com.facebook.react.ReactNativeHost; 10 | import com.facebook.react.ReactPackage; 11 | import com.facebook.soloader.SoLoader; 12 | import java.lang.reflect.InvocationTargetException; 13 | import java.util.List; 14 | 15 | public class MainApplication extends Application implements ReactApplication { 16 | 17 | private final ReactNativeHost mReactNativeHost = 18 | new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | @SuppressWarnings("UnnecessaryLocalVariable") 27 | List packages = new PackageList(this).getPackages(); 28 | // Packages that cannot be autolinked yet can be added manually here, for example: 29 | // packages.add(new MyReactNativePackage()); 30 | return packages; 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 49 | } 50 | 51 | /** 52 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like 53 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 54 | * 55 | * @param context 56 | * @param reactInstanceManager 57 | */ 58 | private static void initializeFlipper( 59 | Context context, ReactInstanceManager reactInstanceManager) { 60 | if (BuildConfig.DEBUG) { 61 | try { 62 | /* 63 | We use reflection here to pick up the class that initializes Flipper, 64 | since Flipper library is not available in release mode 65 | */ 66 | Class aClass = Class.forName("com.foodnet.ReactNativeFlipper"); 67 | aClass 68 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) 69 | .invoke(null, context, reactInstanceManager); 70 | } catch (ClassNotFoundException e) { 71 | e.printStackTrace(); 72 | } catch (NoSuchMethodException e) { 73 | e.printStackTrace(); 74 | } catch (IllegalAccessException e) { 75 | e.printStackTrace(); 76 | } catch (InvocationTargetException e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Foodnet 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "29.0.2" 6 | minSdkVersion = 16 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | mavenLocal() 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | 33 | google() 34 | jcenter() 35 | maven { url 'https://www.jitpack.io' } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.54.0 29 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | @rem Execute Gradle 88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 89 | 90 | :end 91 | @rem End local scope for the variables with windows NT shell 92 | if "%ERRORLEVEL%"=="0" goto mainEnd 93 | 94 | :fail 95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 96 | rem the _cmd.exe /c_ return code! 97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 98 | exit /b 1 99 | 100 | :mainEnd 101 | if "%OS%"=="Windows_NT" endlocal 102 | 103 | :omega 104 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'foodnet' 2 | include ':@react-native-community_netinfo' 3 | project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android') 4 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 5 | include ':app' 6 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foodnet", 3 | "displayName": "foodnet" 4 | } -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '10.0' 5 | 6 | target 'foodnet' do 7 | config = use_native_modules! 8 | 9 | use_react_native!(:path => config["reactNativePath"]) 10 | 11 | pod 'react-native-netinfo', :path => '../node_modules/@react-native-community/netinfo' 12 | 13 | target 'foodnetTests' do 14 | inherit! :complete 15 | # Pods for testing 16 | end 17 | 18 | # Enables Flipper. 19 | # 20 | # Note that if you have use_frameworks! enabled, Flipper will not work and 21 | # you should disable these next few lines. 22 | use_flipper! 23 | post_install do |installer| 24 | flipper_post_install(installer) 25 | end 26 | end 27 | 28 | target 'foodnet-tvOS' do 29 | # Pods for foodnet-tvOS 30 | 31 | target 'foodnet-tvOSTests' do 32 | inherit! :search_paths 33 | # Pods for testing 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /ios/foodnet-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ios/foodnet-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/foodnet.xcodeproj/xcshareddata/xcschemes/foodnet-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ios/foodnet.xcodeproj/xcshareddata/xcschemes/foodnet.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 54 | 56 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /ios/foodnet.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/foodnet.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/foodnet/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /ios/foodnet/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #ifdef FB_SONARKIT_ENABLED 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | static void InitializeFlipper(UIApplication *application) { 16 | FlipperClient *client = [FlipperClient sharedClient]; 17 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 18 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 19 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 20 | [client addPlugin:[FlipperKitReactPlugin new]]; 21 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 22 | [client start]; 23 | } 24 | #endif 25 | 26 | @implementation AppDelegate 27 | 28 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 29 | { 30 | #ifdef FB_SONARKIT_ENABLED 31 | InitializeFlipper(application); 32 | #endif 33 | 34 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 35 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 36 | moduleName:@"foodnet" 37 | initialProperties:nil]; 38 | 39 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 40 | 41 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 42 | UIViewController *rootViewController = [UIViewController new]; 43 | rootViewController.view = rootView; 44 | self.window.rootViewController = rootViewController; 45 | [self.window makeKeyAndVisible]; 46 | return YES; 47 | } 48 | 49 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 50 | { 51 | #if DEBUG 52 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 53 | #else 54 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 55 | #endif 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /ios/foodnet/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /ios/foodnet/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /ios/foodnet/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/foodnet/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | $(PRODUCT_NAME) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UIAppFonts 43 | 44 | AntDesign.ttf 45 | Entypo.ttf 46 | EvilIcons.ttf 47 | Feather.ttf 48 | FontAwesome.ttf 49 | FontAwesome5_Brands.ttf 50 | FontAwesome5_Regular.ttf 51 | FontAwesome5_Solid.ttf 52 | Foundation.ttf 53 | Ionicons.ttf 54 | MaterialIcons.ttf 55 | MaterialCommunityIcons.ttf 56 | SimpleLineIcons.ttf 57 | Octicons.ttf 58 | Zocial.ttf 59 | 60 | UILaunchStoryboardName 61 | LaunchScreen 62 | UIRequiredDeviceCapabilities 63 | 64 | armv7 65 | 66 | UISupportedInterfaceOrientations 67 | 68 | UIInterfaceOrientationPortrait 69 | 70 | UIViewControllerBasedStatusBarAppearance 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /ios/foodnet/hu.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /ios/foodnet/hu.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Loading application.."; ObjectID = "EfI-wG-ZAk"; */ 3 | "EfI-wG-ZAk.text" = "Alkalmazás betöltése .."; 4 | -------------------------------------------------------------------------------- /ios/foodnet/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ios/foodnet/ro.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /ios/foodnet/ro.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Loading application.."; ObjectID = "EfI-wG-ZAk"; */ 3 | "EfI-wG-ZAk.text" = "Se încarcă aplicația .."; 4 | -------------------------------------------------------------------------------- /ios/foodnetTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /ios/foodnetTests/foodnetTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface foodnetTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation foodnetTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 38 | if (level >= RCTLogLevelError) { 39 | redboxError = message; 40 | } 41 | }); 42 | #endif 43 | 44 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 45 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | 48 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 49 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 50 | return YES; 51 | } 52 | return NO; 53 | }]; 54 | } 55 | 56 | #ifdef DEBUG 57 | RCTSetLogFunction(RCTDefaultLogFunction); 58 | #endif 59 | 60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foodnet", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "@react-native-community/async-storage": "^1.12.1", 14 | "@react-native-community/geolocation": "^2.0.2", 15 | "@react-native-community/masked-view": "^0.1.10", 16 | "@react-native-community/netinfo": "^5.9.7", 17 | "@react-navigation/bottom-tabs": "^5.10.6", 18 | "@react-navigation/drawer": "^5.10.6", 19 | "@react-navigation/material-bottom-tabs": "^5.3.6", 20 | "@react-navigation/native": "^5.8.6", 21 | "@react-navigation/stack": "^5.12.3", 22 | "axios": "^0.21.0", 23 | "i18n-js": "^3.8.0", 24 | "intl": "^1.2.5", 25 | "moment": "^2.29.1", 26 | "native-base": "^2.13.14", 27 | "prop-types": "^15.7.2", 28 | "react": "16.13.1", 29 | "react-native": "0.63.3", 30 | "react-native-animatable": "^1.3.3", 31 | "react-native-code-input": "^1.0.6", 32 | "react-native-countdown-component": "^2.7.1", 33 | "react-native-easy-content-loader": "^0.3.2", 34 | "react-native-elements": "^3.0.0-alpha.1", 35 | "react-native-fast-image": "^8.3.4", 36 | "react-native-gesture-handler": "^1.8.0", 37 | "react-native-infinite-scroll-grid": "^0.1.0", 38 | "react-native-linear-gradient": "^2.5.6", 39 | "react-native-localization": "^2.1.6", 40 | "react-native-material-textfield": "^0.16.1", 41 | "react-native-paper": "^4.3.0", 42 | "react-native-parallax-header": "^1.1.4", 43 | "react-native-progress": "^4.1.2", 44 | "react-native-reanimated": "^1.13.1", 45 | "react-native-responsive-screen": "^1.4.1", 46 | "react-native-safe-area-context": "^3.1.8", 47 | "react-native-screens": "^2.13.0", 48 | "react-native-simple-toast": "^1.1.3", 49 | "react-native-svg": "^12.1.0", 50 | "react-native-svg-icon": "^0.9.0", 51 | "react-native-swiper": "^1.6.0", 52 | "react-native-tab-view": "^2.15.2", 53 | "react-native-vector-icons": "^7.1.0", 54 | "react-navigation": "^4.4.3", 55 | "react-redux": "^7.2.2", 56 | "redux": "^4.0.5", 57 | "redux-logger": "^3.0.6", 58 | "redux-persist": "^6.0.0", 59 | "redux-thunk": "^2.3.0" 60 | }, 61 | "devDependencies": { 62 | "@babel/core": "^7.12.3", 63 | "@babel/runtime": "^7.12.5", 64 | "@react-native-community/eslint-config": "^2.0.0", 65 | "babel-jest": "^26.6.3", 66 | "eslint": "^7.12.1", 67 | "jest": "^26.6.3", 68 | "metro-react-native-babel-preset": "^0.64.0", 69 | "react-test-renderer": "16.13.1" 70 | }, 71 | "jest": { 72 | "preset": "react-native" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/assets/icons/Left Accessory.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/Vector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/alert-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/alert-circle1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/check-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/check-circle1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/clipboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/icons/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/help-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/hungary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/icons/hungary.png -------------------------------------------------------------------------------- /src/assets/icons/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/icons/loader.gif -------------------------------------------------------------------------------- /src/assets/icons/logo-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/icons/logo-big.png -------------------------------------------------------------------------------- /src/assets/icons/map-pin-grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/map-pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/percent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/reply_24px_outlined.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/romania.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/icons/romania.png -------------------------------------------------------------------------------- /src/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/shopping-bag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/shopping-bag1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/assets/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/star2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/trash-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/trash-5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/icons/united-states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/icons/united-states.png -------------------------------------------------------------------------------- /src/assets/icons/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/images/background.jpg -------------------------------------------------------------------------------- /src/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/images/bg.jpg -------------------------------------------------------------------------------- /src/assets/images/loader1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/images/loader1.gif -------------------------------------------------------------------------------- /src/assets/images/loaderimg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/images/loaderimg.gif -------------------------------------------------------------------------------- /src/assets/images/pizza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/images/pizza.png -------------------------------------------------------------------------------- /src/assets/nodes/@codler.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/nodes/@codler.zip -------------------------------------------------------------------------------- /src/assets/nodes/react-native-code-input.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/nodes/react-native-code-input.zip -------------------------------------------------------------------------------- /src/assets/nodes/react-native-material-textfield.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/nodes/react-native-material-textfield.zip -------------------------------------------------------------------------------- /src/assets/nodes/react-native-swiper.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/nodes/react-native-swiper.zip -------------------------------------------------------------------------------- /src/assets/nodes/react-native-tab-view.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reactnative1126/Foodnet_ReactNative/dfeec766fd998ebd0223e8531567b81a607dbf27/src/assets/nodes/react-native-tab-view.zip -------------------------------------------------------------------------------- /src/assets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assets" 3 | } -------------------------------------------------------------------------------- /src/components/Athena/Card.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet, View } from "react-native"; 3 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from "react-native-responsive-screen"; 4 | 5 | export default Card = (props) => { 6 | return ( 7 | {props.children} 8 | ); 9 | }; 10 | 11 | const styles = StyleSheet.create({ 12 | card: { 13 | width: wp("100%") 14 | }, 15 | }); -------------------------------------------------------------------------------- /src/components/Athena/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { StyleSheet, ActivityIndicator, View } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { colors } from '@constants/themes'; 6 | 7 | const Loading = () => { 8 | const { loading } = useSelector(state => state.auth); 9 | 10 | return ( 11 | loading ? ( 12 | 13 | 14 | 15 | 16 | 17 | ) : null 18 | ) 19 | } 20 | 21 | const styles = StyleSheet.create({ 22 | container: { 23 | flex: 1, 24 | position: 'absolute', 25 | top: 0, 26 | left: 0, 27 | width: wp('100%'), 28 | height: hp('100%'), 29 | backgroundColor: '#00000080', 30 | justifyContent: 'center', 31 | alignItems: 'center' 32 | }, 33 | indicator: { 34 | flexDirection: 'row', 35 | justifyContent: "center", 36 | alignItems: 'center', 37 | } 38 | }); 39 | 40 | export default Loading; -------------------------------------------------------------------------------- /src/components/Athena/Picker.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity } from "react-native"; 3 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from "react-native-responsive-screen"; 4 | import { Icon } from "react-native-elements"; 5 | import { colors } from "@constants/themes"; 6 | 7 | const Picker = ({ data, one, onSelect }) => { 8 | return ( 9 | 10 | 11 | 12 | {data.map((item, key) => { 13 | return ( 14 | onSelect(item)}> 15 | {item.label} 16 | 17 | 18 | ) 19 | })} 20 | 21 | 22 | 23 | ); 24 | }; 25 | 26 | const styles = StyleSheet.create({ 27 | 28 | dialog: { 29 | position: 'absolute', 30 | justifyContent: 'center', 31 | alignItems: 'center', 32 | width: wp('100.0%'), 33 | height: hp('100.0%'), 34 | backgroundColor: '#000000BF' 35 | }, 36 | dialogMain: { 37 | alignItems: 'center', 38 | width: wp('50%'), 39 | backgroundColor: '#FFF', 40 | zIndex: 1000, 41 | borderRadius: 5 42 | }, 43 | dialogHeader: { 44 | justifyContent: 'center', 45 | alignItems: 'center', 46 | width: '100%', 47 | height: 50, 48 | backgroundColor: '#AD7A32', 49 | borderTopLeftRadius: 20, 50 | borderTopRightRadius: 20, 51 | shadowColor: '#000', 52 | shadowOpacity: 0.9, 53 | shadowOffset: { height: 2, width: 1 }, 54 | shadowRadius: 5, 55 | elevation: 10, 56 | }, 57 | item: { 58 | flexDirection: 'row', 59 | justifyContent: 'space-between', 60 | alignItems: 'center', 61 | width: '100%', 62 | height: 30, 63 | paddingLeft: 10, 64 | paddingRight: 10, 65 | alignItems: 'center', 66 | borderWidth: 0.5, 67 | borderRadius: 5, 68 | borderColor: colors.BLACK, 69 | marginBottom: 5 70 | }, 71 | }); 72 | 73 | export default Picker; -------------------------------------------------------------------------------- /src/components/Dashboard/Featured.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, Fragment } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Platform, StatusBar, StyleSheet, LogBox, FlatList, View, Text, TouchableOpacity } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import Card from '../Athena/Card'; 7 | import { isEmpty } from '@utils/functions'; 8 | import { common, colors } from '@constants/themes'; 9 | import { RES_URL } from '@constants/configs'; 10 | import i18n from '@utils/i18n'; 11 | 12 | import moment from 'moment'; 13 | import FastImage from 'react-native-fast-image'; 14 | import ContentLoader from 'react-native-easy-content-loader'; 15 | 16 | const RenderItem = ({ featured, index, onDetail }) => { 17 | const [loader, setLoader] = useState(true); 18 | return ( 19 | 20 | 29 | onDetail(featured.item)}> 30 | setLoader(false)} /> 31 | {!loader && ( 32 | 33 | {(parseInt(moment().format('HH:mm').replace(':', '')) <= parseInt(featured.item.restaurant_open.replace(':', '')) || parseInt(moment().format('HH:mm').replace(':', '')) >= parseInt(featured.item.restaurant_close.replace(':', ''))) && ( 34 | {i18n.translate('CLOSED')} 35 | )} 36 | = parseInt(featured.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={1}>{featured.item.restaurant_name} 37 | 38 | 39 | {featured.item.restaurant_rating}/5 40 | 41 | = parseInt(featured.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={2}>{featured.item.restaurant_description} 42 | 43 | )} 44 | 45 | 46 | ) 47 | } 48 | 49 | export default Featured = (props) => { 50 | useEffect(() => LogBox.ignoreLogs(['VirtualizedLists should never be nested']), []); 51 | 52 | return ( 53 | 54 | 55 | {i18n.translate('Featured restaurants')} 56 | {props.shown && ({i18n.translate('All results')}: {props.count})} 57 | 58 | index.toString()} 63 | renderItem={(featured, index) => ()} 64 | /> 65 | 66 | ); 67 | } 68 | 69 | const styles = StyleSheet.create({ 70 | card: { 71 | width: '100%', 72 | marginTop: 20 73 | }, 74 | cardHeader: { 75 | flexDirection: 'row', 76 | justifyContent: 'space-between', 77 | alignItems: 'center', 78 | width: '100%', 79 | }, 80 | cardTitle: { 81 | marginVertical: 12, 82 | fontSize: 18, 83 | fontWeight: 'bold', 84 | color: '#111', 85 | width: '60%' 86 | }, 87 | cardCount: { 88 | textAlign: 'right', 89 | color: '#666', 90 | width: '40%' 91 | }, 92 | loader: { 93 | marginTop: -10, 94 | marginRight: 16, 95 | width: 200, 96 | }, 97 | default: { 98 | width: 0 99 | }, 100 | featured: { 101 | marginRight: 16, 102 | width: 200, 103 | }, 104 | image: { 105 | width: 200, 106 | height: 125, 107 | borderRadius: 8 108 | }, 109 | overlay: { 110 | position: 'absolute', 111 | top: 0, 112 | left: 0, 113 | width: '100%', 114 | height: 125, 115 | backgroundColor: '#000000D0', 116 | borderRadius: 8, 117 | justifyContent: 'center', 118 | alignItems: 'center' 119 | }, 120 | closeText: { 121 | fontSize: 32, 122 | fontWeight: 'bold', 123 | color: colors.WHITE 124 | }, 125 | title: { 126 | width: '100%', 127 | marginVertical: 12, 128 | fontSize: 16, 129 | fontWeight: 'bold', 130 | color: '#111' 131 | }, 132 | rating: { 133 | flexDirection: 'row', 134 | justifyContent: 'space-between', 135 | alignItems: 'center', 136 | paddingHorizontal: 8, 137 | width: 50, 138 | height: 25, 139 | backgroundColor: '#FEEBD6', 140 | borderRadius: 6 141 | }, 142 | rate: { 143 | fontSize: 12, 144 | fontWeight: 'bold', 145 | color: colors.YELLOW.PRIMARY 146 | }, 147 | description: { 148 | marginVertical: 8, 149 | fontSize: 14, 150 | fontWeight: '400', 151 | lineHeight: 21 152 | }, 153 | disabled: { 154 | opacity: 0.5 155 | }, 156 | time: { 157 | paddingHorizontal: 10, 158 | borderWidth: 1, 159 | borderColor: colors.RED.PRIMARY 160 | } 161 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/Result.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, Fragment } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Platform, StatusBar, StyleSheet, LogBox, FlatList, View, Text, TouchableOpacity } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import Card from '../Athena/Card'; 7 | import { isEmpty } from '@utils/functions'; 8 | import { common, colors } from '@constants/themes'; 9 | import { RES_URL } from '@constants/configs'; 10 | import i18n from '@utils/i18n'; 11 | 12 | import moment from 'moment'; 13 | import FastImage from 'react-native-fast-image'; 14 | import ContentLoader from 'react-native-easy-content-loader'; 15 | 16 | const RenderItem = ({ result, index, onDetail }) => { 17 | const [loader, setLoader] = useState(true); 18 | return ( 19 | 20 | 29 | onDetail(result.item)}> 30 | setLoader(false)} /> 31 | {!loader && ( 32 | 33 | {(result.item.restaurant_new > 0 || result.item.restaurant_discount > 0) && ( 34 | 35 | {result.item.restaurant_new > 0 && ( 36 | 37 | 38 | {i18n.translate('NEW RESTAURANT')} 39 | 40 | 41 | )} 42 | {result.item.restaurant_discount > 0 && ( 43 | 44 | 45 | {i18n.translate('SPECIAL PRICE')} 46 | 47 | 48 | )} 49 | 50 | )} 51 | {(parseInt(moment().format('HH:mm').replace(':', '')) <= parseInt(result.item.restaurant_open.replace(':', '')) || parseInt(moment().format('HH:mm').replace(':', '')) >= parseInt(result.item.restaurant_close.replace(':', ''))) && ( 52 | 53 | {i18n.translate('CLOSED')} 54 | 55 | )} 56 | 57 | = parseInt(result.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={1}>{result.item.restaurant_name} 58 | 59 | 60 | {result.item.restaurant_rating}/5 61 | 62 | 63 | = parseInt(result.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={2}>{result.item.restaurant_description} 64 | 65 | )} 66 | 67 | 68 | ) 69 | } 70 | 71 | export default Result = (props) => { 72 | useEffect(() => LogBox.ignoreLogs(['VirtualizedLists should never be nested']), []); 73 | 74 | return ( 75 | 76 | {i18n.translate('All restaurants')} 77 | {!isEmpty(props.data) ? ( 78 | index.toString()} 82 | renderItem={(result, index) => ()} 83 | /> 84 | ) : ( 85 | 86 | {i18n.translate('No restaurant found')} 87 | 88 | )} 89 | 90 | ); 91 | } 92 | 93 | const styles = StyleSheet.create({ 94 | card: { 95 | width: wp('100%'), 96 | paddingHorizontal: 20, 97 | marginTop: 20 98 | }, 99 | cardTitle: { 100 | marginVertical: 12, 101 | fontSize: 18, 102 | fontWeight: 'bold', 103 | color: '#111' 104 | }, 105 | loader: { 106 | marginBottom: 20, 107 | width: '100%', 108 | }, 109 | default: { 110 | height: 0 111 | }, 112 | result: { 113 | marginBottom: 30, 114 | width: '100%', 115 | }, 116 | image: { 117 | width: '100%', 118 | height: 125, 119 | borderRadius: 8 120 | }, 121 | overlay: { 122 | position: 'absolute', 123 | top: 0, 124 | left: 0, 125 | width: '100%', 126 | height: 125, 127 | backgroundColor: '#000000D0', 128 | borderRadius: 8, 129 | justifyContent: 'center', 130 | alignItems: 'center' 131 | }, 132 | closeText: { 133 | fontSize: 32, 134 | fontWeight: 'bold', 135 | color: colors.WHITE 136 | }, 137 | tagView: { 138 | position: 'absolute', 139 | flexDirection: 'column', 140 | top: 16, 141 | left: 16 142 | }, 143 | tag: { 144 | padding: 5, 145 | backgroundColor: colors.YELLOW.PRIMARY, 146 | borderRadius: 4, 147 | marginBottom: 10 148 | }, 149 | tagText: { 150 | fontSize: 12, 151 | fontWeight: 'bold', 152 | color: colors.WHITE 153 | }, 154 | titleView: { 155 | marginTop: 12, 156 | marginBottom: 10, 157 | width: '100%', 158 | flexDirection: 'row', 159 | justifyContent: 'space-between', 160 | alignItems: 'center' 161 | }, 162 | title: { 163 | width: '80%', 164 | fontSize: 16, 165 | fontWeight: 'bold', 166 | color: '#111' 167 | }, 168 | rating: { 169 | flexDirection: 'row', 170 | justifyContent: 'space-between', 171 | alignItems: 'center', 172 | paddingHorizontal: 8, 173 | width: 50, 174 | height: 25, 175 | backgroundColor: '#FEEBD6', 176 | borderRadius: 6 177 | }, 178 | rate: { 179 | fontSize: 12, 180 | fontWeight: 'bold', 181 | color: colors.YELLOW.PRIMARY 182 | }, 183 | description: { 184 | fontSize: 14, 185 | fontWeight: '400', 186 | lineHeight: 21 187 | }, 188 | disabled: { 189 | opacity: 0.5 190 | }, 191 | time: { 192 | paddingHorizontal: 10, 193 | borderWidth: 1, 194 | borderColor: colors.RED.PRIMARY 195 | }, 196 | emptyView: { 197 | width: '100%', 198 | paddingVertical: 50, 199 | justifyContent: 'center', 200 | alignItems: 'center' 201 | } 202 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/Trendy.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, Fragment } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Platform, StatusBar, StyleSheet, LogBox, FlatList, View, Text, TouchableOpacity } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import Card from '../Athena/Card'; 7 | import { isEmpty } from '@utils/functions'; 8 | import { common, colors } from '@constants/themes'; 9 | import { RES_URL } from '@constants/configs'; 10 | import i18n from '@utils/i18n'; 11 | 12 | import moment from 'moment'; 13 | import FastImage from 'react-native-fast-image'; 14 | import ContentLoader from 'react-native-easy-content-loader'; 15 | 16 | const RenderItem = ({ trendy, index, onDetail }) => { 17 | const [loader, setLoader] = useState(true); 18 | return ( 19 | 20 | 29 | onDetail(trendy.item)}> 30 | setLoader(false)} /> 31 | {!loader && ( 32 | 33 | {(parseInt(moment().format('HH:mm').replace(':', '')) <= parseInt(trendy.item.restaurant_open.replace(':', '')) || parseInt(moment().format('HH:mm').replace(':', '')) >= parseInt(trendy.item.restaurant_close.replace(':', ''))) && ( 34 | {i18n.translate('CLOSED')} 35 | )} 36 | = parseInt(trendy.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={1}>{trendy.item.restaurant_name} 37 | 38 | 39 | {trendy.item.restaurant_rating}/5 40 | 41 | = parseInt(trendy.item.restaurant_close.replace(':', ''))) && styles.disabled]} numberOfLines={2}>{trendy.item.restaurant_description} 42 | 43 | )} 44 | 45 | 46 | ) 47 | } 48 | 49 | export default Trendy = (props) => { 50 | useEffect(() => LogBox.ignoreLogs(['VirtualizedLists should never be nested']), []); 51 | 52 | return ( 53 | 54 | {i18n.translate('Trendy restaurants')} 55 | index.toString()} 60 | renderItem={(trendy, index) => ()} 61 | /> 62 | 63 | ); 64 | } 65 | 66 | const styles = StyleSheet.create({ 67 | card: { 68 | width: '100%', 69 | marginTop: 20 70 | }, 71 | cardTitle: { 72 | marginVertical: 12, 73 | fontSize: 18, 74 | fontWeight: 'bold', 75 | color: '#111' 76 | }, 77 | loader: { 78 | marginTop: -10, 79 | marginRight: 16, 80 | width: 200, 81 | }, 82 | default: { 83 | width: 0 84 | }, 85 | trendy: { 86 | marginRight: 16, 87 | width: 200, 88 | }, 89 | image: { 90 | width: 200, 91 | height: 125, 92 | borderRadius: 8 93 | }, 94 | overlay: { 95 | position: 'absolute', 96 | top: 0, 97 | left: 0, 98 | width: '100%', 99 | height: 125, 100 | backgroundColor: '#000000D0', 101 | borderRadius: 8, 102 | justifyContent: 'center', 103 | alignItems: 'center' 104 | }, 105 | closeText: { 106 | fontSize: 32, 107 | fontWeight: 'bold', 108 | color: colors.WHITE 109 | }, 110 | title: { 111 | width: '100%', 112 | marginVertical: 12, 113 | fontSize: 16, 114 | fontWeight: 'bold', 115 | color: '#111' 116 | }, 117 | rating: { 118 | flexDirection: 'row', 119 | justifyContent: 'space-between', 120 | alignItems: 'center', 121 | paddingHorizontal: 8, 122 | width: 50, 123 | height: 25, 124 | backgroundColor: '#FEEBD6', 125 | borderRadius: 6 126 | }, 127 | rate: { 128 | fontSize: 12, 129 | fontWeight: 'bold', 130 | color: colors.YELLOW.PRIMARY 131 | }, 132 | description: { 133 | marginVertical: 8, 134 | fontSize: 14, 135 | fontWeight: '400', 136 | lineHeight: 21 137 | }, 138 | disabled: { 139 | opacity: 0.5 140 | }, 141 | time: { 142 | paddingHorizontal: 10, 143 | borderWidth: 1, 144 | borderColor: colors.RED.PRIMARY 145 | } 146 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Content, Body } from 'native-base'; 4 | import { Platform, StatusBar, StyleSheet, View, Image, Text, TouchableOpacity } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import Featured from './Featured'; 8 | import Trendy from './Trendy'; 9 | import Result from './Result'; 10 | import { isEmpty } from '@utils/functions'; 11 | import { common, colors } from '@constants/themes'; 12 | import { images, icons } from '@constants/assets'; 13 | import { SearchIcon, FilterIcon } from '@constants/svgs'; 14 | import i18n from '@utils/i18n'; 15 | 16 | import { TextField } from 'react-native-material-textfield'; 17 | import Grid from 'react-native-infinite-scroll-grid'; 18 | 19 | export default Dashboard = (props) => { 20 | return ( 21 | ( 24 | 25 | 26 | 27 | 28 | {i18n.translate('Extra discounts')} 29 | 30 | 31 | 32 | {i18n.translate('Know more')} 33 | 34 | 35 | 36 | 37 | 38 | 39 | { 51 | return ( 52 | 53 | ) 54 | }} 55 | renderRightAccessory={() => { 56 | return ( 57 | props.onFilter()} > 58 | 59 | 60 | ) 61 | }} 62 | onChangeText={(value) => props.onSearch(value)} 63 | /> 64 | 65 | {!isEmpty(props.featured) && ( 66 | props.onDetail(item)} 70 | count={isEmpty(props.result) ? 0 : props.result.length} 71 | shown={(props.search == '' && 72 | props.filters.freeDelivery == 0 && 73 | props.filters.newest == 0 && 74 | props.filters.pizza == 0 && 75 | props.filters.hamburger == 0 && 76 | props.filters.dailyMenu == 0 && 77 | props.filters.soup == 0 && 78 | props.filters.salad == 0 && 79 | props.filters.money == 0 && 80 | props.filters.card == 0 && 81 | props.filters.withinOneHour == 0) ? false : true} 82 | />)} 83 | {!isEmpty(props.trendy) && ( props.onDetail(item)} />)} 84 | {!isEmpty(props.result) && ( props.onDetail(item)} />)} 85 | 86 | 87 | 88 | )} 89 | refreshing={props.refresh} 90 | onRefresh={() => props.onRefresh()} 91 | /> 92 | ); 93 | } 94 | 95 | const styles = StyleSheet.create({ 96 | content: { 97 | padding: 20 98 | }, 99 | topView: { 100 | flexDirection: 'row', 101 | justifyContent: 'flex-start', 102 | width: wp('100%'), 103 | paddingVertical: 10, 104 | backgroundColor: '#FEEBD6' 105 | }, 106 | topRight: { 107 | marginLeft: 22, 108 | justifyContent: 'center', 109 | }, 110 | topTitle: { 111 | fontSize: 20, 112 | fontWeight: 'bold', 113 | lineHeight: 30, 114 | color: colors.YELLOW.PRIMARY 115 | }, 116 | topSpace: { 117 | height: 16 118 | }, 119 | topButton: { 120 | flexDirection: 'row', 121 | justifyContent: 'center', 122 | paddingHorizontal: 16, 123 | paddingVertical: 8, 124 | backgroundColor: colors.YELLOW.PRIMARY, 125 | borderRadius: 6 126 | }, 127 | topText: { 128 | fontSize: 14, 129 | fontWeight: 'bold', 130 | color: colors.WHITE 131 | }, 132 | inputView: { 133 | width: '100%' 134 | }, 135 | textContainer: { 136 | flexDirection: 'row', 137 | justifyContent: 'space-between', 138 | alignItems: 'center', 139 | width: '100%', 140 | marginTop: 10, 141 | height: 50, 142 | borderWidth: 1, 143 | borderRadius: 8, 144 | paddingHorizontal: 10, 145 | borderColor: colors.GREY.PRIMARY 146 | }, 147 | inputContainer: { 148 | width: '100%', 149 | marginTop: -20, 150 | borderWidth: 0 151 | }, 152 | }); -------------------------------------------------------------------------------- /src/components/Restaurant/Information.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Platform, StatusBar, StyleSheet, LogBox, View, Text } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import Card from '../Athena/Card'; 7 | import { isEmpty } from '@utils/functions'; 8 | import i18n from '@utils/i18n'; 9 | 10 | export default Information = (props) => { 11 | useEffect(() => LogBox.ignoreLogs(['VirtualizedLists should never be nested']), []); 12 | 13 | return ( 14 | 15 | 16 | {i18n.translate('INFORMATION & PROMOTIONS')} 17 | 18 | 19 | {i18n.translate('Average delivery time')} 20 | {i18n.translate('Aproximativ')} {isEmpty(props.information.restaurant_avgTransport) ? 0 : props.information.restaurant_avgTransport} {i18n.translate('minute')} 21 | 22 | 23 | {i18n.translate('Discount')} 24 | {isEmpty(props.information.restaurant_discount) ? 0 : props.information.restaurant_discount}% 25 | 26 | 27 | {i18n.translate('Address & Contact')} 28 | {isEmpty(props.information.restaurant_address) ? '' : props.information.restaurant_address} 29 | {isEmpty(props.information.restaurant_phoneNumber) ? '' : props.information.restaurant_phoneNumber} 30 | 31 | 32 | {i18n.translate('Description')} 33 | {isEmpty(props.information.restaurant_description) ? '' : props.information.restaurant_description} 34 | 35 | {!isEmpty(props.information.result) && ( 36 | 37 | {i18n.translate('Opening Hours')} 38 | 39 | {props.information.result.map((open, key) => ( 40 | 41 | {open.day} 42 | {open.open} - {open.close} 43 | 44 | ))} 45 | 46 | 47 | )} 48 | 49 | ); 50 | } 51 | 52 | const styles = StyleSheet.create({ 53 | container: { 54 | padding: 20 55 | }, 56 | card: { 57 | width: '100%', 58 | marginBottom: 15, 59 | }, 60 | cardTitle: { 61 | marginVertical: 12, 62 | fontSize: 18, 63 | fontWeight: 'bold', 64 | color: '#111', 65 | width: '100%' 66 | }, 67 | cardText: { 68 | fontSize: 16, 69 | color: '#333', 70 | width: '100%' 71 | }, 72 | open: { 73 | width: '100%', 74 | borderWidth: 1, 75 | borderColor: '#C4C4C4', 76 | borderRadius: 8 77 | }, 78 | item: { 79 | flexDirection: 'row', 80 | justifyContent: 'space-between', 81 | alignItems: 'center', 82 | width: '100%', 83 | padding: 20, 84 | borderColor: '#C4C4C4', 85 | }, 86 | time: { 87 | flexDirection: 'row', 88 | justifyContent: 'flex-end', 89 | alignItems: 'center', 90 | } 91 | }); -------------------------------------------------------------------------------- /src/components/Splash.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Platform, StatusBar, StyleSheet, View, ActivityIndicator, Text } from 'react-native'; 3 | import { Container } from 'native-base'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import { common, colors } from '@constants/themes'; 7 | import { SplashIcon } from '@constants/svgs'; 8 | import i18n from '@utils/i18n'; 9 | 10 | export default Splash = (props) => { 11 | return ( 12 | 13 | 20 | ); 21 | } 22 | 23 | const styles = StyleSheet.create({ 24 | content: { 25 | flex: 1, 26 | justifyContent: 'center', 27 | alignItems: 'center', 28 | backgroundColor: colors.WHITE 29 | }, 30 | indicator: { 31 | marginTop: 24 32 | }, 33 | text: { 34 | marginTop: 8, 35 | fontSize: 14, 36 | fontWeight: 'bold', 37 | color: '#666' 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | 2 | import Loading from './Athena/Loading'; 3 | import Picker from './Athena/Picker'; 4 | import Card from './Athena/Card'; 5 | import Splash from './Splash'; 6 | import Cities from './Cities'; 7 | import Dashboard from './Dashboard'; 8 | import Featured from './Dashboard/Featured'; 9 | import Trendy from './Dashboard/Trendy'; 10 | import Result from './Dashboard/Result'; 11 | import Filters from './Dashboard/Filters'; 12 | 13 | import Menu from './Restaurant/Menu'; 14 | import Information from './Restaurant/Information'; 15 | import Reviews from './Restaurant/Reviews'; 16 | 17 | 18 | export { 19 | Loading, 20 | Picker, 21 | Card, 22 | Splash, 23 | Cities, 24 | Dashboard, 25 | Featured, 26 | Trendy, 27 | Result, 28 | Filters, 29 | 30 | Menu, 31 | Information, 32 | Reviews 33 | }; -------------------------------------------------------------------------------- /src/components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@components" 3 | } -------------------------------------------------------------------------------- /src/constants/assets.js: -------------------------------------------------------------------------------- 1 | export const images = { 2 | bgImage: require('@assets/images/background.jpg'), 3 | pizzaImage: require('@assets/images/pizza.png'), 4 | loadImage: require('@assets/images/loaderimg.gif'), 5 | foodImage: require('@assets/images/bg.jpg'), 6 | } 7 | 8 | export const icons = { 9 | en: require('@assets/icons/united-states.png'), 10 | hu: require('@assets/icons/hungary.png'), 11 | ro: require('@assets/icons/romania.png'), 12 | } 13 | -------------------------------------------------------------------------------- /src/constants/configs.js: -------------------------------------------------------------------------------- 1 | // const API_URL = 'https://shielded-anchorage-51692.herokuapp.com/api'; 2 | const API_URL = 'https://api.foodnet.ro/app/api'; 3 | // const RES_URL = 'https://shielded-anchorage-51692.herokuapp.com/'; 4 | const RES_URL = 'https://admin.foodnet.ro/'; 5 | 6 | const GOOGLE_MAP_API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; 7 | const FACEBOOK_ID = 'XXXXXXXXXXXXXX'; 8 | export { API_URL, RES_URL, GOOGLE_MAP_API_KEY, FACEBOOK_ID } 9 | -------------------------------------------------------------------------------- /src/constants/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@constants" 3 | } -------------------------------------------------------------------------------- /src/constants/regexs.js: -------------------------------------------------------------------------------- 1 | // const EMAIL_PATTERN = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])/; 2 | // const MOBILE_PATTERN = /^(\\+\\d{1,3}[- ]?)?\\d{10}$/; 3 | const NAME_PATTERN = /^(?=[a-zA-Z0-9~@#$^*()_+=[\]{}|\\,.?: -]*$)(?!.*[<>'"/;`%])/; 4 | const EMAIL_PATTERN = /^(([^<>()[\]\\.,;:\s@']+(\.[^<>()[\]\\.,;:\s@']+)*)|('.+'))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 5 | const MOBILE_PATTERN = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,8}$/im; 6 | const ALIAS_PATTERN = /^[a-zA-Z0-9_]{3,}[a-zA-Z]+[0-9]*$/; 7 | const PASSWORD_PATTERN = /^[a-zA-Z0-9!@#$%^&*()_+{}[:;"'|<>?,./]{5,30}$/; 8 | 9 | export { NAME_PATTERN, EMAIL_PATTERN, PASSWORD_PATTERN, ALIAS_PATTERN, MOBILE_PATTERN }; -------------------------------------------------------------------------------- /src/constants/themes.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | import { color } from 'react-native-reanimated'; 3 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 4 | export const themes = { 5 | LIGHT: { 6 | PRIMARY: '#FFFFFF', 7 | SECONDARY: '#DDDDDD' 8 | }, 9 | DARK: { 10 | PRIMARY: '#000000', 11 | SECONDARY: '#555555' 12 | }, 13 | BLUE: { 14 | PRIMARY: '#7FE2ED', 15 | SECONDARY: '#659FF8' 16 | }, 17 | PINK: { 18 | PRIMARY: '#F382EB', 19 | SECONDARY: '#E62FC7' 20 | } 21 | }; 22 | 23 | export const colors = { 24 | TRANSPARENT: 'transparent', 25 | WHITE: '#FFF', 26 | BLACK: '#000', 27 | RED: { 28 | DEFAULT: 'red', 29 | PRIMARY: '#EA4A4A', 30 | }, 31 | GREEN: { 32 | DEFAULT: 'green', 33 | PRIMARY: '#45AB62', 34 | }, 35 | BLUE: { 36 | DEFAULT: 'blue', 37 | PRIMARY: '#0386E1', 38 | }, 39 | GREY: { 40 | DEFAULT: '#243235', 41 | PRIMARY: '#C4C4C4', 42 | SECONDARY: '#EFEFEF', 43 | }, 44 | YELLOW: { 45 | DEFAULT: 'yellow', 46 | PRIMARY: '#F78F1E', 47 | C444: '$444444' 48 | } 49 | } 50 | 51 | export const common = StyleSheet.create({ 52 | container: { 53 | flex: 1, 54 | }, 55 | 56 | shown: { 57 | display: 'flex' 58 | }, 59 | hidden: { 60 | display: 'none', 61 | }, 62 | width10: { 63 | width: 10 64 | }, 65 | width20: { 66 | width: 20 67 | }, 68 | width30: { 69 | width: 30 70 | }, 71 | width100P: { 72 | width: '100%' 73 | }, 74 | 75 | height50: { 76 | height: 50 77 | }, 78 | 79 | marginTop10: { 80 | marginTop: 10 81 | }, 82 | marginTop25: { 83 | marginTop: 25 84 | }, 85 | marginTop35: { 86 | marginTop: 35 87 | }, 88 | marginTop50: { 89 | marginTop: 50, 90 | }, 91 | marginLeftM20: { 92 | marginLeft: -20 93 | }, 94 | 95 | borderWidth1D5: { 96 | borderWidth: 1.5 97 | }, 98 | 99 | underLine: { 100 | textDecorationLine: 'underline' 101 | }, 102 | 103 | flexRow: { 104 | flexDirection: 'row' 105 | }, 106 | header: { 107 | flexDirection: 'row', 108 | justifyContent: 'space-between', 109 | alignItems: 'center', 110 | backgroundColor: colors.WHITE 111 | }, 112 | headerLeft: { 113 | alignItems: 'flex-start', 114 | paddingLeft: 10, 115 | width: '20%' 116 | }, 117 | headerLeftIcon: { 118 | width: 25, 119 | height: 25 120 | }, 121 | headerTitle: { 122 | flexDirection: 'row', 123 | justifyContent: 'center', 124 | alignItems: 'center', 125 | width: '60%' 126 | }, 127 | headerTitleText: { 128 | fontSize: 16, 129 | fontWeight: 'bold', 130 | color: colors.BLACK, 131 | textAlign: 'center' 132 | }, 133 | headerRight: { 134 | alignItems: 'flex-end', 135 | paddingRight: 10, 136 | width: '20%' 137 | }, 138 | headerRightIcon: { 139 | width: 25, 140 | height: 25 141 | }, 142 | headerRightText: { 143 | fontSize: 16, 144 | fontWeight: 'bold', 145 | color: colors.YELLOW.PRIMARY, 146 | }, 147 | 148 | backColorYellow: { 149 | backgroundColor: colors.YELLOW.PRIMARY 150 | }, 151 | backColorWhite: { 152 | backgroundColor: colors.WHITE 153 | }, 154 | backColorGrey: { 155 | backgroundColor: colors.GREY.PRIMARY 156 | }, 157 | 158 | fontWeightBold: { 159 | fontWeight: 'bold' 160 | }, 161 | fontWeightNormal: { 162 | fontWeight: 'normal' 163 | }, 164 | 165 | fontColorWhite: { 166 | color: colors.WHITE 167 | }, 168 | fontColorBlack: { 169 | color: colors.BLACK 170 | }, 171 | fontColorYellow: { 172 | color: colors.YELLOW.PRIMARY 173 | }, 174 | fontColorRed: { 175 | color: colors.RED.PRIMARY 176 | }, 177 | fontColorGrey: { 178 | color: colors.GREY.PRIMARY 179 | }, 180 | fontColor444: { 181 | color: colors.GREY.C444 182 | }, 183 | 184 | borderColorWhite: { 185 | borderColor: colors.WHITE 186 | }, 187 | borderColorGrey: { 188 | borderColor: colors.GREY.PRIMARY 189 | }, 190 | borderColorRed: { 191 | borderColor: colors.RED.PRIMARY 192 | }, 193 | borderColorYellow: { 194 | borderColor: colors.YELLOW.PRIMARY 195 | }, 196 | 197 | button: { 198 | justifyContent: 'center', 199 | alignItems: 'center', 200 | paddingVertical: 15, 201 | paddingHorizontal: 20, 202 | borderRadius: 6, 203 | }, 204 | buttonText: { 205 | fontSize: 16, 206 | fontWeight: 'bold', 207 | }, 208 | 209 | errorContainer: { 210 | flexDirection: 'row', 211 | justifyContent: 'space-between', 212 | alignItems: 'center', 213 | width: '100%', 214 | marginTop: 10, 215 | height: 50, 216 | borderWidth: 1, 217 | borderColor: colors.RED.PRIMARY, 218 | borderRadius: 8, 219 | backgroundColor: '#F0505030', 220 | paddingLeft: 15, 221 | paddingRight: 20, 222 | }, 223 | errorText: { 224 | marginTop: 5, 225 | marginHorizontal: 5, 226 | color: colors.RED.PRIMARY 227 | }, 228 | iconText: { 229 | fontWeight: 'bold', 230 | color: '#F05050' 231 | }, 232 | }); -------------------------------------------------------------------------------- /src/modules/index.js: -------------------------------------------------------------------------------- 1 | import { createStore, combineReducers, applyMiddleware } from 'redux'; 2 | // import { createLogger } from 'redux-logger'; 3 | import thunk from 'redux-thunk'; 4 | import { persistStore, persistReducer } from 'redux-persist'; 5 | import AsyncStorage from '@react-native-community/async-storage'; 6 | 7 | import authReducer from './reducers/auth'; 8 | import foodReducer from './reducers/food'; 9 | import profileReducer from './reducers/profile'; 10 | 11 | const peresistConfig = { 12 | key: 'root', 13 | storage: AsyncStorage, 14 | timeout: null, 15 | whitelist: ['auth', 'food', 'profile'], 16 | blacklist: [], 17 | }; 18 | 19 | const rootReducer = combineReducers({ 20 | auth: authReducer, 21 | food: foodReducer, 22 | profile: profileReducer 23 | }); 24 | 25 | const persistedReducer = persistReducer(peresistConfig, rootReducer); 26 | 27 | const store = createStore(persistedReducer, applyMiddleware(thunk)); 28 | 29 | let persistor = persistStore(store); 30 | 31 | export { store, persistor }; 32 | -------------------------------------------------------------------------------- /src/modules/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@modules" 3 | } -------------------------------------------------------------------------------- /src/modules/reducers/auth/actions.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | 3 | export const setLoading = (data) => ({ 4 | type: types.SET_LOADING, 5 | payload: data, 6 | }); 7 | 8 | export const setCountry = (data) => ({ 9 | type: types.SET_COUNTRY, 10 | payload: data, 11 | }); 12 | export const setCity = (data) => ({ 13 | type: types.SET_CITY, 14 | payload: data, 15 | }); 16 | export const setUser = (data) => ({ 17 | type: types.SET_USER, 18 | payload: data, 19 | }); 20 | export const setUserCity = (data) => ({ 21 | type: types.SET_USER_CITY, 22 | payload: data, 23 | }); 24 | export const deleteUser = (data) => ({ 25 | type: types.DELETE_USER, 26 | payload: data, 27 | }); 28 | -------------------------------------------------------------------------------- /src/modules/reducers/auth/index.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | 3 | const initialState = { 4 | loading: false, 5 | country: 'en', 6 | city: { 7 | id: 0, 8 | name: '', 9 | status: false 10 | }, 11 | logged: false, 12 | user: { 13 | token: null, 14 | email: '', 15 | name: '', 16 | city: { 17 | id: 0, 18 | name: '', 19 | status: false 20 | } 21 | }, 22 | }; 23 | 24 | export default function authReducer(state = initialState, action) { 25 | switch (action.type) { 26 | case types.SET_LOADING: 27 | return { 28 | ...state, 29 | loading: action.payload, 30 | }; 31 | case types.SET_COUNTRY: 32 | return { 33 | ...state, 34 | country: action.payload, 35 | }; 36 | case types.SET_CITY: 37 | return { 38 | ...state, 39 | city: action.payload, 40 | }; 41 | case types.SET_USER: 42 | return { 43 | ...state, 44 | logged: true, 45 | user: action.payload, 46 | }; 47 | case types.SET_USER_CITY: 48 | return { 49 | ...state, 50 | user: action.payload, 51 | }; 52 | case types.DELETE_USER: 53 | return { 54 | ...state, 55 | logged: false, 56 | user: action.payload, 57 | }; 58 | 59 | 60 | default: 61 | return state; 62 | } 63 | } -------------------------------------------------------------------------------- /src/modules/reducers/auth/types.js: -------------------------------------------------------------------------------- 1 | export default { 2 | SET_LOADING: 'SET_LOADING', 3 | SET_COUNTRY: 'SET_COUNTRY', 4 | SET_CITY: 'SET_CITY', 5 | SET_USER: 'SET_USER', 6 | SET_USER_CITY: 'SET_USER_CITY', 7 | DELETE_USER: 'DELETE_USER' 8 | } -------------------------------------------------------------------------------- /src/modules/reducers/food/actions.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | 3 | export const setFilters = (data) => ({ 4 | type: types.SET_FILTERS, 5 | payload: data, 6 | }); 7 | 8 | export const setCartRestaurant = (data) => ({ 9 | type: types.SET_CART_RESTAURANT, 10 | payload: data, 11 | }); 12 | 13 | export const setCartProducts = (data) => ({ 14 | type: types.SET_CART_PRODUCTS, 15 | payload: data, 16 | }); 17 | 18 | export const setCartBadge = (data) => ({ 19 | type: types.SET_CART_BADGE, 20 | payload: data, 21 | }); 22 | 23 | export const setCartToast = (data) => ({ 24 | type: types.SET_CART_TOAST, 25 | payload: data, 26 | }); -------------------------------------------------------------------------------- /src/modules/reducers/food/index.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | import { isEmpty } from '@utils/functions'; 3 | 4 | const initialState = { 5 | filters: { 6 | freeDelivery: 0, 7 | newest: 0, 8 | pizza: 0, 9 | hamburger: 0, 10 | dailyMenu: 0, 11 | soup: 0, 12 | salad: 0, 13 | money: 0, 14 | card: 0, 15 | withinOneHour: 0 16 | }, 17 | cartRestaurant: null, 18 | cartProducts: [], 19 | cartBadge: 0, 20 | cartToast: false 21 | }; 22 | 23 | export default function foodReducer(state = initialState, action) { 24 | switch (action.type) { 25 | case types.SET_FILTERS: 26 | return { 27 | ...state, 28 | filters: action.payload, 29 | }; 30 | case types.SET_CART_RESTAURANT: 31 | return { 32 | ...state, 33 | cartRestaurant: action.payload, 34 | }; 35 | case types.SET_CART_PRODUCTS: 36 | return { 37 | ...state, 38 | cartProducts: isEmpty(action.payload) ? [] : action.payload, 39 | }; 40 | case types.SET_CART_BADGE: 41 | return { 42 | ...state, 43 | cartBadge: isEmpty(action.payload) ? 0 : action.payload, 44 | }; 45 | case types.SET_CART_TOAST: 46 | return { 47 | ...state, 48 | cartToast: action.payload, 49 | }; 50 | 51 | default: 52 | return state; 53 | } 54 | } -------------------------------------------------------------------------------- /src/modules/reducers/food/types.js: -------------------------------------------------------------------------------- 1 | export default { 2 | SET_FILTERS: 'SET_FILTERS', 3 | SET_CART_RESTAURANT: 'SET_CART_RESTAURANT', 4 | SET_CART_PRODUCTS: 'SET_CART_PRODUCTS', 5 | SET_CART_BADGE: 'SET_CART_BADGE', 6 | SET_CART_TOAST: 'SET_CART_TOAST' 7 | } -------------------------------------------------------------------------------- /src/modules/reducers/profile/actions.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | 3 | export const setDeliveryStatus = (data) => ({ 4 | type: types.SET_DELIVERYSTATUS, 5 | payload: data, 6 | }); 7 | 8 | export const setReviewStatus = (data) => ({ 9 | type: types.SET_REVIEWSTATUS, 10 | payload: data, 11 | }); -------------------------------------------------------------------------------- /src/modules/reducers/profile/index.js: -------------------------------------------------------------------------------- 1 | import types from './types'; 2 | 3 | const initialState = { 4 | deliveryStatus: false, 5 | reviewStatus: false, 6 | }; 7 | 8 | export default function profileReducer(state = initialState, action) { 9 | switch (action.type) { 10 | case types.SET_DELIVERYSTATUS: 11 | return { 12 | ...state, 13 | deliveryStatus: action.payload, 14 | }; 15 | case types.SET_REVIEWSTATUS: 16 | return { 17 | ...state, 18 | reviewStatus: action.payload, 19 | }; 20 | 21 | default: 22 | return state; 23 | } 24 | } -------------------------------------------------------------------------------- /src/modules/reducers/profile/types.js: -------------------------------------------------------------------------------- 1 | export default { 2 | SET_DELIVERYSTATUS: 'SET_DELIVERYSTATUS', 3 | SET_REVIEWSTATUS: 'SET_REVIEWSTATUS' 4 | } -------------------------------------------------------------------------------- /src/modules/services/AuthService.js: -------------------------------------------------------------------------------- 1 | import axios from '@utils/axios'; 2 | 3 | const AuthService = { 4 | login: function (email, password) { 5 | return axios.post(`/auth/login`, { 6 | email, 7 | password 8 | }).then((response) => { 9 | return response.data; 10 | }); 11 | }, 12 | register: function (country, name, email, password, newsletter) { 13 | return axios.post(`/auth/register`, { 14 | lang: country, 15 | email, 16 | name, 17 | password, 18 | newsletter 19 | }).then((response) => { 20 | return response.data; 21 | }); 22 | }, 23 | verification: function (email) { 24 | return axios.post(`/auth/verification`, { 25 | email 26 | }).then((response) => { 27 | return response.data; 28 | }); 29 | }, 30 | reset: function (email, password, code) { 31 | return axios.post(`/auth/change-password`, { 32 | email, 33 | newPassword: password, 34 | code 35 | }).then((response) => { 36 | return response.data; 37 | }); 38 | }, 39 | cities: function (country) { 40 | return axios.get(`/location/${country}`).then((response) => { 41 | return response.data; 42 | }); 43 | }, 44 | cityNames: function (cityId) { 45 | return axios.get(`/location/base/city-name/${cityId}`).then((response) => { 46 | return response.data; 47 | }); 48 | }, 49 | } 50 | 51 | export default AuthService; -------------------------------------------------------------------------------- /src/modules/services/FoodService.js: -------------------------------------------------------------------------------- 1 | import axios, { setClientToken, removeClientToken } from '@utils/axios'; 2 | import { isEmpty } from '@utils/functions'; 3 | 4 | const FoodService = { 5 | promotion: function (country, cityName) { 6 | return axios.get(`/location/promotion/${country}/${cityName}`).then((response) => { 7 | return response.data; 8 | }); 9 | }, 10 | popular: function (country, cityName) { 11 | return axios.get(`/location/popular/${country}/${cityName}`).then((response) => { 12 | return response.data; 13 | }); 14 | }, 15 | all: function (country, cityName) { 16 | return axios.get(`/location/${country}/${cityName}`).then((response) => { 17 | return response.data; 18 | }); 19 | }, 20 | result: function (country, cityName, search, filters) { 21 | return axios.post(`/location/home/search`, { 22 | lang: country, 23 | location: cityName, 24 | searchString: search, 25 | filters 26 | }).then((response) => { 27 | return response.data; 28 | }); 29 | }, 30 | 31 | categories: function (country, restaurantId) { 32 | return axios.post(`/product/category`, { 33 | restaurantId, 34 | lang: country 35 | }).then((response) => { 36 | return response.data; 37 | }); 38 | }, 39 | subCategories: function (country, restaurantId, categoryId) { 40 | return axios.post(`/product/subcategories`, { 41 | restaurantId, 42 | lang: country, 43 | categoryId 44 | }).then((response) => { 45 | return response.data; 46 | }); 47 | }, 48 | products: function (country, restaurantId, categoryId, subcategoryId, propertyValTransId, searchedProduct) { 49 | return axios.post(`/product/subcategories-products`, { 50 | restaurantId, 51 | lang: country, 52 | subcategoryId, 53 | propertyValTransId, 54 | categoryId, 55 | searchProduct: searchedProduct 56 | }).then((response) => { 57 | return response.data; 58 | }); 59 | }, 60 | information: function (country, restaurantName) { 61 | return axios.get(`/restaurant/info/${country}/${restaurantName}`).then((response) => { 62 | return response.data; 63 | }); 64 | }, 65 | reviews: function (restaurantName, rating) { 66 | return axios.post(`/restaurant/review-list`, { 67 | restaurantName, 68 | rating 69 | }).then((response) => { 70 | return response.data; 71 | }); 72 | }, 73 | 74 | required: function (country, restaurantId, variantId) { 75 | return axios.post(`/product/required-extra`, { 76 | restaurantId, 77 | lang: country, 78 | variantId 79 | }).then((response) => { 80 | return response.data; 81 | }); 82 | }, 83 | 84 | optional: function (country, restaurantId, variantId) { 85 | return axios.post(`/product/optional-extra`, { 86 | restaurantId, 87 | lang: country, 88 | variantId 89 | }).then((response) => { 90 | return response.data; 91 | }); 92 | }, 93 | 94 | getOrders: function (token) { 95 | setClientToken(token); 96 | return axios.get(`/order`).then((response) => { 97 | removeClientToken(); 98 | return response.data; 99 | }); 100 | }, 101 | 102 | getOrder: function (token, country, orderId) { 103 | setClientToken(token); 104 | console.log(token) 105 | return axios.get(`/order/${country}/${orderId}`).then((response) => { 106 | removeClientToken(); 107 | return response.data; 108 | }); 109 | }, 110 | 111 | order: function (token, city, deliveryAddressId, restaurantId, take, cutlery, products, comment) { 112 | setClientToken(token); 113 | return axios.post(`/order`, { 114 | deliveryAddressId, 115 | restaurantId, 116 | take: take ? 1 : 0, 117 | cutlery: cutlery ? 1 : 0, 118 | products, 119 | messageCourier: comment, 120 | locationId: city.id 121 | }).then((response) => { 122 | removeClientToken(); 123 | console.log(response.data); 124 | return response.data; 125 | }); 126 | }, 127 | orderWithDeliveryAddress: function (token, cityObj, addressStreet, addressHouseNumber, addressFloor, addressDoorNumber, restaurantId, take, cutlery, products, comment) { 128 | !isEmpty(token) && setClientToken(token); 129 | return axios.post(`/order`, { 130 | restaurantId, 131 | take: take ? 1 : 0, 132 | cutlery: cutlery ? 1 : 0, 133 | products, 134 | messageCourier: comment, 135 | street: addressStreet, 136 | houseNumber: addressHouseNumber, 137 | floor: addressFloor, 138 | doorNumber: addressDoorNumber, 139 | locationId: cityObj.id 140 | }).then((response) => { 141 | !isEmpty(token) && removeClientToken(token); 142 | console.log(response.data); 143 | return response.data; 144 | }); 145 | }, 146 | } 147 | 148 | export default FoodService; -------------------------------------------------------------------------------- /src/modules/services/ProfileService.js: -------------------------------------------------------------------------------- 1 | import axios, { setClientToken, removeClientToken } from '@utils/axios'; 2 | 3 | const ProfileService = { 4 | getDeliveryList: function (token, country) { 5 | setClientToken(token); 6 | return axios.get(`/delivery-address/${country}`).then((response) => { 7 | removeClientToken(); 8 | return response.data; 9 | }); 10 | }, 11 | setDeliveryAddress: function (token, id, city, street, houseNumber, floor, doorNumber) { 12 | setClientToken(token); 13 | return axios.post(`/delivery-address`, { 14 | houseNumber, 15 | street, 16 | city: city.cities, 17 | floor, 18 | doorNumber, 19 | deliveryAddressId: id, 20 | locationNameId: city.id, 21 | operation: id === 0 ? 'create' : 'update' 22 | }).then((response) => { 23 | removeClientToken(); 24 | return response.data; 25 | }); 26 | }, 27 | deleteDeliveryAddress: function (token, id) { 28 | setClientToken(token); 29 | return axios.delete(`/delivery-address/${id}`).then((response) => { 30 | removeClientToken(); 31 | return response.data; 32 | }); 33 | }, 34 | getProfileInformation: function (token) { 35 | setClientToken(token); 36 | return axios.get(`/profile/me`).then((response) => { 37 | removeClientToken(); 38 | return response.data; 39 | }); 40 | }, 41 | modifyProfileInformation: function (token, fullName, email, phoneNumber) { 42 | console.log(token) 43 | setClientToken(token); 44 | return axios.post(`/profile/me`, { 45 | email, 46 | fullName, 47 | phoneNumber 48 | }).then((response) => { 49 | removeClientToken(); 50 | return response.data; 51 | }); 52 | }, 53 | deleteProfile: function (token) { 54 | setClientToken(token); 55 | return axios.delete(`/profile`).then((response) => { 56 | removeClientToken(); 57 | return response.data; 58 | }); 59 | }, 60 | modifyProfilePassword: function (token, oldPassword, newPassword, newPasswordAgain) { 61 | setClientToken(token); 62 | return axios.post(`/profile/change-password`, { 63 | oldPassword, 64 | newPassword, 65 | newPasswordAgain 66 | }).then((response) => { 67 | removeClientToken(); 68 | return response.data; 69 | }); 70 | }, 71 | addReviews: function (token) { 72 | setClientToken(token); 73 | return axios.get(`/restaurant-review/addition-list`).then((response) => { 74 | removeClientToken(); 75 | return response.data; 76 | }); 77 | }, 78 | viewReviews: function (token) { 79 | setClientToken(token); 80 | return axios.get(`/restaurant-review/added-list`).then((response) => { 81 | removeClientToken(); 82 | return response.data; 83 | }); 84 | }, 85 | getReview: function (token, reviewId) { 86 | setClientToken(token); 87 | return axios.get(`/restaurant-review/${reviewId}`).then((response) => { 88 | removeClientToken(); 89 | return response.data; 90 | }); 91 | }, 92 | setReview: function (token, genLink, rating, message) { 93 | setClientToken(token); 94 | return axios.post(`/restaurant-review`, { 95 | genLink, 96 | rating, 97 | message 98 | }).then((response) => { 99 | removeClientToken(); 100 | return response.data; 101 | }); 102 | }, 103 | deleteReview: function (token, reviewId) { 104 | setClientToken(token); 105 | return axios.delete(`/restaurant-review/${reviewId}`).then((response) => { 106 | removeClientToken(); 107 | return response.data; 108 | }); 109 | }, 110 | } 111 | 112 | export default ProfileService; -------------------------------------------------------------------------------- /src/modules/services/index.js: -------------------------------------------------------------------------------- 1 | import AuthService from './AuthService'; 2 | import FoodService from './FoodService'; 3 | import ProfileService from './ProfileService'; 4 | 5 | export { 6 | AuthService, 7 | FoodService, 8 | ProfileService 9 | } -------------------------------------------------------------------------------- /src/modules/stores/AuthStore.js: -------------------------------------------------------------------------------- 1 | import { isEmpty } from '@utils/functions'; 2 | 3 | class Store { 4 | 5 | } 6 | 7 | const AuthStore = new Store(); 8 | export default AuthStore; -------------------------------------------------------------------------------- /src/modules/stores/index.js: -------------------------------------------------------------------------------- 1 | import AuthStore from './AuthStore'; 2 | 3 | export { 4 | AuthStore, 5 | } -------------------------------------------------------------------------------- /src/navigations/StackNavigators/AuthStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { SignIn, SignUp, Forgot, Reset } from '@screens'; 5 | import { navOptionHandler } from '@utils/functions'; 6 | 7 | const StackAuth = createStackNavigator(); 8 | export default AuthStack = () => { 9 | return ( 10 | 12 | 13 | 14 | 15 | 16 | 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /src/navigations/StackNavigators/CartStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { CartIndex, CartDetail } from '@screens'; 5 | import { navOptionHandler } from '@utils/functions'; 6 | 7 | const StackCart = createStackNavigator(); 8 | export default CartStack = () => { 9 | return ( 10 | 12 | 13 | 14 | 15 | ) 16 | } -------------------------------------------------------------------------------- /src/navigations/StackNavigators/DeliveryStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { 5 | DeliveryList, DeliveryAdd, 6 | Success, Errors 7 | } from '@screens'; 8 | import { navOptionHandler } from '@utils/functions'; 9 | 10 | const StackDelivery = createStackNavigator(); 11 | export default DeliveryStack = () => { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | ) 20 | } -------------------------------------------------------------------------------- /src/navigations/StackNavigators/HomeStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { Home, Detail, Extra } from '@screens'; 5 | import { navOptionHandler } from '@utils/functions'; 6 | 7 | const StackHome = createStackNavigator(); 8 | export default HomeStack = () => { 9 | return ( 10 | 12 | 13 | 14 | 15 | 16 | ) 17 | } -------------------------------------------------------------------------------- /src/navigations/StackNavigators/OrderStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { OrderIndex, OrderDetail } from '@screens'; 5 | import { navOptionHandler } from '@utils/functions'; 6 | 7 | const StackOrder = createStackNavigator(); 8 | export default OrderStack = () => { 9 | return ( 10 | 12 | 13 | 14 | 15 | ) 16 | } -------------------------------------------------------------------------------- /src/navigations/StackNavigators/ProfileStackNavigator.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 3 | 4 | import { 5 | Profile, ProfileEdit, ProfileDelete, ProfilePassword, 6 | ReviewList, ReviewAdd, ReviewDelete, 7 | CouponCodes, 8 | Success, Errors 9 | } from '@screens'; 10 | import { navOptionHandler } from '@utils/functions'; 11 | 12 | const StackProfile = createStackNavigator(); 13 | export default ProfileStack = () => { 14 | return ( 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ) 30 | } -------------------------------------------------------------------------------- /src/navigations/index.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment, useEffect } from 'react'; 2 | import { useSelector } from 'react-redux'; 3 | import { NavigationContainer, StackActions } from '@react-navigation/native'; 4 | import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; 5 | import NetInfo from '@react-native-community/netinfo'; 6 | import i18n from '@utils/i18n'; 7 | 8 | import { Internet, Start, Cities, Languages, OrderSuccess } from '@screens'; 9 | import { Loading } from '@components'; 10 | import DrawerNavigator from '@navigations/DrawerNavigator'; 11 | import AuthStack from '@navigations/StackNavigators/AuthStackNavigator'; 12 | import { navOptionHandler } from '@utils/functions'; 13 | 14 | const StackApp = createStackNavigator(); 15 | export default AppContainer = () => { 16 | const { logged, country, city, user } = useSelector(state => state.auth); 17 | i18n.setLocale(country); 18 | 19 | useEffect(() => { 20 | const handleEventListener = state => { 21 | if (!state.isConnected && navigator && global.internet) { 22 | global.internet = false; 23 | navigator.dispatch(StackActions.push('Internet')); 24 | } 25 | if (state.isConnected && navigator && !global.internet) { 26 | global.internet = true; 27 | navigator.dispatch(StackActions.pop()); 28 | } 29 | } 30 | const unsubscribe = NetInfo.addEventListener(state => handleEventListener(state)); 31 | return () => unsubscribe(); 32 | }, []); 33 | 34 | return ( 35 | 36 | navigator = nav}> 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | } -------------------------------------------------------------------------------- /src/navigations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@navigations" 3 | } -------------------------------------------------------------------------------- /src/screens/Athena/Errors.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Header } from 'native-base'; 3 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import { common, colors } from '@constants/themes'; 7 | import { InternetIcon } from '@constants/svgs'; 8 | import i18n from '@utils/i18n'; 9 | 10 | export default Errors = (props) => { 11 | return ( 12 | 13 | 14 |

15 | 16 | props.navigation.pop()}> 17 | 18 | 19 | 20 | 21 | {i18n.translate('Profile data')} 22 | 23 | 24 |
25 | 26 | 27 | {i18n.translate('Operation failed')} 28 | {i18n.translate('Server error, please try again')} 29 | props.navigation.pop()}> 30 | {i18n.translate('Again')} 31 | 32 | 33 | 34 | 35 | ); 36 | } 37 | 38 | const styles = StyleSheet.create({ 39 | content: { 40 | flex: 1, 41 | padding: 20, 42 | justifyContent: 'center', 43 | alignItems: 'center' 44 | }, 45 | mainText: { 46 | marginTop: 30, 47 | fontSize: 24, 48 | fontWeight: 'bold', 49 | color: '#111' 50 | }, 51 | subText: { 52 | marginTop: 20, 53 | fontSize: 16, 54 | color: '#666' 55 | }, 56 | button: { 57 | marginTop: 50, 58 | justifyContent: 'center', 59 | alignItems: 'center', 60 | paddingHorizontal: 20, 61 | paddingVertical: 15, 62 | borderRadius: 6, 63 | backgroundColor: '#FEEBD6' 64 | }, 65 | buttonText: { 66 | fontSize: 16, 67 | fontWeight: 'bold', 68 | color: colors.YELLOW.PRIMARY 69 | } 70 | 71 | }); -------------------------------------------------------------------------------- /src/screens/Athena/Internet.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Container, Header } from 'native-base'; 3 | import { Platform, StatusBar, StyleSheet, View, Text } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import { isEmpty } from '@utils/functions'; 7 | import { common, colors } from '@constants/themes'; 8 | import { InternetIcon } from '@constants/svgs'; 9 | import i18n from '@utils/i18n'; 10 | 11 | export default Internet = (props) => { 12 | return ( 13 | 14 | 15 |
16 | 17 | 18 | {i18n.translate('No internet')} 19 | 20 | 21 |
22 | 23 | 24 | {i18n.translate('No internet connection')} 25 | {i18n.translate('Please connect to the internet and refresh')} 26 | 27 | 28 |
29 | ); 30 | } 31 | 32 | const styles = StyleSheet.create({ 33 | content: { 34 | flex: 1, 35 | padding: 20, 36 | justifyContent: 'center', 37 | alignItems: 'center' 38 | }, 39 | mainText: { 40 | marginTop: 30, 41 | fontSize: 24, 42 | fontWeight: 'bold', 43 | color: '#111' 44 | }, 45 | subText: { 46 | marginTop: 20, 47 | fontSize: 16, 48 | color: '#666' 49 | }, 50 | button: { 51 | marginTop: 50, 52 | justifyContent: 'center', 53 | alignItems: 'center', 54 | paddingHorizontal: 20, 55 | paddingVertical: 15, 56 | borderRadius: 6, 57 | backgroundColor: '#FEEBD6' 58 | }, 59 | 60 | }); -------------------------------------------------------------------------------- /src/screens/Athena/Success.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useDispatch } from 'react-redux'; 3 | import { Container, Header } from 'native-base'; 4 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import { setLoading } from '@modules/reducers/auth/actions'; 8 | import { common, colors } from '@constants/themes'; 9 | import { SuccessIcon } from '@constants/svgs'; 10 | import i18n from '@utils/i18n'; 11 | 12 | export default Success = (props) => { 13 | const dispatch = useDispatch(); 14 | const [type] = useState(props.route.params.type); 15 | 16 | return ( 17 | 18 | 19 |
20 | 21 | props.navigation.pop(2)}> 22 | 23 | 24 | 25 | 26 | {i18n.translate('Profile data')} 27 | 28 | 29 |
30 | 31 | 32 | {type == 1 ? i18n.translate('Successful data creation') : i18n.translate('Successful data modification')} 33 | props.navigation.pop(2)}> 34 | {i18n.translate('Operations')} 35 | 36 | 37 | 38 |
39 | ); 40 | } 41 | 42 | const styles = StyleSheet.create({ 43 | content: { 44 | flex: 1, 45 | padding: 20, 46 | justifyContent: 'center', 47 | alignItems: 'center' 48 | }, 49 | mainText: { 50 | marginTop: 30, 51 | fontSize: 24, 52 | fontWeight: 'bold', 53 | color: '#111' 54 | }, 55 | button: { 56 | marginTop: 50, 57 | justifyContent: 'center', 58 | alignItems: 'center', 59 | paddingHorizontal: 20, 60 | paddingVertical: 15, 61 | borderRadius: 6, 62 | backgroundColor: '#FEEBD6' 63 | }, 64 | buttonText: { 65 | fontSize: 16, 66 | fontWeight: 'bold', 67 | color: colors.YELLOW.PRIMARY 68 | } 69 | }); -------------------------------------------------------------------------------- /src/screens/Auth/index.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Platform, NativeModules, StatusBar, StyleSheet, ImageBackground, View, Text, TouchableOpacity } from 'react-native'; 4 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 5 | import { Icon } from 'react-native-elements'; 6 | import { setLoading, setCountry } from '@modules/reducers/auth/actions'; 7 | import { colors, common } from '@constants/themes'; 8 | import { images } from '@constants/assets'; 9 | import { LogoIcon } from '@constants/svgs'; 10 | import i18n from '@utils/i18n'; 11 | 12 | import Swiper from 'react-native-swiper'; 13 | 14 | const titles = [ 15 | "Foodnet coupon code shopping", 16 | "Foodnet coupon code shopping", 17 | "Foodnet coupon code shopping", 18 | ]; 19 | 20 | export default Start = (props) => { 21 | const dispatch = useDispatch(); 22 | const { country, city, user } = useSelector(state => state.auth); 23 | 24 | useEffect(() => { 25 | dispatch(setLoading(false)); 26 | const onLanguage = () => { 27 | const deviceLanguage = Platform.OS === 'ios' ? NativeModules.SettingsManager.settings.AppleLocale || NativeModules.SettingsManager.settings.AppleLanguages[0] : NativeModules.I18nManager.localeIdentifier; 28 | var deviceCode = deviceLanguage.substring(0, 2); 29 | if (deviceCode !== 'en' && deviceCode !== 'hu' && deviceCode !== 'ro') { 30 | deviceCode = 'en'; 31 | }; 32 | i18n.setLocale(deviceCode); 33 | dispatch(setCountry(deviceCode)); 34 | } 35 | user.city.id === 0 && onLanguage(); 36 | return () => console.log(country); 37 | }, []); 38 | 39 | return ( 40 | 41 | 42 | 43 | 44 | 50 | {titles.map((title, key) => ( 51 | {i18n.translate(title)} 52 | ))} 53 | 54 | 55 | 56 | 57 | props.navigation.navigate('Auth', { screen: 'SignUp' })}> 58 | {i18n.translate('Registration')} 59 | 60 | props.navigation.navigate('Auth', { screen: 'SignIn' })}> 61 | {i18n.translate('Log in')} 62 | 63 | 64 | { 65 | city.id === 0 ? props.navigation.navigate('Cities') : props.navigation.navigate('App'); 66 | }}> 67 | {i18n.translate('Continue without registration')} 68 | 69 | 70 | 71 | ); 72 | } 73 | 74 | const styles = StyleSheet.create({ 75 | bgImage: { 76 | width: wp('100%'), 77 | height: hp('100%'), 78 | }, 79 | logoIcon: { 80 | top: hp('50%') - 190, 81 | left: 25, 82 | width: 100, 83 | }, 84 | descriptionView: { 85 | top: hp('50%') - 150, 86 | left: 25, 87 | height: 100, 88 | }, 89 | descriptionText: { 90 | width: 240, 91 | height: 72, 92 | fontSize: 24, 93 | fontWeight: 'bold', 94 | lineHeight: 36, 95 | color: colors.WHITE, 96 | }, 97 | dotStyle: { 98 | marginBottom: -20, 99 | height: 10, 100 | borderRadius: 5 101 | }, 102 | bottomView: { 103 | position: 'absolute', 104 | bottom: 50, 105 | alignItems: 'center', 106 | width: wp('100%'), 107 | }, 108 | buttonView: { 109 | flexDirection: 'row', 110 | justifyContent: 'space-between', 111 | alignItems: 'center', 112 | width: '100%', 113 | padding: 25, 114 | }, 115 | button: { 116 | justifyContent: 'center', 117 | alignItems: 'center', 118 | width: wp('40%'), 119 | paddingVertical: 15, 120 | borderRadius: 6, 121 | }, 122 | continueText: { 123 | fontSize: 16, 124 | fontWeight: 'bold', 125 | color: colors.WHITE 126 | } 127 | }); -------------------------------------------------------------------------------- /src/screens/Home/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, Fragment } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Container, Header } from 'native-base'; 4 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import { setLoading } from '@modules/reducers/auth/actions'; 8 | import { setFilters } from '@modules/reducers/food/actions'; 9 | import { FoodService } from '@modules/services'; 10 | import { Cities, Dashboard, Filters } from '@components'; 11 | import { common, colors } from '@constants/themes'; 12 | import { CartYellowIcon } from '@constants/svgs'; 13 | import i18n from '@utils/i18n'; 14 | 15 | export default Home = (props) => { 16 | const dispatch = useDispatch(); 17 | const { logged, country, city, user } = useSelector(state => state.auth); 18 | const { cartBadge, filters } = useSelector(state => state.food); 19 | 20 | const [cityStatus, setCityStatus] = useState(false); 21 | const [filterStatus, setFilterStatus] = useState(false); 22 | const [promotion, setPromotion] = useState([]); 23 | const [popular, setPopular] = useState([]); 24 | const [result, setResult] = useState([]); 25 | const [refresh, setRefresh] = useState(false); 26 | const [search, setSearch] = useState(''); 27 | 28 | useEffect(() => { 29 | setCityStatus(false); 30 | setFilterStatus(false); 31 | dispatch(setLoading(true)); 32 | FoodService.promotion(country, logged ? user.city.name : city.name) 33 | .then((response) => { 34 | setRefresh(false); 35 | if (response.status == 200) { 36 | setPromotion(response.result); 37 | } 38 | }) 39 | .catch((error) => { 40 | setRefresh(false); 41 | }); 42 | FoodService.popular(country, logged ? user.city.name : city.name) 43 | .then((response) => { 44 | setRefresh(false); 45 | if (response.status == 200) { 46 | setPopular(response.result); 47 | } 48 | }) 49 | .catch((error) => { 50 | setRefresh(false); 51 | }); 52 | FoodService.all(country, logged ? user.city.name : city.name, search, filters) 53 | .then((response) => { 54 | dispatch(setLoading(false)); 55 | setRefresh(false); 56 | if (response.status == 200) { 57 | setResult(response.result); 58 | } 59 | }) 60 | .catch((error) => { 61 | dispatch(setLoading(false)); 62 | setRefresh(false); 63 | }); 64 | }, [country, city, user, refresh, filters]); 65 | 66 | useEffect(() => { 67 | FoodService.result(country, logged ? user.city.name : city.name, search, filters) 68 | .then((response) => { 69 | setRefresh(false); 70 | if (response.status == 200) { 71 | setResult(response.result); 72 | } 73 | }) 74 | .catch((error) => { 75 | setRefresh(false); 76 | }); 77 | }, [search]); 78 | 79 | return ( 80 | 81 | 82 |
83 | 84 | { 85 | setCityStatus(false); 86 | props.navigation.openDrawer(); 87 | }}> 88 | 89 | 90 | 91 | setCityStatus(!cityStatus)}> 92 | {!logged ? city.name : user.city.name} 93 | 94 | 95 | 96 | { 97 | props.navigation.navigate('Cart'); 98 | }}> 99 | {cartBadge > 0 ? ( 100 | 101 | 102 | 103 | {cartBadge} 104 | 105 | 106 | ) : ( 107 | 108 | {/* 109 | */} 110 | 111 | 112 | )} 113 | 114 | 115 |
116 | { 117 | !cityStatus ? !filterStatus ? 118 | setFilterStatus(!filterStatus)} 126 | onRefresh={() => setRefresh(true)} 127 | onSearch={(value) => setSearch(value)} 128 | onDetail={(item) => props.navigation.push('Detail', { restaurant: item })} 129 | /> : 130 | { 133 | dispatch(setFilters(value)); 134 | setFilterStatus(false); 135 | }} 136 | onCancel={() => setFilterStatus(false)} 137 | /> : 138 | setCityStatus(false)} 140 | onLoading={(load) => dispatch(setLoading(load))} 141 | /> 142 | } 143 |
144 | ); 145 | } 146 | 147 | const styles = StyleSheet.create({ 148 | badge: { 149 | justifyContent: 'center', 150 | alignItems: 'center', 151 | width: 16, 152 | height: 16, 153 | borderRadius: 8, 154 | borderWidth: 2, 155 | borderColor: '#FEEBD6', 156 | backgroundColor: colors.YELLOW.PRIMARY, 157 | marginTop: -30, 158 | marginLeft: 15 159 | }, 160 | badgeEmpty: { 161 | justifyContent: 'center', 162 | alignItems: 'center', 163 | width: 16, 164 | height: 16, 165 | marginTop: -30, 166 | marginLeft: 15 167 | }, 168 | badgeText: { 169 | fontSize: 10, 170 | fontWeight: 'bold', 171 | color: colors.WHITE 172 | }, 173 | }); -------------------------------------------------------------------------------- /src/screens/Order/OrderIndex.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Container, Header } from 'native-base'; 4 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity, FlatList } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import { setLoading } from '@modules/reducers/auth/actions'; 8 | import { FoodService } from '@modules/services'; 9 | import { isEmpty } from '@utils/functions'; 10 | import { common, colors } from '@constants/themes'; 11 | import { TrustIcon } from '@constants/svgs'; 12 | import i18n from '@utils/i18n'; 13 | 14 | export default OrderIndex = (props) => { 15 | const dispatch = useDispatch(); 16 | const { country, user } = useSelector(state => state.auth); 17 | 18 | const [orderList, setOrderList] = useState([]); 19 | 20 | useEffect(() => { 21 | if (!isEmpty(props.route.params.order)) { 22 | props.navigation.push('OrderDetail', { order: props.route.params.order }); 23 | } 24 | dispatch(setLoading(true)); 25 | FoodService.getOrders(user.token) 26 | .then((response) => { 27 | dispatch(setLoading(false)); 28 | if (response.status == 200) { 29 | setOrderList(response.result); 30 | } 31 | }) 32 | .catch((error) => { 33 | dispatch(setLoading(false)); 34 | console.log(error.message); 35 | }); 36 | }, []); 37 | 38 | // useEffect(() => { 39 | // if (finalOrderId === 0) { 40 | // var temp = 0; 41 | // } else { 42 | // props.navigation.push('OrderDetail', { order: finalOrderId }); 43 | // } 44 | // }, [finalOrderId]) 45 | 46 | const goOrder = (orderId) => { 47 | dispatch(setLoading(true)); 48 | FoodService.getOrder(user.token, country, orderId) 49 | .then((response) => { 50 | dispatch(setLoading(false)); 51 | if (response.status == 200) { 52 | props.navigation.push('OrderDetail', { order: response }); 53 | } 54 | }) 55 | .catch((error) => { 56 | dispatch(setLoading(false)); 57 | console.log(error.message); 58 | }); 59 | } 60 | 61 | const renderItem = (order, index) => { 62 | return ( 63 | 64 | 65 | {i18n.translate('Where')} 66 | 67 | 68 | {order.item.restaurant_name} 69 | 70 | 71 | {i18n.translate('Kit')} 72 | {i18n.translate('Operations')} 73 | 74 | 75 | {order.item.total} {i18n.translate('lei')} 76 | goOrder(order.item.order_id)}> 77 | {i18n.translate('View')} 78 | 79 | 80 | 81 | {i18n.translate('When')} 82 | 83 | 84 | {!isEmpty(order.item.time) && order.item.time} 85 | 86 | 87 | ) 88 | } 89 | 90 | return ( 91 | 92 | 93 |
94 | 95 | props.navigation.goBack()}> 96 | 97 | 98 | 99 | 100 | {i18n.translate('My orders')} 101 | 102 | 103 |
104 | 105 | {/* {i18n.translate('You can only write a review if you have ordered at least 5 times before')} */} 106 | index.toString()} 110 | renderItem={renderItem} 111 | /> 112 | 113 |
114 | ); 115 | } 116 | 117 | const styles = StyleSheet.create({ 118 | descriptionText: { 119 | width: '100%', 120 | fontSize: 16, 121 | fontWeight: '400', 122 | color: '#666', 123 | lineHeight: 24, 124 | marginBottom: 10 125 | }, 126 | review: { 127 | width: '100%', 128 | marginTop: 10, 129 | paddingBottom: 5, 130 | borderBottomWidth: 1, 131 | borderBottomColor: '#C4C4C4' 132 | }, 133 | status: { 134 | flexDirection: 'row', 135 | justifyContent: 'flex-start', 136 | alignItems: 'flex-start', 137 | width: '100%', 138 | marginBottom: 5 139 | }, 140 | statusText: { 141 | fontSize: 12, 142 | fontWeight: 'bold', 143 | color: '#999999' 144 | }, 145 | reviewMain: { 146 | flexDirection: 'row', 147 | justifyContent: 'flex-start', 148 | alignItems: 'center', 149 | width: '100%', 150 | height: 30, 151 | marginBottom: 5 152 | }, 153 | reviewText: { 154 | width: '70%', 155 | fontSize: 16, 156 | lineHeight: 24, 157 | color: '#111' 158 | }, 159 | reviewOption: { 160 | flexDirection: 'row', 161 | justifyContent: 'flex-end', 162 | alignItems: 'center', 163 | width: 100 164 | }, 165 | reviewAdd: { 166 | fontSize: 14, 167 | fontWeight: 'bold', 168 | color: colors.YELLOW.PRIMARY 169 | }, 170 | }); -------------------------------------------------------------------------------- /src/screens/Profile/CouponCodes.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect, Fragment } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Container, Header, Content } from 'native-base'; 4 | import { Platform, BackHandler, StatusBar, StyleSheet, View, Text, TouchableOpacity, ScrollView } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import { setLoading, setUser } from '@modules/reducers/auth/actions'; 8 | import { ProfileService } from '@modules/services'; 9 | import { isEmpty, validatePassword } from '@utils/functions'; 10 | import { common, colors } from '@constants/themes'; 11 | import { ErrorIcon } from '@constants/svgs'; 12 | import i18n from '@utils/i18n'; 13 | 14 | import { TextField } from 'react-native-material-textfield'; 15 | 16 | export default CouponCodes = (props) => { 17 | const dispatch = useDispatch(); 18 | const { user } = useSelector(state => state.auth); 19 | 20 | return ( 21 | 22 | 23 |
24 | 25 | props.navigation.goBack()}> 26 | 27 | 28 | 29 | 30 | {i18n.translate('Coupon Codes')} 31 | 32 | 33 |
34 | 35 | 36 | {i18n.translate('Fennmaradt egyenleged')}: 12345FT 37 | 38 | {i18n.translate('Your current subscription')}: Ingyenes 39 | 40 | 41 | 2. {i18n.translate('Package name')} 42 | Havi 1200 {i18n.translate('lei')} 43 | alert('OK')}> 44 | {i18n.translate('Select')} 45 | 46 | 47 | 48 | 3. {i18n.translate('Package name')} 49 | Havi 1200 {i18n.translate('lei')} 50 | alert('OK')}> 51 | {i18n.translate('Select')} 52 | 53 | 54 | 55 | 56 |
57 | ); 58 | } 59 | 60 | const styles = StyleSheet.create({ 61 | content: { 62 | padding: 20 63 | }, 64 | fenText: { 65 | fontSize: 16, 66 | }, 67 | yellowText: { 68 | fontSize: 16, 69 | fontWeight: 'bold', 70 | color: colors.YELLOW.PRIMARY 71 | }, 72 | textContainer: { 73 | justifyContent: 'center', 74 | marginTop: 14, 75 | width: '100%', 76 | height: 50, 77 | borderWidth: 1, 78 | borderColor: '#C4C4C4', 79 | borderRadius: 8, 80 | paddingLeft: 15, 81 | paddingRight: 20, 82 | }, 83 | buttonView: { 84 | marginTop: 24, 85 | padding: 20, 86 | alignItems: 'center', 87 | backgroundColor: '#FEEBD6', 88 | borderRadius: 10 89 | }, 90 | yellowTitle: { 91 | marginTop: 15, 92 | fontSize: 18, 93 | fontWeight: 'bold', 94 | color: colors.YELLOW.PRIMARY 95 | }, 96 | normalText: { 97 | marginTop: 16, 98 | fontSize: 16, 99 | fontWeight: '400' 100 | }, 101 | button: { 102 | marginTop: 18, 103 | width: '100%', 104 | height: 40, 105 | justifyContent: 'center', 106 | alignItems: 'center', 107 | backgroundColor: colors.YELLOW.PRIMARY, 108 | borderRadius: 10 109 | } 110 | }); 111 | -------------------------------------------------------------------------------- /src/screens/Profile/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { useSelector, useDispatch } from 'react-redux'; 3 | import { Container, Header, Content } from 'native-base'; 4 | import { Platform, StatusBar, StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 5 | import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen'; 6 | import { Icon } from 'react-native-elements'; 7 | import { setLoading, deleteUser } from '@modules/reducers/auth/actions'; 8 | import { ProfileService } from '@modules/services'; 9 | import { common, colors } from '@constants/themes'; 10 | import i18n from '@utils/i18n'; 11 | 12 | export default Profile = (props) => { 13 | const dispatch = useDispatch(); 14 | const { user } = useSelector(state => state.auth); 15 | 16 | const onLogout = () => { 17 | dispatch(deleteUser({ 18 | token: null, 19 | email: user.email, 20 | name: user.name, 21 | city: { 22 | id: user.city.id, 23 | name: user.city.name, 24 | status: false 25 | } 26 | })); 27 | props.navigation.reset({ index: 1, routes: [{ name: 'Start' }] }) 28 | } 29 | 30 | const goProfileEdit = () => { 31 | dispatch(setLoading(true)); 32 | ProfileService.getProfileInformation(user.token) 33 | .then((response) => { 34 | dispatch(setLoading(false)); 35 | if (response.status == 200) { 36 | props.navigation.push('ProfileEdit', { userInfo: response.result }); 37 | } 38 | }) 39 | .catch((error) => { 40 | dispatch(setLoading(false)); 41 | }); 42 | } 43 | 44 | return ( 45 | 46 | 47 |
48 | 49 | props.navigation.goBack()}> 50 | 51 | 52 | 53 | 54 | {user.name} 55 | 56 | 57 |
58 | 59 | {/* props.navigation.push('DeliveryList')}> 60 | {i18n.translate('Delivery addresses list')} 61 | 62 | */} 63 | goProfileEdit()}> 64 | {i18n.translate('Edit profile information')} 65 | 66 | 67 | props.navigation.push('ProfilePassword')}> 68 | {i18n.translate('Change password')} 69 | 70 | 71 | {/* props.navigation.push('CouponCodes')}> 72 | {i18n.translate('Coupon codes')} 73 | 74 | 75 | 76 | {i18n.translate('My orders')} 77 | 78 | */} 79 | props.navigation.push('ReviewList')}> 80 | {i18n.translate('Restaurant reviews')} 81 | 82 | 83 | props.navigation.push('ProfileDelete')}> 84 | {i18n.translate('Delete profile')} 85 | 86 | 87 | {/* onLogout()}> 88 | {i18n.translate('Sign out')} 89 | */} 90 | 91 |
92 | ); 93 | } 94 | 95 | const styles = StyleSheet.create({ 96 | item: { 97 | flexDirection: 'row', 98 | justifyContent: 'space-between', 99 | alignItems: 'center', 100 | width: '100%', 101 | height: 60, 102 | borderBottomWidth: 1, 103 | borderBottomColor: '#C4C4C4' 104 | }, 105 | itemText: { 106 | fontSize: 16, 107 | color: '#111111' 108 | }, 109 | signout: { 110 | flexDirection: 'row', 111 | justifyContent: 'space-between', 112 | alignItems: 'center', 113 | width: '100%', 114 | height: 60, 115 | }, 116 | }); -------------------------------------------------------------------------------- /src/screens/index.js: -------------------------------------------------------------------------------- 1 | import Internet from '@screens/Athena/Internet'; 2 | import Languages from '@screens/Athena/Languages'; 3 | import Success from '@screens/Athena/Success'; 4 | import Errors from '@screens/Athena/Errors'; 5 | 6 | import Start from '@screens/Auth'; 7 | import SignIn from '@screens/Auth/SignIn'; 8 | import SignUp from '@screens/Auth/SignUp'; 9 | import Forgot from '@screens/Auth/Forgot'; 10 | import Reset from '@screens/Auth/Reset'; 11 | import Cities from '@screens/Auth/Cities'; 12 | 13 | import Home from '@screens/Home'; 14 | import Detail from '@screens/Home/Detail'; 15 | import Extra from '@screens/Home/Extra'; 16 | 17 | import DeliveryList from '@screens/Delivery/DeliveryList'; 18 | import DeliveryAdd from '@screens/Delivery/DeliveryAdd'; 19 | 20 | import Profile from '@screens/Profile'; 21 | import ProfileEdit from '@screens/Profile/ProfileEdit'; 22 | import ProfileDelete from '@screens/Profile/ProfileDelete'; 23 | import ProfilePassword from '@screens/Profile/ProfilePassword'; 24 | import ReviewList from '@screens/Review/ReviewList'; 25 | import ReviewAdd from '@screens/Review/ReviewAdd'; 26 | import ReviewDelete from '@screens/Review/ReviewDelete'; 27 | import CouponCodes from '@screens/Profile/CouponCodes'; 28 | 29 | import CartIndex from '@screens/Cart/CartIndex'; 30 | import CartDetail from '@screens/Cart/CartDetail'; 31 | 32 | import OrderIndex from '@screens/Order/OrderIndex'; 33 | import OrderDetail from '@screens/Order/OrderDetail'; 34 | import OrderSuccess from '@screens/Order/OrderSuccess'; 35 | 36 | export { 37 | Internet, 38 | Languages, 39 | Success, 40 | Errors, 41 | 42 | Start, 43 | SignIn, 44 | SignUp, 45 | Forgot, 46 | Reset, 47 | Cities, 48 | 49 | Home, 50 | Detail, 51 | Extra, 52 | 53 | Profile, 54 | DeliveryList, 55 | DeliveryAdd, 56 | ProfileEdit, 57 | ProfileDelete, 58 | ProfilePassword, 59 | ReviewList, 60 | ReviewAdd, 61 | ReviewDelete, 62 | CouponCodes, 63 | 64 | CartIndex, 65 | CartDetail, 66 | OrderIndex, 67 | OrderDetail, 68 | OrderSuccess 69 | } -------------------------------------------------------------------------------- /src/screens/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@screens" 3 | } -------------------------------------------------------------------------------- /src/utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { API_URL } from '@constants/configs'; 3 | 4 | axios.defaults.baseURL = API_URL; 5 | axios.defaults.headers.common = { 'Content-Type': 'application/json' }; 6 | // axios.defaults.headers.common = { 'Content-Transfer-Encoding': 'application/gzip' }; 7 | axios.defaults.responseType = 'json'; 8 | 9 | export const setClientToken = token => { 10 | axios.defaults.headers.common['x-auth-token'] = token; 11 | }; 12 | 13 | export const removeClientToken = () => { 14 | delete axios.defaults.headers.common['x-auth-token']; 15 | }; 16 | 17 | export default axios; -------------------------------------------------------------------------------- /src/utils/functions.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import 'intl'; 3 | import 'intl/locale-data/jsonp/en'; 4 | 5 | import { NAME_PATTERN, EMAIL_PATTERN, PASSWORD_PATTERN, ALIAS_PATTERN, MOBILE_PATTERN } from '@constants/regexs'; 6 | 7 | export const navOptionHandler = () => ({ 8 | headerShown: false, 9 | animationEnabled: true, 10 | // gestureEnabled: true 11 | }); 12 | 13 | export const validateName = (value) => { 14 | if (value.length >= 3 && value.length <= 20) { 15 | return true; 16 | } 17 | return false; 18 | } 19 | 20 | export const validateEmail = (value) => { 21 | if (EMAIL_PATTERN.test(value)) { 22 | return true; 23 | } 24 | return false; 25 | } 26 | 27 | export const validateMobile = (value) => { 28 | if (MOBILE_PATTERN.test(value)) { 29 | return true; 30 | } 31 | return false; 32 | } 33 | 34 | export const validatePassword = (value) => { 35 | if (PASSWORD_PATTERN.test(value)) { 36 | return true; 37 | } 38 | return false; 39 | } 40 | 41 | export const validateAlias = (value) => { 42 | if (ALIAS_PATTERN.test(value)) { 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | export const validateLength = (value, length) => { 49 | if (value.length >= length) { 50 | return true; 51 | } 52 | return false; 53 | } 54 | export const validateBetween = (value, min, max) => { 55 | if (value.length >= min && value.length <= max) { 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | export const isEmpty = (param) => { 62 | return param == undefined || param == null || (typeof param === 'string' && param == '') || (typeof param === 'object' && param.length == 0) || (typeof param === 'array' && param.length == 0); 63 | } 64 | 65 | export function SendPushNotification(token, title, body, data) { 66 | axios({ 67 | method: 'POST', 68 | url: 'https://fcm.googleapis.com/fcm/send', 69 | headers: { 70 | 'Content-Type': 'application/json', 71 | 'Authorization': 'key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' 72 | }, 73 | data: { 74 | to: token, 75 | notification: { 76 | title: title, 77 | body: body, 78 | data: data 79 | } 80 | }, 81 | }).then((response) => { 82 | console.log(response); 83 | }); 84 | } -------------------------------------------------------------------------------- /src/utils/i18n.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { I18nManager } from "react-native"; 3 | import * as Localization from "react-native-localization"; 4 | import i18n from "i18n-js"; 5 | 6 | const en = require("@assets/languages/en"); 7 | const hu = require("@assets/languages/hu"); 8 | const ro = require("@assets/languages/ro"); 9 | 10 | const rtlLanguages = ['ar', 'arc', 'dv', 'fa', 'ha', 'he', 'khw', 'ks', 'ku', 'ps', 'ur', 'yi']; 11 | 12 | const translate = (key, config) => { 13 | let msg = i18n.t(key, config) 14 | if (missingTranslationRegex.test(msg)) { 15 | msg = i18n.t(key, 'en') 16 | } 17 | return msg 18 | } 19 | 20 | const missingTranslationRegex = /^\[missing ".*" translation\]$/; 21 | 22 | const setI18nConfig = () => { 23 | i18n.fallbacks = true 24 | i18n.translations = { en, hu, ro }; 25 | i18n.defaultLocale = 'en' 26 | // I18nManager.forceRTL(false); 27 | }; 28 | 29 | const setLocale = (locale = 'en') => { 30 | i18n.locale = locale 31 | } 32 | 33 | const getCurrentLocale = () => { 34 | return i18n.locale 35 | } 36 | 37 | const setDefaultLocale = (locale = 'en') => { 38 | i18n.defaultLocale = locale 39 | } 40 | 41 | const enableFallbacks = () => { 42 | i18n.fallbacks = true; 43 | } 44 | 45 | const getLocales = async () => { 46 | return await Localization.getLocales() 47 | } 48 | 49 | const isRTL = () => { 50 | const currLocale = i18n.locale 51 | let count = 0 52 | for (let i = 0; i < 12; i++) { 53 | if (rtlLanguages[i] == currLocale) { 54 | count = 1; 55 | break; 56 | } 57 | } 58 | if (count == 0) { 59 | // I18nManager.forceRTL(false); 60 | return false; 61 | } else { 62 | // I18nManager.forceRTL(true); 63 | return true; 64 | } 65 | } 66 | 67 | export default { 68 | enableFallbacks, 69 | setDefaultLocale, 70 | getCurrentLocale, 71 | setLocale, 72 | setI18nConfig, 73 | translate, 74 | getLocales, 75 | isRTL 76 | } -------------------------------------------------------------------------------- /src/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@utils" 3 | } --------------------------------------------------------------------------------