├── .bundle └── config ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── App.js ├── Gemfile ├── README.md ├── __tests__ └── App.test.tsx ├── android ├── app │ ├── build.gradle │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── fonts │ │ │ ├── Poppins-Black.ttf │ │ │ ├── Poppins-Bold.ttf │ │ │ ├── Poppins-Light.ttf │ │ │ ├── Poppins-Medium.ttf │ │ │ ├── Poppins-Regular.ttf │ │ │ ├── Poppins-SemiBold.ttf │ │ │ ├── Poppins-Thin.ttf │ │ │ └── feather1s.ttf │ │ ├── java │ │ └── com │ │ │ └── frontendsource │ │ │ └── grocerystore │ │ │ ├── MainActivity.kt │ │ │ └── MainApplication.kt │ │ └── res │ │ ├── drawable │ │ └── rn_edit_text_material.xml │ │ ├── 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 ├── link-assets-manifest.json └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios ├── .xcode.env ├── GroceryStore.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── GroceryStore.xcscheme ├── GroceryStore │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ ├── LaunchScreen.storyboard │ └── main.m ├── Podfile ├── grocerystoreTests │ ├── Info.plist │ └── grocerystoreTests.m └── link-assets-manifest.json ├── jest.config.js ├── metro.config.js ├── package-lock.json ├── package.json ├── react-native.config.js ├── src ├── assets │ ├── fonts │ │ ├── Poppins-Black.ttf │ │ ├── Poppins-Bold.ttf │ │ ├── Poppins-Light.ttf │ │ ├── Poppins-Medium.ttf │ │ ├── Poppins-Regular.ttf │ │ ├── Poppins-SemiBold.ttf │ │ ├── Poppins-Thin.ttf │ │ └── feather1s.ttf │ └── images │ │ ├── emptycart.png │ │ ├── emptyproduct.png │ │ ├── home.png │ │ ├── image.png │ │ ├── logo.png │ │ ├── mail_box_img.png │ │ ├── offer1.jpg │ │ ├── offer2.jpg │ │ ├── original-logo.png │ │ ├── slide1.png │ │ ├── slide2.png │ │ ├── slide3.png │ │ ├── thankyou.png │ │ ├── thumb1.png │ │ ├── thumb2.png │ │ ├── thumb3.png │ │ └── user.png ├── axios │ ├── API.js │ └── ServerRequest.js ├── components │ ├── AppIntro │ │ ├── AppIntro.js │ │ └── components │ │ │ ├── DoneButton.android.js │ │ │ ├── DoneButton.ios.js │ │ │ ├── Dots.js │ │ │ ├── SkipButton.android.js │ │ │ └── SkipButton.ios.js │ ├── AppStatusBar.js │ ├── BadgeIcon.js │ ├── BannerSlider.js │ ├── Card │ │ └── index.js │ ├── CartItem │ │ └── index.js │ ├── CountDownTimer.js │ ├── Loading.js │ ├── LoadingButton │ │ └── index.js │ ├── Logo │ │ └── index.js │ ├── Popup-UI │ │ ├── assets │ │ │ ├── Error.png │ │ │ ├── Success.png │ │ │ ├── Warning.png │ │ │ └── wifi.png │ │ ├── basic │ │ │ ├── Popup │ │ │ │ └── index.js │ │ │ └── Root │ │ │ │ └── index.js │ │ └── index.js │ ├── ProductItem │ │ ├── OrderItem.js │ │ ├── ProductRow.js │ │ └── index.js │ ├── SearchBar │ │ └── index.js │ ├── ToastMessage │ │ ├── Toast.js │ │ ├── ToastStyles.android.js │ │ ├── ToastStyles.ios.js │ │ ├── Toaster.js │ │ └── index.js │ ├── ToolBar.js │ ├── UserInput │ │ └── index.js │ ├── ViewSlider │ │ ├── dots.js │ │ └── index.js │ └── styles │ │ └── styles.js ├── navigation │ └── CustomSidebarMenu.js ├── screen │ ├── AddressScreen.js │ ├── CategoryScreen.js │ ├── ForgotPasswordScreen.js │ ├── HomeScreen.js │ ├── LoginScreen.js │ ├── MyCartScreen.js │ ├── MyOrderScreen.js │ ├── NewProductScreen.js │ ├── OTPScreen.js │ ├── OffersScreen.js │ ├── PlaceOrder.js │ ├── PopularProductScreen.js │ ├── ProductView.js │ ├── ProductsScreen.js │ ├── ProfileScreen.js │ ├── RegisterScreen.js │ ├── SplashScreen.js │ ├── ThankYou.js │ └── WelcomeScreen.js ├── theme │ ├── Color.js │ ├── Dimension.js │ ├── Fonts.js │ ├── Layout.js │ ├── Strings.js │ ├── appStyles.js │ └── index.js └── utils │ ├── Cart.js │ ├── LocalStorage │ └── index.js │ └── Validator │ ├── Validator.js │ └── rule │ └── index.js └── tsconfig.json /.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /.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 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper 7 | # bound in the template on Cocoapods with next React Native release. 8 | gem 'cocoapods', '>= 1.13', '< 1.15' 9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | >**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. 6 | 7 | ## Step 1: Start the Metro Server 8 | 9 | First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 10 | 11 | To start Metro, run the following command from the _root_ of your React Native project: 12 | 13 | ```bash 14 | # using npm 15 | npm start 16 | 17 | # OR using Yarn 18 | yarn start 19 | ``` 20 | 21 | ## Step 2: Start your Application 22 | 23 | Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: 24 | 25 | ### For Android 26 | 27 | ```bash 28 | # using npm 29 | npm run android 30 | 31 | # OR using Yarn 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | # using npm 39 | npm run ios 40 | 41 | # OR using Yarn 42 | yarn ios 43 | ``` 44 | 45 | If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. 46 | 47 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 48 | 49 | ## Step 3: Modifying your App 50 | 51 | Now that you have successfully run the app, let's modify it. 52 | 53 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 54 | 2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! 55 | 56 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 57 | 58 | ## Congratulations! :tada: 59 | 60 | You've successfully run and modified your React Native App. :partying_face: 61 | 62 | ### Now what? 63 | 64 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). 65 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 66 | 67 | # Troubleshooting 68 | 69 | If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. 70 | 71 | # Learn More 72 | 73 | To learn more about React Native, take a look at the following resources: 74 | 75 | - [React Native Website](https://reactnative.dev) - learn more about React Native. 76 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. 77 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. 78 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. 79 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. 80 | -------------------------------------------------------------------------------- /__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shipped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(); 17 | }); 18 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | /** 6 | * This is the configuration block to customize your React Native Android app. 7 | * By default you don't need to apply any configuration, just uncomment the lines you need. 8 | */ 9 | react { 10 | /* Folders */ 11 | // The root of your project, i.e. where "package.json" lives. Default is '..' 12 | // root = file("../") 13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 14 | // reactNativeDir = file("../node_modules/react-native") 15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 16 | // codegenDir = file("../node_modules/@react-native/codegen") 17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 18 | // cliFile = file("../node_modules/react-native/cli.js") 19 | 20 | /* Variants */ 21 | // The list of variants to that are debuggable. For those we're going to 22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 24 | // debuggableVariants = ["liteDebug", "prodDebug"] 25 | 26 | /* Bundling */ 27 | // A list containing the node command and its flags. Default is just 'node'. 28 | // nodeExecutableAndArgs = ["node"] 29 | // 30 | // The command to run when bundling. By default is 'bundle' 31 | // bundleCommand = "ram-bundle" 32 | // 33 | // The path to the CLI configuration file. Default is empty. 34 | // bundleConfig = file(../rn-cli.config.js) 35 | // 36 | // The name of the generated asset file containing your JS bundle 37 | // bundleAssetName = "MyApplication.android.bundle" 38 | // 39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 40 | // entryFile = file("../js/MyApplication.android.js") 41 | // 42 | // A list of extra flags to pass to the 'bundle' commands. 43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 44 | // extraPackagerArgs = [] 45 | 46 | /* Hermes Commands */ 47 | // The hermes compiler command to run. By default it is 'hermesc' 48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 49 | // 50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 51 | // hermesFlags = ["-O", "-output-source-map"] 52 | } 53 | 54 | /** 55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 56 | */ 57 | def enableProguardInReleaseBuilds = false 58 | 59 | /** 60 | * The preferred build flavor of JavaScriptCore (JSC) 61 | * 62 | * For example, to use the international variant, you can use: 63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 64 | * 65 | * The international variant includes ICU i18n library and necessary data 66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 67 | * give correct results when using with locales other than en-US. Note that 68 | * this variant is about 6MiB larger per architecture than default. 69 | */ 70 | def jscFlavor = 'org.webkit:android-jsc:+' 71 | 72 | android { 73 | ndkVersion rootProject.ext.ndkVersion 74 | buildToolsVersion rootProject.ext.buildToolsVersion 75 | compileSdk rootProject.ext.compileSdkVersion 76 | 77 | namespace "com.grocerystore" 78 | defaultConfig { 79 | applicationId "com.grocerystore" 80 | minSdkVersion rootProject.ext.minSdkVersion 81 | targetSdkVersion rootProject.ext.targetSdkVersion 82 | versionCode 1 83 | versionName "1.0" 84 | } 85 | signingConfigs { 86 | debug { 87 | storeFile file('debug.keystore') 88 | storePassword 'android' 89 | keyAlias 'androiddebugkey' 90 | keyPassword 'android' 91 | } 92 | } 93 | buildTypes { 94 | debug { 95 | signingConfig signingConfigs.debug 96 | } 97 | release { 98 | // Caution! In production, you need to generate your own keystore file. 99 | // see https://reactnative.dev/docs/signed-apk-android. 100 | signingConfig signingConfigs.debug 101 | minifyEnabled enableProguardInReleaseBuilds 102 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 103 | } 104 | } 105 | } 106 | 107 | dependencies { 108 | // The version of react-native is set by the React Native Gradle Plugin 109 | implementation("com.facebook.react:react-android") 110 | implementation("com.facebook.react:flipper-integration") 111 | 112 | if (hermesEnabled.toBoolean()) { 113 | implementation("com.facebook.react:hermes-android") 114 | } else { 115 | implementation jscFlavor 116 | } 117 | } 118 | 119 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 120 | apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") 121 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Black.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Bold.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Light.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Medium.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Regular.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Poppins-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/Poppins-Thin.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/feather1s.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/assets/fonts/feather1s.ttf -------------------------------------------------------------------------------- /android/app/src/main/java/com/frontendsource/grocerystore/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.grocerystore 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | override fun getMainComponentName(): String = "GroceryStore" 15 | 16 | /** 17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 19 | */ 20 | override fun createReactActivityDelegate(): ReactActivityDelegate = 21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 22 | } 23 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/frontendsource/grocerystore/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.grocerystore 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 11 | import com.facebook.react.defaults.DefaultReactNativeHost 12 | import com.facebook.react.flipper.ReactNativeFlipper 13 | import com.facebook.soloader.SoLoader 14 | 15 | class MainApplication : Application(), ReactApplication { 16 | 17 | override val reactNativeHost: ReactNativeHost = 18 | object : DefaultReactNativeHost(this) { 19 | override fun getPackages(): List = 20 | PackageList(this).packages.apply { 21 | // Packages that cannot be autolinked yet can be added manually here, for example: 22 | // add(MyReactNativePackage()) 23 | } 24 | 25 | override fun getJSMainModuleName(): String = "index" 26 | 27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 28 | 29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 31 | } 32 | 33 | override val reactHost: ReactHost 34 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost) 35 | 36 | override fun onCreate() { 37 | super.onCreate() 38 | SoLoader.init(this, false) 39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 40 | // If you opted-in for the New Architecture, we load the native entry point for this app. 41 | load() 42 | } 43 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Grocery Store 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 21 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "25.1.8937393" 8 | kotlinVersion = "1.8.0" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /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: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 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 | # Use this property to specify which architecture you want to build. 28 | # You can also override it from the CLI using 29 | # ./gradlew -PreactNativeArchitectures=x86_64 30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 31 | 32 | # Use this property to enable support to the new architecture. 33 | # This will allow you to use TurboModules and the Fabric render in 34 | # your application. You should enable this flag either if you want 35 | # to write custom TurboModules/Fabric components OR use libraries that 36 | # are providing them. 37 | newArchEnabled=false 38 | 39 | # Use this property to enable or disable the Hermes JS engine. 40 | # If set to false, you will be using JSC instead. 41 | hermesEnabled=true 42 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/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-8.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /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 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /android/link-assets-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "migIndex": 1, 3 | "data": [ 4 | { 5 | "path": "src/assets/fonts/feather1s.ttf", 6 | "sha1": "aa86fd4ad427f5b98a1c7b80e2737191125b9e2b" 7 | }, 8 | { 9 | "path": "src/assets/fonts/Poppins-Black.ttf", 10 | "sha1": "6b1dd041c24de51d8859c4d83909c35c099a8219" 11 | }, 12 | { 13 | "path": "src/assets/fonts/Poppins-Bold.ttf", 14 | "sha1": "f68e7e93da3f4a710d28b0ee5f744b5112351401" 15 | }, 16 | { 17 | "path": "src/assets/fonts/Poppins-Light.ttf", 18 | "sha1": "987ef3e07d6361fbb658624e297750133f2343bd" 19 | }, 20 | { 21 | "path": "src/assets/fonts/Poppins-Medium.ttf", 22 | "sha1": "72b668cb1639c6b0588c6fffa1ae9a967409e8ae" 23 | }, 24 | { 25 | "path": "src/assets/fonts/Poppins-Regular.ttf", 26 | "sha1": "a4ef48c17479236fea2197b9a68bf7c6163e0388" 27 | }, 28 | { 29 | "path": "src/assets/fonts/Poppins-SemiBold.ttf", 30 | "sha1": "e1a01a240fb449797ac08a37490d59b61a059e6d" 31 | }, 32 | { 33 | "path": "src/assets/fonts/Poppins-Thin.ttf", 34 | "sha1": "561e8929100d5e1b8e6bba314ef1e59c22906eba" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'GroceryStore' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GroceryStore", 3 | "displayName": "GroceryStore" 4 | } 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | plugins: ['react-native-reanimated/plugin'], 4 | }; 5 | -------------------------------------------------------------------------------- /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/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /ios/GroceryStore.xcodeproj/xcshareddata/xcschemes/GroceryStore.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/GroceryStore/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/GroceryStore/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"GroceryStore"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | return [self getBundleURL]; 20 | } 21 | 22 | - (NSURL *)getBundleURL 23 | { 24 | #if DEBUG 25 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 26 | #else 27 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 28 | #endif 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /ios/GroceryStore/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ios/GroceryStore/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/GroceryStore/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Grocery Store 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 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsLocalNetworking 32 | 33 | 34 | NSLocationWhenInUseUsageDescription 35 | 36 | UILaunchStoryboardName 37 | LaunchScreen 38 | UIRequiredDeviceCapabilities 39 | 40 | armv7 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | UIAppFonts 51 | 52 | feather1s.ttf 53 | Poppins-Black.ttf 54 | Poppins-Bold.ttf 55 | Poppins-Light.ttf 56 | Poppins-Medium.ttf 57 | Poppins-Regular.ttf 58 | Poppins-SemiBold.ttf 59 | Poppins-Thin.ttf 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ios/GroceryStore/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/GroceryStore/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target 'GroceryStore' do 29 | config = use_native_modules! 30 | 31 | use_react_native!( 32 | :path => config[:reactNativePath], 33 | # Enables Flipper. 34 | # 35 | # Note that if you have use_frameworks! enabled, Flipper will not work and 36 | # you should disable the next line. 37 | :flipper_configuration => flipper_config, 38 | # An absolute path to your application root. 39 | :app_path => "#{Pod::Config.instance.installation_root}/.." 40 | ) 41 | 42 | target 'GroceryStoreTests' do 43 | inherit! :complete 44 | # Pods for testing 45 | end 46 | 47 | post_install do |installer| 48 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 49 | react_native_post_install( 50 | installer, 51 | config[:reactNativePath], 52 | :mac_catalyst_enabled => false 53 | ) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /ios/grocerystoreTests/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/grocerystoreTests/grocerystoreTests.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 GroceryStoreTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation GroceryStoreTests 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( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /ios/link-assets-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "migIndex": 1, 3 | "data": [ 4 | { 5 | "path": "src/assets/fonts/feather1s.ttf", 6 | "sha1": "aa86fd4ad427f5b98a1c7b80e2737191125b9e2b" 7 | }, 8 | { 9 | "path": "src/assets/fonts/Poppins-Black.ttf", 10 | "sha1": "6b1dd041c24de51d8859c4d83909c35c099a8219" 11 | }, 12 | { 13 | "path": "src/assets/fonts/Poppins-Bold.ttf", 14 | "sha1": "f68e7e93da3f4a710d28b0ee5f744b5112351401" 15 | }, 16 | { 17 | "path": "src/assets/fonts/Poppins-Light.ttf", 18 | "sha1": "987ef3e07d6361fbb658624e297750133f2343bd" 19 | }, 20 | { 21 | "path": "src/assets/fonts/Poppins-Medium.ttf", 22 | "sha1": "72b668cb1639c6b0588c6fffa1ae9a967409e8ae" 23 | }, 24 | { 25 | "path": "src/assets/fonts/Poppins-Regular.ttf", 26 | "sha1": "a4ef48c17479236fea2197b9a68bf7c6163e0388" 27 | }, 28 | { 29 | "path": "src/assets/fonts/Poppins-SemiBold.ttf", 30 | "sha1": "e1a01a240fb449797ac08a37490d59b61a059e6d" 31 | }, 32 | { 33 | "path": "src/assets/fonts/Poppins-Thin.ttf", 34 | "sha1": "561e8929100d5e1b8e6bba314ef1e59c22906eba" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config"); 2 | 3 | const defaultConfig = getDefaultConfig(__dirname); 4 | const { assetExts, sourceExts } = defaultConfig.resolver; 5 | 6 | /** 7 | * Metro configuration 8 | * https://facebook.github.io/metro/docs/configuration 9 | * 10 | * @type {import('metro-config').MetroConfig} 11 | */ 12 | const config = { 13 | transformer: { 14 | babelTransformerPath: require.resolve("react-native-svg-transformer") 15 | }, 16 | resolver: { 17 | assetExts: assetExts.filter((ext) => ext !== "svg"), 18 | sourceExts: [...sourceExts, "svg"] 19 | } 20 | }; 21 | 22 | module.exports = mergeConfig(defaultConfig, config); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GroceryStore", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@react-native-async-storage/async-storage": "^1.21.0", 14 | "@react-native-community/checkbox": "^0.5.17", 15 | "@react-native-community/geolocation": "^3.1.0", 16 | "@react-native-community/netinfo": "^11.3.1", 17 | "@react-native-community/picker": "^1.8.1", 18 | "@react-native-firebase/app": "^18.8.0", 19 | "@react-native-firebase/auth": "^18.8.0", 20 | "@react-native-firebase/messaging": "^18.8.0", 21 | "@react-native-masked-view/masked-view": "^0.3.1", 22 | "@react-navigation/bottom-tabs": "^6.5.20", 23 | "@react-navigation/drawer": "^6.6.6", 24 | "@react-navigation/native": "^6.1.9", 25 | "@react-navigation/native-stack": "^6.9.17", 26 | "@reduxjs/toolkit": "^2.1.0", 27 | "axios": "^1.6.7", 28 | "moment": "^2.30.1", 29 | "react": "18.2.0", 30 | "react-moment": "^1.1.3", 31 | "react-native": "0.73.7", 32 | "react-native-app-intro-slider": "^4.0.4", 33 | "react-native-country-codes-picker": "^2.3.5", 34 | "react-native-custom-picker": "^0.4.0", 35 | "react-native-geocoding": "^0.5.0", 36 | "react-native-gesture-handler": "^2.15.0", 37 | "react-native-image-picker": "^7.1.0", 38 | "react-native-internet-connection-alert": "^0.1.9", 39 | "react-native-linear-gradient": "^2.8.3", 40 | "react-native-loader-kit": "^2.0.8", 41 | "react-native-modal": "^13.0.1", 42 | "react-native-popup-menu": "^0.16.1", 43 | "react-native-progress-circle": "^2.1.0", 44 | "react-native-reanimated": "^3.6.2", 45 | "react-native-render-html": "^6.3.4", 46 | "react-native-safe-area-context": "^4.9.0", 47 | "react-native-screens": "^3.29.0", 48 | "react-native-simple-toast": "^3.2.0", 49 | "react-native-smooth-pincode-input": "^1.0.9", 50 | "react-native-star-rating": "^1.0.8", 51 | "react-native-step-indicator": "^1.0.3", 52 | "react-native-svg": "^14.1.0", 53 | "react-native-svg-transformer": "^1.3.0", 54 | "react-native-vector-icons": "^10.0.3", 55 | "react-native-web": "^0.19.10", 56 | "react-number-format": "^5.3.1", 57 | "react-redux": "^9.1.0", 58 | "redux-thunk": "^3.1.0", 59 | "rn-progress-loader": "^1.0.8" 60 | }, 61 | "devDependencies": { 62 | "@babel/core": "^7.20.0", 63 | "@babel/preset-env": "^7.20.0", 64 | "@babel/runtime": "^7.20.0", 65 | "@react-native/babel-preset": "0.73.21", 66 | "@react-native/eslint-config": "0.73.2", 67 | "@react-native/metro-config": "0.73.5", 68 | "@react-native/typescript-config": "0.73.1", 69 | "@types/react": "^18.2.6", 70 | "@types/react-test-renderer": "^18.0.0", 71 | "babel-jest": "^29.6.3", 72 | "eslint": "^8.19.0", 73 | "jest": "^29.6.3", 74 | "metro-react-native-babel-preset": "^0.77.0", 75 | "prettier": "2.8.8", 76 | "react-test-renderer": "18.2.0", 77 | "typescript": "5.0.4" 78 | }, 79 | "engines": { 80 | "node": ">=18" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dependencies: { 3 | 'react-native-vector-icons': { 4 | platforms: { 5 | ios: null, 6 | }, 7 | }, 8 | }, 9 | project: { 10 | ios: {}, 11 | android: {}, // grouped into "project" 12 | }, 13 | assets: ['./src/assets/fonts/'], // stays the same 14 | }; 15 | -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Black.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Bold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Medium.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-SemiBold.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Poppins-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/Poppins-Thin.ttf -------------------------------------------------------------------------------- /src/assets/fonts/feather1s.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/fonts/feather1s.ttf -------------------------------------------------------------------------------- /src/assets/images/emptycart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/emptycart.png -------------------------------------------------------------------------------- /src/assets/images/emptyproduct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/emptyproduct.png -------------------------------------------------------------------------------- /src/assets/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/home.png -------------------------------------------------------------------------------- /src/assets/images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/image.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/mail_box_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/mail_box_img.png -------------------------------------------------------------------------------- /src/assets/images/offer1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/offer1.jpg -------------------------------------------------------------------------------- /src/assets/images/offer2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/offer2.jpg -------------------------------------------------------------------------------- /src/assets/images/original-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/original-logo.png -------------------------------------------------------------------------------- /src/assets/images/slide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/slide1.png -------------------------------------------------------------------------------- /src/assets/images/slide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/slide2.png -------------------------------------------------------------------------------- /src/assets/images/slide3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/slide3.png -------------------------------------------------------------------------------- /src/assets/images/thankyou.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/thankyou.png -------------------------------------------------------------------------------- /src/assets/images/thumb1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/thumb1.png -------------------------------------------------------------------------------- /src/assets/images/thumb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/thumb2.png -------------------------------------------------------------------------------- /src/assets/images/thumb3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/thumb3.png -------------------------------------------------------------------------------- /src/assets/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/assets/images/user.png -------------------------------------------------------------------------------- /src/axios/API.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | // const URL = 'http://192.168.50.150/grocerystore/'; 3 | const URL = 'https://freshmart.frontendsourcecode.com/'; 4 | export const BASE_URL = URL; 5 | 6 | const API = async config => { 7 | // const token = await getApiKey(); 8 | // console.log(token); 9 | // if (token) { 10 | // config.headers = { 11 | // authorization: token, 12 | // }; 13 | // } 14 | //interceptors handle network error 15 | axios.interceptors.response.use( 16 | response => { 17 | return response; 18 | }, 19 | function(error) { 20 | if (!error.response) { 21 | error.response = { 22 | data: 'net work error', 23 | status: 500, 24 | }; 25 | } 26 | if (error.response.status === 401) { 27 | console.log('Unauthorised'); 28 | } 29 | return Promise.reject(error); 30 | }, 31 | ); 32 | config.baseURL = URL; 33 | return axios(config); 34 | }; 35 | export default API; 36 | -------------------------------------------------------------------------------- /src/axios/ServerRequest.js: -------------------------------------------------------------------------------- 1 | import API, {BASE_URL} from './API'; 2 | import NetInfo from '@react-native-community/netinfo'; 3 | import Toast from 'react-native-simple-toast'; 4 | import {getToken} from '../utils/LocalStorage'; 5 | 6 | export const CategoryImage = BASE_URL + 'assets/images/ProductImage/category/'; 7 | export const ProductImage = BASE_URL + 'assets/images/ProductImage/product/'; 8 | 9 | export const checkInternetConnection = () => { 10 | NetInfo.fetch().then(state => { 11 | if (state.isConnected === false) { 12 | Toast.showWithGravity( 13 | 'No internet connection', 14 | Toast.SHORT, 15 | Toast.BOTTOM, 16 | ); 17 | } 18 | }); 19 | }; 20 | 21 | export const userLogin = async (mobile, password) => { 22 | const body = { 23 | mobile: mobile, 24 | password: password, 25 | }; 26 | return await API({ 27 | method: 'POST', 28 | url: 'api/v1/login', 29 | data: body, 30 | }).then(res => { 31 | return res; 32 | }); 33 | }; 34 | 35 | export const userRegister = async (name, mobile, password) => { 36 | const body = { 37 | name: name, 38 | mobile: mobile, 39 | password: password, 40 | }; 41 | return await API({ 42 | method: 'POST', 43 | url: 'api/v1/register', 44 | data: body, 45 | }).then(res => { 46 | return res; 47 | }); 48 | }; 49 | export const getAllCategory = async () => { 50 | return await API({ 51 | method: 'POST', 52 | url: 'api/v1/categories', 53 | data: {token: await getToken()}, 54 | }).then(res => { 55 | return res; 56 | }); 57 | }; 58 | export const getNewProducts = async () => { 59 | return await API({ 60 | method: 'POST', 61 | url: 'api/v1/newProducts', 62 | data: {token: await getToken()}, 63 | }).then(res => { 64 | return res; 65 | }); 66 | }; 67 | export const getBanners = async () => { 68 | return await API({ 69 | method: 'GET', 70 | url: 'api/v1/banners', 71 | }).then(res => { 72 | return res; 73 | }); 74 | }; 75 | export const getOffers = async () => { 76 | return await API({ 77 | method: 'GET', 78 | url: 'api/v1/offers', 79 | }).then(res => { 80 | return res; 81 | }); 82 | }; 83 | 84 | export const getPopularProducts = async () => { 85 | return await API({ 86 | method: 'POST', 87 | url: 'api/v1/homepage', 88 | data: {token: await getToken()}, 89 | }).then(res => { 90 | return res; 91 | }); 92 | }; 93 | 94 | export const getProductList = async categoryName => { 95 | return await API({ 96 | method: 'POST', 97 | url: 'api/v1/getlist', 98 | data: {token: await getToken(), categry: categoryName}, 99 | }).then(res => { 100 | return res; 101 | }); 102 | }; 103 | 104 | export const getProductByCategory = async id => { 105 | return await API({ 106 | method: 'POST', 107 | url: 'api/v1/category/products', 108 | data: {token: await getToken(), category_id: id}, 109 | }).then(res => { 110 | return res; 111 | }); 112 | }; 113 | 114 | export const getProductBySubCategory = async id => { 115 | return await API({ 116 | method: 'POST', 117 | url: 'api/v1/sub-category/products', 118 | data: {token: await getToken(), category_id: id}, 119 | }).then(res => { 120 | return res; 121 | }); 122 | }; 123 | 124 | export const updateUser = async user => { 125 | return await API({ 126 | method: 'POST', 127 | url: 'api/v1/update_user', 128 | data: user, 129 | }).then(res => { 130 | return res; 131 | }); 132 | }; 133 | export const searchProduct = async text => { 134 | return await API({ 135 | method: 'GET', 136 | url: `api/v1/product/search?s=${text}`, 137 | }).then(res => { 138 | return res; 139 | }); 140 | }; 141 | 142 | export const orderPlace = async orderDetails => { 143 | return await API({ 144 | method: 'Post', 145 | url: 'api/v1/placeOrder', 146 | data: orderDetails, 147 | }).then(res => { 148 | return res; 149 | }); 150 | }; 151 | export const getOrderDetails = async (token, id) => { 152 | return await API({ 153 | method: 'Post', 154 | url: 'api/v1/orderDetails', 155 | data: { 156 | token: token, 157 | user_id: id, 158 | }, 159 | }).then(res => { 160 | return res; 161 | }); 162 | }; 163 | 164 | export const forgotPassword = async mobile => { 165 | const body = { 166 | mobile: mobile, 167 | }; 168 | return await API({ 169 | method: 'POST', 170 | url: 'api/v1/forgot_password', 171 | data: body, 172 | }).then(res => { 173 | return res; 174 | }); 175 | }; 176 | 177 | export const resetPassword = async (otp, password) => { 178 | const body = { 179 | otp: otp, 180 | password: password, 181 | }; 182 | return await API({ 183 | method: 'POST', 184 | url: 'api/v1/reset_password', 185 | data: body, 186 | }).then(res => { 187 | return res; 188 | }); 189 | }; 190 | -------------------------------------------------------------------------------- /src/components/AppIntro/components/DoneButton.android.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View, 5 | TouchableOpacity, 6 | } from 'react-native'; 7 | 8 | export const DoneButton = ({ 9 | styles, onDoneBtnClick, onNextBtnClick, 10 | rightTextColor, isDoneBtnShow, 11 | doneBtnLabel, nextBtnLabel, 12 | }) => { 13 | return ( 14 | 15 | 18 | 19 | {isDoneBtnShow ? doneBtnLabel : nextBtnLabel} 20 | 21 | 22 | 23 | ) 24 | } 25 | 26 | export default DoneButton -------------------------------------------------------------------------------- /src/components/AppIntro/components/DoneButton.ios.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View, 5 | TouchableOpacity, 6 | Animated 7 | } from 'react-native'; 8 | 9 | export const DoneButton = ({ 10 | styles, onDoneBtnClick, onNextBtnClick, 11 | rightTextColor, isDoneBtnShow, 12 | doneBtnLabel, nextBtnLabel, 13 | doneFadeOpacity, skipFadeOpacity, nextOpacity 14 | }) => { 15 | return ( 16 | 17 | 27 | 28 | 31 | {doneBtnLabel} 32 | 33 | 34 | 35 | 36 | 38 | 39 | {nextBtnLabel} 40 | 41 | 42 | 43 | 44 | ) 45 | } 46 | 47 | export default DoneButton 48 | -------------------------------------------------------------------------------- /src/components/AppIntro/components/Dots.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View 5 | } from 'react-native'; 6 | 7 | export const Dot = ({ 8 | styles, dotColor, activeDotColor, active 9 | }) => { 10 | if (active) { 11 | return ( 12 | 17 | ); 18 | } else { 19 | return ( 20 | 24 | ); 25 | } 26 | } 27 | 28 | export const RenderDots = (index, total, props) => { 29 | let dots = []; 30 | for (let i = 0; i < total; i++) { 31 | dots.push(React.createElement(Dot, { 32 | ...props, 33 | key: i, 34 | active: i === index 35 | })); 36 | } 37 | return dots; 38 | } 39 | 40 | export default RenderDots; -------------------------------------------------------------------------------- /src/components/AppIntro/components/SkipButton.android.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View, 5 | TouchableOpacity, 6 | Animated 7 | } from 'react-native'; 8 | 9 | export const SkipButton = ({ 10 | styles, onSkipBtnClick, isSkipBtnShow, 11 | leftTextColor, 12 | skipBtnLabel, 13 | skipFadeOpacity 14 | }) => { 15 | return ( 16 | 20 | onSkipBtnClick() : null}> 23 | 24 | {skipBtnLabel} 25 | 26 | 27 | 28 | ) 29 | } 30 | 31 | export default SkipButton 32 | -------------------------------------------------------------------------------- /src/components/AppIntro/components/SkipButton.ios.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View, 5 | TouchableOpacity, 6 | Animated 7 | } from 'react-native'; 8 | 9 | export const SkipButton = ({ 10 | styles, onSkipBtnClick, isSkipBtnShow, 11 | leftTextColor, 12 | skipBtnLabel, 13 | skipFadeOpacity 14 | }) => { 15 | return ( 16 | 26 | onSkipBtnClick() : null}> 29 | 30 | {skipBtnLabel} 31 | 32 | 33 | 34 | ) 35 | } 36 | 37 | export default SkipButton 38 | -------------------------------------------------------------------------------- /src/components/AppStatusBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, StatusBar, View, Platform} from 'react-native'; 3 | 4 | const AppStatusBar = ({backgroundColor, ...props}) => ( 5 | 6 | 7 | 8 | ); 9 | 10 | const BAR_HEIGHT = Platform.OS === 'ios' ? 35 : StatusBar.currentHeight; 11 | 12 | const styles = StyleSheet.create({ 13 | statusBar: { 14 | height: BAR_HEIGHT, 15 | }, 16 | }); 17 | 18 | export default AppStatusBar; 19 | -------------------------------------------------------------------------------- /src/components/BadgeIcon.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import Icon from 'react-native-vector-icons/Feather'; 4 | import Color from '../theme/Color'; 5 | 6 | import {TouchableOpacity} from 'react-native'; 7 | 8 | function BadgeIcon(props) { 9 | return ( 10 | 19 | 20 | {props.icon ? ( 21 | 22 | ) : null} 23 | {props.count && props.count > 0 ? ( 24 | 25 | {props.count} 26 | 27 | ) : null} 28 | 29 | 30 | ); 31 | } 32 | 33 | const styles = StyleSheet.create({ 34 | badgeContainer: { 35 | position: 'relative', 36 | }, 37 | 38 | badge: { 39 | position: 'absolute', 40 | top: -10, 41 | right: 0, 42 | alignItems: 'center', 43 | backgroundColor: 'white', 44 | borderRadius: 20, 45 | width: 20, 46 | height: 20, 47 | textAlign: 'center', 48 | paddingTop: 2, 49 | fontSize: 10, 50 | color: Color.colorPrimary, 51 | }, 52 | badgeText: { 53 | fontSize: 10, 54 | }, 55 | }); 56 | 57 | export default BadgeIcon; 58 | -------------------------------------------------------------------------------- /src/components/BannerSlider.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, ScrollView, Image} from 'react-native'; 3 | import ViewSlider from '../components/ViewSlider'; 4 | import Dimension from '../theme/Dimension'; 5 | import {TouchableOpacity} from 'react-native'; 6 | import Color from '../theme/Color'; 7 | import Fonts from '../theme/Fonts'; 8 | import Strings from '../theme/Strings'; 9 | import {BASE_URL} from '../axios/API'; 10 | const {width, height} = Dimension.window; 11 | 12 | function BannerSlider(props) { 13 | return ( 14 | 17 | {props.banners.map((item, index) => { 18 | return ( 19 | 20 | console.log(BASE_URL + item.image)}> 22 | 28 | 29 | 30 | ); 31 | })} 32 | 33 | } 34 | style={styles.slider} //Main slider container style 35 | height={180} //Height of your slider 36 | slideCount={props.banners.length} //How many views you are adding to slide 37 | dots={true} // Pagination dots visibility true for visibile 38 | dotActiveColor={Color.colorPrimary} //Pagination dot active color 39 | dotInactiveColor={Color.gray} // Pagination do inactive color 40 | dotsContainerStyle={styles.dotContainer} // Container style of the pagination dots 41 | autoSlide={true} //The views will slide automatically 42 | slideInterval={3000} //In Miliseconds 43 | /> 44 | ); 45 | } 46 | const styles = StyleSheet.create({ 47 | viewBox: { 48 | paddingHorizontal: 20, 49 | justifyContent: 'center', 50 | width: width, 51 | alignItems: 'center', 52 | height: '100%', 53 | }, 54 | slider: { 55 | alignSelf: 'center', 56 | justifyContent: 'center', 57 | alignItems: 'center', 58 | backgroundColor: 'transparent', 59 | }, 60 | dotContainer: { 61 | backgroundColor: 'transparent', 62 | position: 'absolute', 63 | bottom: 0, 64 | }, 65 | }); 66 | 67 | export default BannerSlider; 68 | -------------------------------------------------------------------------------- /src/components/Card/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, StyleSheet} from 'react-native'; 3 | 4 | function Card(props) { 5 | return ( 6 | {props.children} 7 | ); 8 | } 9 | 10 | const styles = StyleSheet.create({ 11 | cardContainer: { 12 | backgroundColor: '#ffffff', 13 | shadowColor: '#000', 14 | shadowOffset: { 15 | width: 0, 16 | height: 2, 17 | }, 18 | shadowOpacity: 0.25, 19 | shadowRadius: 3.84, 20 | 21 | elevation: 5, 22 | borderRadius: 20, 23 | padding: 10, 24 | margin: 10, 25 | zIndex: 999999999, 26 | }, 27 | }); 28 | 29 | export default Card; 30 | -------------------------------------------------------------------------------- /src/components/CartItem/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, ScrollView, Image} from 'react-native'; 3 | import {Color, Fonts, Strings, Dimension} from '../../theme'; 4 | import {ProductImage} from '../../axios/ServerRequest'; 5 | import Icon from 'react-native-vector-icons/Feather'; 6 | import {TouchableOpacity} from 'react-native'; 7 | import AppStatusBar from '../../components/AppStatusBar'; 8 | import ToolBar from '../../components/ToolBar'; 9 | import { BASE_URL } from '../../axios/API'; 10 | class ProductItem extends Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = { 14 | item: this.props.item, 15 | count: this.props.count ? this.props.count : 0, 16 | cart: null, 17 | totalPrice: 0, 18 | }; 19 | } 20 | 21 | setCart = (item, id, value, price) => { 22 | let cart = { 23 | count: value, 24 | id: id, 25 | item: item, 26 | subTotal: parseFloat(price) * value, 27 | }; 28 | this.setState( 29 | { 30 | cart: cart, 31 | }, 32 | () => { 33 | this.props.addToCart(this.state.cart); 34 | }, 35 | ); 36 | }; 37 | 38 | render() { 39 | const {item, count} = this.props; 40 | return ( 41 | 42 | 43 | 44 | 45 | 51 | 52 | 53 | {item.name} 54 | 55 | {' '} 56 | {item.attribute + ' - ' + item.currency + ' ' + item.price} 57 | 58 | 59 | { 61 | this.setState({ 62 | count: this.state.count - 1, 63 | }); 64 | this.setCart( 65 | item, 66 | item.id, 67 | this.state.count - 1, 68 | item.price, 69 | ); 70 | }}> 71 | 72 | 73 | 74 | {count + 75 | '*' + 76 | item.price + 77 | ' = ' + 78 | item.currency + 79 | ' ' + 80 | count * item.price} 81 | 82 | { 84 | this.setState({ 85 | count: this.state.count + 1, 86 | }); 87 | this.setCart( 88 | item, 89 | item.id, 90 | this.state.count + 1, 91 | item.price, 92 | ); 93 | }}> 94 | 95 | 96 | 97 | 98 | 99 | 100 | { 102 | this.setState({ 103 | count: 0, 104 | }); 105 | this.setCart(item, item.id, 0, item.price); 106 | }}> 107 | 108 | 109 | 110 | 111 | 112 | ); 113 | } 114 | } 115 | 116 | 117 | 118 | const styles = StyleSheet.create({ 119 | mainContainer: { 120 | paddingLeft: 15, 121 | paddingRight: 15, 122 | paddingBottom: 10, 123 | paddingTop: 10, 124 | }, 125 | container: { 126 | width: '100%', 127 | backgroundColor: Color.white, 128 | shadowColor: '#000', 129 | shadowOffset: { 130 | width: 0, 131 | height: 2, 132 | }, 133 | shadowOpacity: 0.25, 134 | shadowRadius: 3.84, 135 | borderRadius: 10, 136 | elevation: 2, 137 | display: 'flex', 138 | flexDirection: 'column', 139 | }, 140 | row: { 141 | display: 'flex', 142 | flexDirection: 'row', 143 | justifyContent: 'space-around', 144 | alignItems: 'center', 145 | padding: 10, 146 | }, 147 | innerContainer: { 148 | display: 'flex', 149 | flexDirection: 'column', 150 | justifyContent: 'center', 151 | alignItems: 'center', 152 | }, 153 | title: { 154 | fontFamily: Fonts.primarySemiBold, 155 | fontSize: 14, 156 | color: Color.titleColor, 157 | textAlign: 'left', 158 | marginLeft: 20, 159 | marginRight: 10, 160 | }, 161 | quantityCount: { 162 | fontFamily: Fonts.primarySemiBold, 163 | fontSize: 14, 164 | color: Color.black, 165 | marginLeft: 10, 166 | marginRight: 10, 167 | }, 168 | attribute: { 169 | fontFamily: Fonts.primarySemiBold, 170 | fontSize: 14, 171 | color: Color.colorPrimary, 172 | textAlign: 'left', 173 | marginLeft: 20, 174 | marginRight: 10, 175 | marginBottom: 10, 176 | marginTop:10 177 | }, 178 | counter: { 179 | fontFamily: Fonts.primarySemiBold, 180 | fontSize: 16, 181 | color: Color.black, 182 | textAlign: 'center', 183 | width: 30, 184 | }, 185 | option: { 186 | fontFamily: Fonts.primarySemiBold, 187 | fontSize: 14, 188 | color: Color.red, 189 | textAlign: 'center', 190 | marginLeft: 10, 191 | marginRight: 10, 192 | marginBottom: 10, 193 | }, 194 | productImage: { 195 | height: 70, 196 | width: 70, 197 | }, 198 | addToCart: { 199 | backgroundColor: Color.colorPrimary, 200 | color: Color.white, 201 | textAlign: 'center', 202 | borderRadius: 20, 203 | }, 204 | quantity: { 205 | display: 'flex', 206 | flexDirection: 'row', 207 | backgroundColor: Color.white, 208 | color: Color.white, 209 | textAlign: 'center', 210 | borderRadius: 20, 211 | justifyContent: 'center', 212 | alignItems: 'center', 213 | height: 33, 214 | shadowColor: '#000', 215 | shadowOffset: { 216 | width: 0, 217 | height: 1, 218 | }, 219 | shadowOpacity: 0.2, 220 | shadowRadius: 1.41, 221 | 222 | elevation: 2, 223 | }, 224 | quantitContainer: { 225 | display: 'flex', 226 | flexDirection: 'row', 227 | marginLeft: 20, 228 | }, 229 | 230 | addToCartText: { 231 | paddingTop: 7, 232 | paddingBottom: 7, 233 | paddingLeft: 20, 234 | paddingRight: 20, 235 | color: Color.white, 236 | }, 237 | box2: { 238 | display: 'flex', 239 | width: '100%', 240 | flexDirection: 'row', 241 | paddingLeft: 15, 242 | paddingRight: 15, 243 | paddingBottom: 10, 244 | paddingTop: 10, 245 | justifyContent: 'center', 246 | alignItems: 'center', 247 | }, 248 | plusBtn: { 249 | padding: 10, 250 | }, 251 | border: { 252 | borderBottomWidth: 1, 253 | borderColor: Color.graylight, 254 | }, 255 | deleteBtn: { 256 | position: 'absolute', 257 | bottom: 10, 258 | right: 10, 259 | zIndex: 999, 260 | }, 261 | }); 262 | export default ProductItem; 263 | -------------------------------------------------------------------------------- /src/components/CountDownTimer.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {render} from 'react-dom'; 3 | import {View, Text} from 'react-native'; 4 | 5 | function CountDownTimer(props) { 6 | const [counter, setCounter] = React.useState(props.time); 7 | 8 | // Third Attempts 9 | React.useEffect(() => { 10 | const timer = 11 | counter > 0 && setInterval(() => setCounter(counter - 1), 1000); 12 | return () => clearInterval(timer); 13 | }, [counter]); 14 | 15 | return ( 16 | 17 | {counter} 18 | 19 | ); 20 | } 21 | 22 | export default CountDownTimer; 23 | -------------------------------------------------------------------------------- /src/components/Loading.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | View, 4 | StyleSheet, 5 | Animated, 6 | Easing, 7 | ActivityIndicator, 8 | Modal, 9 | } from 'react-native'; 10 | 11 | export default class Loading extends Component { 12 | static EasingType = Easing; 13 | 14 | 15 | 16 | constructor(props) { 17 | super(props); 18 | this.doingAnimation = false; 19 | this.easing = Easing.ease; 20 | this.state = { 21 | rotate_value: new Animated.Value(0), 22 | show: false, 23 | startAnimation: false, 24 | }; 25 | } 26 | 27 | _startAnimation = () => { 28 | this.doingAnimation = true; 29 | this.state.rotate_value.setValue(0); 30 | Animated.timing(this.state.rotate_value, { 31 | toValue: 1, 32 | duration: 1000, 33 | easing: Easing.out(this.easing), 34 | }).start(() => { 35 | if (this.state.startAnimation) { 36 | this._startAnimation(); 37 | } 38 | }); 39 | }; 40 | 41 | /** 42 | * show loading 43 | * @param isShow 44 | */ 45 | show(isShow = true) { 46 | if (isShow) { 47 | this.setState(state => { 48 | state.show = true; 49 | state.startAnimation = true; 50 | return state; 51 | }); 52 | !this.doingAnimation && this._startAnimation(); 53 | } else { 54 | this.close(); 55 | } 56 | } 57 | 58 | /** 59 | * hide loading 60 | */ 61 | close() { 62 | this.doingAnimation = false; 63 | this.setState(state => { 64 | state.show = false; 65 | state.startAnimation = false; 66 | return state; 67 | }); 68 | } 69 | 70 | render() { 71 | const { 72 | image = null, 73 | backgroundColor = '#ffffffF2', 74 | borderRadius = 5, 75 | size = 70, 76 | imageSize = 40, 77 | indicatorColor = 'gray', 78 | easing = Easing.ease, 79 | loading = null, 80 | } = this.props; 81 | this.easing = easing; 82 | 83 | let {show} = this.state; 84 | if (loading != null) { 85 | show = loading; 86 | } 87 | return ( 88 | {}} visible={show}> 89 | 90 | 100 | {image ? ( 101 | 116 | ) : ( 117 | 122 | )} 123 | 124 | 125 | 126 | ); 127 | } 128 | } 129 | 130 | const styles = StyleSheet.create({ 131 | loadingView: { 132 | flex: 1, 133 | backgroundColor: '#00000033', 134 | alignItems: 'center', 135 | justifyContent: 'center', 136 | }, 137 | loading: { 138 | alignItems: 'center', 139 | justifyContent: 'center', 140 | }, 141 | }); 142 | 143 | export const EasingType = Loading.EasingType; 144 | -------------------------------------------------------------------------------- /src/components/LoadingButton/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Button, StyleSheet, Text, ActivityIndicator} from 'react-native'; 3 | import Color from '../../theme/Color'; 4 | import Font from '../../theme/Fonts'; 5 | import {TouchableOpacity} from 'react-native'; 6 | function LoadingButton(props) { 7 | return ( 8 | 9 | {props.loading ? ( 10 | 21 | 22 | 23 | ) : ( 24 | 27 | {props.title} 28 | 29 | )} 30 | 31 | ); 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | buttonStyle: { 36 | color: Color.white, 37 | paddingLeft: 20, 38 | paddingRight: 20, 39 | paddingTop: 5, 40 | paddingBottom: 5, 41 | borderRadius: 5, 42 | backgroundColor: Color.colorPrimary, 43 | }, 44 | buttonText: { 45 | color: Color.white, 46 | fontFamily: Font.primaryRegular, 47 | fontSize: 14, 48 | textAlign: 'center', 49 | }, 50 | }); 51 | 52 | export default LoadingButton; 53 | -------------------------------------------------------------------------------- /src/components/Logo/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Image, StyleSheet} from 'react-native'; 3 | 4 | function Logo(props) { 5 | return ( 6 | 7 | 11 | 12 | ); 13 | } 14 | 15 | const styles = StyleSheet.create({ 16 | logoContainer: { 17 | justifyContent: 'center', 18 | alignItems: 'center', 19 | display: 'flex', 20 | width: '100%', 21 | }, 22 | logo: { 23 | width: 150, 24 | height: 150, 25 | resizeMode: 'contain', 26 | }, 27 | }); 28 | 29 | export default Logo; 30 | -------------------------------------------------------------------------------- /src/components/Popup-UI/assets/Error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/components/Popup-UI/assets/Error.png -------------------------------------------------------------------------------- /src/components/Popup-UI/assets/Success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/components/Popup-UI/assets/Success.png -------------------------------------------------------------------------------- /src/components/Popup-UI/assets/Warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/components/Popup-UI/assets/Warning.png -------------------------------------------------------------------------------- /src/components/Popup-UI/assets/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frontendsourcecode/GroceryStore-ReactNative/2ba29508ac3ba06d2c2c582fe6c50b2260a16612/src/components/Popup-UI/assets/wifi.png -------------------------------------------------------------------------------- /src/components/Popup-UI/basic/Popup/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { View, Text, TouchableOpacity, StyleSheet, Image, Animated, Dimensions, Alert } from 'react-native' 3 | 4 | const WIDTH = Dimensions.get('screen').width 5 | const HEIGHT = Dimensions.get('screen').height 6 | 7 | class Popup extends Component { 8 | static popupInstance 9 | 10 | static show({ ...config }) { 11 | this.popupInstance.start(config) 12 | } 13 | 14 | static hide() { 15 | this.popupInstance.hidePopup() 16 | } 17 | 18 | state = { 19 | positionView: new Animated.Value(HEIGHT), 20 | opacity: new Animated.Value(0), 21 | positionPopup: new Animated.Value(HEIGHT), 22 | popupHeight: 0 23 | } 24 | 25 | start({ ...config }){ 26 | this.setState({ 27 | title: config.title, 28 | type: config.type, 29 | textBody: config.textBody, 30 | button: config.button || true, 31 | buttonText: config.buttonText || 'Ok', 32 | callback: config.callback !== undefined ? config.callback : this.defaultCallback(), 33 | background: config.background || 'rgba(0, 0, 0, 0.5)', 34 | timing: config.timing, 35 | autoClose: config.autoClose || false 36 | }) 37 | 38 | Animated.sequence([ 39 | Animated.timing(this.state.positionView, { 40 | toValue: 0, 41 | duration: 100 42 | }), 43 | Animated.timing(this.state.opacity, { 44 | toValue: 1, 45 | duration: 300 46 | }), 47 | Animated.spring(this.state.positionPopup, { 48 | toValue: (HEIGHT / 2) - (this.state.popupHeight / 2), 49 | bounciness: 15, 50 | useNativeDriver: true 51 | }) 52 | ]).start() 53 | 54 | if(config.autoClose && config.timing !== 0) { 55 | const duration = config.timing > 0 ? config.timing : 5000 56 | setTimeout(() => { 57 | this.hidePopup() 58 | }, duration) 59 | } 60 | } 61 | 62 | hidePopup(){ 63 | Animated.sequence([ 64 | Animated.timing(this.state.positionPopup, { 65 | toValue: HEIGHT, 66 | duration: 250, 67 | useNativeDriver: true 68 | }), 69 | Animated.timing(this.state.opacity, { 70 | toValue: 0, 71 | duration: 300 72 | }), 73 | Animated.timing(this.state.positionView, { 74 | toValue: HEIGHT, 75 | duration: 100 76 | }) 77 | ]).start() 78 | } 79 | 80 | defaultCallback() { 81 | return Alert.alert( 82 | 'Callback!', 83 | 'Callback complete!', 84 | [ 85 | { text: 'Ok', onPress: () => this.hidePopup() } 86 | ] 87 | ) 88 | } 89 | 90 | handleImage(type){ 91 | switch(type){ 92 | case 'Success': return require('../../assets/Success.png') 93 | case 'Danger': return require('../../assets/Error.png') 94 | case 'Warning': return require('../../assets/Warning.png') 95 | } 96 | } 97 | 98 | render(){ 99 | const { title, type, textBody, button, buttonText, callback, background } = this.state 100 | 101 | return( 102 | this._root = c} 104 | style={[styles.Container, { 105 | backgroundColor: background || 'transparent', 106 | opacity: this.state.opacity, 107 | transform: [ 108 | { translateY: this.state.positionView } 109 | ] 110 | }]}> 111 | { 113 | this.setState({ popupHeight: event.nativeEvent.layout.height }) 114 | }} 115 | style={[styles.Message, { 116 | transform: [ 117 | { translateY: this.state.positionPopup } 118 | ] 119 | }]} 120 | 121 | > 122 | 123 | 128 | 129 | { title } 130 | { textBody } 131 | { 132 | button && 133 | 134 | { buttonText } 135 | 136 | } 137 | 138 | 139 | 140 | ) 141 | } 142 | } 143 | 144 | const styles = StyleSheet.create({ 145 | Container: { 146 | position: 'absolute', 147 | zIndex: 9, 148 | width: WIDTH, 149 | height: HEIGHT, 150 | backgroundColor: 'rgba(0, 0, 0, 0.5)', 151 | alignItems: 'center', 152 | top: 0, 153 | left: 0 154 | }, 155 | Message: { 156 | maxWidth: 300, 157 | width: 230, 158 | minHeight: 300, 159 | backgroundColor: '#fff', 160 | borderRadius: 30, 161 | alignItems: 'center', 162 | overflow: 'hidden', 163 | position: 'absolute', 164 | }, 165 | Content: { 166 | padding: 20, 167 | alignItems: 'center' 168 | }, 169 | Header: { 170 | height: 230, 171 | width: 230, 172 | backgroundColor: '#FBFBFB', 173 | borderRadius: 100, 174 | marginTop: -120 175 | }, 176 | Image: { 177 | width: 150, 178 | height: 80, 179 | position: 'absolute', 180 | top: 20 181 | }, 182 | Title: { 183 | fontWeight: 'bold', 184 | fontSize: 18, 185 | color: '#333' 186 | }, 187 | Desc: { 188 | textAlign: 'center', 189 | color: '#666', 190 | marginTop: 10 191 | }, 192 | Button: { 193 | borderRadius: 50, 194 | height: 40, 195 | width: 130, 196 | justifyContent: 'center', 197 | alignItems: 'center', 198 | marginTop: 30 199 | }, 200 | TextButton: { 201 | color: '#fff', 202 | fontWeight: 'bold' 203 | }, 204 | Success: { 205 | backgroundColor: '#AAF577', 206 | shadowColor: "#AAF577", 207 | shadowOffset: { 208 | width: 0, 209 | height: 5, 210 | }, 211 | shadowOpacity: 0.36, 212 | shadowRadius: 6.68, 213 | elevation: 11 214 | }, 215 | Danger: { 216 | backgroundColor: '#F29091', 217 | shadowColor: "#F29091", 218 | shadowOffset: { 219 | width: 0, 220 | height: 5, 221 | }, 222 | shadowOpacity: 0.36, 223 | shadowRadius: 6.68, 224 | elevation: 11 225 | }, 226 | Warning: { 227 | backgroundColor: '#fbd10d', 228 | shadowColor: "#fbd10d", 229 | shadowOffset: { 230 | width: 0, 231 | height: 5, 232 | }, 233 | shadowOpacity: 0.36, 234 | shadowRadius: 6.68, 235 | elevation: 11 236 | } 237 | }) 238 | 239 | export default Popup -------------------------------------------------------------------------------- /src/components/Popup-UI/basic/Root/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, ViewPropTypes} from 'react-native'; 3 | 4 | import Popup from '../Popup'; 5 | 6 | class Root extends Component { 7 | render() { 8 | return ( 9 | (this._root = c)} style={{flex: 1}} {...this.props}> 10 | {this.props.children} 11 | { 13 | if (c) Popup.popupInstance = c; 14 | }} 15 | /> 16 | 17 | ); 18 | } 19 | } 20 | 21 | 22 | 23 | export default Root; 24 | -------------------------------------------------------------------------------- /src/components/Popup-UI/index.js: -------------------------------------------------------------------------------- 1 | import Root from './basic/Root'; 2 | import Popup from './basic/Popup'; 3 | 4 | export {Root, Popup}; 5 | -------------------------------------------------------------------------------- /src/components/ProductItem/OrderItem.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, ScrollView, Image} from 'react-native'; 3 | import {Color, Fonts, Strings, Dimension} from '../../theme'; 4 | import {ProductImage} from '../../axios/ServerRequest'; 5 | import { BASE_URL } from '../../axios/API'; 6 | 7 | class OrderItem extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = {}; 11 | } 12 | render() { 13 | const {item, count, subTotal} = this.props; 14 | return ( 15 | 16 | 17 | 18 | 24 | 25 | 26 | {item.name} 27 | 28 | {item.attribute + ' - ' + item.currency + ' ' + item.price} 29 | 30 | 31 | {count}X{item.currency + ' ' + item.price}= 32 | {item.currency + ' ' + subTotal} 33 | 34 | 35 | 36 | 37 | ); 38 | } 39 | } 40 | 41 | export default OrderItem; 42 | 43 | const styles = StyleSheet.create({ 44 | container: { 45 | height: 130, 46 | flex: 1, 47 | backgroundColor: Color.white, 48 | shadowColor: '#000', 49 | shadowOffset: { 50 | width: 0, 51 | height: 2, 52 | }, 53 | shadowOpacity: 0.25, 54 | shadowRadius: 3.84, 55 | borderRadius: 10, 56 | elevation: 5, 57 | margin: 10, 58 | justifyContent: 'center', 59 | alignItems: 'center', 60 | display: 'flex', 61 | flexDirection: 'column', 62 | }, 63 | box1: { 64 | width: '100%', 65 | height: '100%', 66 | display: 'flex', 67 | flexDirection: 'row', 68 | paddingTop: 20, 69 | }, 70 | innerContainer: { 71 | display: 'flex', 72 | flexDirection: 'column', 73 | justifyContent: 'center', 74 | alignItems: 'center', 75 | }, 76 | title: { 77 | fontFamily: Fonts.primaryRegular, 78 | fontSize: 14, 79 | color: Color.gray, 80 | display: 'flex', 81 | justifyContent: 'center', 82 | alignItems: 'center', 83 | fontWeight: '600', 84 | marginLeft: 10, 85 | marginRight: 10, 86 | 87 | height: 40, 88 | width: Dimension.window.width - 150, 89 | }, 90 | option: { 91 | fontFamily: Fonts.primarySemiBold, 92 | fontSize: 14, 93 | color: Color.red, 94 | marginLeft: 10, 95 | marginRight: 10, 96 | }, 97 | productImage: { 98 | height: 70, 99 | width: 70, 100 | }, 101 | }); 102 | -------------------------------------------------------------------------------- /src/components/ProductItem/ProductRow.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, ScrollView, Image} from 'react-native'; 3 | import {Color, Fonts, Strings, Dimension} from '../../theme'; 4 | import {ProductImage} from '../../axios/ServerRequest'; 5 | import Icon from 'react-native-vector-icons/Feather'; 6 | import {TouchableOpacity} from 'react-native'; 7 | import {BASE_URL} from '../../axios/API'; 8 | class ProductItem extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | item: this.props.item, 13 | count: this.props.count ? this.props.count : 0, 14 | cart: null, 15 | }; 16 | } 17 | 18 | setCart = (item, id, value, price) => { 19 | let cart = { 20 | count: value, 21 | id: id, 22 | item: item, 23 | subTotal: parseFloat(price) * value, 24 | }; 25 | this.setState( 26 | { 27 | cart: cart, 28 | }, 29 | () => { 30 | this.props.addToCart(this.state.cart); 31 | }, 32 | ); 33 | }; 34 | 35 | render() { 36 | const {item, count} = this.props; 37 | return ( 38 | 39 | 40 | 41 | 45 | 51 | 52 | 53 | 54 | 56 | 57 | 58 | {item.name} 59 | 60 | 61 | 62 | {item.attribute + ' - ' + item.currency + ' ' + item.price} 63 | 64 | 65 | {count > 0 ? ( 66 | 67 | { 71 | this.setState({ 72 | count: this.state.count - 1, 73 | }); 74 | this.setCart( 75 | item, 76 | item.id, 77 | this.state.count - 1, 78 | item.price, 79 | ); 80 | }}> 81 | 82 | 83 | {count} 84 | { 88 | this.setState({ 89 | count: this.state.count + 1, 90 | }); 91 | this.setCart( 92 | item, 93 | item.id, 94 | this.state.count + 1, 95 | item.price, 96 | ); 97 | }}> 98 | 99 | 100 | 101 | ) : ( 102 | 103 | { 106 | this.setState({count: this.state.count + 1}); 107 | this.setCart( 108 | item, 109 | item.id, 110 | this.state.count + 1, 111 | item.price, 112 | ); 113 | }}> 114 | Add To Cart 115 | 116 | 117 | )} 118 | 119 | 120 | 121 | {/* 122 | 123 | */} 124 | 125 | 126 | ); 127 | } 128 | } 129 | 130 | 131 | const styles = StyleSheet.create({ 132 | container: { 133 | height: 130, 134 | flex: 1, 135 | backgroundColor: Color.white, 136 | shadowColor: '#000', 137 | shadowOffset: { 138 | width: 0, 139 | height: 2, 140 | }, 141 | shadowOpacity: 0.25, 142 | shadowRadius: 3.84, 143 | borderRadius: 10, 144 | elevation: 5, 145 | margin: 10, 146 | justifyContent: 'center', 147 | alignItems: 'center', 148 | display: 'flex', 149 | flexDirection: 'column', 150 | }, 151 | box1: { 152 | width: '100%', 153 | height: '100%', 154 | display: 'flex', 155 | flexDirection: 'row', 156 | paddingTop: 20, 157 | }, 158 | innerContainer: { 159 | display: 'flex', 160 | flexDirection: 'column', 161 | justifyContent: 'center', 162 | alignItems: 'center', 163 | }, 164 | title: { 165 | fontFamily: Fonts.primaryRegular, 166 | fontSize: 14, 167 | color: Color.gray, 168 | display: 'flex', 169 | justifyContent: 'center', 170 | alignItems: 'center', 171 | fontWeight: '600', 172 | marginLeft: 10, 173 | marginRight: 10, 174 | 175 | height: 40, 176 | width: Dimension.window.width - 150, 177 | }, 178 | counter: { 179 | fontFamily: Fonts.primarySemiBold, 180 | fontSize: 16, 181 | color: Color.black, 182 | textAlign: 'center', 183 | width: 30, 184 | }, 185 | option: { 186 | fontFamily: Fonts.primarySemiBold, 187 | fontSize: 14, 188 | color: Color.red, 189 | marginLeft: 10, 190 | marginRight: 10, 191 | }, 192 | productImage: { 193 | height: 70, 194 | width: 70, 195 | }, 196 | addToCart: { 197 | backgroundColor: Color.colorPrimary, 198 | color: Color.white, 199 | textAlign: 'center', 200 | borderRadius: 20, 201 | width: 100, 202 | marginTop: 5, 203 | }, 204 | quantity: { 205 | display: 'flex', 206 | flexDirection: 'row', 207 | backgroundColor: Color.white, 208 | color: Color.white, 209 | textAlign: 'center', 210 | borderRadius: 20, 211 | justifyContent: 'center', 212 | alignItems: 'center', 213 | height: 33, 214 | width: 100, 215 | shadowColor: '#000', 216 | shadowOffset: { 217 | width: 0, 218 | height: 1, 219 | }, 220 | shadowOpacity: 0.2, 221 | shadowRadius: 1.41, 222 | elevation: 2, 223 | marginTop: 5, 224 | }, 225 | 226 | addToCartText: { 227 | paddingTop: 7, 228 | paddingBottom: 7, 229 | paddingLeft: 10, 230 | paddingRight: 10, 231 | color: Color.white, 232 | }, 233 | plusBtn: { 234 | padding: 10, 235 | }, 236 | box2: { 237 | position: 'absolute', 238 | top: 2, 239 | right: 2, 240 | width: 20, 241 | height: 20, 242 | }, 243 | }); 244 | export default ProductItem; 245 | -------------------------------------------------------------------------------- /src/components/ProductItem/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, ScrollView, Image} from 'react-native'; 3 | import {Color, Fonts, Strings, Dimension} from '../../theme'; 4 | import {ProductImage} from '../../axios/ServerRequest'; 5 | import Icon from 'react-native-vector-icons/Feather'; 6 | import {TouchableOpacity} from 'react-native'; 7 | import { BASE_URL } from '../../axios/API'; 8 | class ProductItem extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | item: this.props.item, 13 | count: this.props.count ? this.props.count : 0, 14 | cart: null, 15 | }; 16 | } 17 | 18 | setCart = (item, id, value, price) => { 19 | let cart = { 20 | count: value, 21 | id: id, 22 | item: item, 23 | subTotal: parseFloat(price) * value, 24 | }; 25 | this.setState( 26 | { 27 | cart: cart, 28 | }, 29 | () => { 30 | this.props.addToCart(this.state.cart); 31 | }, 32 | ); 33 | }; 34 | 35 | onItemClicked = item => { 36 | this.props.navi; 37 | }; 38 | 39 | render() { 40 | const {item, count, navigation} = this.props; 41 | return ( 42 | 43 | 44 | 45 | 46 | 52 | {item.name} 53 | 54 | 55 | {item.attribute + ' - ' + item.currency + ' ' + item.price} 56 | 57 | 58 | 59 | {count > 0 ? ( 60 | 61 | { 65 | this.setState({ 66 | count: this.state.count - 1, 67 | }); 68 | this.setCart(item, item.id, this.state.count - 1, item.price); 69 | }}> 70 | 71 | 72 | {count} 73 | { 77 | this.setState({ 78 | count: this.state.count + 1, 79 | }); 80 | this.setCart(item, item.id, this.state.count + 1, item.price); 81 | }}> 82 | 83 | 84 | 85 | ) : ( 86 | 87 | { 90 | this.setState({count: this.state.count + 1}); 91 | this.setCart(item, item.id, this.state.count + 1, item.price); 92 | }}> 93 | Add To Cart 94 | 95 | 96 | )} 97 | 98 | 99 | {/* 100 | 101 | */} 102 | 103 | 104 | ); 105 | } 106 | } 107 | 108 | 109 | 110 | const styles = StyleSheet.create({ 111 | container: { 112 | height: 220, 113 | width: 220, 114 | backgroundColor: Color.white, 115 | shadowColor: '#000', 116 | shadowOffset: { 117 | width: 0, 118 | height: 2, 119 | }, 120 | shadowOpacity: 0.25, 121 | shadowRadius: 3.84, 122 | borderRadius: 10, 123 | elevation: 5, 124 | margin: 10, 125 | justifyContent: 'center', 126 | alignItems: 'center', 127 | display: 'flex', 128 | flexDirection: 'column', 129 | }, 130 | box1: { 131 | width: '100%', 132 | height: '100%', 133 | justifyContent: 'center', 134 | alignItems: 'center', 135 | }, 136 | innerContainer: { 137 | display: 'flex', 138 | flexDirection: 'column', 139 | justifyContent: 'center', 140 | alignItems: 'center', 141 | }, 142 | title: { 143 | fontFamily: Fonts.primarySemiBold, 144 | fontSize: 14, 145 | color: Color.black, 146 | display: 'flex', 147 | justifyContent: 'center', 148 | alignItems: 'center', 149 | fontWeight: '600', 150 | textAlign: 'center', 151 | marginLeft: 10, 152 | marginRight: 10, 153 | marginTop: 10, 154 | height: 35, 155 | }, 156 | counter: { 157 | fontFamily: Fonts.primarySemiBold, 158 | fontSize: 16, 159 | color: Color.black, 160 | textAlign: 'center', 161 | width: 30, 162 | }, 163 | option: { 164 | fontFamily: Fonts.primarySemiBold, 165 | fontSize: 14, 166 | color: Color.red, 167 | textAlign: 'center', 168 | marginLeft: 10, 169 | marginRight: 10, 170 | marginBottom: 10, 171 | }, 172 | productImage: { 173 | height: 100, 174 | width: 100, 175 | resizeMode:'cover', 176 | alignSelf:'center' 177 | }, 178 | addToCart: { 179 | backgroundColor: Color.colorPrimary, 180 | color: Color.white, 181 | textAlign: 'center', 182 | borderRadius: 20, 183 | }, 184 | quantity: { 185 | display: 'flex', 186 | flexDirection: 'row', 187 | backgroundColor: Color.white, 188 | color: Color.white, 189 | textAlign: 'center', 190 | borderRadius: 20, 191 | justifyContent: 'center', 192 | alignItems: 'center', 193 | height: 33, 194 | shadowColor: '#000', 195 | shadowOffset: { 196 | width: 0, 197 | height: 1, 198 | }, 199 | shadowOpacity: 0.2, 200 | shadowRadius: 1.41, 201 | 202 | elevation: 2, 203 | }, 204 | 205 | addToCartText: { 206 | paddingTop: 7, 207 | paddingBottom: 7, 208 | paddingLeft: 20, 209 | paddingRight: 20, 210 | color: Color.white, 211 | }, 212 | box2: { 213 | position: 'absolute', 214 | top: 2, 215 | right: 2, 216 | width: 30, 217 | height: 30, 218 | }, 219 | plusBtn: { 220 | padding: 10, 221 | }, 222 | }); 223 | export default ProductItem; 224 | -------------------------------------------------------------------------------- /src/components/SearchBar/index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, StyleSheet, FlatList, Image, Text} from 'react-native'; 3 | import UserInput from '../../components/UserInput'; 4 | import {Color, Fonts, Strings, Dimension} from '../../theme'; 5 | import {TouchableOpacity} from 'react-native';import Icon from 'react-native-vector-icons/Feather'; 6 | import {CategoryImage} from '../../axios/ServerRequest'; 7 | 8 | class SearchBar extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = {}; 12 | } 13 | 14 | render() { 15 | return ( 16 | 17 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | ); 36 | } 37 | } 38 | 39 | export default SearchBar; 40 | const styles = StyleSheet.create({ 41 | container: { 42 | display: 'flex', 43 | flexDirection: 'column', 44 | backgroundColor: '#FFFFFF', 45 | }, 46 | containerStyle: { 47 | width: '93%', 48 | height: 45, 49 | }, 50 | 51 | itemContainer: { 52 | marginTop: 10, 53 | }, 54 | }); 55 | -------------------------------------------------------------------------------- /src/components/ToastMessage/Toast.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | Animated, 4 | TouchableWithoutFeedback, 5 | View, 6 | Text 7 | } from 'react-native' 8 | import ToastStyles from './ToastStyles' 9 | 10 | const noop = () => 0 11 | 12 | class Toast extends Component { 13 | 14 | 15 | 16 | 17 | state = { animatedValue: new Animated.Value(0), timeoutId: null } 18 | 19 | componentWillMount () { 20 | this.showToast() 21 | } 22 | 23 | componentWillUnmount () { 24 | const { timeoutId } = this.state; 25 | clearTimeout(timeoutId) 26 | } 27 | 28 | componentWillReceiveProps (nextProps) { 29 | if (this.props.id !== nextProps.id) { 30 | this.showToast() 31 | } 32 | } 33 | 34 | showToast () { 35 | const animatedValue = new Animated.Value(0) 36 | 37 | this.setState({ animatedValue }) 38 | 39 | Animated 40 | .timing(animatedValue, { toValue: 1, duration: 350 }) 41 | .start() 42 | 43 | const { duration, onShow } = this.props 44 | const timeoutId = setTimeout(() => this.hideToast(), duration + 350) 45 | 46 | this.setState({ timeoutId }, onShow) 47 | } 48 | 49 | hideToast () { 50 | const { timeoutId, animatedValue } = this.state 51 | 52 | clearTimeout(timeoutId) 53 | 54 | Animated 55 | .timing(animatedValue, { toValue: 0, duration: 350 }) 56 | .start() 57 | 58 | setTimeout(this.props.onHide, 350) 59 | } 60 | 61 | onPress = () => { 62 | this.hideToast() 63 | this.props.onPress() 64 | } 65 | 66 | render () { 67 | const y = this.state.animatedValue.interpolate({ 68 | inputRange: [0, 1], 69 | outputRange: [-this.props.height, 0] 70 | }) 71 | 72 | const { styles } = this.props 73 | let text = this.props.text 74 | 75 | if (Object.prototype.toString.call(text) === '[object String]') { 76 | text = ( 77 | 78 | {text} 79 | 80 | ) 81 | } 82 | 83 | return ( 84 | 92 | 93 | {text} 94 | 95 | 96 | ) 97 | } 98 | } 99 | 100 | export default Toast 101 | -------------------------------------------------------------------------------- /src/components/ToastMessage/ToastStyles.android.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native' 2 | 3 | export const base = { 4 | container: { 5 | paddingTop: 15, 6 | paddingRight: 15, 7 | paddingBottom: 15, 8 | paddingLeft: 15 9 | }, 10 | text: { 11 | color: '#ffffff', 12 | fontWeight: 'bold' 13 | } 14 | } 15 | 16 | export default { 17 | info: StyleSheet.create({ 18 | container: StyleSheet.flatten([base.container, { backgroundColor: '#2487DB' }]), 19 | text: base.text 20 | }), 21 | success: StyleSheet.create({ 22 | container: StyleSheet.flatten([base.container, { backgroundColor: 'green' }]), 23 | text: base.text 24 | }), 25 | warning: StyleSheet.create({ 26 | container: StyleSheet.flatten([base.container, { backgroundColor: '#ec971f' }]), 27 | text: base.text 28 | }), 29 | error: StyleSheet.create({ 30 | container: StyleSheet.flatten([base.container, { backgroundColor: 'red' }]), 31 | text: base.text 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /src/components/ToastMessage/ToastStyles.ios.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native' 2 | 3 | export const base = { 4 | container: { 5 | paddingTop: 25, 6 | paddingRight: 15, 7 | paddingBottom: 15, 8 | paddingLeft: 15 9 | }, 10 | text: { 11 | color: '#ffffff', 12 | fontWeight: 'bold' 13 | } 14 | } 15 | 16 | export default { 17 | info: StyleSheet.create({ 18 | container: StyleSheet.flatten([base.container, { backgroundColor: '#2487DB' }]), 19 | text: base.text 20 | }), 21 | success: StyleSheet.create({ 22 | container: StyleSheet.flatten([base.container, { backgroundColor: 'green' }]), 23 | text: base.text 24 | }), 25 | warning: StyleSheet.create({ 26 | container: StyleSheet.flatten([base.container, { backgroundColor: '#ec971f' }]), 27 | text: base.text 28 | }), 29 | error: StyleSheet.create({ 30 | container: StyleSheet.flatten([base.container, { backgroundColor: 'red' }]), 31 | text: base.text 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /src/components/ToastMessage/Toaster.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Toast from './Toast' 3 | 4 | 5 | const noop = () => 0 6 | 7 | // Inspired by https://github.com/dabit3/react-native-toasts 8 | class Toaster extends Component { 9 | 10 | 11 | 12 | constructor (props) { 13 | super(props) 14 | 15 | let messages = [] 16 | 17 | if (props.message) { 18 | messages = this.cloneWithId(props.message) 19 | messages = Array.isArray(messages) ? messages : [messages] 20 | } 21 | 22 | this.state = { messages } 23 | } 24 | 25 | cloneWithId (obj) { 26 | if (Array.isArray(obj)) { 27 | return obj.map(this.cloneWithId) 28 | } 29 | 30 | return Object.assign({ id: Math.random().toString(36) }, obj) 31 | } 32 | 33 | componentWillReceiveProps (nextProps) { 34 | if (!nextProps.message) return 35 | const message = this.cloneWithId(nextProps.message) 36 | this.setState({ messages: this.state.messages.concat(message) }) 37 | } 38 | 39 | onShow = () => { 40 | const message = this.state.messages[0] 41 | 42 | if (message.onShow) { 43 | message.onShow() 44 | } 45 | 46 | this.props.onShow(message) 47 | } 48 | 49 | onHide = () => { 50 | const message = this.state.messages[0] 51 | 52 | this.setState({ messages: this.state.messages.slice(1) }, () => { 53 | if (message.onHide) { 54 | message.onHide() 55 | } 56 | 57 | this.props.onHide(message) 58 | }) 59 | } 60 | 61 | onPress = () => { 62 | const message = this.state.messages[0] 63 | 64 | if (message.onPress) { 65 | message.onPress() 66 | } 67 | 68 | this.props.onPress(message) 69 | } 70 | 71 | render () { 72 | const { messages } = this.state 73 | if (!messages.length) return null 74 | return 75 | } 76 | } 77 | 78 | export default Toaster 79 | -------------------------------------------------------------------------------- /src/components/ToastMessage/index.js: -------------------------------------------------------------------------------- 1 | import Toaster from './Toaster' 2 | import ToastStyles from './ToastStyles' 3 | 4 | export default Toaster 5 | export { ToastStyles } 6 | -------------------------------------------------------------------------------- /src/components/ToolBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text} from 'react-native'; 3 | import {styles} from './styles/styles.js'; 4 | import {TouchableOpacity} from 'react-native'; 5 | import Icon from 'react-native-vector-icons/Feather'; 6 | 7 | function ToolBar(props) { 8 | return ( 9 | 10 | 11 | {props.icon ? ( 12 | 16 | 17 | 18 | ) : null} 19 | {props.title} 20 | 21 | 29 | {props.children} 30 | 31 | 32 | ); 33 | } 34 | 35 | ToolBar.propTypes = {}; 36 | 37 | export default ToolBar; 38 | -------------------------------------------------------------------------------- /src/components/UserInput/index.js: -------------------------------------------------------------------------------- 1 | import React, {useState} from 'react'; 2 | import {View, Platform, StyleSheet, TextInput, Text} from 'react-native'; 3 | import Color from '../../theme/Color'; 4 | import Font from '../../theme/Fonts'; 5 | import Dimension from '../../theme/Dimension'; 6 | 7 | function UserInput(props) { 8 | const [hasFocus, sethasFocus] = useState(false); 9 | const onFocus = () => { 10 | sethasFocus(true); 11 | }; 12 | 13 | const onBlur = () => { 14 | sethasFocus(false); 15 | }; 16 | return ( 17 | 18 | 35 | 42 | 43 | {props.errorMessage ? ( 44 | {props.errorMessage} 45 | ) : null} 46 | 47 | ); 48 | } 49 | 50 | UserInput.propTypes = {}; 51 | UserInput.defaultProps = {}; 52 | 53 | const styles = StyleSheet.create({ 54 | textInputContainer: { 55 | display: 'flex', 56 | flexDirection: 'column', 57 | marginBottom: 15, 58 | }, 59 | textInput: { 60 | fontSize: 16, 61 | color: Color.textColor, 62 | fontFamily: Font.primaryRegular, 63 | }, 64 | borderText: { 65 | borderBottomColor: Color.borderColor, 66 | borderBottomWidth: 1, 67 | }, 68 | focusedTextInput: { 69 | fontSize: 14, 70 | color: Color.gray, 71 | borderBottomColor: Color.colorPrimary, 72 | borderBottomWidth: 1, 73 | }, 74 | 75 | errorTextInput: { 76 | fontSize: 14, 77 | color: Color.gray, 78 | borderBottomColor: Color.red, 79 | borderBottomWidth: 1, 80 | }, 81 | 82 | error: { 83 | fontSize: 10, 84 | color: Color.red, 85 | }, 86 | }); 87 | 88 | export default UserInput; 89 | -------------------------------------------------------------------------------- /src/components/ViewSlider/dots.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, StyleSheet} from 'react-native'; 3 | 4 | export default (Indicators = props => { 5 | const activeColor = props.activeColor; 6 | const inactiveColor = props.inactiveColor; 7 | const dotsCount = props.count; 8 | const activeDot = props.activeDot; 9 | const containerStyle = props.containerStyle; 10 | 11 | const createDots = () => { 12 | let dot = []; 13 | for (let i = 1; i <= dotsCount; i++) { 14 | dot.push( 15 | , 22 | ); 23 | } 24 | return dot; 25 | }; 26 | 27 | return ( 28 | 29 | {createDots().map((dot, i) => ( 30 | {dot} 31 | ))} 32 | 33 | ); 34 | }); 35 | 36 | const styles = StyleSheet.create({ 37 | dotContainer: { 38 | marginVertical: 10, 39 | flexDirection: 'row', 40 | justifyContent: 'space-between', 41 | }, 42 | dot: { 43 | marginHorizontal: 10, 44 | padding: 5, 45 | borderRadius: 100, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /src/components/ViewSlider/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View, Text, ScrollView, Dimensions} from 'react-native'; 3 | import Dots from './dots'; 4 | 5 | const {width, height} = Dimensions.get('window'); 6 | 7 | export default class ViewSlider extends React.Component { 8 | state = { 9 | activeDot: 1, 10 | autoSlide: false, 11 | intervalId: null, 12 | }; 13 | 14 | static getDerivedStateFromProps(prevState, nextProp) { 15 | return (autoSlide = nextProp.autoSlide); 16 | } 17 | 18 | componentDidMount() { 19 | if (this.props.autoSlide == true && this.scroll.scrollTo) { 20 | this.startAutoSlide(); 21 | } 22 | } 23 | 24 | startAutoSlide = () => { 25 | const interval = this.props.slideInterval; 26 | if (interval < 1000) { 27 | console.warn('slideInterval time must be at least 1000 milisecond.'); 28 | } else { 29 | const count = this.props.slideCount; 30 | let step = 1; 31 | let intervalId = setInterval(() => { 32 | this.scroll.scrollTo({x: width * step}); 33 | this.setState({activeDot: step + 1}); 34 | if (count == step + 1) { 35 | step = 0; 36 | } else { 37 | step++; 38 | } 39 | }, interval); 40 | this.setState({intervalId: intervalId}); 41 | } 42 | }; 43 | 44 | componentWillUnmount() { 45 | clearInterval(this.state.intervalId); 46 | } 47 | 48 | onScroll = event => { 49 | const scrollPositionX = event.nativeEvent.contentOffset.x; 50 | const offset = 100; 51 | 52 | if (scrollPositionX >= 0 && scrollPositionX <= parseInt(width - offset)) { 53 | this.setState({activeDot: 1}); 54 | } else if ( 55 | scrollPositionX >= width - offset && 56 | scrollPositionX <= width * 2 - offset 57 | ) { 58 | this.setState({activeDot: 2}); 59 | } else if ( 60 | scrollPositionX >= width * 2 - offset && 61 | scrollPositionX <= width * 3 - offset 62 | ) { 63 | this.setState({activeDot: 3}); 64 | } else if ( 65 | scrollPositionX >= width * 3 - offset && 66 | scrollPositionX <= width * 4 - offset 67 | ) { 68 | this.setState({activeDot: 4}); 69 | } else if ( 70 | scrollPositionX >= width * 4 - offset && 71 | scrollPositionX <= width * 5 - offset 72 | ) { 73 | this.setState({activeDot: 5}); 74 | } else if ( 75 | scrollPositionX >= width * 5 - offset && 76 | scrollPositionX <= width * 6 - offset 77 | ) { 78 | this.setState({activeDot: 6}); 79 | } else if ( 80 | scrollPositionX >= width * 6 - offset && 81 | scrollPositionX <= width * 7 - offset 82 | ) { 83 | this.setState({activeDot: 7}); 84 | } else if ( 85 | scrollPositionX >= width * 7 - offset && 86 | scrollPositionX <= width * 8 - offset 87 | ) { 88 | this.setState({activeDot: 8}); 89 | } else if ( 90 | scrollPositionX >= width * 8 - offset && 91 | scrollPositionX <= width * 9 - offset 92 | ) { 93 | this.setState({activeDot: 9}); 94 | } else if ( 95 | scrollPositionX >= width * 9 - offset && 96 | scrollPositionX <= width * 10 - offset 97 | ) { 98 | this.setState({activeDot: 10}); 99 | } else if ( 100 | scrollPositionX >= width * 10 - offset && 101 | scrollPositionX <= width * 11 - offset 102 | ) { 103 | this.setState({activeDot: 11}); 104 | } else if ( 105 | scrollPositionX >= width * 11 - offset && 106 | scrollPositionX <= width * 12 - offset 107 | ) { 108 | this.setState({activeDot: 12}); 109 | } else if ( 110 | scrollPositionX >= width * 12 - offset && 111 | scrollPositionX <= width * 13 - offset 112 | ) { 113 | this.setState({activeDot: 13}); 114 | } else if ( 115 | scrollPositionX >= width * 13 - offset && 116 | scrollPositionX <= width * 14 - offset 117 | ) { 118 | this.setState({activeDot: 14}); 119 | } else if ( 120 | scrollPositionX >= width * 14 - offset && 121 | scrollPositionX <= width * 15 - offset 122 | ) { 123 | this.setState({activeDot: 15}); 124 | } else if ( 125 | scrollPositionX >= width * 15 - offset && 126 | scrollPositionX <= width * 16 - offset 127 | ) { 128 | this.setState({activeDot: 16}); 129 | } else if ( 130 | scrollPositionX >= width * 16 - offset && 131 | scrollPositionX <= width * 17 - offset 132 | ) { 133 | this.setState({activeDot: 17}); 134 | } else if ( 135 | scrollPositionX >= width * 17 - offset && 136 | scrollPositionX <= width * 18 - offset 137 | ) { 138 | this.setState({activeDot: 18}); 139 | } else if ( 140 | scrollPositionX >= width * 18 - offset && 141 | scrollPositionX <= width * 19 - offset 142 | ) { 143 | this.setState({activeDot: 19}); 144 | } else if ( 145 | scrollPositionX >= width * 19 - offset && 146 | scrollPositionX <= width * 20 - offset 147 | ) { 148 | this.setState({activeDot: 20}); 149 | } 150 | }; 151 | 152 | render() { 153 | const { 154 | dots, 155 | dotActiveColor, 156 | dotInactiveColor, 157 | slideCount, 158 | dotsContainerStyle, 159 | } = this.props; 160 | const {activeDot} = this.state; 161 | return ( 162 | 163 | (this.scroll = node)} 168 | scrollEventThrottle={70} 169 | onScroll={s => this.onScroll(s)} 170 | showsHorizontalScrollIndicator={false}> 171 | {this.props.renderSlides} 172 | 173 | {dots && ( 174 | 181 | )} 182 | 183 | ); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/components/styles/styles.js: -------------------------------------------------------------------------------- 1 | import {StyleSheet} from 'react-native'; 2 | import Colors from '../../theme/Color'; 3 | import Dimensions from '../../theme/Dimension'; 4 | import Fonts from '../../theme/Fonts'; 5 | export const styles = StyleSheet.create({ 6 | container: { 7 | flex: 1, 8 | flexDirection: 'column', 9 | }, 10 | center: { 11 | flex: 1, 12 | justifyContent: 'center', 13 | alignItems: 'center', 14 | }, 15 | toolbarTitle: { 16 | fontSize: 16, 17 | color: Colors.white, 18 | fontWeight: '700', 19 | marginRight: 20, 20 | }, 21 | androidButtonText: { 22 | color: 'blue', 23 | fontSize: Dimensions.headerText, 24 | }, 25 | 26 | toolBar: { 27 | width: '100%', 28 | display: 'flex', 29 | backgroundColor: Colors.colorPrimary, 30 | fontSize: Dimensions.headerText, 31 | height: Dimensions.headerheight, 32 | flexDirection: 'row', 33 | color: Colors.white, 34 | alignItems: 'center', 35 | fontFamily: Fonts.primarySemiBold, 36 | }, 37 | title: { 38 | color: Colors.white, 39 | fontSize: Dimensions.title, 40 | fontWeight: '700', 41 | marginBottom: 16, 42 | }, 43 | 44 | toggle: { 45 | padding: 10, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /src/screen/AddressScreen.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet} from 'react-native'; 3 | import AppStatusBar from '../components/AppStatusBar'; 4 | import {Color, Fonts, Strings, Dimension} from '../theme'; 5 | import ToolBar from '../components/ToolBar'; 6 | import {TouchableOpacity, ScrollView} from 'react-native'; 7 | import {getUserDetails} from '../utils/LocalStorage'; 8 | import UserInput from '../components/UserInput'; 9 | import LoadingButton from '../components/LoadingButton'; 10 | import {DEFAULT_RULE, EMAIL_RULE} from '../utils/Validator/rule'; 11 | import {updateUser} from '../axios/ServerRequest'; 12 | import {getToken, setUserDetails} from '../utils/LocalStorage'; 13 | import Validator from '../utils/Validator/Validator'; 14 | 15 | class AddressScreen extends Component { 16 | constructor(props) { 17 | super(props); 18 | this.state = { 19 | user: null, 20 | name: '', 21 | phone: '', 22 | id: '', 23 | email: '', 24 | address: '', 25 | city: '', 26 | state: '', 27 | zip: '', 28 | emailError: '', 29 | addressError: '', 30 | cityError: '', 31 | stateError: '', 32 | zipError: '', 33 | token: '', 34 | loading: false, 35 | }; 36 | } 37 | async componentDidMount() { 38 | let user = await getUserDetails(); 39 | this.setState({ 40 | user: user, 41 | id: user.id, 42 | phone: user.mobile, 43 | name: user.name, 44 | email: user.email, 45 | address: user.address, 46 | city: user.city, 47 | state: user.state, 48 | zip: user.zip, 49 | token: user.token, 50 | }); 51 | } 52 | 53 | updateAddress = () => { 54 | const { 55 | user, 56 | email, 57 | address, 58 | state, 59 | city, 60 | zip, 61 | token, 62 | emailError, 63 | addressError, 64 | stateError, 65 | cityError, 66 | zipError, 67 | } = this.state; 68 | 69 | if (!Validator(email, DEFAULT_RULE)) { 70 | this.setState({ 71 | emailError: true, 72 | }); 73 | return; 74 | } 75 | 76 | if (!Validator(email, EMAIL_RULE)) { 77 | this.setState({ 78 | emailError: true, 79 | }); 80 | return; 81 | } 82 | 83 | if (!Validator(address, DEFAULT_RULE)) { 84 | this.setState({ 85 | addressError: true, 86 | }); 87 | return; 88 | } 89 | if (!Validator(state, DEFAULT_RULE)) { 90 | this.setState({ 91 | stateError: true, 92 | }); 93 | return; 94 | } 95 | if (!Validator(city, DEFAULT_RULE)) { 96 | this.setState({ 97 | cityError: true, 98 | }); 99 | return; 100 | } 101 | if (!Validator(zip, DEFAULT_RULE)) { 102 | this.setState({ 103 | zipError: true, 104 | }); 105 | return; 106 | } 107 | 108 | this.setState({loading: true}); 109 | user.email = email; 110 | user.address = address; 111 | user.state = state; 112 | user.city = city; 113 | user.zip = zip; 114 | 115 | updateUser(user) 116 | .then(response => { 117 | let data = response.data; 118 | console.log(response); 119 | if (data.status === 200) { 120 | this.props.navigation.navigate('PlaceOrder'); 121 | setUserDetails(user); 122 | } 123 | 124 | this.setState({loading: false}); 125 | }) 126 | .catch(error => { 127 | console.log(error); 128 | this.setState({loading: false}); 129 | }); 130 | }; 131 | 132 | render() { 133 | const {navigation} = this.props; 134 | const {user} = this.state; 135 | 136 | return ( 137 | 138 | 139 | 143 | navigation.goBack()} 147 | /> 148 | {user !== null ? ( 149 | 155 | 162 | 168 | { 174 | this.setState({ 175 | email, 176 | }); 177 | }} 178 | /> 179 | { 185 | this.setState({ 186 | address, 187 | }); 188 | }} 189 | /> 190 | { 196 | this.setState({ 197 | state, 198 | }); 199 | }} 200 | /> 201 | { 207 | this.setState({ 208 | city, 209 | }); 210 | }} 211 | /> 212 | { 219 | this.setState({ 220 | zip, 221 | }); 222 | }} 223 | /> 224 | 225 | { 229 | this.updateAddress(); 230 | }} 231 | /> 232 | 233 | 234 | ) : null} 235 | 236 | 237 | ); 238 | } 239 | } 240 | 241 | export default AddressScreen; 242 | 243 | const styles = StyleSheet.create({ 244 | container: { 245 | flex: 1, 246 | flexDirection: 'column', 247 | }, 248 | box1: { 249 | display: 'flex', 250 | flexDirection: 'column', 251 | }, 252 | text: { 253 | fontSize: 18, 254 | color: Color.textColor, 255 | }, 256 | title: { 257 | fontSize: 16, 258 | color: Color.black, 259 | paddingTop: 5, 260 | paddingBottom: 10, 261 | paddingLeft: 5, 262 | }, 263 | 264 | addContainer: { 265 | display: 'flex', 266 | flexDirection: 'column', 267 | padding: 10, 268 | }, 269 | }); 270 | -------------------------------------------------------------------------------- /src/screen/CategoryScreen.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Text, StyleSheet, Image, FlatList} from 'react-native'; 3 | import AppStatusBar from '../components/AppStatusBar'; 4 | import {Color, Fonts, Strings, Dimension} from '../theme'; 5 | import ToolBar from '../components/ToolBar'; 6 | import {TouchableOpacity} from 'react-native'; 7 | import {getCart} from '../utils/LocalStorage'; 8 | import BadgeIcon from '../components/BadgeIcon'; 9 | import Cart from '../utils/Cart'; 10 | import Loading from '../components/Loading'; 11 | 12 | import { 13 | getAllCategory, 14 | CategoryImage, 15 | ProductImage, 16 | } from '../axios/ServerRequest'; 17 | class CategoryScreen extends Component { 18 | constructor(props) { 19 | super(props); 20 | this.state = { 21 | cartCount: 0, 22 | category: [], 23 | }; 24 | } 25 | 26 | async componentDidMount() { 27 | this.reRenderSomething = this.props.navigation.addListener('focus', () => { 28 | this.init(); 29 | }); 30 | } 31 | 32 | init = async () => { 33 | let cart = await getCart(); 34 | this.fetchCategory(); 35 | this.setState({ 36 | cartCount: Cart.getTotalCartCount(cart), 37 | }); 38 | }; 39 | 40 | fetchCategory = () => { 41 | this.refs.loading.show(); 42 | 43 | getAllCategory() 44 | .then(response => { 45 | console.log(response.data.categories); 46 | this.setState({category: response.data.categories}); 47 | this.refs.loading.close(); 48 | }) 49 | .catch(error => { 50 | console.log(error); 51 | this.refs.loading.close(); 52 | }); 53 | }; 54 | 55 | renderCategoryItem = (item, index) => { 56 | return ( 57 | { 60 | this.props.navigation.navigate('ProductView', { 61 | screen: 'Products', 62 | params: {item: item}, 63 | }); 64 | }}> 65 | 66 | 72 | {item.categry} 73 | 74 | 75 | ); 76 | }; 77 | 78 | render() { 79 | const {navigation} = this.props; 80 | return ( 81 | 82 | 86 | navigation.openDrawer()}> 90 | { 94 | navigation.navigate('MyCart'); 95 | }} 96 | /> 97 | 98 | 99 | this.renderCategoryItem(item, index)} 102 | keyExtractor={item => item.id} 103 | /> 104 | 105 | 106 | ); 107 | } 108 | } 109 | const styles = StyleSheet.create({ 110 | mainContainer: { 111 | flex: 1, 112 | backgroundColor: Color.white, 113 | flexDirection: 'column', 114 | }, 115 | scrollView: { 116 | flex: 1, 117 | backgroundColor: Color.white, 118 | flexDirection: 'column', 119 | padding: 20, 120 | }, 121 | categoryItem: { 122 | display: 'flex', 123 | flexDirection: 'row', 124 | justifyContent: 'space-between', 125 | alignItems: 'center', 126 | shadowColor: '#000', 127 | shadowOffset: { 128 | width: 0, 129 | height: 4, 130 | }, 131 | shadowOpacity: 0.3, 132 | shadowRadius: 4.65, 133 | elevation: 6, 134 | backgroundColor: Color.white, 135 | borderRadius: 15, 136 | padding: 20, 137 | marginLeft: 20, 138 | marginRight: 20, 139 | marginTop: 10, 140 | marginBottom: 10, 141 | }, 142 | title: { 143 | fontFamily: Fonts.primarySemiBold, 144 | fontSize: 16, 145 | }, 146 | }); 147 | export default CategoryScreen; 148 | -------------------------------------------------------------------------------- /src/screen/MyCartScreen.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | import { 4 | View, 5 | Text, 6 | StyleSheet, 7 | ScrollView, 8 | Image, 9 | FlatList, 10 | Button, 11 | } from 'react-native'; 12 | import AppStatusBar from '../components/AppStatusBar'; 13 | import {Color, Fonts, Strings, Dimension} from '../theme'; 14 | import ToolBar from '../components/ToolBar'; 15 | import {TouchableOpacity} from 'react-native'; 16 | import Icon from 'react-native-vector-icons/Feather'; 17 | import {getUserDetails, getCart, setCart} from '../utils/LocalStorage'; 18 | import BadgeIcon from '../components/BadgeIcon'; 19 | import Cart from '../utils/Cart'; 20 | import CartItem from '../components/CartItem'; 21 | import EmptyCart from '../assets/images/emptycart.png'; 22 | class MyCartScreen extends Component { 23 | constructor(props) { 24 | super(props); 25 | this.state = { 26 | cartCount: 0, 27 | user: null, 28 | cartList: [], 29 | totalPrice: '', 30 | }; 31 | } 32 | 33 | async componentDidMount() { 34 | this.reRenderSomething = this.props.navigation.addListener('focus', () => { 35 | this.init(); 36 | }); 37 | } 38 | 39 | init = async () => { 40 | let cart = await getCart(); 41 | let userDetails = await getUserDetails(); 42 | let totalPrice = cart.reduce((accum, item) => accum + item.subTotal, 0); 43 | 44 | this.setState({ 45 | cartCount: Cart.getTotalCartCount(cart), 46 | cartList: cart, 47 | user: userDetails, 48 | totalPrice: totalPrice, 49 | }); 50 | }; 51 | 52 | addToCart = async params => { 53 | let cart = await getCart(); 54 | let cartListData = cart !== null ? cart : []; 55 | let itemIndex = Cart.isProductExist(cartListData, params); 56 | if (itemIndex === -1) { 57 | cartListData.push(params); 58 | } else { 59 | if (params.count > 0) { 60 | cartListData[itemIndex] = params; 61 | } else { 62 | let filterData = cartListData.filter(item => item.id !== params.id); 63 | cartListData = filterData; 64 | } 65 | } 66 | console.log(cartListData); 67 | let totalCount = Cart.getTotalCartCount(cartListData); 68 | let totalPrice = cartListData.reduce( 69 | (accum, item) => accum + item.subTotal, 70 | 0, 71 | ); 72 | this.setState({ 73 | cartCount: totalCount, 74 | cartList: cartListData, 75 | totalPrice: totalPrice, 76 | }); 77 | setCart(cartListData); 78 | //this.resetData(); 79 | }; 80 | renderCartItem(item) { 81 | let count = Cart.getItemCount(this.state.cartList, item); 82 | return ( 83 | 84 | ); 85 | } 86 | 87 | render() { 88 | const {navigation} = this.props; 89 | return ( 90 | 91 | 92 | 96 | navigation.goBack()} 100 | /> 101 | this.renderCartItem(item, index)} 105 | keyExtractor={item => item.id} 106 | extraData={this.state} 107 | contentInset={{bottom: 150}} 108 | contentContainerStyle={{paddingBottom: 150}} 109 | /> 110 | 111 | {this.state.cartCount > 0 ? ( 112 | 113 | 114 | 115 | Total: RS. {this.state.totalPrice} 116 | 117 | 118 | 119 | { 122 | this.props.navigation.navigate('ProductView', { 123 | screen: 'Address', 124 | }); 125 | }}> 126 | Checkout 127 | 128 | 129 | 130 | ) : ( 131 | 137 | 138 | 139 | 140 | Empty Cart 141 |