Compare commits

..

No commits in common. "cr/powercondo/update_react_native" and "main" have entirely different histories.

132 changed files with 5052 additions and 13105 deletions

7
.gitignore vendored
View File

@ -58,10 +58,3 @@ buck-out/
# CocoaPods # CocoaPods
/ios/Pods/ /ios/Pods/
.vscode
.bundle
android/.settings
android/app/.settings
android/*.hprof

46
App.js
View File

@ -7,22 +7,21 @@
*/ */
import React, { Component } from 'react' import React, { Component } from 'react'
import { StatusBar, StyleSheet, Text, TouchableOpacity } from 'react-native' import { Platform, StyleSheet, Text, StatusBar, TouchableOpacity, View } from 'react-native'
import MainNav from './src/navigation/MainNav' import MainNav from './src/navigation/MainNav'
import messaging from "@react-native-firebase/messaging" import firebase, { Notification } from 'react-native-firebase'
import { persistor, store } from './src/redux/store' import { store, persistor } from './src/redux/store'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import { registerDevice } from './src/api/UserApi' import { registerDevice, testConnect ,news} from './src/api/UserApi'
import { appSetDevice, appSetPushToken } from './src/redux/app/action' import { appSetPushToken, appSetDevice, appCleanDevice,appSetNotification } from './src/redux/app/action'
import { setLanguage, setToken } from 'src/api/api' import { setLanguage, setStore as setApiStore, setToken } from 'src/api/api'
import { PersistGate } from 'redux-persist/integration/react' import { PersistGate } from 'redux-persist/integration/react'
import Toast from 'react-native-toast-message' import { create } from 'apisauce'
import SplashScreen from 'react-native-splash-screen' import SplashScreen from 'react-native-splash-screen'
import { setBaseUrlByServerMode } from './src/api/api'
Text.defaultProps = Text.defaultProps || {} Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false Text.defaultProps.allowFontScaling = false;
if (TouchableOpacity.defaultProps == null) TouchableOpacity.defaultProps = {} if (TouchableOpacity.defaultProps == null) TouchableOpacity.defaultProps = {}
TouchableOpacity.defaultProps.activeOpacity = 0.7 TouchableOpacity.defaultProps.activeOpacity = 0.7
@ -30,7 +29,7 @@ TouchableOpacity.defaultProps.activeOpacity = 0.7
// setApiStore(store) // setApiStore(store)
class App extends Component { class App extends Component {
constructor (props) { constructor(props) {
super(props) super(props)
this._setDataFromInitState = this._setDataFromInitState.bind(this) this._setDataFromInitState = this._setDataFromInitState.bind(this)
} }
@ -38,15 +37,15 @@ class App extends Component {
componentDidMount = () => { componentDidMount = () => {
SplashScreen.hide() SplashScreen.hide()
} };
initNotification = async () => { initNotification = async () => {
await this.setPermission() await this.setPermission()
const fcmToken = await messaging().getAPNSToken(); const fcmToken = await firebase.messaging().getToken()
if (fcmToken) { if (fcmToken) {
store.dispatch(appSetPushToken(fcmToken)) store.dispatch(appSetPushToken(fcmToken))
const resultSendDevice = await registerDevice(fcmToken) const resultSendDevice = await registerDevice(fcmToken)
console.log(' re sult register_device =>', resultSendDevice) console.log(' re sult register_device =>',resultSendDevice);
if (resultSendDevice.ok && resultSendDevice.data.success) { if (resultSendDevice.ok && resultSendDevice.data.success) {
store.dispatch(appSetDevice(resultSendDevice.data.device)) store.dispatch(appSetDevice(resultSendDevice.data.device))
} }
@ -56,27 +55,23 @@ class App extends Component {
setPermission = async () => { setPermission = async () => {
try { try {
await messaging().registerDeviceForRemoteMessages(); const enabled = await firebase.messaging().hasPermission()
const authStatus = await messaging().requestPermission();
const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (!enabled) { if (!enabled) {
await messaging().requestPermission() await firebase.messaging().requestPermission()
} }
} catch (error) { } catch (error) {
console.log('error', error) console.log('error', error)
} }
} }
_setDataFromInitState () { _setDataFromInitState() {
const appState = store.getState().app const appState = store.getState().app
let device = appState.device let device = appState.device;
setBaseUrlByServerMode(appState.server_mode)
if (appState.token) { if (appState.token) {
setToken(appState.token) setToken(appState.token)
} }
if (appState.lang) { if(appState.lang){
setLanguage(appState.lang) setLanguage(appState.lang)
} }
@ -88,15 +83,14 @@ class App extends Component {
} }
render () { render() {
return ( return (
<Provider store={store}> <Provider store={store}>
<PersistGate persistor={persistor} loading={null} onBeforeLift={this._setDataFromInitState}> <PersistGate persistor={persistor} loading={null} onBeforeLift={this._setDataFromInitState}>
<StatusBar barStyle="light-content"/> <StatusBar barStyle="light-content"/>
<MainNav/> <MainNav />
</PersistGate> </PersistGate>
<Toast />
</Provider> </Provider>
) )
} }

0
README.md Normal file
View File

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>charoensin</name> <name>csareactrn60</name>
<comment>Project android created by Buildship.</comment> <comment>Project android created by Buildship.</comment>
<projects> <projects>
</projects> </projects>
@ -14,15 +14,4 @@
<natures> <natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature> <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures> </natures>
<filteredResources>
<filter>
<id>0</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription> </projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=
eclipse.preferences.version=1

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/> <classpathentry kind="output" path="bin/default"/>
</classpath> </classpath>

View File

@ -20,15 +20,4 @@
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature> <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures> </natures>
<filteredResources>
<filter>
<id>1673516293498</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription> </projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=..
eclipse.preferences.version=1

View File

@ -131,11 +131,9 @@ android {
applicationId "th.co.csasset.mobile" applicationId "th.co.csasset.mobile"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 84 versionCode 60
versionName "2.33" versionName "2.12"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
missingDimensionStrategy 'react-native-camera', 'general'
multiDexEnabled true
} }
splits { splits {
abi { abi {
@ -210,10 +208,7 @@ android {
} }
} }
// def multidex_version = "2.0.1"
dependencies { dependencies {
implementation project(':react-native-permissions')
implementation project(':react-native-camera')
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules implementation "com.facebook.react:react-native:+" // From node_modules
if (enableHermes) { if (enableHermes) {
@ -228,7 +223,6 @@ dependencies {
implementation "com.google.firebase:firebase-core:16.0.9" implementation "com.google.firebase:firebase-core:16.0.9"
implementation "com.google.firebase:firebase-config:17.0.0" implementation "com.google.firebase:firebase-config:17.0.0"
implementation "com.google.firebase:firebase-messaging:18.0.0" implementation "com.google.firebase:firebase-messaging:18.0.0"
// implementation "androidx.multidex:multidex:$multidex_version"
// implementation 'com.facebook.android:facebook-android-sdk:[5,6)' // implementation 'com.facebook.android:facebook-android-sdk:[5,6)'
} }

View File

@ -1,42 +0,0 @@
{
"project_info": {
"project_number": "300814322402",
"firebase_url": "https://charoensin-ec628.firebaseio.com",
"project_id": "charoensin-ec628",
"storage_bucket": "charoensin-ec628.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:300814322402:android:61e2ca18a6ba4174",
"android_client_info": {
"package_name": "th.co.csasset.mobile"
}
},
"oauth_client": [
{
"client_id": "300814322402-82gqcb4dte5m2tv1dr2imsf0u7regk87.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAIXzIwPy-023B3sbDQv42LaxXaSnJcWmU"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

View File

@ -1,45 +1,39 @@
{ {
"project_info": { "project_info": {
"project_number": "468878476620", "project_number": "300814322402",
"firebase_url": "https://csasset-mobile.firebaseio.com", "firebase_url": "https://charoensin-ec628.firebaseio.com",
"project_id": "csasset-mobile", "project_id": "charoensin-ec628",
"storage_bucket": "csasset-mobile.appspot.com" "storage_bucket": "charoensin-ec628.appspot.com"
}, },
"client": [ "client": [
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:468878476620:android:61e2ca18a6ba4174", "mobilesdk_app_id": "1:300814322402:android:61e2ca18a6ba4174",
"android_client_info": { "android_client_info": {
"package_name": "th.co.csasset.mobile" "package_name": "th.co.csasset.mobile"
} }
}, },
"oauth_client": [ "oauth_client": [
{ {
"client_id": "468878476620-v3rqr1b2bta862r6q974csuc3rq917ni.apps.googleusercontent.com", "client_id": "300814322402-82gqcb4dte5m2tv1dr2imsf0u7regk87.apps.googleusercontent.com",
"client_type": 3 "client_type": 3
} }
], ],
"api_key": [ "api_key": [
{ {
"current_key": "AIzaSyB7o8KiFwABvfyYubdWTcjpm3Y6ciCrO1I" "current_key": "AIzaSyAIXzIwPy-023B3sbDQv42LaxXaSnJcWmU"
} }
], ],
"services": { "services": {
"analytics_service": {
"status": 1
},
"appinvite_service": { "appinvite_service": {
"other_platform_oauth_client": [ "status": 1,
{ "other_platform_oauth_client": []
"client_id": "468878476620-v3rqr1b2bta862r6q974csuc3rq917ni.apps.googleusercontent.com", },
"client_type": 3 "ads_service": {
}, "status": 2
{
"client_id": "468878476620-dn0mrhcve5jjpfst3u1vlm4k00uackb6.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "th.co.csasset.mobile",
"app_store_id": "1455804320"
}
}
]
} }
} }
} }

Binary file not shown.

View File

@ -1,18 +0,0 @@
{
"version": 2,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "th.co.csasset.mobile",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"versionCode": 84,
"versionName": "2.33",
"outputFile": "app-release.apk"
}
]
}

View File

@ -1,75 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.csareactrn60;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
/**
* Class responsible of loading Flipper inside your React Native application. This is the debug
* flavor of it. Here you can add your own plugins and customize the Flipper setup.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
new NetworkingModule.CustomClientBuilder() {
@Override
public void apply(OkHttpClient.Builder builder) {
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
}
});
client.addPlugin(networkFlipperPlugin);
client.start();
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
reactContext.runOnNativeModulesQueueThread(
new Runnable() {
@Override
public void run() {
client.addPlugin(new FrescoFlipperPlugin());
}
});
}
});
} else {
client.addPlugin(new FrescoFlipperPlugin());
}
}
}
}

View File

@ -1,6 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" package="th.co.csasset.mobile">
package="th.co.csasset.mobile">
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
@ -17,32 +16,25 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:allowBackup="false" android:allowBackup="false"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:hardwareAccelerated="true" android:hardwareAccelerated="false"
android:largeHeap="true"> android:largeHeap="true">
<!-- android:usesCleartextTraffic="true" -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize" android:windowSoftInputMode="adjustResize">
android:exported="true">
<intent-filter> <intent-filter>
<action <action android:name="android.intent.action.MAIN" />
android:name="android.intent.action.MAIN"
android:exported="true"/>
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService" <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
android:exported="true"
tools:ignore="MissingClass">
<intent-filter> <intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/> <action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter> </intent-filter>
</service> </service>
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService" <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
android:exported="false">
<intent-filter> <intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter> </intent-filter>

View File

@ -9,17 +9,15 @@ import com.facebook.react.bridge.JavaScriptExecutorFactory;
import com.facebook.react.ReactApplication; import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage; import com.facebook.react.ReactPackage;
//import com.facebook.reactnative.androidsdk.BuildConfig;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
import com.learnium.RNDeviceInfo.RNDeviceInfo; import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.reactnativecommunity.cameraroll.CameraRollPackage; import com.reactnativecommunity.cameraroll.CameraRollPackage;
import org.reactnative.camera.RNCameraPackage;
// Firebase // Firebase
//import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage; import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
//import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage; import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
//import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage; import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage;
import com.facebook.reactnative.androidsdk.FBSDKPackage; import com.facebook.reactnative.androidsdk.FBSDKPackage;
@ -39,10 +37,9 @@ public class MainApplication extends Application implements ReactApplication {
List<ReactPackage> packages = new PackageList(this).getPackages(); List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example: // Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage()); // packages.add(new MyReactNativePackage());
// packages.add(new RNFirebaseNotificationsPackage()); packages.add(new RNFirebaseNotificationsPackage());
// packages.add(new ReactNativeFirebaseMessagingPackage()); packages.add(new RNFirebaseMessagingPackage());
// packages.add(new RNFirebaseRemoteConfigPackage()); packages.add(new RNFirebaseRemoteConfigPackage());
// packages.add(new RNCameraPackage());
return packages; return packages;
} }

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
android:insetTop="@dimen/abc_edit_text_inset_top_material"
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
<selector>
<!--
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
-->
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
</selector>
</inset>

View File

@ -1,20 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.csareactrn60;
import android.content.Context;
import com.facebook.react.ReactInstanceManager;
/**
* Class responsible of loading Flipper inside your React Native application. This is the release
* flavor of it so it's empty as we don't want to load Flipper.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
// Do nothing as we don't want to initialize Flipper on Release.
}
}

View File

@ -4,30 +4,26 @@ buildscript {
ext { ext {
googlePlayServiceVersion = "17.0.0" googlePlayServiceVersion = "17.0.0"
buildToolsVersion = "28.0.3" buildToolsVersion = "28.0.3"
kotlinVersion = "1.5.20"
minSdkVersion = 21 minSdkVersion = 21
compileSdkVersion = 31 compileSdkVersion = 28
targetSdkVersion = 31 targetSdkVersion = 28
} }
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
// jcenter() jcenter()
} }
dependencies { dependencies {
classpath('com.android.tools.build:gradle:4.2.2') classpath("com.android.tools.build:gradle:3.4.1")
classpath('com.google.gms:google-services:4.3.14') classpath 'com.google.gms:google-services:4.2.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }
} }
def REACT_NATIVE_VERSION = new File(['node', '--print',"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim())
allprojects { allprojects {
repositories { repositories {
mavenCentral()
mavenLocal() mavenLocal()
maven { maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
@ -39,14 +35,9 @@ allprojects {
} }
google() google()
// jcenter() jcenter()
maven { url 'https://maven.google.com' } maven { url 'https://maven.google.com' }
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
} }
configurations.all {
resolutionStrategy {
force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
}
}
} }

View File

@ -1,20 +1,26 @@
## For more details on how to configure your build environment visit # Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m # Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Fri Apr 07 15:17:20 ICT 2023
MYAPP_RELEASE_STORE_FILE=charoensin.release.keystore
MYAPP_RELEASE_KEY_ALIAS=charoensin
MYAPP_RELEASE_KEY_PASSWORD=aabbccddee
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
MYAPP_RELEASE_STORE_FILE=charoensin.release.keystore
MYAPP_RELEASE_KEY_ALIAS=charoensin
MYAPP_RELEASE_STORE_PASSWORD=aabbccddee MYAPP_RELEASE_STORE_PASSWORD=aabbccddee
MYAPP_RELEASE_KEY_PASSWORD=aabbccddee

Binary file not shown.

View File

@ -1,7 +1,5 @@
#Fri Jan 13 09:46:32 ICT 2023
networkTimeout=10000
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

282
android/gradlew vendored
View File

@ -1,13 +1,13 @@
#!/bin/sh #!/usr/bin/env sh
# #
# Copyright © 2015-2021 the original authors. # Copyright 2015 the original author or authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# https://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
@ -17,113 +17,78 @@
# #
############################################################################## ##############################################################################
# ##
# Gradle start up script for POSIX generated by Gradle. ## Gradle start up script for UN*X
# ##
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
app_path=$0 PRG="$0"
# Need this for relative symlinks.
# Need this for daisy-chained symlinks. while [ -h "$PRG" ] ; do
while ls=`ls -ld "$PRG"`
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path link=`expr "$ls" : '.*-> \(.*\)$'`
[ -h "$app_path" ] if expr "$link" : '/.*' > /dev/null; then
do PRG="$link"
ls=$( ls -ld "$app_path" ) else
link=${ls#*' -> '} PRG=`dirname "$PRG"`"/$link"
case $link in #( fi
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
# This is normally unused APP_NAME="Gradle"
# shellcheck disable=SC2034 APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD="maximum"
warn () { warn () {
echo "$*" echo "$*"
} >&2 }
die () { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} >&2 }
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "$( uname )" in #( case "`uname`" in
CYGWIN* ) cygwin=true ;; #( CYGWIN* )
Darwin* ) darwin=true ;; #( cygwin=true
MSYS* | MINGW* ) msys=true ;; #( ;;
NONSTOP* ) nonstop=true ;; Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java JAVACMD="$JAVA_HOME/jre/sh/java"
else else
JAVACMD=$JAVA_HOME/bin/java JAVACMD="$JAVA_HOME/bin/java"
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -132,7 +97,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
@ -140,105 +105,84 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
case $MAX_FD in #( MAX_FD_LIMIT=`ulimit -H -n`
max*) if [ $? -eq 0 ] ; then
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
# shellcheck disable=SC3045 MAX_FD="$MAX_FD_LIMIT"
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi fi
# Roll the args list around exactly as many times as the number of ulimit -n $MAX_FD
# args, so each arg winds up back in the position where it started, but if [ $? -ne 0 ] ; then
# possibly modified. warn "Could not set maximum file descriptor limit: $MAX_FD"
# fi
# NB: a `for` loop captures its iteration list before it begins, so else
# changing the positional parameters here affects neither the number of warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
# iterations, nor the values presented in `arg`. fi
shift # remove old arg fi
set -- "$@" "$arg" # push replacement arg
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi fi
# Collect all arguments for the java command; # Escape application args
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of save () {
# shell script including quotes and variable substitutions, so put them in for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
# double quotes to make sure that they get re-expanded; and echo " "
# * put everything else in single quotes, so that it's not re-expanded. }
APP_ARGS=$(save "$@")
set -- \ # Collect all arguments for the java command, following the shell quoting and substitution rules
"-Dorg.gradle.appname=$APP_BASE_NAME" \ eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available. # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if ! command -v xargs >/dev/null 2>&1 if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
then cd "$(dirname "$0")"
die "xargs is not available"
fi fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

40
android/gradlew.bat vendored
View File

@ -5,7 +5,7 @@
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem http://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,14 +25,10 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@ -41,7 +37,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if "%ERRORLEVEL%" == "0" goto init
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -55,7 +51,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto init
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -65,26 +61,38 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL% if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
if %EXIT_CODE% equ 0 set EXIT_CODE=1 exit /b 1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

View File

@ -1,20 +1,4 @@
rootProject.name = 'charoensin' rootProject.name = 'charoensin'
include ':@react-native-firebase_config'
project(':@react-native-firebase_config').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/config/android')
include ':@react-native-firebase_config'
project(':@react-native-firebase_config').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/config/android')
include ':@react-native-firebase_config'
project(':@react-native-firebase_config').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/config/android')
include ':@react-native-firebase_config'
project(':@react-native-firebase_config').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-firebase/config/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-permissions'
project(':react-native-permissions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-permissions/android')
include ':react-native-camera'
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
include ':react-native-device-info' include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-fbsdk' include ':react-native-fbsdk'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 669 B

View File

@ -1,9 +1,3 @@
export default { export default {
API_BASE_URL_PROD: 'https://app.csasset.co.th/mobile', API_BASE_URL: 'https://app.csasset.co.th/mobile',
// API_BASE_URL_POWER_CONDO_DEV: 'https://power-condo.testsiteth.xyz',
API_BASE_URL_POWER_CONDO_DEV: 'http://54.255.251.43',
API_BASE_URL_POWER_CONDO_PROD: 'https://powercondo.csasset.co.th',
WEB_BASE_URL_PROD: 'https://app.csasset.co.th',
API_BASE_URL_DEV: 'https://csa-test.bda.co.th/mobile',
WEB_BASE_URL_DEV: 'https://csa-test.bda.co.th'
} }

View File

@ -1,11 +0,0 @@
{
"react-native": {
"messaging_ios_auto_register_for_remote_messages": false,
"crashlytics_auto_collection_enabled": false,
"messaging_android_notification_channel_id": "high-priority",
"crashlytics_debug_enabled": true,
"crashlytics_ndk_enabled": false,
"crashlytics_is_error_generation_on_js_crash_enabled": false,
"crashlytics_javascript_exception_handler_chaining_enabled": false
}
}

View File

@ -1,3 +0,0 @@
source "https://rubygems.org"
gem "fastlane"

View File

@ -1,8 +1,6 @@
platform :ios, '13.0' platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
xcodeproj 'csareactrn60'
target 'csareactrn60' do target 'csareactrn60' do
# Pods for csareactrn60 # Pods for csareactrn60
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
@ -28,7 +26,7 @@ target 'csareactrn60' do
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'React-callinvoker', :path => "../node_modules/react-native/ReactCommon/callinvoker" pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
@ -39,47 +37,15 @@ target 'csareactrn60' do
pod 'react-native-fbsdk', :path => '../node_modules/react-native-fbsdk' pod 'react-native-fbsdk', :path => '../node_modules/react-native-fbsdk'
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons' pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
pod 'Permission-BluetoothPeripheral', :path => "#{permissions_path}/BluetoothPeripheral"
pod 'Permission-Calendars', :path => "#{permissions_path}/Calendars"
pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
pod 'Permission-Contacts', :path => "#{permissions_path}/Contacts"
pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID"
pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy"
pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways"
pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
pod 'Permission-MediaLibrary', :path => "#{permissions_path}/MediaLibrary"
pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone"
pod 'Permission-Motion', :path => "#{permissions_path}/Motion"
pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
pod 'Permission-PhotoLibraryAddOnly', :path => "#{permissions_path}/PhotoLibraryAddOnly"
pod 'Permission-Reminders', :path => "#{permissions_path}/Reminders"
pod 'Permission-Siri', :path => "#{permissions_path}/Siri"
pod 'Permission-SpeechRecognition', :path => "#{permissions_path}/SpeechRecognition"
pod 'Permission-StoreKit', :path => "#{permissions_path}/StoreKit"
pod 'FBSDKCoreKit' pod 'FBSDKCoreKit'
pod 'FBSDKLoginKit' pod 'FBSDKLoginKit'
pod 'FBSDKShareKit' pod 'FBSDKShareKit'
#Firebase
pod 'Firebase/Messaging', '~> 6.8.0'
pod 'react-native-view-shot', :path => '../node_modules/react-native-view-shot' pod 'react-native-view-shot', :path => '../node_modules/react-native-view-shot'
pod 'RNImageCropPicker', :path => '../node_modules/react-native-image-crop-picker' pod 'RNImageCropPicker', :path => '../node_modules/react-native-image-crop-picker'
use_native_modules! use_native_modules!
pod 'RNDeviceInfo', :path => '../node_modules/react-native-device-info'
pod 'react-native-camera', :path => '../node_modules/react-native-camera'
pod 'RNPermissions', :path => '../node_modules/react-native-permissions'
pod 'react-native-webview', :path => '../node_modules/react-native-webview'
pod 'Firebase', :modular_headers => true
pod 'FirebaseCoreInternal', :modular_headers => true
pod 'FirebaseCore', :modular_headers => true
pod 'GoogleUtilities', :modular_headers => true
end end

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1120" LastUpgradeVersion = "0940"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "NO" parallelizeBuildables = "NO"
@ -55,15 +55,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
BuildableName = "csareactrn60-tvOS.app"
BlueprintName = "csareactrn60-tvOS"
ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables> <Testables>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
@ -76,6 +67,17 @@
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
</Testables> </Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
BuildableName = "csareactrn60-tvOS.app"
BlueprintName = "csareactrn60-tvOS"
ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@ -97,6 +99,8 @@
ReferencedContainer = "container:csareactrn60.xcodeproj"> ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1120" LastUpgradeVersion = "0940"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "NO" parallelizeBuildables = "NO"
@ -55,15 +55,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "csareactrn60.app"
BlueprintName = "csareactrn60"
ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables> <Testables>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
@ -76,6 +67,17 @@
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
</Testables> </Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "csareactrn60.app"
BlueprintName = "csareactrn60"
ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@ -97,6 +99,8 @@
ReferencedContainer = "container:csareactrn60.xcodeproj"> ReferencedContainer = "container:csareactrn60.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@ -69,20 +69,6 @@
<string>Choose a picture for user profile image or save image.</string> <string>Choose a picture for user profile image or save image.</string>
<key>NSPhotoLibraryUsageDescription</key> <key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to choose photos to upload profile picture and create support ticket.</string> <string>This app needs access to choose photos to upload profile picture and create support ticket.</string>
<key>NSContactsUsageDescription</key>
<string>no use</string>
<key>NSCalendarsUsageDescription</key>
<string>no use</string>
<key>NSAppleMusicUsageDescription</key>
<string>no use</string>
<key>NSMotionUsageDescription</key>
<string>no use</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>no use</string>
<key>NSSiriUsageDescription</key>
<string>no use</string>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>no use</string>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>arial.ttf</string> <string>arial.ttf</string>

View File

@ -4,9 +4,5 @@
<dict> <dict>
<key>aps-environment</key> <key>aps-environment</key>
<string>development</string> <string>development</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict> </dict>
</plist> </plist>

View File

@ -1,8 +0,0 @@
app_identifier("th.co.csasset.mobile") # The bundle identifier of your app
apple_id("btanawut@gmail.com") # Your Apple email address
itc_team_id("120264177") # App Store Connect Team ID
team_id("84F3R56BUC") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile

View File

@ -1,27 +0,0 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
increment_build_number(xcodeproj: "csareactrn60.xcodeproj")
build_app(workspace: "csareactrn60.xcworkspace", scheme: "csareactrn60")
upload_to_testflight(
skip_waiting_for_build_processing:true
)
end
end

View File

@ -9,9 +9,7 @@
"postinstall": "sh ./fix.sh", "postinstall": "sh ./fix.sh",
"prod-android": "cd android && ./gradlew assembleRelease", "prod-android": "cd android && ./gradlew assembleRelease",
"run-android": "react-native run-android", "run-android": "react-native run-android",
"run-ios": "react-native run-ios --simulator \"iPhone 14 Pro Max\"", "run-ios": "react-native run-ios --simulator \"iPhone 11\""
"run-device": "react-native run-ios --device",
"ios": "react-native run-ios --simulator \"iPhone 14 Pro Max\""
}, },
"rnpm": { "rnpm": {
"assets": [ "assets": [
@ -20,66 +18,51 @@
] ]
}, },
"dependencies": { "dependencies": {
"@invertase/react-native-apple-authentication": "^1.1.2",
"@react-native-community/cameraroll": "^1.2.1", "@react-native-community/cameraroll": "^1.2.1",
"@react-native-community/datetimepicker": "^3.0.2",
"@react-native-community/toolbar-android": "^0.2.1",
"@react-native-firebase/app": "^17.3.2",
"@react-native-firebase/messaging": "^17.3.2",
"apisauce": "^1.1.0", "apisauce": "^1.1.0",
"deprecated-react-native-listview": "^0.0.5", "deprecated-react-native-listview": "^0.0.5",
"i18n-js": "^3.5.1", "i18n-js": "^3.5.1",
"intl": "^1.2.5", "intl": "^1.2.5",
"jetifier": "^2.0.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"native-base": "^2.13.8", "native-base": "^2.13.8",
"react": "16.9.0", "react": "16.9.0",
"react-native": "^0.63", "react-native": "0.61.5",
"react-native-action-sheet": "^2.2.0", "react-native-action-sheet": "^2.2.0",
"react-native-camera": "^4.2.1", "react-native-appearance": "^0.2.2",
"react-native-countdown-component": "^2.7.1",
"react-native-device-info": "^5.5.7", "react-native-device-info": "^5.5.7",
"react-native-dropdown-picker": "^5.4.6",
"react-native-easy-grid": "^0.2.2", "react-native-easy-grid": "^0.2.2",
"react-native-elastic-image-slider": "^1.0.0", "react-native-elastic-image-slider": "^1.0.0",
"react-native-elements": "^1.2.0", "react-native-elements": "^1.2.0",
"react-native-fast-image": "^8.1.5", "react-native-fast-image": "^8.1.5",
"react-native-fbsdk": "^1.1.2", "react-native-fbsdk": "^1.1.2",
"react-native-firebase": "^5.5.6",
"react-native-gesture-handler": "^1.4.1", "react-native-gesture-handler": "^1.4.1",
"react-native-hyperlink": "^0.0.16", "react-native-hyperlink": "^0.0.16",
"react-native-image-crop-picker": "^0.32.2", "react-native-image-crop-picker": "0.25.3",
"react-native-image-slider-show": "^1.0.3", "react-native-image-slider-show": "^1.0.3",
"react-native-image-slideshow": "^1.0.1", "react-native-image-slideshow": "^1.0.1",
"react-native-image-view": "^2.1.5", "react-native-image-view": "^2.1.5",
"react-native-linear-gradient": "^2.5.6", "react-native-linear-gradient": "^2.5.6",
"react-native-modal-datetime-picker": "^7.5.0", "react-native-modal-datetime-picker": "^7.5.0",
"react-native-pager-view": "^5.4.25",
"react-native-permissions": "^3.6.1",
"react-native-picker-dropdown": "^0.1.2", "react-native-picker-dropdown": "^0.1.2",
"react-native-qrcode": "^0.2.7", "react-native-qrcode": "^0.2.7",
"react-native-qrcode-scanner": "^1.5.5",
"react-native-qrcode-svg": "^5.2.0", "react-native-qrcode-svg": "^5.2.0",
"react-native-render-html": "^4.1.2", "react-native-render-html": "^4.1.2",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"react-native-searchable-dropdown": "^1.1.1", "react-native-searchable-dropdown": "^1.1.1",
"react-native-signature-canvas": "^4.4.1", "react-native-signature-canvas": "^2.4.0",
"react-native-signature-pad": "^0.1.0",
"react-native-snap-carousel": "^3.8.0", "react-native-snap-carousel": "^3.8.0",
"react-native-splash-screen": "^3.2.0", "react-native-splash-screen": "^3.2.0",
"react-native-svg": "^9.9.3", "react-native-svg": "^9.9.3",
"react-native-switch-toggle": "^1.1.0", "react-native-switch-toggle": "^1.1.0",
"react-native-tab-view": "^3.1.1",
"react-native-toast-message": "^2.2.1",
"react-native-vector-icons": "^6.6.0", "react-native-vector-icons": "^6.6.0",
"react-native-view-shot": "^3.0.2", "react-native-view-shot": "^3.0.2",
"react-native-webview": "^11.23.0", "react-native-webview": "^9.4.0",
"react-navigation": "^3.3.0", "react-navigation": "^3.3.0",
"react-redux": "^7.1.1", "react-redux": "^7.1.1",
"react-select2-native": "^1.3.0",
"redux": "^4.0.4", "redux": "^4.0.4",
"redux-persist": "^5.10.0", "redux-persist": "^5.10.0",
"redux-persist-transform-encrypt": "^2.0.1", "redux-persist-transform-encrypt": "^2.0.1"
"rn-tooltip": "^2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.6.0", "@babel/core": "^7.6.0",
@ -88,7 +71,7 @@
"babel-jest": "^24.9.0", "babel-jest": "^24.9.0",
"eslint": "^6.3.0", "eslint": "^6.3.0",
"jest": "^24.9.0", "jest": "^24.9.0",
"metro-react-native-babel-preset": "^0.59.0", "metro-react-native-babel-preset": "^0.56.0",
"react-test-renderer": "16.8.6" "react-test-renderer": "16.8.6"
}, },
"jest": { "jest": {

View File

@ -2,11 +2,9 @@ import Api from './api'
import { Platform } from 'react-native' import { Platform } from 'react-native'
import Config from 'src/utils/Config' import Config from 'src/utils/Config'
import DeviceInfo from 'react-native-device-info' import DeviceInfo from 'react-native-device-info'
import ApiPowerCondo from "./apiPowerCondo";
import moment from "moment";
export const getUserProfile = () => { export const getUserProfile = () => {
return Api.get('/mobile/me'); return Api.get('/me');
} }
export const testConnect = () => { export const testConnect = () => {
@ -14,7 +12,7 @@ export const testConnect = () => {
} }
export const registerDevice = (pushToken) => { export const registerDevice = (pushToken) => {
return Api.post('/mobile/register/device', { return Api.post('/register/device', {
push_token: pushToken, push_token: pushToken,
uid: DeviceInfo.getUniqueId(), uid: DeviceInfo.getUniqueId(),
brand: DeviceInfo.getBrand(), brand: DeviceInfo.getBrand(),
@ -23,56 +21,43 @@ export const registerDevice = (pushToken) => {
} }
export const register = (user) => { export const register = (user) => {
const formData = new FormData() return Api.post('/register',
for (let k in user) { user
formData.append(k, user[k]) );
}
return Api.post('/register', formData );
} }
export const login = (params) => { export const login = (params) => {
params = { return Api.post('/login',
...params,
uid: DeviceInfo.getUniqueId(),
brand: DeviceInfo.getBrand(),
model: DeviceInfo.getModel()
}
return Api.post('/api/login',
params params
); );
} }
export const logout = () => {
return Api.post('/api/logout');
}
export const dashboard = (params) => { export const dashboard = (params) => {
return Api.get('/mobile/me/dashboard'); return Api.get('/me/dashboard');
} }
export const getNews = (params) => { export const getNews = (params) => {
return Api.get('/mobile/news'); return Api.get('/news');
} }
export const getNewsPage = (page = 1) => { export const getNewsPage = (page = 1) => {
return Api.get('/mobile/news?page='+page); return Api.get('/news?page='+page);
} }
export const getNewsDetail = (news_id) => { export const getNewsDetail = (news_id) => {
return Api.get('/mobile/news/'+news_id); return Api.get('/news/'+news_id);
} }
export const getNewsByProject = (project_id) => { export const getNewsByProject = (project_id) => {
return Api.get('/mobile/news-projects/'+project_id); return Api.get('/news_projects/'+project_id);
} }
export const project = (keyword) => { export const project = (keyword) => {
return Api.get('/mobile/project'); return Api.get('/project');
} }
export const getBuildingByProjectId = (project_id) => { export const getBuildingByProjectId = (project_id) => {
return Api.get(`/mobile/project/${project_id}/building`); return Api.get(`/project/${project_id}/building`);
} }
export const room = (project_id) => { export const room = (project_id) => {
@ -86,13 +71,13 @@ export const roomdetail = (room_id) => {
} }
export const payment = (user_id) => { export const payment = (user_id) => {
return Api.get('/mobile/me/invoice', { return Api.get('/payment', {
user_id: user_id user_id: user_id
}); });
} }
export const payment_detail = (payments_id) => { export const payment_detail = (payments_id) => {
return Api.get('/mobile/payment/'+payments_id); return Api.get('/payment/'+payments_id);
} }
export const total_payment = (user_id) => { export const total_payment = (user_id) => {
@ -100,52 +85,51 @@ export const total_payment = (user_id) => {
} }
export const edit_profile = (user) => { export const edit_profile = (user) => {
// const formData = new FormData() const formData = new FormData()
// for (let k in user) { for (let k in user) {
// formData.append(k, user[k]) formData.append(k, user[k])
// } }
// let formDataParts = formData._parts ? formData._parts : formData; return Api.post('/me/profile', formData );
return Api.post('/mobile/me/profile', user );
} }
export const get_notification = (user_id, page) => { export const get_notification = (user_id, page) => {
return Api.get('/mobile/notification', { return Api.get('/notification', {
user_id: user_id, user_id: user_id,
page: page page: page
}) })
} }
export const read_notification = (noti_id) => { export const read_notification = (noti_id) => {
return Api.post('/mobile/notification',{noti_id: noti_id}) return Api.post('/notification',{noti_id: noti_id})
} }
export const count_notification = (user_id) => { export const count_notification = (user_id) => {
return Api.get('/mobile/notification/count', { return Api.get('/notification/count', {
user_id: user_id user_id: user_id
}) })
} }
export const getSubscription = (customer_id,type) => { export const getSubscription = (customer_id,type) => {
return Api.get('/mobile/subscription', { return Api.get('/subscription', {
customer_id: customer_id, customer_id: customer_id,
type: type, type: type,
}) })
} }
export const postSubscription = (customer_id,type) => { export const postSubscription = (customer_id,type) => {
return Api.post('/mobile/subscription', { return Api.post('/subscription', {
customer_id: customer_id, customer_id: customer_id,
type: type, type: type,
}) })
} }
export const getProductList = () => { export const getProductList = () => {
return Api.get('/mobile/product'); return Api.get('/product');
} }
export const getProductDetail = (product_id) => { export const getProductDetail = (product_id) => {
return Api.get('/mobile/product/'+product_id); return Api.get('/product/'+product_id);
} }
export const getServices = () => { export const getServices = () => {
@ -164,8 +148,8 @@ export const getRepairList = (service_id) => {
return Api.get('/repair'); return Api.get('/repair');
} }
export const getRepairById = (repair_id, type = '') => { export const getRepairById = (repair_id) => {
return Api.get(`/repair/${repair_id}?self_room=${(type === 'effect_responsible' ? 'true' : 'false')}`); return Api.get('/repair/'+repair_id);
} }
export const postRepair = (param) => { export const postRepair = (param) => {
@ -182,8 +166,7 @@ export const postSuggestion = (params) => {
for (let k in params) { for (let k in params) {
formData.append(k, params[k]) formData.append(k, params[k])
} }
let newFormData = formData._parts ? formData._parts : formData; return Api.post('/suggestion',formData)
return Api.post('/mobile/suggestion', newFormData)
} }
export const postSuggestionLogin = (params) => { export const postSuggestionLogin = (params) => {
@ -191,22 +174,22 @@ export const postSuggestionLogin = (params) => {
for (let k in params) { for (let k in params) {
formData.append(k, params[k]) formData.append(k, params[k])
} }
return Api.post('/mobile/service-suggestion',formData) return Api.post('/service_suggestion',formData)
} }
//Question & Answer //Question & Answer
export const getConversation = () => { export const getConversation = () => {
return Api.get('/mobile/conversation'); return Api.get('/conversation');
} }
export const postConversation = (param) => { export const postConversation = (param) => {
return Api.post('/mobile/conversation/messages',param); return Api.post('/conversation/messages',param);
} }
//Object & Message //Object & Message
export const getObjectMessage = () => { export const getObjectMessage = () => {
return Api.get('/mobile/parcel'); return Api.get('/parcel');
} }
export const postSignatureImage = (params) => { export const postSignatureImage = (params) => {
@ -214,29 +197,29 @@ export const postSignatureImage = (params) => {
for (let k in params) { for (let k in params) {
formData.append(k, params[k]) formData.append(k, params[k])
} }
return Api.post('/mobile/parcel',formData); return Api.post('/parcel',formData);
} }
export const getObjectMessageByID = (id) => { export const getObjectMessageByID = (id) => {
return Api.get(`/mobile/parcel/${id}`); return Api.get(`/parcel/${id}`);
} }
//Meter //Meter
export const getMeterList = () => { export const getMeterList = () => {
return Api.get('/mobile/meter'); return Api.get('/meter');
} }
export const getRoomSlideList = (roon_id) => { export const getRoomSlideList = (roon_id) => {
return Api.get('/mobile/meter?room_id='+roon_id); return Api.get('/meter?room_id='+roon_id);
} }
export const postMeter = (params) => { export const postMeter = (params) => {
// const formData = new FormData() const formData = new FormData()
// for (let k in params) { for (let k in params) {
// formData.append(k, params[k]) formData.append(k, params[k])
// } }
return Api.post('/mobile/meter',params); return Api.post('/meter',formData);
} }
export const postMeterImage = (params) => { export const postMeterImage = (params) => {
@ -245,7 +228,7 @@ export const postMeterImage = (params) => {
formData.append(k, params[k]) formData.append(k, params[k])
} }
return Api.post('/mobile/ocr',formData); return Api.post('/ocr',formData);
} }
export const disconnectFacebook = (user) => { export const disconnectFacebook = (user) => {
@ -253,126 +236,3 @@ export const disconnectFacebook = (user) => {
user user
); );
} }
export const getRoomParcel = (room_no) => {
return Api.get('/check_room_parcel?room_no='+room_no);
}
export const setPaymentLater = () => {
return Api.get('/set_payment_later')
}
export const setFillInMeterLater = () => {
return Api.get('/set_record_meter_later')
}
export const checkPaymentMeter = () => {
return Api.get('/mobile/me/check-payment-meter')
}
export const getRoomUser = () => {
return Api.get('/mobile/get_room_user');
}
export function cancelRepair(id) {
return Api.post('/repair/cancel', {id: id})
}
export function postEvaluateRepair(params) {
return Api.post('/repair/point', params)
}
export function setLanguage(language) {
return Api.post('/mobile/me/set-language', {language: language})
}
export function getRoomPowerCondo(project_id, customer_id) {
return Api.get(`/api/project/${project_id}/room/list/customer?customer_id=${customer_id}`)
}
export function getRoomSelfPowerCondo() {
return Api.get(`/mobile/me/room`)
}
export function getRepairDropdownList(query) {
return Api.get(`/api/dropdowns?name=${query}`)
}
export function getRepairListPowerCondo(project_id) {
return Api.get(`/api/project/${project_id}/maintenance-setting`)
}
export function sendRequestRepair(project_id, body){
return Api.post(`/api/project/${project_id}/maintenance`, body)
}
export function sendMoveOutData(project_id, body){
return Api.post(`/api/project/${project_id}/move-out`, body)
}
export function getListReward(category_id='') {
category_id = category_id ? category_id : '';
return Api.get(`/mobile/reward?category_id=${category_id}`)
}
export function getRewardDetail(id, is_my_reward) {
let url = is_my_reward ? '/mobile/me/reward' : '/mobile/reward';
return Api.get(`${url}/${id}`)
}
export function getListMyReward(type_id = '', category_id = '', customer_finance_id='') {
return Api.get(`/mobile/me/reward?type=${type_id}&category_id=${category_id}&customer_finance_id=${customer_finance_id}`)
}
export function getHistoryRedeemPoint(datetime) {
datetime = moment(datetime, 'MMMM YYYY')
return Api.get(`/mobile/me/history-point?month=${datetime.format('M')}&year=${datetime.format('YYYY')}`)
}
export function redeemReward(id) {
return Api.post(`/mobile/redeem/${id}`)
}
export function scanReward(id, code) {
return Api.post(`/mobile/coupon/${id}/qr/${code}`)
}
export function usedCoupon(id) {
return Api.post(`/mobile/coupon/${id}/qr`)
}
export function useMyReward(id) {
return Api.post(`/mobile/me/reward/${id}`)
}
export function forgetPassword(mobile) {
return Api.post('/api/forget-password', {mobile});
}
export function sendVerifyOTP(token, otp) {
return Api.post(`/api/verify-otp/${token}`, {otp})
}
export function getRewardTermAndCondition(reward_id) {
return Api.get(`/mobile/reward/${reward_id}/term-and-condition`);
}
export function useRentalDiscount(coupon_id, payment_id){
return Api.post(`/mobile/coupon/${coupon_id}/discount/${payment_id}`)
}
export function removeRentalDiscount(coupon_id, payment_id){
return Api.delete(`/mobile/coupon/${coupon_id}/discount/${payment_id}`)
}
export function getLevelMembership(){
return Api.get(`/mobile/me/loyalty`);
}
export function getLevelMemberDetail(){
return Api.get(`/mobile/loyalty/privilege`)
}
export function getPointExpire(){
return Api.get('/mobile/me/expired-point')
}

View File

@ -1,7 +1,8 @@
import { create } from 'apisauce' import { create } from 'apisauce'
import Config from 'src/utils/Config' import Config from 'src/utils/Config'
import DeviceInfo from 'react-native-device-info' import DeviceInfo from 'react-native-device-info'
import { Alert, Platform } from 'react-native' import { Alert, NetInfo, Platform } from 'react-native'
import NavigationService from 'src/utils/NavigationService'
// import { strings as t } from '../i18n' // import { strings as t } from '../i18n'
// import { userLogout } from 'src/redux/app/action' // import { userLogout } from 'src/redux/app/action'
@ -10,26 +11,15 @@ import { Alert, Platform } from 'react-native'
let store let store
const Api = create({ const Api = create({
// baseURL: Config.API_BASE_URL_PROD, baseURL: Config.API_BASE_URL,
baseURL: Config.API_BASE_URL_POWER_CONDO_DEV,
headers: { headers: {
'X-Frame-Options': 'sameorigin', 'X-Frame-Options': 'sameorigin',
'X-App-Version': DeviceInfo.getVersion(), 'X-App-Version': DeviceInfo.getVersion(),
'X-Device-OS': Platform.OS, 'X-Device-OS': Platform.OS,
'X-Device-Version': Platform.Version, 'X-Device-Version': Platform.Version,
'Content-Type': 'application/json'
} }
}) })
export function setBaseUrl (baseUrl) {
Api.setBaseURL(baseUrl)
}
export function setBaseUrlByServerMode (mode) {
// Api.setBaseURL(mode === 'production' ? Config.API_BASE_URL_PROD : Config.API_BASE_URL_DEV)
Api.setBaseURL(mode === 'production' ? Config.API_BASE_URL_PROD : Config.API_BASE_URL_POWER_CONDO_DEV)
}
DeviceInfo.getDeviceName().then(name => { DeviceInfo.getDeviceName().then(name => {
Api.setHeader('X-Device-Name', name) Api.setHeader('X-Device-Name', name)
}) })
@ -39,11 +29,11 @@ Api.addRequestTransform(request => {
}) })
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
Api.addRequestTransform(request => { Api.addRequestTransform(request => {
console.info('--> [' + request.method + '] ' + Api.getBaseURL() + request.url, request.params, request.data) console.info('--> [' + request.method + '] ' + Api.getBaseURL() + request.url,request.params, request.data)
console.info('header --' + request.url + ' -- ', request.headers) console.info('header --' + request.url +' -- ', request.headers)
}) })
Api.addMonitor(response => { Api.addMonitor(response => {
console.info('<-- ' + response.status + ' --- ' + response.config.url, response) console.info('<-- ' + response.status + ' --- ' + response.config.url,response)
}) })
} }
@ -59,7 +49,8 @@ Api.addMonitor(response => {
case 'SERVER_ERROR': case 'SERVER_ERROR':
case 'CANCEL_ERROR': case 'CANCEL_ERROR':
case 'CLIENT_ERROR': // 4XX case 'CLIENT_ERROR': // 4XX
/*if (response.status === 401) { if (response.status === 401) {
// store.dispatch(userLogout)
Alert.alert('Session timeout', 'Please login again to continue using application', [ Alert.alert('Session timeout', 'Please login again to continue using application', [
{ {
text: 'ok', text: 'ok',
@ -67,20 +58,20 @@ Api.addMonitor(response => {
// NavigationService.navigate('AppLoading') // NavigationService.navigate('AppLoading')
} }
} }
], { cancelable: false }) ], {cancelable: false})
return return
}*/ }
// Alert.alert(null, 'error_getting_data', [{text: 'ok'}]) // Alert.alert(null, 'error_getting_data', [{text: 'ok'}])
break break
} }
} }
}) })
export function setStore (reduxStore) { export function setStore(reduxStore) {
store = reduxStore store = reduxStore
} }
export function setToken (token) { export function setToken(token) {
Api.setHeader('Authorization', 'Bearer ' + token) Api.setHeader('Authorization', 'Bearer ' + token)
} }
@ -88,11 +79,11 @@ export function setLanguage (languageCode) {
Api.setHeader('language', languageCode) Api.setHeader('language', languageCode)
} }
export function clearToken () { export function clearToken() {
Api.deleteHeader('Authorization') Api.deleteHeader('Authorization')
} }
export function setLocation (lat, lng) { export function setLocation(lat, lng) {
Api.setHeader('X-Current-Latitude', lat.toString() || '0.0') Api.setHeader('X-Current-Latitude', lat.toString() || '0.0')
Api.setHeader('X-Current-Longitude', lng.toString() || '0.0') Api.setHeader('X-Current-Longitude', lng.toString() || '0.0')
} }

View File

@ -1,68 +0,0 @@
import { create } from 'apisauce'
import Config from 'src/utils/Config'
import DeviceInfo from 'react-native-device-info'
import { Platform } from 'react-native'
const ApiPowerCondo = create({
baseURL: Config.API_BASE_URL_POWER_CONDO_DEV,
headers: {
'X-Frame-Options': 'sameorigin',
'X-App-Version': DeviceInfo.getVersion(),
'X-Device-OS': Platform.OS,
'X-Device-Version': Platform.Version,
'Content-Type': 'application/json'
}
})
DeviceInfo.getDeviceName().then(name => {
ApiPowerCondo.setHeader('X-Device-Name', name)
})
ApiPowerCondo.addRequestTransform(request => {
// request.headers['X-App-Locale'] = I18n.locale
})
if (process.env.NODE_ENV !== 'production') {
ApiPowerCondo.addRequestTransform(request => {
console.info('--> [' + request.method + '] ' + ApiPowerCondo.getBaseURL() + request.url, request.params, request.data)
console.info('header --' + request.url + ' -- ', request.headers)
})
ApiPowerCondo.addMonitor(response => {
console.info('<-- ' + response.status + ' --- ' + response.config.url, response)
})
}
// error alert monitor
ApiPowerCondo.addMonitor(response => {
if (!response.ok) {
switch (response.problem) {
case 'CONNECTION_ERROR':
case 'NETWORK_ERROR':
case 'TIMEOUT_ERROR':
// Alert.alert('error_internet_title', 'error_internet_message', [{text: 'ok'}])
break
case 'SERVER_ERROR':
case 'CANCEL_ERROR':
case 'CLIENT_ERROR': // 4XX
break
}
}
})
export function setTokenPowerCondo (token) {
ApiPowerCondo.setHeader('Authorization', 'Bearer ' + token)
}
export function setLanguagePowerCondo (languageCode) {
ApiPowerCondo.setHeader('language', languageCode)
}
export function clearTokenPowerCondo () {
ApiPowerCondo.deleteHeader('Authorization')
}
export function setLocationPowerCondo (lat, lng) {
ApiPowerCondo.setHeader('X-Current-Latitude', lat.toString() || '0.0')
ApiPowerCondo.setHeader('X-Current-Longitude', lng.toString() || '0.0')
}
export default ApiPowerCondo

View File

@ -1,83 +0,0 @@
import appleAuth, {
AppleAuthRequestOperation,
AppleAuthRequestScope,
AppleAuthCredentialState,
} from '@invertase/react-native-apple-authentication';
import { setToken } from '../api/api'
import { store } from '../redux/store'
import {appSetToken, appSetUser} from '../redux/app/action';
import {login, register} from '../api/UserApi';
import {Alert} from 'react-native';
export const signinApple = async (onSuccess) => {
try {
const requestOptions = {
requestedOperation: AppleAuthRequestOperation.LOGIN,
requestedScopes: [AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME],
}
// register({
// ...this.props.user,
// device_id: deviceId
// }).then((res) => {
//
// });
// login
/* const { user } = await appleAuth.performRequest(requestOptions);
console.log(user) */
// register
const appleAuthRequestResponse = await appleAuth.performRequest({
requestedOperation: AppleAuthRequestOperation.LOGIN,
requestedScopes: [AppleAuthRequestScope.EMAIL, AppleAuthRequestScope.FULL_NAME],
})
console.log(appleAuthRequestResponse)
// get current authentication state for user
// /!\ This method must be tested on a real device. On the iOS simulator it always throws an error
// use credentialState response to ensure the user is authenticated
if (AppleAuthCredentialState.AUTHORIZED) {
// user is authenticated
// sent and login
let params = {
identityToken: appleAuthRequestResponse.identityToken,
authorizationCode: appleAuthRequestResponse.authorizationCode,
email_apple: appleAuthRequestResponse.email
}
login(params)
.then(async (res) => {
if(res.status == 500){
Alert.alert('','ไม่สามารถเชื่อมต่อกับเซิฟเวอร์ได้ กรุณาลองใหม่อีกครั้ง')
return
}
if (res.ok) {
if (res.data.token) {
//Alert.alert('Connect with Facebook Success')
setToken(res.data.token)
store.dispatch(appSetToken(res.data.token))
store.dispatch(appSetUser(res.data.user))
onSuccess && onSuccess()
}
} else {
if(res.data.msg != null){
Alert.alert('',res.data.msg)
}
}
})
}
} catch (e) {
console.log(e);
if (e.code === 'ERR_CANCELED') {
// handle that the user canceled the sign-in flow
} else {
// handle other errors
}
}
}

View File

@ -1,7 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { TextInput, View } from 'react-native' import { TextInput, View } from 'react-native'
import Icon from 'src/components/Icon' import Icon from 'src/components/Icon'
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'
import Text from 'src/components/Text'; import Text from 'src/components/Text';
export class CustomInput extends Component { export class CustomInput extends Component {
@ -9,30 +8,10 @@ export class CustomInput extends Component {
let props = this.props let props = this.props
return ( return (
<View style={[styles.container, props.style]}> <View style={[styles.container, props.style]}>
{/* { {props.iconName && <View style={styles.icon}>
props.iconType === 'fontAwesome' ? <Icon name={props.iconName} size={16} color={props.iconColor || 'white'}> </Icon>
props.iconName && <View style={styles.icon}> </View>
<FontAwesomeIcon name={props.iconName} size={16} color={props.iconColor || 'white'}/>
</View>
:
props.iconName && <View style={styles.icon}>
<Icon name={props.iconName} size={16} color={props.iconColor || 'white'}> </Icon>
</View>
} */}
{ props.iconName ?
props.iconType ?
<View style={styles.icon}>
<FontAwesomeIcon name={props.iconName} size={18} color={props.iconColor || 'white'}> </FontAwesomeIcon>
</View>
:
<View style={styles.icon}>
<Icon name={props.iconName} size={16} color={props.iconColor || 'white'}> </Icon>
</View>
: <View></View>
} }
{props.labelName && <View style={styles.icon}> {props.labelName && <View style={styles.icon}>
<Text style={{ color: props.labelColor || 'rgba(0, 0, 0, 0.5)' }}>{props.labelName}</Text> <Text style={{ color: props.labelColor || 'rgba(0, 0, 0, 0.5)' }}>{props.labelName}</Text>
</View> </View>
@ -41,12 +20,10 @@ export class CustomInput extends Component {
<View style={{ flex: 1 , justifyContent:'center'}}> <View style={{ flex: 1 , justifyContent:'center'}}>
<TextInput <TextInput
{...props} {...props}
style={{ padding: 7, textAlign: 'right', color: props.afterInput || 'white', fontFamily: 'Prompt-Regular', ...props.textInputStyles }} style={{ padding: 7, textAlign: 'right', color: props.afterInput || 'white', fontFamily: 'Prompt-Regular' }}
secureTextEntry={props.secureTextEntry} secureTextEntry={props.secureTextEntry}
textAlign={props.inputTextAlign || 'right'} textAlign={props.inputTextAlign || 'right'}
placeholder={props.placeholder} placeholder={props.placeholder} value={props.value} />
value={props.value}
/>
</View> </View>
</View> </View>
) )

View File

@ -5,7 +5,6 @@ import { login, disconnectFacebook } from '../api/UserApi'
import { store } from '../redux/store' import { store } from '../redux/store'
import { Alert } from 'react-native' import { Alert } from 'react-native'
import NavigationService from '../utils/NavigationService'; import NavigationService from '../utils/NavigationService';
import messaging from "@react-native-firebase/messaging";
let requestManager = new GraphRequestManager(); let requestManager = new GraphRequestManager();
@ -34,22 +33,10 @@ export function loginWithFacebook(onSuccess){
); );
} }
async function loginAccessTokenToServer(accessToken,onSuccess){ function loginAccessTokenToServer(accessToken,onSuccess){
const fcm = messaging();
if (!await fcm.hasPermission()) {
try {
await messaging().requestPermission();
} catch (error) {
}
}
const fcmToken = await messaging().getAPNSToken();
let params = { let params = {
access_token: accessToken, access_token: accessToken,
fcm_token: fcmToken
} }
login(params) login(params)
.then(async (res) => { .then(async (res) => {
if(res.status == 500){ if(res.status == 500){
@ -79,15 +66,13 @@ export function logoutFacebook() {
export function disconnectWithFacebook(onSuccess){ export function disconnectWithFacebook(onSuccess){
AccessToken.getCurrentAccessToken()
.then((data) => { AccessToken.getCurrentAccessToken().then(
(data) => {
console.log("AccessToken.getCurrentAccessToken():") console.log("AccessToken.getCurrentAccessToken():")
console.log(data) console.log(data)
let accessToken = null; const accessToken = data.accessToken.toString()
if(data && data.accessToken){
accessToken = data.accessToken.toString();
}
//console.log("accessToken:") //console.log("accessToken:")
//console.log(accessToken) //console.log(accessToken)
@ -106,7 +91,20 @@ export function disconnectWithFacebook(onSuccess){
} }
if (res.ok) { if (res.ok) {
onSuccess && onSuccess(); Alert.alert('Disconnect with Facebook Success')
// if (res.data.token) {
// setToken(res.data.token)
// store.dispatch(appSetToken(res.data.token))
this.state.user.fb_token = null
this.state.user.fb_is_link = 'f'
//Alert.alert(this.state.user)
//console.log('console.log(this.state.user):')
//console.log(this.state.user)
// store.dispatch(appSetUser(this.state.user))
// store.dispatch(appSetFacebook('f'))
onSuccess && onSuccess()
// }
} else { } else {
if(res.data.msg != null){ if(res.data.msg != null){
Alert.alert('',res.data.msg) Alert.alert('',res.data.msg)

View File

@ -1,53 +0,0 @@
import React, { Component } from 'react';
import { View, Modal, TouchableOpacity } from 'react-native';
import Text from "./Text";
export default class Popup extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<View>
<Modal animationType="none"
transparent={true}
visible={this.props.modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{flex:1,backgroundColor:'#00000080',justifyContent:'center',alignItems:'center'}}>
<View style={{width: '90%',backgroundColor:'white',borderRadius:5,paddingVertical: 27, paddingHorizontal: 17}}>
<Text style={[{color:'#2C7C0B',fontSize: 18}, this.props.styleTitle ? this.props.styleTitle : {}]}>
{this.props.title}
</Text>
{
this.props.message && <Text style={[{color:'#00000080',fontSize: 14,marginVertical: 15}, this.props.styleMessage ? this.props.styleMessage : {}]}>{this.props.message}</Text>
}
<View style={[{flexDirection:'row', width: '100%', justifyContent: 'center', marginTop: 30}, this.props.styleFooter ? this.props.styleFooter : {}]}>
<View style={{width: '50%'}}>
{
this.props.onCancel &&
<TouchableOpacity onPress={() => {this.props.onCancel()}}>
<Text style={{color:'#269A21',fontSize: 14, textAlign: 'center'}}>Cancel</Text>
</TouchableOpacity>
}
</View>
<View style={{width: '50%'}}>
<TouchableOpacity onPress={() => {this.props.onConfirm && this.props.onConfirm()}}>
<Text style={[{color:'#269A21',fontSize: 14,textAlign: 'center'}, this.props.styleConfirmBtn ? this.props.styleConfirmBtn : {} ]}>
OK
</Text>
</TouchableOpacity>
</View>
</View>
</View>
</View>
</Modal>
</View>
);
}
}

View File

@ -1,7 +1,7 @@
import React, {useCallback, useRef, useState} from 'react' import React from 'react'
import {Modal, StyleSheet, TouchableOpacity, View} from 'react-native' import { TouchableOpacity, View, StyleSheet } from 'react-native'
import Image from 'react-native-fast-image' import Image from 'react-native-fast-image'
import {createBottomTabNavigator, createStackNavigator} from 'react-navigation' import { createStackNavigator, createBottomTabNavigator } from 'react-navigation'
import NewsScreen from '../screens/news/News' import NewsScreen from '../screens/news/News'
import RoomScreen from '../screens/room/Room' import RoomScreen from '../screens/room/Room'
import ProductScreen from '../screens/product/Product' import ProductScreen from '../screens/product/Product'
@ -19,50 +19,33 @@ import Icon from 'src/components/Icon'
import PersonRoomReservationScreen from '../screens/room/PersonRoomReservation' import PersonRoomReservationScreen from '../screens/room/PersonRoomReservation'
import CompanyRoomReservationScreen from '../screens/room/CompanyRoomReservation' import CompanyRoomReservationScreen from '../screens/room/CompanyRoomReservation'
import RoomHeaderReservationScreen from '../screens/room/RoomHeaderReservation' import RoomHeaderReservationScreen from '../screens/room/RoomHeaderReservation'
import Text from 'src/components/Text' import Text from 'src/components/Text';
import {bindActionCreators} from 'redux' import { news } from '../api/UserApi';
import {appCleanUser, appSetNotification, setServerMode} from '../redux/app/action' import { bindActionCreators } from 'redux'
import {connect, useDispatch, useSelector} from 'react-redux' import { appSetNotification } from '../redux/app/action'
import PaymentScreen from '../screens/bill/Payment' import { connect } from 'react-redux'
import MessageObject from '../screens/object/MessageObject' import PaymentScreen from "../screens/bill/Payment";
import MessageObjectDetail from '../screens/object/MessageObjectDetail' import MessageObject from '../screens/object/MessageObject';
import MessageObjectDetail from '../screens/object/MessageObjectDetail';
import RegisterScreen from '../screens/login/Register' import RegisterScreen from '../screens/login/Register'
import RegisterProfileScreen from '../screens/login/RegisterProfile' import RegisterProfileScreen from '../screens/login/RegisterProfile'
import RegisterFormLoginScreen from '../screens/login/RegisterFormLogin' import RegisterFormLoginScreen from '../screens/login/RegisterFormLogin'
import LoginScreen from '../screens/login/Login' import LoginScreen from '../screens/login/Login'
import SignaturePadScreen from '../screens/object/SignaturePadScreen' import SignaturePadScreen from '../screens/object/SignaturePadScreen';
import WaterMeter from '../screens/meters/WaterMeter' import WaterMeter from '../screens/meters/WaterMeter';
import PEAMeter from '../screens/meters/PEAMeter' import PEAMeter from '../screens/meters/PEAMeter';
import ZoneAreaScreen from '../screens/room/ZoneAreaScreen' import ZoneAreaScreen from '../screens/room/ZoneAreaScreen';
import RepairServiceDetail from '../screens/repair/RepairServiceDetail' import RepairServiceDetail from '../screens/repair/RepairServiceDetail';
import RepairService from '../screens/repair/RepairService' import RepairService from '../screens/repair/RepairService';
import RepairIndex from '../screens/repair/RepairIndex' import RepairConfirm from '../screens/repair/RepairConfirm';
import RepairConfirm from '../screens/repair/RepairConfirm' import RepairHistory from '../screens/repair/RepairHistory';
import RepairHistory from '../screens/repair/RepairHistory' import RepairSuccess from '../screens/repair/RepairSuccess';
import RepairSuccess from '../screens/repair/RepairSuccess' import RepairHistoryDetail from '../screens/repair/RepairHistoryDetail';
import RepairHistoryDetail from '../screens/repair/RepairHistoryDetail' import RewardScreen from '../screens/reward/RewardScreen';
import RewardScreen from '../screens/reward/RewardScreen' import RewardDetailScreen from '../screens/reward/RewardDetailScreen';
import RewardDetailScreen from '../screens/reward/RewardDetailScreen' import QuestionScreen from '../screens/service/QuestionScreen';
import QuestionScreen from '../screens/service/QuestionScreen'
import TermsAndCondition from '../screens/login/TermsAndCondition' import TermsAndCondition from '../screens/login/TermsAndCondition'
import MoveOutScreen from "../screens/service/MoveOutScreen"; import { locale, t } from 'src/utils/i18n'
import RoomReservation from "../screens/room/RoomReservationWebView";
import {locale, t} from 'src/utils/i18n'
import {store} from 'src/redux/store'
import RedeemScreen from "../screens/redeem/RedeemScreen";
import HistoryRedeem from "../screens/redeem/HistoryRedeem";
import AllRewards from "../screens/redeem/AllRewards";
import MyRewards from "../screens/redeem/MyRewards";
import RewardDetail from "../screens/redeem/RewardDetail";
import RewardTermCondition from "../screens/redeem/RewardTermCondition"
import ScanCoupon from "../screens/redeem/ScanCoupon";
import ForgetPasswordScreen from '../screens/forget_password/ForgetPasswordScreen'
import VerifyOTP from '../screens/forget_password/VerifyOTP'
import PasswordCode from '../screens/forget_password/PasswordCode'
import PaymentDetail from '../screens/bill/PaymentDetail'
import PaymentConfirm from '../screens/bill/PaymentConfirm'
import MembershipLevelDetail from '../screens/redeem/MembershipLeveDetail'
import MemberPoinExpire from '../screens/redeem/MemberPoinExpire'
const screenConfig = (screen, title, backgroundColor = undefined) => ({ const screenConfig = (screen, title, backgroundColor = undefined) => ({
screen, screen,
@ -103,11 +86,11 @@ const NavWithRightIcon = (title, iconName, routeName) => ({ navigation }) => ({
<TouchableOpacity <TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }} style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => navigation.goBack()}> onPress={() => navigation.goBack()}>
<Icon name="ic_back" size={20} color="#fff"/> <Icon name="ic_back" size={20} color="#fff" />
</TouchableOpacity> </TouchableOpacity>
), ),
headerRight: ( headerRight: (
<TouchableOpacity style={{ paddingRight: 16 }} onPress={() => {navigation.navigate(routeName)}}> <TouchableOpacity style={{paddingRight:16}} onPress={() => {navigation.navigate(routeName)}}>
<Icon name={iconName} color={'white'} size={20}/> <Icon name={iconName} color={'white'} size={20}/>
</TouchableOpacity> </TouchableOpacity>
) )
@ -118,7 +101,6 @@ const defaultNavOption = (title, backgroundColor) => ({ navigation }) => ({
headerStyle: { headerStyle: {
backgroundColor: backgroundColor || '#00420A', backgroundColor: backgroundColor || '#00420A',
height: 50, height: 50,
marginTop: 25,
elevation: 0, elevation: 0,
shadowOpacity: 0, shadowOpacity: 0,
}, },
@ -148,7 +130,7 @@ const defaultNavOption = (title, backgroundColor) => ({ navigation }) => ({
<TouchableOpacity <TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }} style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => navigation.goBack()}> onPress={() => navigation.goBack()}>
<Icon name="ic_back" size={20} color="#fff"/> <Icon name="ic_back" size={20} color="#fff" />
</TouchableOpacity> </TouchableOpacity>
), ),
headerRight: ( headerRight: (
@ -159,104 +141,104 @@ const defaultNavOption = (title, backgroundColor) => ({ navigation }) => ({
}) })
const BottomTab = createBottomTabNavigator({ const BottomTab = createBottomTabNavigator({
HomeScreen: { HomeScreen: {
screen: NewsScreen, screen: NewsScreen,
navigationOptions: ({ navigation }) => ({ navigationOptions: ({ navigation }) => ({
tabBarVisible: true, tabBarVisible: true,
tabBarLabel: ({ focused, tintColor }) => { tabBarLabel: ({ focused, tintColor }) => {
if (focused) { if (focused) {
tintColor = '#FFCC00' tintColor = '#FFCC00'
} else { } else {
tintColor = 'rgba(255, 255, 255, 0.65)' tintColor = 'rgba(255, 255, 255, 0.65)'
} }
return <View style={{ justifyContent: 'center', alignItems: 'center' }}> return <View style={{justifyContent:'center',alignItems:'center'}}>
<Icon name={'ic_newspaper'} size={20} color={tintColor}/> <Icon name={'ic_newspaper'} size={20} color={tintColor} />
<Text style={[styles.textBottomTab, { color: tintColor }]}>{t('news')}</Text> <Text style={[styles.textBottomTab,{color: tintColor}]}>{t('news')}</Text>
</View> /* 'Room' */ </View> /* 'Room' */
}, },
tabBarIcon: ({ focused, tintColor }) => { tabBarIcon: ({ focused, tintColor }) => {
if (focused) { if (focused) {
tintColor = '#FFCC00' tintColor = '#FFCC00'
} else { } else {
tintColor = 'rgba(255, 255, 255, 0.65)' tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View></View>
} }
}) return <View></View>
}, }
RoomScreen: { })
// screen: ZoneAreaScreen,
screen: RoomReservation,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Icon name={'ic_bed-outline'} size={22} color={tintColor}/>
<Text style={[styles.textBottomTab, { color: tintColor }]}>{t('room')}</Text>
</View> /* 'Room' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
},
FavorsScreen: {
screen: RewardScreen,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Icon name={'ic_star_sq'} size={20} color={tintColor}/>
<Text style={[styles.textBottomTab, { color: tintColor }]}>{t('products')}</Text>
</View> /* 'Favaors' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
},
ServiceScreen: {
screen: ServiceScreen/* ServiceScreen */,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Icon name={'ic_grid'} size={20} color={tintColor}/>
<Text style={[styles.textBottomTab, { color: tintColor }]}>{t('service')}</Text>
</View> /* 'Room' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
}
}, },
RoomScreen: {
screen: ZoneAreaScreen,
// screen: RoomScreen,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{justifyContent:'center',alignItems:'center'}}>
<Icon name={'ic_bed-outline'} size={22} color={tintColor} />
<Text style={[styles.textBottomTab,{color: tintColor}]}>{t('room')}</Text>
</View> /* 'Room' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
},
FavorsScreen: {
screen: RewardScreen,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{justifyContent:'center',alignItems:'center'}}>
<Icon name={'ic_star_sq'} size={20} color={tintColor} />
<Text style={[styles.textBottomTab,{color: tintColor}]}>{t('products')}</Text>
</View> /* 'Favaors' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
},
ServiceScreen: {
screen: ServiceScreen/* ServiceScreen */,
navigationOptions: ({ navigation }) => ({
tabBarLabel: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
return <View style={{justifyContent:'center',alignItems:'center'}}>
<Icon name={'ic_grid'} size={20} color={tintColor} />
<Text style={[styles.textBottomTab,{color: tintColor}]}>{t('service')}</Text>
</View> /* 'Room' */
},
tabBarIcon: ({ focused, tintColor }) => {
if (focused) {
tintColor = '#FFCC00'
} else {
tintColor = 'rgba(255, 255, 255, 0.65)'
}
}
})
}
},
{ {
tabBarOptions: { tabBarOptions: {
activeTintColor: '#FFCC00', activeTintColor: '#FFCC00',
@ -264,157 +246,72 @@ const BottomTab = createBottomTabNavigator({
} }
}) })
//export default LoginScreen //export default LoginScreen
const mapDisPatchToProps = state => { const mapDisPatchToProps = state => {
return state.app return state.app
}
const setNotification = dispatch => bindActionCreators({ appSetNotification }, dispatch)
const NotificationIcon = connect(mapDisPatchToProps, setNotification)(({ count_noti, user }) => {
let count = 0
if (count_noti) {
count = count_noti
} }
if (count > 0) { const setNotification = dispatch => bindActionCreators({ appSetNotification }, dispatch)
return <View> const NotificationIcon = connect(mapDisPatchToProps, setNotification)(({count_noti,user}) => {
<View let count = 0;
style={{ if(count_noti){
width: 16, count = count_noti
height: 16, }
backgroundColor: '#FF2D55', if(count > 0){
borderRadius: 50, return <View>
justifyContent: 'center', <View
alignItems: 'center', style={{
position: 'absolute', width: 16,
right: '10%', height: 16,
top: '-10%', backgroundColor: '#FF2D55',
zIndex: 1, borderRadius: 50,
roomLength: 0 justifyContent: 'center',
}}> alignItems: 'center',
<Text style={{ color: 'white', fontSize: 8 }}>{count && count > 9 ? '9+' : count}</Text> position: 'absolute',
</View> right: '10%',
<View style={{ marginRight: 10 }}> top: '-10%',
<Icon name={'ic_bell'} size={20} color={'white'}/> zIndex: 1
</View> }}>
</View> <Text style={{ color: 'white', fontSize: 8 }}>{count && count > 9 ? '9+' : count }</Text>
} else {
return (
<View>
<View style={{ marginRight: 10 }}>
<Icon name={'ic_bell'} size={20} color={'white'}/>
</View> </View>
</View> <View style={{ marginRight: 10 }}>
) <Icon name={'ic_bell'} size={20} color={'white'} />
} </View>
</View>;
}else{
return (
<View>
<View style={{ marginRight: 10 }}>
<Icon name={'ic_bell'} size={20} color={'white'} />
</View>
</View>
)
}
}) })
const MainTitle = connect(state => ({ const MainTitle = connect(state => ({
user: state.app.user, user: state.app.user,
state_app: state.app,
}))((props) => { }))((props) => {
let userText = '' let userText = '';
let room = '' let room = '';
let roomPopup = '' let name = '';
let name = '' console.log("props.user.", props.user);
let projectName = '' if(props.user && typeof props.user.room != 'undefined'){
console.log('props.user.', props.user) room = " "+props.user.room;
console.log('props.state_app:', props.state_app) }
if (props.user && typeof props.user.room != 'undefined') { if(props.user && typeof props.user.name != 'undefined'){
room = ' ' + props.user.room name = props.user.name.split(" ");
roomPopup = props.user.room
// console.log('room',room)
if (room.length >= 16) {
room = room.substring(0, 16) + '...'
} }
}
if (props.user && typeof props.user.name != 'undefined') {
name = props.user.name.split(' ')
}
if (props.user) { if (props.user) {
userText = `${name[0]}`; userText = `(${name[0]}${room})`
projectName = props.user.project_name
} }
return <View> return <Text style={{ fontSize: 18, color: '#FFFFFF', marginLeft: 15, marginTop: 3 }}>{t('charoensin_asset')} {userText} </Text>
<Text style={{ fontSize: 16, color: '#FFFFFF', marginLeft: 10, marginTop: 3, marginBottom: 5 }}>{t('charoensin_asset')} {projectName}</Text>
</View>
}) })
const MainHeader = ({ navigation }) => {
const lastCount = useRef(0)
const counter = useRef(0)
const [showModal, setShowModal] = useState(false)
const dispatch = useDispatch()
const server_mode = useSelector(state => state.app.server_mode)
const openSecretChamber = useCallback(() => {
const t = new Date().getTime()
if (t - lastCount.current < 500) {
if (++counter.current >= 10) {
setShowModal(true)
}
} else {
counter.current = 1
}
lastCount.current = t
}, [])
const changeServer = useCallback((mode) => {
dispatch(setServerMode(mode))
setShowModal(false)
}, [])
return <View style={[{ flex: 1, alignItems: 'center', flexDirection: 'row', marginTop: 0, paddingLeft: 10, backgroundColor: server_mode === 'develop' ? '#ff0000' : 'transparent' }]}>
<TouchableOpacity
onPress={openSecretChamber}
activeOpacity={1}>
<Image
style={{ width: 35, height: 35, }}
source={require('../../assets/images/logo_white_border.png')}
/>
</TouchableOpacity>
<MainTitle/>
<Modal transparent={true} visible={showModal}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View style={{ backgroundColor: 'white', padding: 20, borderRadius: 10 }}>
<View>
<Text>งค Server</Text>
</View>
<View style={{ marginTop: 10 }}>
<TouchableOpacity style={{ padding: 10 }} onPress={() => changeServer('production')}>
<Text style={{ color: server_mode == 'production' ? '#004287' : '#aaa' }}>PRODUCTION</Text>
</TouchableOpacity>
<TouchableOpacity style={{ padding: 10 }} onPress={() => changeServer('develop')}>
<Text style={{ color: server_mode == 'develop' ? '#004287' : '#aaa' }}>DEVELOP</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
</View>
}
const HeaderLeftComponent = (navigation, routeName = null, propsRoute = null) => {
return (
<TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => routeName ? navigation.navigate(routeName, propsRoute || null) : navigation.goBack()}>
<Icon name="ic_back" size={20} color="#fff"/>
</TouchableOpacity>
)
}
const defaultHeaderStyle = () => {
return {
headerStyle: styles.defaultHeaderStyle,
headerTintColor: '#000',
headerTitleStyle: styles.defaultHeaderTitleStyle,
headerTitleContainerStyle: styles.defaultHeaderTitleContainerStyle,
headerLeftContainerStyle: styles.defaultHeaderLeftContainerStyle,
headerTitleAllowFontScaling: false,
}
}
const AppStack = createStackNavigator({ const AppStack = createStackNavigator({
BottomTab: { BottomTab: {
screen: BottomTab, screen: BottomTab,
navigationOptions: ({navigation}) => { navigationOptions: ({ navigation }) => {
let langIcon let langIcon
switch (locale()) { switch (locale()) {
case 'th': case 'th':
@ -435,7 +332,6 @@ const AppStack = createStackNavigator({
headerStyle: { headerStyle: {
backgroundColor: '#00420A', backgroundColor: '#00420A',
height: 50, height: 50,
marginTop: 25,
elevation: 0, elevation: 0,
shadowOpacity: 0, shadowOpacity: 0,
}, },
@ -448,23 +344,31 @@ const AppStack = createStackNavigator({
marginLeft: 30, marginLeft: 30,
}, },
headerRight: ( headerRight: (
<View style={{marginRight: 0, justifyContent: 'center', alignItems: 'center', flexDirection: 'row'}}> <View style={{ marginRight: 0, justifyContent: 'center', alignItems: 'center', flexDirection: 'row' }}>
<TouchableOpacity onPress={() => navigation.navigate('LanguageSelect')} style={{marginRight: 8}}> <TouchableOpacity onPress={() => navigation.navigate('LanguageSelect')} style={{marginRight:8}}>
<View style={{width: 30, height: 30, alignItems: 'center', justifyContent: 'center'}}> <View style={{ width: 30, height: 30, alignItems: 'center', justifyContent: 'center' }}>
<Image style={{width: 25, height: 25}} source={langIcon}/></View> <Image style={{width:25,height:25}} source={langIcon}/></View>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={{marginRight: 6}} onPress={() => navigation.navigate('Notification')}> <TouchableOpacity style={{ marginRight: 6 }} onPress={() => navigation.navigate('Notification')}>
<NotificationIcon/> <NotificationIcon/>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
), ),
headerLeftContainerStyle: { headerLeftContainerStyle: {
width: '80%', width:'80%',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
}, },
headerLeft: () => <MainHeader navigation={navigation}/>, headerLeft: (
} <View style={[{ flex: 1, flexDirection: 'row', marginTop: 0, paddingLeft: 10 }]}>
<Image
style={{ width: 35, height: 35, }}
source={require('../../assets/images/logo_white_border.png')}
/>
<MainTitle/>
</View>
),
};
} }
@ -477,7 +381,7 @@ const AppStack = createStackNavigator({
RoomHeaderReservation: screenConfig(RoomHeaderReservationScreen, 'book_room'), RoomHeaderReservation: screenConfig(RoomHeaderReservationScreen, 'book_room'),
News: { News: {
screen: NewsScreen, screen: NewsScreen,
navigationOptions: ({navigation}) => ({ navigationOptions: ({ navigation }) => ({
title: t('charoensin_asset'), title: t('charoensin_asset'),
headerLeft: ( headerLeft: (
<TouchableOpacity onPress={() => navigation.goBack()}> <TouchableOpacity onPress={() => navigation.goBack()}>
@ -488,12 +392,11 @@ const AppStack = createStackNavigator({
}, },
NewsDetail: { NewsDetail: {
screen: NewsDetailScreen, screen: NewsDetailScreen,
navigationOptions: ({navigation}) => ({ navigationOptions: ({ navigation }) => ({
title: '', title: '',
headerStyle: { headerStyle: {
backgroundColor: '#00420A', backgroundColor: '#00420A',
height: 50, height: 50,
marginTop: 25,
elevation: 0, elevation: 0,
shadowOpacity: 0, shadowOpacity: 0,
}, },
@ -507,14 +410,14 @@ const AppStack = createStackNavigator({
headerLeft: null, headerLeft: null,
headerRight: ( headerRight: (
<TouchableOpacity onPress={() => navigation.goBack()}> <TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={{color: '#fff', fontSize: 16}}> {t('close')} </Text> <Text style={{ color: '#fff', fontSize: 16 }}> {t('close')} </Text>
</TouchableOpacity> </TouchableOpacity>
) )
}) })
}, },
Product: { Product: {
screen: ProductScreen, screen: ProductScreen,
navigationOptions: ({navigation}) => ({ navigationOptions: ({ navigation }) => ({
title: t('products'), title: t('products'),
headerLeft: ( headerLeft: (
<TouchableOpacity onPress={() => navigation.goBack()}> <TouchableOpacity onPress={() => navigation.goBack()}>
@ -537,46 +440,39 @@ const AppStack = createStackNavigator({
// } // }
, ,
Meter: screenConfig(MeterScreen, 'smart_meter'), Meter: screenConfig(MeterScreen, 'smart_meter'),
WaterMeter: screenConfig(WaterMeter, 'save_water_meter'), WaterMeter: screenConfig(WaterMeter,'save_water_meter'),
PEAMeter: screenConfig(PEAMeter, 'save_electric_meter'), PEAMeter: screenConfig(PEAMeter,'save_electric_meter'),
// Bill: screenConfig(BillScreen, 'รายละเอียดยอดค้างชำระ'), // Bill: screenConfig(BillScreen, 'รายละเอียดยอดค้างชำระ'),
Bill: screenConfig(BillScreen, 'outstanding_balance_detail'), Bill: screenConfig(BillScreen,'outstanding_balance_detail'),
Payment: screenConfig(PaymentScreen, 'pay'), Payment: screenConfig(PaymentScreen, 'pay'),
PaymentDetail: screenConfig(PaymentDetail, 'payment_detail'),
PaymentConfirm: screenConfig(PaymentConfirm, 'payment_detail'),
SettingsNotification: screenConfig(SettingsNotificationScreen, 'noti_setting'), SettingsNotification: screenConfig(SettingsNotificationScreen, 'noti_setting'),
MoveOut: screenConfig(MoveOutScreen, 'move_out'),
Suggestion: screenConfig(SuggestionScreen, 'suggestion'), Suggestion: screenConfig(SuggestionScreen, 'suggestion'),
Question: { Question: {
screen: QuestionScreen, screen: QuestionScreen,
navigationOptions: ({navigation}) => ({ navigationOptions: ({ navigation }) => ({
title: t('faqs'), title: t('faqs'),
headerStyle: { headerStyle:{
backgroundColor: '#00420A', backgroundColor: '#00420A',
marginTop: 25,
height: 50
}, },
headerTitleStyle: { headerTitleStyle: {
fontSize: 18, fontSize: 18,
color: '#fff', color: '#fff',
fontFamily: 'Prompt-Regular', fontFamily: 'Prompt-Regular',
fontWeight: undefined, fontWeight: undefined,
textAlign: 'left', }, headerLeftContainerStyle: {
flex: 1,
marginLeft: 0
}, headerLeftContainerStyle: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
width: '10%', width: '10%',
}, },
headerLeft: ( headerLeft: (
<TouchableOpacity onPress={() => navigation.goBack()} style={{flex: 1, alignItems: 'center'}}> <TouchableOpacity onPress={() => navigation.goBack()} style={{flex:1,alignItems:'center'}}>
<Icon name={'ic_back'} color={'white'} size={20}/> <Icon name={'ic_back'} color={'white'} size={20}/>
</TouchableOpacity> </TouchableOpacity>
), ),
headerRight: ( headerRight:(
<TouchableOpacity onPress={() => navigation.state.params.onRefreshMessage()} style={{paddingRight: 16}}> <TouchableOpacity onPress={() => navigation.state.params.onRefreshMessage()} style={{paddingRight:16}}>
<Icon name={'ic_refresh'} color={'white'} size={20}/> <Icon name={'ic_refresh'} color={'white'} size={20}/>
</TouchableOpacity> </TouchableOpacity>
) )
@ -584,58 +480,15 @@ const AppStack = createStackNavigator({
}, },
Profile: screenConfig(ProfileScreen, 'profile', '#3AA40C'), Profile: screenConfig(ProfileScreen, 'profile', '#3AA40C'),
EditProfile: screenConfig(EditProfileScreen, 'edit_profile', '#3AA40C'), EditProfile: screenConfig(EditProfileScreen, 'edit_profile', '#3AA40C'),
Object: { Object: screenConfig(MessageObject, 'mail_and_parcel'),
screen: MessageObject,
navigationOptions: ({navigation}) => ({
title: t('mail_and_parcel'),
headerStyle: {
backgroundColor: '#00420A',
height: 50,
marginTop: 25,
elevation: 0,
shadowOpacity: 0,
},
headerTintColor: '#000',
headerTitleStyle: {
fontWeight: '400',
fontSize: 18,
color: '#fff',
textAlign: 'left',
flex: 1,
fontFamily: 'Prompt-Regular',
marginLeft: 0,
},
headerTitleContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
},
headerLeftContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
width: '10%',
},
headerTitleAllowFontScaling: false,
headerLeft: (
<TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => navigation.navigate('HomeScreen')}>
<Icon name="ic_back" size={20} color="#fff"/>
</TouchableOpacity>
)
})
},
ObjectDetail: screenConfig(MessageObjectDetail, 'mail_and_parcel'), ObjectDetail: screenConfig(MessageObjectDetail, 'mail_and_parcel'),
Signature: screenConfig(SignaturePadScreen, 'please_sign'), Signature: screenConfig(SignaturePadScreen, 'please_sign'),
Login: { Login: {
screen: LoginScreen, screen: LoginScreen,
navigationOptions: ({navigation}) => ({ navigationOptions: ({ navigation }) => ({
title: t('login'), title: t('login'),
headerStyle: { headerStyle:{
backgroundColor: '#00420A', backgroundColor: '#00420A',
marginTop: 25,
height: 50
}, },
headerTitleStyle: { headerTitleStyle: {
@ -643,7 +496,7 @@ const AppStack = createStackNavigator({
color: '#fff', color: '#fff',
fontFamily: 'Prompt-Regular', fontFamily: 'Prompt-Regular',
fontWeight: undefined, fontWeight: undefined,
}, headerLeftContainerStyle: { }, headerLeftContainerStyle: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
width: '10%', width: '10%',
@ -656,200 +509,32 @@ const AppStack = createStackNavigator({
) )
}) })
}, },
//Forget Password Screen
ForgetPassword: {
screen: ForgetPasswordScreen,
navigationOptions: ({navigation}) => ({
title: t('forget_password'),
headerStyle: styles.defaultHeaderStyle,
headerTitleStyle: {
...styles.defaultHeaderTitleStyle,
fontWeight: undefined,
},
headerLeftContainerStyle: styles.defaultHeaderLeftContainerStyle,
headerLeft: (
<TouchableOpacity onPress={() => navigation.navigate('HomeScreen')}>
<Icon name={'ic_back'} color={'white'} size={20}/>
</TouchableOpacity>
)
})
},
VerifyOTP: {
screen: VerifyOTP,
navigationOptions: ({navigation}) => ({
title: t('verify_otp'),
headerStyle: styles.defaultHeaderStyle,
headerTitleStyle: {
...styles.defaultHeaderTitleStyle,
fontWeight: undefined,
},
headerLeftContainerStyle: styles.defaultHeaderLeftContainerStyle,
headerLeft: (
<TouchableOpacity onPress={() => navigation.navigate('ForgetPassword')}>
<Icon name={'ic_back'} color={'white'} size={20}/>
</TouchableOpacity>
)
})
},
PasswordCode: {
screen: PasswordCode,
navigationOptions: ({navigation}) => ({
title: t('new_password'),
headerStyle: styles.defaultHeaderStyle,
headerTitleStyle: {
...styles.defaultHeaderTitleStyle,
fontWeight: undefined,
},
headerLeftContainerStyle: styles.defaultHeaderLeftContainerStyle,
headerLeft: (
<TouchableOpacity onPress={() => navigation.navigate('VerifyOTP')}>
<Icon name={'ic_back'} color={'white'} size={20}/>
</TouchableOpacity>
)
})
},
//Register Screen //Register Screen
Register: screenConfig(RegisterScreen, 'register'), Register: screenConfig(RegisterScreen,'register'),
RegisterFormLogin: screenConfig(RegisterFormLoginScreen, 'register'), RegisterFormLogin: screenConfig(RegisterFormLoginScreen, 'register'),
RegisterProfile: screenConfig(RegisterProfileScreen, 'register'), RegisterProfile: screenConfig(RegisterProfileScreen, 'register'),
//Repair Service //Repair Service
/*RepairService: { RepairService: {
screen: RepairService, screen: RepairService,
navigationOptions: NavWithRightIcon('request_repair_and_Other', 'ic_clock_history', 'RepairHistory') navigationOptions: NavWithRightIcon('request_repair_and_Other','ic_clock_history','RepairHistory')
},*/ },
Repair: screenConfig(RepairIndex, 'request_repair'), RepairDetail: screenConfig(RepairServiceDetail,'service_detail'),
RepairDetail: screenConfig(RepairServiceDetail, 'service_detail'),
RepairConfirm: screenConfig(RepairConfirm, 'confirm_info'), RepairConfirm: screenConfig(RepairConfirm, 'confirm_info'),
RepairHistory: screenConfig(RepairHistory, 'repair_history'), RepairHistory: screenConfig(RepairHistory, 'repair_history'),
RepairSuccess: screenConfig(RepairSuccess, 'request_sent'), RepairSuccess: screenConfig(RepairSuccess, 'request_sent'),
// RepairHistoryDetail: screenConfig(RepairHistoryDetail, 'repair_history_detail'), RepairHistoryDetail: screenConfig(RepairHistoryDetail, 'รายละเอียดประวัติ'),
RepairHistoryDetail: {
screen: RepairHistoryDetail,
navigationOptions: ({navigation}) => ({
title: t('repair_history_detail'),
headerStyle: {
backgroundColor: '#00420A',
height: 50,
elevation: 0,
shadowOpacity: 0,
},
headerTintColor: '#000',
headerTitleStyle: {
fontWeight: '400',
fontSize: 18,
color: '#fff',
textAlign: 'left',
flex: 1,
fontFamily: 'Prompt-Regular',
marginLeft: 0,
},
headerTitleContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
},
headerLeftContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
width: '10%',
},
headerTitleAllowFontScaling: false,
headerLeft: (
<TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => navigation.goBack()}>
<Icon name="ic_back" size={20} color="#fff"/>
</TouchableOpacity>
),
headerRight: (
navigation.state.params.statusRepair !== 'Success' && navigation.state.params.statusRepair !== 'Cancel' && navigation.state.params.type !== 'effect_repair' &&
<TouchableOpacity onPress={() => navigation.state.params.cancelRepair()} style={{marginRight: 15}}>
<Text style={{color: '#FF3B30', fontSize: 18}}>{t('cancel')}</Text>
</TouchableOpacity>
)
})
},
//Reward //Reward
Reward: screenConfig(RewardScreen, 'redeem_reward'), Reward: screenConfig(RewardScreen, 'redeem_reward'),
RewardDetailScreen: screenConfig(RewardDetailScreen, 'product_detail'), RewardDetail: screenConfig(RewardDetailScreen,'product_detail'),
//Redeem
Redeem: screenConfig(RedeemScreen, 'reward'),
HistoryRedeem: screenConfig(HistoryRedeem, 'history_point'),
AllRewards: screenConfig(AllRewards, 'all_reward'),
MyRewards: screenConfig(MyRewards, 'my_reward'),
RewardDetail: screenConfig(RewardDetail, 'all_reward'),
ScanCoupon: {
screen: ScanCoupon,
navigationOptions: ({navigation}) => ({
title: t('coupon'),
...defaultHeaderStyle(),
headerLeft: () => {
console.log('navigation state', navigation.state)
return HeaderLeftComponent(navigation, 'MyRewards', {index: navigation.state.params.index})
}
})
},
RewardTermCondition: screenConfig(RewardTermCondition, 'term_condition'),
MembershipLevelDetail: screenConfig(MembershipLevelDetail, 'membership_detail'),
MemberPoinExpire: screenConfig(MemberPoinExpire, 'membership_detail'),
//Terms and Condition //Terms and Condition
Terms: { Terms: screenConfig(TermsAndCondition, 'term_condition'),
screen: TermsAndCondition,
navigationOptions: ({navigation}) => ({
title: t('term_condition'),
...defaultHeaderStyle(),
headerLeft: (
<TouchableOpacity
style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', }}
onPress={() => {
store.dispatch(appCleanUser());
navigation.goBack()
}}>
<Icon name="ic_back" size={20} color="#fff"/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity>
{/*<Icon name="ic_back" size={20} color="#fff"/>*/}
</TouchableOpacity>
)
})
}
}) })
const styles = StyleSheet.create({ const styles = StyleSheet.create({
textBottomTab: { textBottomTab:{
fontSize: 12, fontSize:12,
textAlign: 'center', textAlign: 'center',
}, }
defaultHeaderStyle: {
backgroundColor: '#00420A',
height: 50,
marginTop: 25,
elevation: 0,
shadowOpacity: 0,
},
defaultHeaderTitleStyle: {
fontWeight: '400',
fontSize: 18,
color: '#fff',
textAlign: 'left',
flex: 1,
fontFamily: 'Prompt-Regular',
marginLeft: 0,
},
defaultHeaderTitleContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
},
defaultHeaderLeftContainerStyle: {
alignItems: 'center',
justifyContent: 'center',
width: '10%',
},
}) })
export default AppStack export default AppStack

View File

@ -1,5 +1,5 @@
import { switchLanguage } from 'src/utils/i18n' import { switchLanguage } from 'src/utils/i18n'
import { setBaseUrlByServerMode, setLanguage } from '../../api/api' import { setLanguage } from '../../api/api'
// action type // action type
export const ACTION_APP_SET_TOKEN = 'APP_SET_TOKEN' export const ACTION_APP_SET_TOKEN = 'APP_SET_TOKEN'
@ -14,12 +14,9 @@ export const ACTION_APP_CHANGE_NOTIFICATION = 'ACTION_APP_CHANGE_NOTIFICATION'
export const ACTION_APP_SET_PROJECT_ID = 'ACTION_APP_SET_PROJECT_ID' export const ACTION_APP_SET_PROJECT_ID = 'ACTION_APP_SET_PROJECT_ID'
export const ACTION_APP_CLEAN_PROJECT_ID = 'ACTION_APP_CLEAN_PROJECT_ID' export const ACTION_APP_CLEAN_PROJECT_ID = 'ACTION_APP_CLEAN_PROJECT_ID'
export const ACTION_APP_SET_LANGUAGE = 'ACTION_APP_SET_LANGUAGE' export const ACTION_APP_SET_LANGUAGE = 'ACTION_APP_SET_LANGUAGE'
export const ACTION_APP_SET_SERVER_MODE = 'ACTION_APP_SET_SERVER_MODE'
export const ACTION_SET_POPUP_NOTIFICATION = 'ACTION_SET_POPUP_NOTIFICATION'
// action creator // action creator
export function appSetToken (token) { export function appSetToken (token) {
console.log('token appSetToken >>>>>>>>>>>>>>> ', token)
return { return {
type: ACTION_APP_SET_TOKEN, type: ACTION_APP_SET_TOKEN,
token token
@ -100,18 +97,3 @@ export function appSetLanguage (langCode) {
lang: langCode lang: langCode
} }
} }
export function setServerMode (mode) {
setBaseUrlByServerMode(mode)
return {
type: ACTION_APP_SET_SERVER_MODE,
mode
}
}
export function setPopupNotification(data) {
return {
type: ACTION_SET_POPUP_NOTIFICATION,
popup_notification : data
}
}

View File

@ -11,8 +11,6 @@ import {
ACTION_APP_SET_PROJECT_ID, ACTION_APP_SET_PROJECT_ID,
ACTION_APP_CLEAN_PROJECT_ID, ACTION_APP_CLEAN_PROJECT_ID,
ACTION_APP_SET_LANGUAGE, ACTION_APP_SET_LANGUAGE,
ACTION_APP_SET_SERVER_MODE,
ACTION_SET_POPUP_NOTIFICATION
} from './action' } from './action'
const initialState = { const initialState = {
@ -23,39 +21,34 @@ const initialState = {
notification: null, notification: null,
project_id: null, project_id: null,
lang: null, lang: null,
server_mode: 'production', };
}
export default function (state = initialState, action) { export default function (state = initialState, action) {
switch (action.type) { switch (action.type) {
case ACTION_APP_SET_LANGUAGE: case ACTION_APP_SET_LANGUAGE:
return { ...state, lang: action.lang } return { ...state, lang: action.lang }
case ACTION_APP_SET_TOKEN: case ACTION_APP_SET_TOKEN:
return { ...state, token: action.token } return { ...state, token: action.token };
case ACTION_APP_CLEAN_TOKEN: case ACTION_APP_CLEAN_TOKEN:
return { ...state, token: null } return { ...state, token: null };
case ACTION_APP_SET_PUSH_TOKEN: case ACTION_APP_SET_PUSH_TOKEN:
return { ...state, push_token: action.pushToken } return { ...state, push_token: action.pushToken };
case ACTION_APP_SET_DEVICE: case ACTION_APP_SET_DEVICE:
return { ...state, device: action.device } return { ...state, device: action.device };
case ACTION_APP_CLEAN_DEVICE: case ACTION_APP_CLEAN_DEVICE:
return { ...state, device: null } return { ...state, device: null };
case ACTION_APP_SET_USER: case ACTION_APP_SET_USER:
return { ...state, user: action.user } return { ...state, user: action.user };
case ACTION_APP_CLEAN_USER: case ACTION_APP_CLEAN_USER:
return { ...state, user: null } return { ...state, user: null };
case ACTION_APP_SET_NOTIFICATION: case ACTION_APP_SET_NOTIFICATION:
return { ...state, count_noti: action.count_noti } return { ...state, count_noti: action.count_noti };
case ACTION_APP_CHANGE_NOTIFICATION: case ACTION_APP_CHANGE_NOTIFICATION:
return { ...state, notification: action.notification } return { ...state, notification: action.notification };
case ACTION_APP_SET_PROJECT_ID: case ACTION_APP_SET_PROJECT_ID:
return { ...state, project_id: action.project_id } return { ...state, project_id: action.project_id };
case ACTION_APP_CLEAN_PROJECT_ID: case ACTION_APP_CLEAN_PROJECT_ID:
return { ...state, project_id: null } return { ...state, project_id: null };
case ACTION_APP_SET_SERVER_MODE:
return { ...state, server_mode: action.mode }
case ACTION_SET_POPUP_NOTIFICATION:
return { ...state, popup_notification: action.popup_notification }
default: default:
return state return state
} }

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import {appSetDevice, appSetPushToken, appSetToken, appSetUser} from '../../redux/app/action' import { appSetDevice, appSetPushToken, appSetToken, appSetUser } from '../../redux/app/action'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { View } from 'react-native' import { View } from 'react-native'
import { switchLanguage } from '../../utils/i18n' import { switchLanguage } from '../../utils/i18n'
@ -24,8 +24,7 @@ class AppLoading extends Component {
const mapStateToProps = state => { const mapStateToProps = state => {
return { return {
lang: state.app.lang, lang: state.app.lang
user: state.app.user
} }
} }
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser }, dispatch) const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser }, dispatch)

View File

@ -5,7 +5,6 @@ import { useDispatch } from 'react-redux'
import { appSetLanguage } from '../../redux/app/action' import { appSetLanguage } from '../../redux/app/action'
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm' import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
import LinearGradient from 'react-native-linear-gradient' import LinearGradient from 'react-native-linear-gradient'
import {setLanguage} from "../../api/UserApi";
const languages = [ const languages = [
{ code: 'th', name: 'ภาษาไทย' }, { code: 'th', name: 'ภาษาไทย' },
@ -19,18 +18,7 @@ export default function ({ navigation }) {
function selectLanguage (code) { function selectLanguage (code) {
dispatch(appSetLanguage(code)) dispatch(appSetLanguage(code))
if(code === 'th'){ navigation.navigate('HomeScreen')
code = 'th_TH';
}
setLanguage(code)
.then(res => {
if(res.success){
navigation.navigate('HomeScreen')
}else{
navigation.navigate('HomeScreen')
}
})
} }
return <LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{ return <LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{

View File

@ -24,8 +24,7 @@ import {appSetDevice, appSetPushToken, appSetToken, appSetUser} from "../../redu
import moment from "moment"; import moment from "moment";
import IndicatorLoading from '../../components/IndicatorLoading'; import IndicatorLoading from '../../components/IndicatorLoading';
import { t } from 'src/utils/i18n' import { t } from 'src/utils/i18n'
import parseDateLocale from 'src/utils/parseDateLocale';
import { NavigationEvents } from 'react-navigation'
const { height, width } = Dimensions.get('window') const { height, width } = Dimensions.get('window')
function ItemOrder({title,cost,description,type}){ function ItemOrder({title,cost,description,type}){
@ -99,8 +98,10 @@ class BillScreen extends Component {
this.checkstatusBill = this.checkstatusBill.bind(this) this.checkstatusBill = this.checkstatusBill.bind(this)
} }
getData = () => { componentDidMount() {
payment(this.props.user.id) this.setState({isLoading: true})
if(this.props.user){
payment(this.props.user.id)
.then(res => { .then(res => {
if(res.ok){ if(res.ok){
let sum_payment = []; let sum_payment = [];
@ -155,10 +156,7 @@ class BillScreen extends Component {
let date_now = moment() let date_now = moment()
let findTimeout = array_payment.find((item) => { let findTimeout = array_payment.find((item) => {return moment(item.due_at) == date_now})
console.log('item >>> ',item)
return moment(item.due_at) == date_now
})
//check bill timeout //check bill timeout
if(findTimeout !== undefined){ if(findTimeout !== undefined){
this.setState({ this.setState({
@ -183,61 +181,65 @@ class BillScreen extends Component {
}) })
} }
}) })
// if(res.ok){ }
// let sum_payment = []; }
// let array_payment = [];
// let sum_cost_room = res.data.sum_cost_room;
// let all_payment = res.data.payment_room_period;
// let room_number_array = [];
// if(Object.keys(sum_cost_room).length > 0) { getMonth(period_month){
// Object.keys(sum_cost_room).map((sum_cost) => { let new_month = 'มกราคม'
// sum_payment.push({ switch (period_month) {
// total_cost : sum_cost_room[sum_cost].total_cost, case '01':
// room: sum_cost_room[sum_cost].room, new_month = 'มกราคม';
// room_id: sum_cost_room[sum_cost].room_id, break;
// project: sum_cost_room[sum_cost].project, case '02':
// due_at: sum_cost_room[sum_cost].due_at, new_month = 'กุมภาพันธ์';
// } break;
// ) case '03':
// room_number_array.push(sum_cost_room[sum_cost].room_id) new_month = 'มีนาคม';
// }) break;
case '04':
new_month = 'เมษายน';
break;
case '05':
new_month = 'พฤษภาคม';
break;
case '06':
new_month = 'มิถุนายน';
break;
case '07':
new_month = 'กรกฎาคม';
break;
case '08':
new_month = 'สิงหาคม';
break;
case '09':
new_month = 'กันยายน';
break;
case '10':
new_month = 'ตุลาคม';
break;
case '11':
new_month = 'พฤศจิกายน';
break;
case '12':
new_month = 'ธันวาคม';
break;
default:
new_month = 'มกราคม';
break;
}
// let first_room = room_number_array && room_number_array.length > 0 && room_number_array[0]; return new_month;
// array_payment = all_payment && all_payment.length > 0 && all_payment.filter((payment)=>{
// return payment.room_id === first_room
// });
// let date_now = moment()
// let findTimeout = array_payment && array_payment.length > 0 && array_payment.find((item) => {return moment(item.due_date) == date_now})
// //check bill timeout
// if(findTimeout !== undefined){
// this.setState({
// isCanPay: false
// })
// }
// }
// this.setState({
// isLoading: false,
// payment: array_payment,
// sum_payment: sum_payment,
// all_payment,
// room_number_array
// })
// }else {
// this.setState({
// isLoading: false
// })
// }
// })
} }
getTitle (period) { getTitle (period) {
let period_month = moment(period, "MM/Y").format('MMMM'); let period_month = moment(period, "MM/Y").format('MM');
let period_year = parseInt(moment(period, "MM/Y").locale('en').format('Y')); let period_year = parseInt(moment(period, "MM/Y").format('Y')) + 543;
let new_month = ''; let new_month = 'มกราคม';
let new_period = period_month + ' ' + period_year; let new_period = new_month + ' ' + period_year;
new_month = this.getMonth(period_month)
new_period = new_month + ' ' + period_year;
return new_period; return new_period;
} }
@ -252,7 +254,7 @@ class BillScreen extends Component {
return true return true
} }
checkstatusBill(data, isOverdue){ checkstatusBill(data,boolDate){
if(data.status == 'paid'){ if(data.status == 'paid'){
return <TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white', return <TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white',
height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5, height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5,
@ -261,13 +263,13 @@ class BillScreen extends Component {
disabled={data.status === 'pending' ? false : true} disabled={data.status === 'pending' ? false : true}
onPress={() => { onPress={() => {
this.state.isCanPay ? this.state.isCanPay ?
data.status === 'pending' && this.props.navigation.navigate('PaymentDetail',{payment_id:data.payment_id}) data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
: Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}]) : Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}])
}}> }}>
<Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'ดูเพิ่มเติม' : 'จ่ายแล้ว'}</Text> <Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'จ่ายเงิน' : 'จ่ายแล้ว'}</Text>
</TouchableOpacity> </TouchableOpacity>
}else{ }else{
if(isOverdue){ if(!boolDate){
return <View> return <View>
<Text style={{ color: 'red',borderWidth:1,borderColor:'#00000040',borderRadius:5,paddingHorizontal:6}}>{'เกินกำหนดชำระ'}</Text> <Text style={{ color: 'red',borderWidth:1,borderColor:'#00000040',borderRadius:5,paddingHorizontal:6}}>{'เกินกำหนดชำระ'}</Text>
</View> </View>
@ -279,10 +281,10 @@ class BillScreen extends Component {
disabled={data.status === 'pending' ? false : true} disabled={data.status === 'pending' ? false : true}
onPress={() => { onPress={() => {
this.state.isCanPay ? this.state.isCanPay ?
data.status === 'pending' && this.props.navigation.navigate('PaymentDetail',{payment_id:data.payment_id}) data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
: Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}]) : Alert.alert(null, 'รายการค้างชำระของคุณ เกินกำหนดชำระ กรุณาติดต่อสำนักงานบริการลูกค้า',[{text: t('ok')}])
}}> }}>
<Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'ดูเพิ่มเติม' : 'จ่ายแล้ว'}</Text> <Text style={{ color: data.status === 'pending' ? 'white' : 'rgba(0, 0, 0, 0.25)'}}>{data.status === 'pending' ? 'จ่ายเงิน' : 'จ่ายแล้ว'}</Text>
</TouchableOpacity> </TouchableOpacity>
} }
} }
@ -290,39 +292,19 @@ class BillScreen extends Component {
_renderHeader(data, expanded) { _renderHeader(data, expanded) {
// if(data.room_id == this.state.sum_payment[this.state.activePage].room.id){ // if(data.room_id == this.state.sum_payment[this.state.activePage].room.id){
let checkBool = this.checkDueDate(data.due_date == null || data.due_date == undefined ? moment() : data.due_date) let checkBool = this.checkDueDate(data.due_at == null || data.due_at == undefined ? moment() : data.due_at)
return ( return (
<View style={{flex:1,flexDirection:'row',backgroundColor:'#B8DAAA',height: 64,borderBottomWidth:1,borderBottomColor:'white',alignItems:'center',justifyContent:'space-between',paddingHorizontal:16}}> <View style={{flex:1,flexDirection:'row',backgroundColor:'#B8DAAA',height: 64,borderBottomWidth:1,borderBottomColor:'white',alignItems:'center',justifyContent:'space-between',paddingHorizontal:16}}>
<View style={{justifyContent:'center',flex:1}}> <View style={{justifyContent:'center',flex:1}}>
{/*<Text>{t('month')} {parseDateLocale(moment(data.period, 'MM/Y'), 'MMMM Y')}</Text>*/} <Text>{t('month')} {this.getTitle(data.period)}</Text>
<Text>{t('payment_no')} : {data.invoice_code}</Text>
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between'}}> <View style={{flexDirection:'row',alignItems:'center',justifyContent:'space-between'}}>
{ {expanded || data.status != 'pending' ? <Text /> : <Text note style={styles.colorTextPayment}>{t('outstanding_balance')} {data.total_cost}</Text>}
data.status !== 'complete' && <Text note style={styles.colorTextPayment}>{t('outstanding_balance')} {data.total_cost}</Text>
}
{expanded || <Text style={{fontSize:10,marginRight:16}}>{t('view_more')}</Text>} {expanded || <Text style={{fontSize:10,marginRight:16}}>{t('view_more')}</Text>}
</View> </View>
</View> </View>
{/*{ {
this.checkstatusBill(data, data.is_overdue) this.checkstatusBill(data,checkBool)
}*/} }
<TouchableOpacity style={{
backgroundColor: data.status === 'complete' ? 'lightgrey' : '#145EB3',
height: 32,width: 103,
justifyContent:'center',
alignItems:'center',
borderRadius:5,
borderColor: data.status === 'complete' ? 'grey' : '',
borderWidth: data.status === 'complete' ? 1 : 0
}}
onPress={ data.status === 'complete' ? () => {} : () => { this.props.navigation.navigate('PaymentDetail',{payment_id: data.id, room: data.room_id})}}
disabled={ data.status === 'complete'}
>
<Text style={{ color: 'white' }}>{data.status === 'complete' ? 'จ่ายแล้ว' : 'ดูเพิ่มเติม'}</Text>
</TouchableOpacity>
{/* { {/* {
checkBool ? checkBool ?
data.enable_qr && data.enable_qr &&
@ -349,51 +331,51 @@ class BillScreen extends Component {
} }
_renderContent(data) { _renderContent(data) {
// let water_cost = 0; let water_cost = 0;
// let electrict_cost = 0; let electrict_cost = 0;
// let room_cost = 0; let room_cost = 0;
// let service_cost = 0; let service_cost = 0;
// let date_payment = ''; let date_payment = '';
// let extra_info = ''; let extra_info = '';
// let d = moment(data.created_at).format('D') let d = moment(data.created_at).format('D')
// let m = moment(data.created_at).format('MM') let m = moment(data.created_at).format('MM')
// let y = parseInt(moment(data.created_at).format('Y')) + 543 let y = parseInt(moment(data.created_at).format('Y')) + 543
//date_payment = d + ' ' + this.getMonth(m) + ' ' + y date_payment = d + ' ' + this.getMonth(m) + ' ' + y
// let descriptionRoom = '-' let descriptionRoom = '-'
// let descriptionWater = '-' let descriptionWater = '-'
// let descriptionElec = '-' let descriptionElec = '-'
// let descriptionService = '-' let descriptionService = '-'
// console.log('check data ----------> ',data) // console.log('check data ----------> ',data)
// if(data.details){ if(data.details){
// data.details.map((det) => { data.details.map((det) => {
// if(det.sequence === 1){ if(det.sequence === 1){
// room_cost = det.cost room_cost = det.cost
// room_extra_info = det.extra_info != null ? det.extra_info : '' room_extra_info = det.extra_info != null ? det.extra_info : ''
// descriptionRoom = det.descript == '' ? '-' : det.descript descriptionRoom = det.descript == '' ? '-' : det.descript
// } }
// if(det.sequence === 2){ if(det.sequence === 2){
// water_cost = det.cost water_cost = det.cost
// water_extra_info = det.extra_info != null ? det.extra_info : '' water_extra_info = det.extra_info != null ? det.extra_info : ''
// descriptionWater = det.descript == '' ? '-' : det.descript descriptionWater = det.descript == '' ? '-' : det.descript
// } }
// if(det.sequence === 3){ if(det.sequence === 3){
// electrict_cost = det.cost electrict_cost = det.cost
// electrict_extra_info = det.extra_info != null ? det.extra_info : '' electrict_extra_info = det.extra_info != null ? det.extra_info : ''
// descriptionElec = det.descript == '' ? '-' : det.descript descriptionElec = det.descript == '' ? '-' : det.descript
// } }
// if(det.sequence === 4){ if(det.sequence === 4){
// service_cost = det.cost service_cost = det.cost
// service_extra_info = det.extra_info != null ? det.extra_info : '' service_extra_info = det.extra_info != null ? det.extra_info : ''
// descriptionService = det.descript == '' ? '-' : det.descript descriptionService = det.descript == '' ? '-' : det.descript
// } }
// }) })
// } }
return ( return (
<View> <View>
@ -480,7 +462,7 @@ class BillScreen extends Component {
item.due_at !== null item.due_at !== null
? ( ? (
<View style={{height:24,backgroundColor: '#FF2D55',justifyContent:'center',alignItems:'center'}}> <View style={{height:24,backgroundColor: '#FF2D55',justifyContent:'center',alignItems:'center'}}>
<Text style={{ fontSize: 12, color: 'white'}}>{t('please_pay_within')} {this.getDueDate(item.due_at)}</Text> <Text style={{ fontSize: 12, color: 'white'}}>{t('please_pay_before')} {this.getDueDate(item.due_at)}</Text>
</View> </View>
) )
: null : null
@ -508,12 +490,11 @@ class BillScreen extends Component {
roomFilter(index){ roomFilter(index){
let payment_exits = this.state.all_payment; let payment_exits = this.state.all_payment;
let another_room = this.state.room_number_array[index]; let another_room = this.state.room_number_array[index];
let payment_array = []; let payment_array = payment_exits.filter((obj)=>{
if(payment_exits && payment_exits.length > 0){ return Object.keys(obj).reduce((acc, curr)=>{
payment_array = payment_exits.filter((payment) => { return obj.room_id === another_room
return payment.room_id === another_room; }, false);
}) });
}
this.state.payment = payment_array; this.state.payment = payment_array;
} }
@ -523,15 +504,6 @@ class BillScreen extends Component {
return ( return (
<SafeAreaView style={{flex: 1}}> <SafeAreaView style={{flex: 1}}>
<ScrollView contentContainerStyle={styles.contentContainer}> <ScrollView contentContainerStyle={styles.contentContainer}>
<NavigationEvents
onDidFocus={() => {
this.setState({
isLoading: true
}, () => {
this.getData()
})
}}
/>
<View style={{ alignItems: 'center'}}> <View style={{ alignItems: 'center'}}>
{ {
this.state.sum_payment.length == 0 && this.state.sum_payment.length == 0 &&
@ -556,7 +528,7 @@ class BillScreen extends Component {
<View style={{flex:1}}> <View style={{flex:1}}>
<Accordion <Accordion
dataArray={ this.state.payment } dataArray={ this.state.payment }
expanded={this.state.payment && this.state.payment.length > 0 ? this.state.payment.length - 1 : []} expanded={this.state.payment.length - 1}
renderHeader={(data, expanded) => { return this._renderHeader(data, expanded) }} renderHeader={(data, expanded) => { return this._renderHeader(data, expanded) }}
renderContent={(data) => { return this._renderContent(data) }} /> renderContent={(data) => { return this._renderContent(data) }} />
</View> </View>

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import {ScrollView, StyleSheet, TouchableOpacity, Alert, PermissionsAndroid, ImageBackground, Platform} from "react-native"; import {ScrollView, StyleSheet, Image, TouchableOpacity, Alert, PermissionsAndroid, ImageBackground, Platform} from "react-native";
import CameraRoll from "@react-native-community/cameraroll"; import CameraRoll from "@react-native-community/cameraroll";
import {View} from "native-base"; import {View} from "native-base";
import Text from '../../components/Text'; import Text from '../../components/Text';
@ -8,7 +8,6 @@ import ViewShot, { captureRef } from "react-native-view-shot";
import IndicatorLoading from '../../components/IndicatorLoading'; import IndicatorLoading from '../../components/IndicatorLoading';
import QRCode from 'react-native-qrcode-svg'; import QRCode from 'react-native-qrcode-svg';
import { t } from '../../utils/i18n'; import { t } from '../../utils/i18n';
import Image from 'react-native-fast-image'
class PaymentScreen extends Component { class PaymentScreen extends Component {
constructor(props) { constructor(props) {
@ -27,24 +26,11 @@ class PaymentScreen extends Component {
this.setState({isLoading:true}) this.setState({isLoading:true})
payment_detail(this.state.payment_id) payment_detail(this.state.payment_id)
.then( res => { .then( res => {
if(res.data && res.data.success){ this.setState({
this.setState({ payment_data: res.data
payment_data: res.data },() => {
},() => { this.setState({isLoading: false})
this.setState({isLoading: false}) })
})
}else {
Alert.alert(res.data.message, '', [{
text: 'ok',
onPress: () => {
this.setState({
isLoading: false
}, () => {
this.props.navigation.goBack()
})
}
}])
}
}) })
}; };
@ -95,24 +81,23 @@ class PaymentScreen extends Component {
render(){ render(){
return( return(
<ImageBackground source={require('../../../assets/images/tree2.png')} style={{width: '100%', height: '100%', backgroundColor:'#EEFFD7'}}> <ImageBackground source={require('../../../assets/images/tree2.png')} style={{width: '100%', height: '100%', backgroundColor:'#EEFFD7'}}>
<ViewShot style={{flex: 1}} options={{format: "jpg", quality: 1}} ref={ref => this.viewshot = ref}> <ScrollView contentContainerStyle={styles.contentContainer}>
<ScrollView contentContainerStyle={styles.contentContainer}> <View style={{flex: 1}}>
<View style={styles.QrContainer}> <View style={{ alignItems: 'center', padding:20}}>
<View style={styles.headerQr}> <ViewShot style={{width: '100%',alignItems:'center'}} options={{format: "jpg", quality: 1}} ref={ref => this.viewshot = ref}>
<Image source={require('../../../assets/images/icon_payment.png')} style={{height: 40}} resizeMode={'contain'}/> <View style={{backgroundColor:'white', borderRadius:10,width: '90%',alignItems:'center'}}>
</View> <View style={{width: '100%',backgroundColor:'#29558D',height: 55,borderTopLeftRadius:10,borderTopEndRadius:10,alignItems:'center',justifyContent:'center'}}>
<Image source={require('../../../assets/images/icon_promptpay.png')} style={{height: 35, marginVertical: 18}} resizeMode={'contain'}/> <Image source={require('../../../assets/images/icon_payment.png')} style={{height: 40}} resizeMode={'contain'}/>
<Text style={{fontSize: 18,color:'#00420A', textAlign: 'center'}}>{t('scan_to_pay')}</Text> </View>
<View style={{flex: 0.9, alignItems: 'center'}}> <Image source={require('../../../assets/images/icon_promptpay.png')} style={{height: 24,marginVertical: 18}} resizeMode={'contain'}/>
{/* <Image source={{uri: this.state.payment_data.qr}} style={{flex: 1}} resizeMode="contain"/> */} <Text style={{fontSize: 18,color:'#00420A'}}>{t('scan_to_pay')}</Text>
<View style={{paddingVertical:10}}> <View style={{paddingVertical:10}}>
<QRCode <QRCode
value={this.state.payment_data.qr} value={this.state.payment_data.qr}
size={140} size={140}
color='black' color='black'
backgroundColor='white'/> backgroundColor='white'/>
</View> </View>
<View style={{alignItems: 'center'}}>
<Text style={{fontSize: 12,color:'#000000'}}>อบญช : {this.state.payment_data.receiver_name}</Text> <Text style={{fontSize: 12,color:'#000000'}}>อบญช : {this.state.payment_data.receiver_name}</Text>
<Text style={{fontSize: 12,color:'#000000'}}>{t('account')} : {this.state.payment_data.receiver_account}</Text> <Text style={{fontSize: 12,color:'#000000'}}>{t('account')} : {this.state.payment_data.receiver_account}</Text>
<Text style={{fontSize: 10,color:'#00000080'}}>{t('ref_no')}: { this.state.payment_data.payment != null && this.state.payment_data.payment.reference}</Text> <Text style={{fontSize: 10,color:'#00000080'}}>{t('ref_no')}: { this.state.payment_data.payment != null && this.state.payment_data.payment.reference}</Text>
@ -123,17 +108,15 @@ class PaymentScreen extends Component {
<View style={{margin: 10,height:1,width: '100%',backgroundColor:'#D7D7D7'}}/> <View style={{margin: 10,height:1,width: '100%',backgroundColor:'#D7D7D7'}}/>
<Text style={{fontSize: 10,color:'#00000080',marginBottom: 10}}>Accepts all banks | {t('support_all_bank')}</Text> <Text style={{fontSize: 10,color:'#00000080',marginBottom: 10}}>Accepts all banks | {t('support_all_bank')}</Text>
</View> </View>
</View> </ViewShot>
</View> </View>
</ScrollView> <View style={{alignItems: 'center', paddingHorizontal:20}}>
</ViewShot> <TouchableOpacity style={{backgroundColor:'#269A21',width: '90%',height: 40,justifyContent:'center',alignItems:'center',borderRadius:5}} onPress={this.snapScreen}>
<Text style={{color:'white',fontSize:14}}>{t('save')}</Text>
<View style={{flex: 0.1, justifyContent: 'center'}}> </TouchableOpacity>
<TouchableOpacity style={{backgroundColor:'#269A21',height: 40,justifyContent:'center',alignItems:'center',borderRadius:5, marginHorizontal: 20}} </View>
onPress={this.snapScreen}> </View>
<Text style={{color:'white',fontSize:14}}>{t('save')}</Text> </ScrollView>
</TouchableOpacity>
</View>
<IndicatorLoading loadingVisible={this.state.isLoading}/> <IndicatorLoading loadingVisible={this.state.isLoading}/>
</ImageBackground> </ImageBackground>
) )
@ -150,24 +133,11 @@ const styles = StyleSheet.create({
alignItems: 'center' alignItems: 'center'
}, },
contentContainer: { contentContainer: {
flex:1, paddingVertical: 0,
padding: 20 flex:1
}, },
colorTextPayment: { colorTextPayment: {
color: '#7CBB33' color: '#7CBB33'
},
QrContainer: {
flex: 1,
backgroundColor:'white',
borderRadius:10
},
headerQr: {
width: '100%',
backgroundColor:'#29558D',
height: 55,
borderTopLeftRadius:10,
borderTopEndRadius:10,
justifyContent:'center'
} }
}) })

View File

@ -1,197 +0,0 @@
import React, {Component} from "react";
import { ImageBackground, View, StyleSheet, Text, TouchableOpacity } from "react-native";
import { payment_detail, removeRentalDiscount } from "../../api/UserApi";
import IndicatorLoading from "../../components/IndicatorLoading";
import IconMaterial from 'react-native-vector-icons/MaterialCommunityIcons'
import { FlatList, NavigationEvents } from "react-navigation";
class PaymentConfirm extends Component {
constructor(props){
super(props);
this.state = {
payment_id: null,
payment: null,
isLoading: false
}
}
componentDidMount(){
const payment_id = this.props.navigation.getParam('payment_id');
const room = this.props.navigation.getParam('room');
this.setState({
room
})
if(payment_id){
this.setState({
payment_id
}, () => {
this.getPayment()
})
}
}
getPayment = () => {
this.setState({
isLoading: true
}, () => {
payment_detail(this.state.payment_id)
.then(res => {
if(res.data && res.data.success){
this.setState({
payment: res.data,
isLoading: false
})
}else {
this.setState({
isLoading: false
})
}
})
})
}
renderItem = (item) => {
return (
<View style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', marginBottom: 8}}>
<Text style={[styles.mainText, {color: 'black'}]}>{item.cost_name}</Text>
<Text style={[styles.mainText, {color: '#7CBB33', fontWeight: '500'}]}>{parseFloat(item.total).toLocaleString()} บาท</Text>
</View>
)
}
removeCoupon = () => {
this.setState({
isLoading: true
}, () => {
removeRentalDiscount(this.state.payment.coupon.id, this.state.payment_id)
.then(res => {
if(res.data && res.data.success){
this.setState({
payment_id: res.data.payment_id
}, () => {
this.getPayment()
this.setState({
isLoading: false
})
})
}else {
this.setState({
isLoading: false
})
}
})
})
}
render(){
return (
<ImageBackground source={require('../../../assets/images/tree2.png')} style={styles.ImageBackground}>
<IndicatorLoading loadingVisible={this.state.isLoading}/>
<NavigationEvents
onDidFocus={() => {
this.setState({
isLoading: true
}, () => {
this.getPayment()
})
}}
/>
<View style={{padding: 16, flex: 0.9}}>
<View style={styles.detialContainer}>
<View style={styles.borderBottom}>
<Text style={[styles.mainText, {fontSize: 18, textAlign: 'center'}]}>ใบตงหน</Text>
{
this.state.payment && this.state.payment.detail.length > 0 &&
<Text style={[styles.mainText, {fontSize: 14, textAlign: 'center'}]}>
อง {this.state.room ? this.state.room : ''}
</Text>
}
</View>
<View style={styles.borderBottom}>
<View style={{flexDirection: 'row', display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8}}>
<Text style={[styles.mainText, {color: '#269A21'}]}>รายการ</Text>
<Text style={[styles.mainText, {color: '#269A21'}]}>จำนวนเง</Text>
</View>
{
this.state.payment && this.state.payment.detail && this.state.payment.detail.length > 0 &&
<FlatList
data={this.state.payment.detail}
renderItem={({ item }) => this.renderItem(item)}
pagingEnabled={true}
extraData={this.state}
keyExtractor={this._keyExtractor}
/>
}
</View>
<View style={{flexDirection: 'row', justifyContent: 'flex-end', marginTop: 10, paddingHorizontal: 10}}>
<Text style={[styles.mainText, {textAlign: 'right',}]}>รวม</Text>
<Text style={[styles.mainText, {fontWeight: '500', paddingLeft: 10}]}>
{this.state.payment && this.state.payment.total_cost ? parseFloat(this.state.payment.total_cost).toLocaleString() : 0} บาท
</Text>
</View>
<View style={[styles.useCoupon]}>
<Text style={[styles.mainText, {fontSize: 16}]}>ใชปองสวนลด </Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text style={[styles.mainText, {fontSize: 16, marginRight: 5}]}>
{
this.state.payment && this.state.payment.coupon && this.state.payment.coupon.value ? this.state.payment.coupon.value : 0
} บาท
</Text>
<TouchableOpacity onPress={() => this.removeCoupon()}>
<IconMaterial name="close-circle-outline" size={18} color="#FF2D55"/>
</TouchableOpacity>
</View>
</View>
</View>
</View>
<View style={{padding: 16, flex: 0.1}}>
<TouchableOpacity style={{backgroundColor: '#145EB3', paddingVertical: 12, borderRadius: 5}}
onPress={() => this.props.navigation.navigate('Payment', {payment_id: this.state.payment_id })}
>
<Text style={{color: 'white', textAlign: 'center', fontFamily: 'Prompt-Regular'}}>นยนรายการและชำระเง</Text>
</TouchableOpacity>
</View>
</ImageBackground>
)
}
}
const styles = StyleSheet.create({
ImageBackground: {
backgroundColor:'#EEFFD7',
flex: 1
},
detialContainer: {
backgroundColor: 'white',
borderRadius: 5,
padding: 15
},
borderBottom: {
borderBottomWidth: 1,
borderColor: '#EAEAF4',
padding: 10
},
mainText: {
color: '#00420A',
fontFamily: 'Prompt-Regular'
},
useCoupon: {
marginTop: 10,
backgroundColor: '#E6FFC2',
paddingHorizontal: 10,
paddingVertical: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
}
})
export default PaymentConfirm;

View File

@ -1,381 +0,0 @@
import React, {Component} from 'react'
import { View, StyleSheet, ImageBackground, Text, FlatList, TouchableOpacity, Modal, Alert, ScrollView } from 'react-native';
import FastImage from 'react-native-fast-image';
import { getListMyReward, payment_detail, useRentalDiscount, removeRentalDiscount } from '../../api/UserApi';
import IndicatorLoading from '../../components/IndicatorLoading';
import IconFontawesome from 'react-native-vector-icons/FontAwesome'
import IconMaterial from "react-native-vector-icons/MaterialCommunityIcons";
import { NavigationEvents } from 'react-navigation';
class PaymentDetail extends Component {
constructor(props){
super(props);
this.state = {
payment: null,
coupon_list: [],
modalVisible: false,
isLoading: false,
couponSelected: null,
couponHighlight: null,
payment_id: null,
room: null
}
}
componentDidMount(){
const payment_id = this.props.navigation.getParam('payment_id', null);
const room = this.props.navigation.getParam('room', null);
this.setState({
room
})
if(payment_id){
this.setState({
isLoading: true,
payment_id
})
}
}
getPaymentDetail = () => {
payment_detail(this.state.payment_id)
.then(res => {
if(res.data && res.data.success){
this.setState({
payment: res.data,
isLoading: false
}, () => {
this.getCouponList()
})
}else {
this.setState({
isLoading: false
})
}
})
}
getCouponList = () => {
getListMyReward('', 1, this.state.payment.is_coupon ? this.state.payment_id : '')
.then(res => {
if(res.data && res.data.data){
let coupon = null;
if(res.data.data.length > 0 && this.state.payment && this.state.payment.coupon && this.state.payment.coupon.id){
coupon = res.data.data.filter((item) => item.id === this.state.payment.coupon.id);
if(coupon && coupon.length > 0){
coupon = coupon[0]
}
}
this.setState({
coupon_list: res.data.data,
isLoading: false,
couponSelected: coupon
})
}else{
this.setState({
isLoading: false
})
}
})
}
renderItem = (item) => {
return (
<View style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', marginBottom: 8}}>
<Text style={[styles.mainText, {color: 'black'}]}>{item.cost_name}</Text>
<Text style={[styles.mainText, {color: '#7CBB33', fontWeight: '500'}]}>{parseFloat(item.total).toLocaleString()} บาท</Text>
</View>
)
}
_keyExtractor = (item, index) => 'payment_detail_'+index
visibleCoupon = () => {
this.setState({
modalVisible: true
})
}
useCoupon = () => {
this.setState({
modalVisible: false,
isLoading: true
}, () => {
useRentalDiscount(this.state.couponHighlight.id, this.state.payment_id)
.then(res => {
if(res.data && res.data.success){
this.setState({
couponSelected: this.state.couponHighlight,
// isLoading: false,
modalVisible: false,
payment_id: res.data.new_payment_id,
}, () => {
setTimeout(() => {
this.getPaymentDetail()
}, 3000)
})
}else {
let message = res.data && res.data.message ? res.data.message : 'ใช้คูปองส่วนลดไม่สำเร็จ'
Alert.alert(message)
this.setState({
isLoading: false
})
}
})
})
}
removeCoupon = () => {
this.setState({
isLoading: true
}, () => {
removeRentalDiscount(this.state.couponSelected.id, this.state.payment_id)
.then(res => {
if(res.data && res.data.success){
this.setState({
payment_id: res.data.payment_id
}, () => {
this.getPaymentDetail()
this.setState({
isLoading: false
})
})
}else {
this.setState({
isLoading: false
})
}
})
})
}
render(){
const room = this.state.room
return (
<ImageBackground source={require('../../../assets/images/tree2.png')} style={styles.ImageBackground}>
<NavigationEvents
onDidFocus={() => {
this.setState({
isLoading: true
}, () => {
this.getPaymentDetail()
})
}}
/>
<IndicatorLoading loadingVisible={this.state.isLoading}/>
<View style={{padding: 16, flex: 0.9}}>
<ScrollView contentContainerStyle={styles.detialContainer}>
<View style={styles.borderBottom}>
<Text style={[styles.mainText, {fontSize: 18, textAlign: 'center'}]}>ใบตงหน</Text>
{
this.state.payment && this.state.payment.detail.length > 0 &&
<Text style={[styles.mainText, {fontSize: 14, textAlign: 'center'}]}>
อง {room ? room : ''}
</Text>
}
</View>
<View style={styles.borderBottom}>
<View style={{flexDirection: 'row', display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8}}>
<Text style={[styles.mainText, {color: '#269A21'}]}>รายการ</Text>
<Text style={[styles.mainText, {color: '#269A21'}]}>จำนวนเง</Text>
</View>
{
this.state.payment && this.state.payment.detail && this.state.payment.detail.length > 0 &&
<FlatList
data={this.state.payment.detail}
renderItem={({ item }) => this.renderItem(item)}
pagingEnabled={true}
extraData={this.state}
keyExtractor={this._keyExtractor}
/>
}
</View>
<View style={{flexDirection: 'row', justifyContent: 'flex-end', marginTop: 10, paddingHorizontal: 10}}>
<Text style={[styles.mainText, {textAlign: 'right',}]}>รวม</Text>
<Text style={[styles.mainText, {fontWeight: '500', paddingLeft: 10}]}>
{this.state.payment && this.state.payment.total_cost ? parseFloat(this.state.payment.total_cost).toLocaleString() : 0} บาท
</Text>
</View>
{
!this.state.couponSelected &&
<View style={styles.useCouponContainer}>
<View>
<Text style={[styles.mainText, {fontSize: 16}]}>ใชปองสวนลด</Text>
{
this.state.coupon_list?.length === 0 && <Text style={[styles.mainText, {color: 'red', fontSize: 10}]}>ไมพบรายการคปอง</Text>
}
</View>
<TouchableOpacity style={{backgroundColor: this.state.coupon_list?.length === 0 ? 'lightgrey' : '#269A21', borderRadius: 5}}
onPress={() => this.visibleCoupon()}
disabled={this.state.coupon_list?.length === 0}
>
<Text style={[styles.mainText, {color: 'white', paddingHorizontal: 25, paddingVertical: 8}]}>เลอก</Text>
</TouchableOpacity>
</View>
}
{
this.state.couponSelected &&
<View>
<Text style={[styles.mainText, {fontSize: 16, marginVertical: 10}]}>ปองสวนลดทเลอก</Text>
<View style={styles.couponCard}>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<FastImage source={{uri: this.state.couponSelected.image_reward}} style={{width: 50, height: 50 }} resizeMode={'contain'}/>
<View style={{marginLeft: 10}}>
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={[styles.mainText, {fontSize: 16, marginRight: 5}]}>{this.state.couponSelected.reward_name}</Text>
<Text style={[styles.mainText, {fontSize: 16}]}>{this.state.couponSelected.value} {this.state.couponSelected.discount_type === 'percent' ? '%' : 'บาท'}</Text>
</View>
<Text style={[styles.mainText, {color: '#FF2D55'}]}>{this.state.couponSelected.detail}</Text>
</View>
</View>
<TouchableOpacity onPress={() => this.removeCoupon()}>
<IconMaterial name="close-circle-outline" size={18} color="#FF2D55"/>
</TouchableOpacity>
</View>
</View>
}
</ScrollView>
</View>
<View style={{padding: 16, flex: 0.1}}>
<TouchableOpacity style={{backgroundColor: '#145EB3', paddingVertical: 12, borderRadius: 5}}
// onPress={() => this.props.navigation.navigate('PaymentConfirm', {payment_id: this.state.new_payment_id ? this.state.new_payment_id : this.state.payment_id, room: this.state.room})}
onPress={() => this.props.navigation.navigate('Payment', {payment_id: this.state.payment_id })}
>
<Text style={{color: 'white', textAlign: 'center', fontFamily: 'Prompt-Regular'}}>นยนรายการและชำระเง</Text>
</TouchableOpacity>
</View>
<Modal animationType="none"
transparent={true}
visible={this.state.modalVisible}
>
<View style={styles.couponContainer}>
<View style={styles.couponBox}>
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={[styles.mainText, {fontSize: 18, marginBottom: 10}]}>
เลอกคปองสวนลด
</Text>
<TouchableOpacity onPress={() => this.setState({modalVisible: false, couponHighlight: null})}>
<IconFontawesome name="close" color="#269A21" size={16}/>
</TouchableOpacity>
</View>
<FlatList
data={this.state.coupon_list}
renderItem={({ item }) => (
<TouchableOpacity
style={[styles.couponCard, this.state.couponHighlight && this.state.couponHighlight.id === item.id ? {}: {backgroundColor: '#FAFAFA', borderColor: '#00000040'}]}
onPress={() => this.setState({couponHighlight: item})}>
<FastImage source={{uri: item.image_reward}} style={{width: 50, height: 50 }} resizeMode={'contain'}/>
<View style={{marginLeft: 10, flex: 1}}>
<View style={{flexDirection: 'row', flex: 1, justifyContent: 'space-between'}}>
<Text style={[styles.mainText, {fontSize: 16, flex: 0.7}]}>{item.reward_name}</Text>
<Text style={[styles.mainText, {fontSize: 16, flex: 0.3}]}>{item.value} {item.discount_type === 'percent' ? '%' : 'บาท'} </Text>
</View>
<Text style={[styles.mainText, {color: '#FF2D55'}]}>{item.detail}</Text>
</View>
</TouchableOpacity>
)}
pagingEnabled={true}
extraData={this.state.coupon_list}
keyExtractor={(item, index) => 'coupon_' + index}
ListEmptyComponent={() =>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', margin: 16,padding:16,borderRadius:5,backgroundColor:'white'}}>
<Text style={{fontSize: 16}}> ไมพบรายการคปอง </Text>
</View>
}
/>
<TouchableOpacity
onPress={() => this.useCoupon()}
style={{
backgroundColor: this.state.coupon_list.length === 0 || this.state.couponHighlight === null ? 'grey' : '#269A21',
marginTop: 10,
borderRadius: 5
}}
disabled={this.state.coupon_list.length === 0 || this.state.couponHighlight === null}
>
<Text style={[styles.mainText, {color: 'white', paddingVertical: 12, textAlign: 'center'}]}>
นยนการใชปอง
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</ImageBackground>
)
}
}
const styles = StyleSheet.create({
contentContainer: {
backgroundColor: '#EEFFD7',
paddingVertical: 0,
flexGrow: 1,
},
detialContainer: {
backgroundColor: 'white',
borderRadius: 5,
padding: 15,
flexGrow: 1
},
ImageBackground: {
backgroundColor:'#EEFFD7',
flex: 1
},
borderBottom: {
borderBottomWidth: 1,
borderColor: '#EAEAF4',
padding: 10
},
mainText: {
color: '#00420A',
fontFamily: 'Prompt-Regular'
},
useCouponContainer: {
backgroundColor: '#E6FFC2',
padding: 8,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: 16
},
couponContainer: {
flex:1,
backgroundColor:'#00000080',
justifyContent:'center',
alignItems:'center'
},
couponBox: {
width: '90%',
maxHeight: '80%',
backgroundColor:'white',
borderRadius:5,
padding:17
},
couponCard: {
backgroundColor: '#FDFFA2',
padding: 8,
// flex: 1,
flexDirection: 'row',
borderLeftWidth: 4,
borderColor: '#FFCC00',
borderRadius: 5,
marginBottom: 8,
justifyContent: 'space-between',
alignItems: 'center',
}
})
export default PaymentDetail;

View File

@ -1,169 +0,0 @@
import React, {Component} from 'react';
import {KeyboardAvoidingView, SafeAreaView, ScrollView, View, Text, Alert, TouchableOpacity} from 'react-native'
import LinearGradient from 'react-native-linear-gradient';
import { forgetPassword } from '../../api/UserApi';
import { BackgroundImage } from '../../components/BackgroundImage';
import { CustomButton } from '../../components/CustomButton';
import { CustomInput } from '../../components/CustomInput';
import IndicatorLoading from '../../components/IndicatorLoading';
import { t } from '../../utils/i18n';
class ForgetPasswordScreen extends Component {
constructor(props) {
super(props)
this.state = {
mobile: '',
isLoading: false
}
}
submitForgetPassword = () => {
this.setState({
isLoading: true
}, () => {
forgetPassword(this.state.mobile)
.then(res => {
if(res.data && res.data.success){
Alert.alert('ทำรายการสำเร็จ', 'กรุณาตรวจสอบ OTP ที่ส่งไปยังเบอร์โทรศัพท์ของท่าน', [
{
text: 'OK',
onPress: () => {
this.props.navigation.navigate('VerifyOTP', {token: res.data.token, mobile: this.state.mobile})
this.setState({
isLoading: false
})
}
}
])
}else {
let message = res && res.data && res.data.message ? res.data.message : '';
Alert.alert('ทำรายการไม่สำเร็จ', message)
this.setState({
isLoading: false
})
}
})
})
}
render() {
return (
<SafeAreaView style={{flex: 1}}>
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
}}>
<BackgroundImage>
<KeyboardAvoidingView style={{flex:1}}
keyboardVerticalOffset={Platform.OS == 'ios' ? 70 : 0}
behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
<View style={styles.container}>
<View style={{flex: 0.7}}>
<View style={{flex: 1, flexDirection: 'column', justifyContent: 'center'}}>
<View>
<Text style={[styles.textStyle, {fontSize: 28, fontFamily: 'Prompt-Bold'}]}>
มรหสผาน
</Text>
<Text style={[styles.textStyle, {fontSize: 18, fontFamily: 'Prompt-Regular'}]}>
กรณากรอกเบอรโทรศพท
</Text>
<Text style={[styles.textStyle, {fontSize: 18, fontFamily: 'Prompt-Regular'}]}>
เพอรบรห OTP ทาง SMS
</Text>
{/* <Text style={[styles.textStyle, {fontSize: 18}]}>
กรณากรอกอเมล ระบบจะสงลงก
</Text>
<Text style={[styles.textStyle, {fontSize: 18}]}>
สำหรบเปลยนรหสผานใหบทาน
</Text> */}
</View>
<View style={{marginVertical: 20}}>
<View style={{flexDirection: 'row', flex: 1}}>
<CustomInput
onChangeText={(e) => {
this.setState({
mobile: e
})
}}
inputTextAlign={'left'}
iconName={'phone'}
iconType={'fontAwesome'}
placeholder={t('phone')}
placeholderTextColor={'#FFFFFF40'}
keyboardType='numeric'
maxLength={10}
style={styles.form_input} />
</View>
</View>
</View>
</View>
<View style={{flex: 0.3, width: '100%', marginTop: 20}}>
<View style={{height: 48}}>
<TouchableOpacity onPress={this.submitForgetPassword}
style={styles.btnSubmit}
disabled={this.state.mobile === ''}
>
<Text style={styles.textBtnSubmit}>
{t('confirm')}
</Text>
</TouchableOpacity>
</View>
</View>
</View>
<View style={{position: 'absolute', bottom: 20, flex: 1, width: '100%', flexDirection: 'row', justifyContent:'center'}}>
<Text style={{color: 'white', textAlign: 'center', marginRight: 10, fontSize: 14, fontFamily: 'Prompt-Regular'}}>กลบไปย</Text>
<TouchableOpacity onPress={() => this.props.navigation.navigate('HomeScreen')}>
<Text style={{color: 'white', fontFamily: 'Prompt-Bold', fontSize: 14}}>ลงชอเขาใชงาน</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</BackgroundImage>
<IndicatorLoading loadingVisible={this.state.isLoading}/>
</LinearGradient>
</SafeAreaView>
)
};
}
const styles = {
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 40
},
textStyle: {
color: 'white',
textAlign: 'center'
},
form_input: {
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'white', borderRadius: 30,
borderWidth: 1,
width: '100%'
},
btnSubmit: {
backgroundColor: 'white',
borderRadius: 30,
paddingVertical: 10,
paddingHorizontal: 50,
flex: 1,
height: 50,
},
textBtnSubmit: {
color: '#2470A1',
fontFamily: 'Prompt-Bold',
fontSize: 16,
textAlign: 'center'
}
}
export default ForgetPasswordScreen;

View File

@ -1,84 +0,0 @@
import React, { Component } from "react";
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, Clipboard, ToastAndroid, Alert } from "react-native";
import LinearGradient from "react-native-linear-gradient";
import { BackgroundImage } from "../../components/BackgroundImage";
import AntdIcon from 'react-native-vector-icons/AntDesign'
import Toast from "react-native-toast-message";
class PasswordCode extends Component {
constructor(props) {
super(props);
this.state = {
password: this.props.navigation.getParam('password', null)
}
}
handleCopy = () => {
Toast.show({
type: 'success',
text1: 'Copy success!',
});
Clipboard.setString(this.state.password)
}
render () {
return (
<SafeAreaView style={{flex: 1}}>
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
}}>
<BackgroundImage>
<View style={styles.container}>
<Text style={[styles.fontPromtBold, {color: 'white', fontSize: 30, marginBottom: 10}]}>รหสผานใหม</Text>
<Text style={{color: 'white', fontSize: 18, fontFamily: 'Prompt-Regular'}}>คลกทรหสผานเพอคดลอก</Text>
<Text style={{color: 'white', fontSize: 18, marginBottom: 50, fontFamily: 'Prompt-Regular'}}>เพอนำไปใชในการเขาสระบบ</Text>
<TouchableOpacity onPress={this.handleCopy}>
<View style={styles.code_form}>
<Text style={{color: 'white', fontSize: 25, fontFamily: 'Prompt-Regular', marginRight: 10}}>
{this.state.password}
</Text>
<AntdIcon name="copy1" color="white" style={{fontSize: 30}}/>
</View>
</TouchableOpacity>
</View>
<View style={{position: 'absolute', bottom: 20, flex: 1, width: '100%', flexDirection: 'row', justifyContent:'center'}}>
<Text style={{color: 'white', textAlign: 'center', marginRight: 10, fontSize: 14, fontFamily: 'Prompt-Regular'}}>กลบไปย</Text>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
<Text style={{color: 'white', fontFamily: 'Prompt-Bold', fontSize: 14}}>ลงชอเขาใชงาน</Text>
</TouchableOpacity>
</View>
</BackgroundImage>
</LinearGradient>
</SafeAreaView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 40
},
code_form: {
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'white', borderRadius: 30,
borderWidth: 1,
width: '100%',
paddingVertical: 10,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center'
},
fontPromtBold: {
fontFamily: 'Prompt-Bold'
}
})
export default PasswordCode;

View File

@ -1,221 +0,0 @@
import React, {Component} from 'react';
import { Alert, KeyboardAvoidingView, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { BackgroundImage } from '../../components/BackgroundImage';
import { CustomInput } from '../../components/CustomInput';
import { t } from '../../utils/i18n';
import IndicatorLoading from '../../components/IndicatorLoading';
import { sendVerifyOTP, forgetPassword } from '../../api/UserApi';
class VerifyOTP extends Component {
constructor(props) {
super(props)
this.state = {
otp: null,
is_loading: false,
seconds: 300000,
minuteLeft: 5,
secondLeft: 0,
token: this.props.navigation.getParam('token', null),
mobile: this.props.navigation.getParam('mobile', null)
}
this.countdownTimer = null
}
componentDidMount () {
this.startTimer()
}
componentWillUnmount () {
this.countdownTimer = null
}
startTimer = () => {
if (this.countdownTimer) return;
this.countdownTimer = setInterval(() => {
if(this.state.seconds > 0) {
this.setState({
seconds: this.state.seconds - 1000
}, () => {
let min = parseInt(this.state.seconds/60000)
this.setState({
minuteLeft: min
})
let min_to_ms = min * 60000
let sec = parseInt((this.state.seconds - min_to_ms)/1000)
this.setState({
secondLeft: sec
})
})
}else {
clearInterval(this.interval);
this.countdownTimer = null;
}
}, 1000);
};
submitVerifyOTP = () => {
this.setState({
is_loading: true
}, async () => {
await sendVerifyOTP(this.state.token, this.state.otp).then(res => {
if(res && res.data && res.data.success) {
this.setState({
is_loading: false
}, () => {
this.props.navigation.navigate('PasswordCode', {password: res.data.password})
})
}else {
let message = res && res.data && res.data.message ? res.data.message : ''
Alert.alert('ทำรายการไม่สำเร็จ', message)
this.setState({
is_loading: false
})
}
})
})
}
resentRequestOTP = async () => {
this.setState({
is_loading: true
}, () => {
forgetPassword(this.state.mobile)
.then(res => {
if(res.data && res.data.success){
Alert.alert('ทำรายการสำเร็จ', 'กรุณาตรวจสอบ OTP ที่ส่งไปยังเบอร์โทรศัพท์ของท่าน', [
{
text: 'OK',
onPress: () => {
this.setState({
is_loading: false,
seconds: 300000,
minuteLeft: 5,
secondLeft: 0,
}, () => {
this.startTimer()
})
}
}
])
}else {
let message = res && res.data && res.data.message ? res.data.message : '';
Alert.alert('ทำรายการไม่สำเร็จ', message)
this.setState({
is_loading: false
})
}
})
})
}
render() {
return (
<SafeAreaView style={{flex: 1}}>
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
}}>
<BackgroundImage>
<KeyboardAvoidingView style={{flex:1}}
keyboardVerticalOffset={Platform.OS == 'ios' ? 70 : 0}
behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
<View style={styles.container}>
<View style={{flex: 0.7, flexDirection: 'column', alignItems: 'center', justifyContent: 'center'}}>
<Text style={[styles.fontPromtBold, {color: 'white', fontSize: 30}]}>นยนรห OTP</Text>
<Text style={[styles.fontPromtRegular, {color: 'white', fontSize: 18, textAlign: 'center'}]}>กรณากรอกรห OTP</Text>
<Text style={[styles.fontPromtRegular, {color: 'white', fontSize: 18, marginBottom: 50, textAlign: 'center'}]}>งไปทเบอร {this.state.mobile}</Text>
<CustomInput
onChangeText={(e) => {
this.setState({
otp: e
})
}}
inputTextAlign={'center'}
placeholder={'XXXX'}
placeholderTextColor={'#FFFFFF40'}
keyboardType='numeric'
maxLength={4}
textInputStyles={{fontSize: 20}}
style={[styles.form_input]} />
{
this.state.minuteLeft > 0 || this.state.secondLeft > 0 ?
<Text style={[styles.fontPromtRegular, {color: 'white', marginTop: 30, fontSize: 17}]}>
งรห OTP ไดกครงใน {this.state.minuteLeft >= 10 ? this.state.minuteLeft : '0' + this.state.minuteLeft}:
{this.state.secondLeft >= 10 ? this.state.secondLeft : '0' + this.state.secondLeft} นาท
</Text>
:
<TouchableOpacity style={{marginTop: 30}} onPress={this.resentRequestOTP}>
<Text style={[styles.fontPromtRegular, {color: 'white', fontSize: 17}]}>ขอรหสอกคร</Text>
</TouchableOpacity>
}
</View>
<View style={{flex: 0.3, marginTop: 20}}>
<TouchableOpacity onPress={this.submitVerifyOTP}
disabled={this.state.otp === null || this.state.otp === ''}
style={styles.btnSubmit}>
<Text style={styles.textBtnSubmit}>
{t('confirm')}
</Text>
</TouchableOpacity>
</View>
</View>
</KeyboardAvoidingView>
</BackgroundImage>
<IndicatorLoading loadingVisible={this.state.is_loading}/>
</LinearGradient>
</SafeAreaView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 40
},
fontPromtBold: {
fontFamily: 'Prompt-Bold'
},
fontPromtRegular: {
fontFamily: 'Prompt-Regular'
},
form_input: {
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'white',
borderRadius: 30,
borderWidth: 1,
width: '50%'
},
btnSubmit: {
marginTop: 35,
backgroundColor: 'white',
borderRadius: 30,
paddingVertical: 10,
paddingHorizontal: 50,
},
textBtnSubmit: {
color: '#2470A1',
fontFamily: 'Prompt-Bold',
fontSize: 16,
textAlign: 'center'
}
})
export default VerifyOTP

View File

@ -1,21 +1,20 @@
import React, {Component, useCallback} from 'react'; import React, { Component } from 'react'
import { TouchableOpacity, View, Alert, ScrollView, SafeAreaView, KeyboardAvoidingView, Platform } from 'react-native' import { TouchableOpacity, View, Alert, ScrollView, SafeAreaView, KeyboardAvoidingView, Platform } from 'react-native'
import Image from 'react-native-fast-image' import Image from 'react-native-fast-image'
import GetWidthHeightDevice from '../../components/GetWidthHeightDevice' import GetWidthHeightDevice from '../../components/GetWidthHeightDevice'
import { CustomButton } from '../../components/CustomButton' import { CustomButton } from '../../components/CustomButton'
import { CustomInput } from '../../components/CustomInput' import { CustomInput } from '../../components/CustomInput'
import {login, payment} from '../../api/UserApi' import { login } from '../../api/UserApi'
import { setToken } from '../../api/api' import { setToken } from '../../api/api'
import { BackgroundImage } from '../../components/BackgroundImage' import { BackgroundImage } from '../../components/BackgroundImage'
import LinearGradient from 'react-native-linear-gradient' import LinearGradient from 'react-native-linear-gradient'
import Text from '../../components/Text' import Text from '../../components/Text'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import {appSetDevice, appSetPushToken, appSetToken, appSetUser} from '../../redux/app/action' import { appSetDevice, appSetPushToken, appSetToken, appSetUser } from '../../redux/app/action'
import {connect} from 'react-redux' import {connect} from 'react-redux'
import IndicatorLoading from '../../components/IndicatorLoading'; import IndicatorLoading from '../../components/IndicatorLoading';
import { locale, t } from '../../utils/i18n' import { locale, t } from '../../utils/i18n'
import moment from "moment";
import messaging from "@react-native-firebase/messaging";
class LoginScreen extends Component { class LoginScreen extends Component {
@ -23,79 +22,50 @@ class LoginScreen extends Component {
super(props) super(props)
this.state = { this.state = {
isLoading: false, isLoading: false,
username: '0935697758', username: null,
password: '123456', password: null,
payment: [],
sum_payment: [],
all_payment : [],
room_number_array : [],
} }
this._login = this._login.bind(this) this._login = this._login.bind(this)
} }
async _login () { _login() {
if (this.state.username && this.state.password) { if (this.state.username && this.state.password) {
var regex = /^\d+$/; var regex = /^\d+$/;
if (regex.test(this.state.username) === true) { if (regex.test(this.state.username) === true) {
console.log('true')
const fcm = messaging()
if (!await fcm.hasPermission()) {
try {
await messaging().requestPermission()
} catch (error) {
}
}
const fcmToken = await messaging().getAPNSToken();
let params = { let params = {
// mobile: this.state.username, mobile: this.state.username,
username: this.state.username, password: this.state.password
password: this.state.password,
fcm_token: fcmToken
} }
console.log('params >> ', params)
console.log('fcmToken >>>>>>>>>>>>>>>>>>>>>>>>> ', fcmToken)
this.setState({isLoading:true}) this.setState({isLoading:true})
login(params) login(params)
.then((res) => { .then((res) => {
if (res.ok) { if (res.ok) {
console.log('data >>>>> ', res.data) if (res.data.token) {
if (res.data.access_token) { setToken(res.data.token)
// setToken(res.data.token) this.props.appSetToken(res.data.token)
// this.props.appSetToken(res.data.token) this.props.appSetUser(res.data.user)
setToken(res.data.access_token)
this.props.appSetToken(res.data.access_token)
this.props.navigation.navigate('HomeScreen',{isLogin:true})
let user_data = res.data.user;
this.props.appSetUser(user_data)
setTimeout(() => {
console.log('tokennnnnnnnnnnnnn >>>>>>>>>>>> ', this.props.token)
console.log('userrrrrrrrrrrrrrr >>>>>>>>>>>> ', this.props.user)
}, 5000)
}else {
setTimeout(() => {
Alert.alert(null, 'ท่านกรอก บัญชีผู้ใช้งาน หรือ รหัสผ่านผิด')
}, 600);
}
} else {
setTimeout(() => { setTimeout(() => {
Alert.alert(null, 'ท่านกรอก บัญชีผู้ใช้งาน หรือ รหัสผ่านผิด') this.setState({isLoading:false},() => {
}, 600); this.props.navigation.navigate('HomeScreen',{isLogin:true})
})
}, 300);
} }
this.setState({isLoading:false}) } else {
}) setTimeout(() => {
Alert.alert(null, 'ท่านกรอก บัญชีผู้ใช้งาน หรือ รหัสผ่านผิด')
}, 600);
}
this.setState({isLoading:false})
})
} else { } else {
Alert.alert(null, 'ท่านกรอกรูปแบบโทรศัพท์ไม่ถูกต้อง') Alert.alert(null, 'ท่านกรอกรูปแบบโทรศัพท์ไม่ถูกต้อง')
} }
} else { } else {
Alert.alert(null, 'กรุณากรอกข้อมูลให้ครบถ้วน') Alert.alert(null, 'กรุณากรอกข้อมูลให้ครบถ้วน')
} }
}; }
render() { render() {
return ( return (
@ -167,11 +137,6 @@ class LoginScreen extends Component {
}} }}
style={styles.form_input} /> style={styles.form_input} />
</View> </View>
<View style={{flex: 1, marginBottom: 10}}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('ForgetPassword')}>
<Text style={{color: '#FFF', fontSize: 15, textAlign: 'right'}}>{t('forget_password')}?</Text>
</TouchableOpacity>
</View>
<View style={[styles.row, { marginTop: 15 }]}> <View style={[styles.row, { marginTop: 15 }]}>
<CustomButton <CustomButton
colorText={'#2470A1'} colorText={'#2470A1'}
@ -184,14 +149,14 @@ class LoginScreen extends Component {
//onPress={() => { this.props.navigation.navigate('HomeScreen') }} //onPress={() => { this.props.navigation.navigate('HomeScreen') }}
/> />
</View> </View>
{/* <View style={{marginTop:10}}> <View style={{marginTop:10}}>
<View style={[styles.row, { flex: 1, flexDirection: locale() == 'my' ? 'column' : 'row', alignItems: 'center', textAlign: 'center', justifyContent: 'center' }]}> <View style={[styles.row, { flex: 1, flexDirection: locale() == 'my' ? 'column' : 'row', alignItems: 'center', textAlign: 'center', justifyContent: 'center' }]}>
<Text style={{ color: '#FFF', fontSize: 15}}> {t('not_a_member')} </Text> <Text style={{ color: '#FFF', fontSize: 15,/* fontFamily: 'Prompt-Regular', */ }}> {t('not_a_member')} </Text>
<TouchableOpacity onPress={() => { this.props.navigation.navigate('Register') }}> <TouchableOpacity onPress={() => { this.props.navigation.navigate('Register') }}>
<Text style={{ color: '#FFF', fontSize: 15, fontFamily: 'Prompt-Bold' }}> {t('create_account')} </Text> <Text style={{ color: '#FFF', fontSize: 15, fontFamily: 'Prompt-Bold' }}> {t('create_account')} </Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> */} </View>
</View> </View>
</View> </View>
</ScrollView> </ScrollView>

View File

@ -26,24 +26,15 @@ class RegisterScreen extends Component {
_onNextStep = async () => { _onNextStep = async () => {
var regex = /^\d+$/; var regex = /^\d+$/;
console.log('mobile ===> ', this.state.user) if (this.state.user.mobile && this.state.user.password && this.state.user.password == this.state.user.password_confirm) {
if (this.state.user.mobile && this.state.user.password && this.state.user.password && this.state.user.password_confirm) { if (regex.test(this.state.user.mobile) === true) {
if (regex.test(this.state.user.mobile) === false) {
Alert.alert(null, 'ท่านกรอกรูปแบบโทรศัพท์ไม่ถูกต้อง')
} else if (this.state.user.password !== this.state.user.password_confirm){
Alert.alert(null, 'รหัสผ่านไม่ตรงกัน')
} else {
this.props.appSetUser(this.state.user) this.props.appSetUser(this.state.user)
this.props.navigation.navigate('RegisterFormLogin'); this.props.navigation.navigate('RegisterFormLogin');
} else {
Alert.alert(null, 'ท่านกรอกรูปแบบโทรศัพท์ไม่ถูกต้อง')
} }
} else { } else {
if(!this.state.user.mobile){ Alert.alert(null, 'รหัสผ่านไม่ตรงกัน')
Alert.alert(null, 'กรุณากรอกเบอร์โทรศัพท์')
} else if(!this.state.user.password){
Alert.alert(null, 'กรุณากรอกรหัสผ่าน')
} else if(!this.state.user.password_confirm){
Alert.alert(null, 'กรุณากรอกยืนยันรหัสผ่าน')
}
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -5,15 +5,14 @@ import { CustomStepIndicator } from '../../components/StepIndicator'
import GetWidthHeightDevice from '../../components/GetWidthHeightDevice' import GetWidthHeightDevice from '../../components/GetWidthHeightDevice'
import { CustomButton } from '../../components/CustomButton' import { CustomButton } from '../../components/CustomButton'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import {checkPaymentMeter, register, registerDevice, testConnect} from '../../api/UserApi' import { register, registerDevice, testConnect } from '../../api/UserApi'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import {appSetDevice, appSetPushToken, appSetToken, appSetUser, setPopupNotification} from '../../redux/app/action' import { appSetDevice, appSetPushToken, appSetToken, appSetUser } from '../../redux/app/action'
import messaging from "@react-native-firebase/messaging"; import firebase, { Notification } from 'react-native-firebase'
import moment from 'moment' import moment from 'moment'
import { setToken } from '../../api/api' import { setToken } from '../../api/api'
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm' import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
import DeviceInfo from 'react-native-device-info';
import Text from '../../components/Text'; import Text from '../../components/Text';
import { t } from '../../utils/i18n' import { t } from '../../utils/i18n'
@ -24,8 +23,7 @@ class RegisterProfileScreen extends Component {
this.state = { this.state = {
auth: false, auth: false,
disableButton: false, disableButton: false
image_url: require('../../../assets/images/profile.png'),
} }
this._register = this._register.bind(this); this._register = this._register.bind(this);
@ -38,31 +36,27 @@ class RegisterProfileScreen extends Component {
if (!this.props.push_token) { if (!this.props.push_token) {
this.initNotification(); this.initNotification();
} }
this.setState({
image_url: this.props.navigation.getParam('image_url', require('../../../assets/images/profile.png'))
})
} }
initNotification = async () => { initNotification = async () => {
await this.setPermission() await this.setPermission()
const fcmToken = await messaging().getToken() const fcmToken = await firebase.messaging().getToken()
console.log('fcmToken', fcmToken) console.log('fcmToken', fcmToken)
if (fcmToken) { if (fcmToken) {
this.props.appSetPushToken(fcmToken) this.props.appSetPushToken(fcmToken)
console.log('fcmToken', this.props) console.log('fcmToken', this.props)
} else { } else {
Alert.alert(null, 'Cannot get push token.', [{ text: 'ok' }]) Alert.alert(null, 'Cannot get push token.', [{ text: 'ok' }])
} }
} }
setPermission = async () => { setPermission = async () => {
try { try {
const enabled = await messaging().hasPermission() const enabled = await firebase.messaging().hasPermission()
if (!enabled) { if (!enabled) {
await messaging().requestPermission() await firebase.messaging().requestPermission()
} }
} catch (error) { } catch (error) {
console.log('error', error) console.log('error', error)
@ -78,22 +72,14 @@ class RegisterProfileScreen extends Component {
this.props.appSetDevice(resultSendDevice.data.device) this.props.appSetDevice(resultSendDevice.data.device)
} }
} }
if (!this.props.device || !this.props.push_token) {
let systemName = DeviceInfo.getSystemName(); Alert.alert(null, 'Cannot get push token or device.', [{ text: 'ok' }])
let deviceId = null return;
if(systemName == "Android") { }
if (!this.props.device) {
Alert.alert(null, 'Cannot get push token or device.', [{ text: 'ok' }])
return;
}
deviceId = this.props.device.id
}
register({ register({
...this.props.user, ...this.props.user,
device_id: deviceId, device_id: this.props.device.id
name: this.props.user.name.replace(/\u00a0/g, /\u0020/),
fcm_token: this.props.push_token
}).then( }).then(
(res) => { (res) => {
if (res.ok && res.data.success) { if (res.ok && res.data.success) {
@ -103,40 +89,8 @@ class RegisterProfileScreen extends Component {
this.props.appSetUser(res.data.customer) this.props.appSetUser(res.data.customer)
this.props.appSetToken(res.data.token) this.props.appSetToken(res.data.token)
setToken(token) setToken(token)
Alert.alert(null, t('register_success'), [{ text: t('ok') }])
Alert.alert( this.props.navigation.navigate('HomeScreen')
'',
t('register_success'),
[
{ text: 'OK', onPress: () => {
/*checkPaymentMeter()
.then(result => {
if(result.data){
let data = {
pending_payment: result.data.pending_payment != null ? result.data.pending_payment : 0,
is_notified_electric: result.data.user.is_notified_electric,
is_notified_overdue: result.data.user.is_notified_overdue,
is_notified_meter: result.data.user.is_notified_meter,
payment_id: result.data.payment_id,
notified_meter_at: result.data.notified_meter_at ? result.data.notified_meter_at : moment().format('DD MMM YYYY')
}
this.props.setPopupNotification(data)
}
})*/
this.setState({isLoading:false},() => {
this.props.navigation.navigate('HomeScreen',{isLogin:true})
})
}
}
],
{ cancelable: false }
)
//Alert.alert(null, t('register_success'), [{ text: t('ok') }])
//this.props.navigation.navigate('HomeScreen')
} }
} else { } else {
this.props.appSetUser(null) this.props.appSetUser(null)
@ -171,7 +125,7 @@ class RegisterProfileScreen extends Component {
}}> }}>
<Image <Image
style={{ width: 100, height: 100, borderRadius: 50, borderColor: 'white', borderWidth: 2 }} style={{ width: 100, height: 100, borderRadius: 50, borderColor: 'white', borderWidth: 2 }}
source={this.state.image_url} source={require('../../../assets/images/profile.png')}
/> />
</View> </View>
{/*<Text> LOGO </Text>*/} {/*<Text> LOGO </Text>*/}
@ -184,10 +138,10 @@ class RegisterProfileScreen extends Component {
<View style={[styles.table]}> <View style={[styles.table]}>
<View style={styles.row_title}> <View style={styles.row_title}>
<Text style={styles.title_data}> {t('name')} </Text> <Text style={styles.title_data}> </Text>
{/* <Text style={styles.title_data}> อีเมล </Text> */} {/* <Text style={styles.title_data}> อีเมล </Text> */}
{/*<Text style={styles.title_data}> {t('gender')} </Text>*/} <Text style={styles.title_data}> {t('gender')} </Text>
{/*<Text style={styles.title_data}> {t('birth_date')} </Text>*/} <Text style={styles.title_data}> {t('birth_date')} </Text>
<Text style={styles.title_data}> {t('phone2')} </Text> <Text style={styles.title_data}> {t('phone2')} </Text>
</View> </View>
{ {
@ -195,8 +149,8 @@ class RegisterProfileScreen extends Component {
<View style={styles.row_data}> <View style={styles.row_data}>
<Text style={styles.detail_data}> {user.name} </Text> <Text style={styles.detail_data}> {user.name} </Text>
{/* <Text style={styles.detail_data}> {user.email} </Text> */} {/* <Text style={styles.detail_data}> {user.email} </Text> */}
{/*<Text style={styles.detail_data}> {user.gender} </Text>*/} <Text style={styles.detail_data}> {user.gender} </Text>
{/*<Text style={styles.detail_data}> {moment(user.birth_date_show).add(543, 'years').format('D MMMM YYYY')} </Text>*/} <Text style={styles.detail_data}> {moment(user.birth_date_show).add(543, 'years').format('D MMMM YYYY')} </Text>
<Text style={styles.detail_data}> {user.mobile} </Text> <Text style={styles.detail_data}> {user.mobile} </Text>
</View> </View>
} }
@ -206,8 +160,8 @@ class RegisterProfileScreen extends Component {
<View style={[styles.table]}> <View style={[styles.table]}>
<View style={styles.row_title}> <View style={styles.row_title}>
<Text style={styles.title_data}> {t('project')} </Text> <Text style={styles.title_data}> {t('project')} </Text>
<Text style={styles.title_data}> {t('building')} </Text> <Text style={styles.title_data}> {t('building')} </Text>
<Text style={styles.title_data}> {t('room2')} </Text> <Text style={styles.title_data}> {t('room2')} </Text>
</View> </View>
{ {
user !== null && user !== null &&
@ -322,5 +276,5 @@ const styles = {
const mapDisPatchToProps = state => { const mapDisPatchToProps = state => {
return state.app return state.app
} }
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser, setPopupNotification }, dispatch) const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser }, dispatch)
export default connect(mapDisPatchToProps, setUser)(RegisterProfileScreen) export default connect(mapDisPatchToProps, setUser)(RegisterProfileScreen)

View File

@ -4,25 +4,14 @@ import Text from '../../components/Text';
import { Badge } from 'native-base' import { Badge } from 'native-base'
import { WebView } from 'react-native-webview'; import { WebView } from 'react-native-webview';
import { t } from '../../utils/i18n' import { t } from '../../utils/i18n'
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
import {appCleanUser} from "../../redux/app/action";
import I18n from "i18n-js";
class TermsAndCondition extends Component { export default class TermsAndCondition extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
currentLocale: 'th'
}; };
} }
componentDidMount(): void {
this.setState({
currentLocale : I18n.currentLocale()
})
}
render() { render() {
return ( return (
<ScrollView contentContainerStyle={{flex:1}}> <ScrollView contentContainerStyle={{flex:1}}>
@ -37,8 +26,7 @@ class TermsAndCondition extends Component {
flex: 1, flex: 1,
}} }}
originWhitelist={['*']} originWhitelist={['*']}
// source={ this.state.currentLocale === 'th' ? { uri: 'https://power-condo-dev.testsiteth.xyz/privacy-policy-new'} : {uri: 'https://power-condo-dev.testsiteth.xyz/privacy-policy-en'}} source={{ uri: 'https://www.csasset.co.th/Privacy-Policy-TH.htm'}}
source={ this.state.currentLocale === 'th' ? { uri: 'https://powercondo.csasset.co.th/privacy-policy-new'} : {uri: 'https://powercondo.csasset.co.th/privacy-policy-en'}}
javaScriptEnabled={true} javaScriptEnabled={true}
domStorageEnabled={true} domStorageEnabled={true}
onNavigationStateChange={(event) => { onNavigationStateChange={(event) => {
@ -53,7 +41,6 @@ class TermsAndCondition extends Component {
</View> </View>
<View style={{flexDirection:'row',justifyContent:'space-around',height:60}}> <View style={{flexDirection:'row',justifyContent:'space-around',height:60}}>
<TouchableOpacity onPress={() => { <TouchableOpacity onPress={() => {
this.props. appCleanUser();
this.props.navigation.goBack() this.props.navigation.goBack()
}}> }}>
<View> <View>
@ -77,6 +64,3 @@ class TermsAndCondition extends Component {
); );
} }
} }
const clearUser = dispatch => bindActionCreators({appCleanUser}, dispatch);
export default connect(null, clearUser)(TermsAndCondition);

View File

@ -32,12 +32,6 @@ export default class Meter extends Component {
this.getMeter = this.getMeter.bind(this) this.getMeter = this.getMeter.bind(this)
} }
componentWillUnmount() {
if(this.props && this.props.navigation && this.props.navigation.state && this.props.navigation.state.params && this.props.navigation.state.params.getNotification){
this.props.navigation.state.params.getNotification()
}
}
getMeter(){ getMeter(){
this.setState({ this.setState({
isLoading: true isLoading: true
@ -77,8 +71,7 @@ export default class Meter extends Component {
cropping: true, cropping: true,
width: 300, width: 300,
height: 100, height: 100,
includeExif: true, includeExif: true
includeBase64: true
}).then(image => { }).then(image => {
console.log('received image', image) console.log('received image', image)
let image_meter = { let image_meter = {
@ -86,15 +79,13 @@ export default class Meter extends Component {
type: image.mime, type: image.mime,
name: 'image_meter.jpg', name: 'image_meter.jpg',
} }
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height};
this.setState({ this.setState({
image_url: image_data, image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
images: null, images: null,
image_preview: image_meter
}, () => { }, () => {
this.selectedImage(this.state.image_url) this.selectedImage(this.state.image_url)
}) })
}).catch(e => {}) }).catch(e => alert(e))
} }
selectedImage(image_meter){ selectedImage(image_meter){
@ -103,9 +94,9 @@ export default class Meter extends Component {
},() => { },() => {
console.log('selected image ',this.state.image_selected) console.log('selected image ',this.state.image_selected)
if(this.state.selected_type == 'pea'){ if(this.state.selected_type == 'pea'){
this.props.navigation.navigate('PEAMeter',{image: this.state.image_selected, image_preview: this.state.image_preview, room_id: this.state.room_list[this.state.room_snap_index].id}) this.props.navigation.navigate('PEAMeter',{image: this.state.image_selected,room_id: this.state.room_list[this.state.room_snap_index].id})
}else{ }else{
this.props.navigation.navigate('WaterMeter',{image: this.state.image_selected, image_preview: this.state.image_preview, room_id: this.state.room_list[this.state.room_snap_index].id}) this.props.navigation.navigate('WaterMeter',{image: this.state.image_selected,room_id: this.state.room_list[this.state.room_snap_index].id})
} }
}) })
} }
@ -113,7 +104,7 @@ export default class Meter extends Component {
_keyExtractor = (item, index) => 'meter_room_'+index; _keyExtractor = (item, index) => 'meter_room_'+index;
_renderItem = ({item}) => ( _renderItem = ({item}) => (
<LinearGradient colors={['#4BAF3B', '#0E5E29']} style={{ borderColor: 'white', borderRadius: 5, height: 120,paddingBottom:10, justifyContent:'space-between'}}> <LinearGradient colors={['#4BAF3B', '#0E5E29']} style={{ height: 120, borderColor: 'white', borderRadius: 5, height: 120,paddingBottom:10, justifyContent:'space-between'}}>
<View style={{ justifyContent: 'center',padding:16 }}> <View style={{ justifyContent: 'center',padding:16 }}>
<Text style={{ color: 'white', fontSize: 16 }}>{item.name}</Text> <Text style={{ color: 'white', fontSize: 16 }}>{item.name}</Text>
<Text style={{ color: 'white', fontSize: 16 }}>{item.project_name}</Text> <Text style={{ color: 'white', fontSize: 16 }}>{item.project_name}</Text>
@ -138,7 +129,7 @@ export default class Meter extends Component {
<View style={{paddingHorizontal:16,height: 96,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}> <View style={{paddingHorizontal:16,height: 96,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}>
<View style={{flex:1,flexDirection:'row'}}> <View style={{flex:1,flexDirection:'row'}}>
<View style={{height: 96,justifyContent:'center',marginRight:16}}> <View style={{height: 96,justifyContent:'center',marginRight:16}}>
<Image source={{uri:item.image_meter}} style={{height: 64,width: 64,}} resizeMode={'contain'}/> <Image source={{uri:item.media.url}} style={{height: 64,width: 64,}} resizeMode={'contain'}/>
</View> </View>
<View style={{flex:1,justifyContent:'center'}}> <View style={{flex:1,justifyContent:'center'}}>
<View style={styles.viewTextFlatlist}> <View style={styles.viewTextFlatlist}>

View File

@ -6,18 +6,15 @@ import PopupMeter from './PopupMeter';
import ImagePicker from 'react-native-image-crop-picker' import ImagePicker from 'react-native-image-crop-picker'
import {postMeter, postMeterImage} from '../../api/UserApi'; import {postMeter, postMeterImage} from '../../api/UserApi';
import moment from 'moment'; import moment from 'moment';
import { t } from '../../utils/i18n'
export default class PEAMeter extends Component { export default class PEAMeter extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
numberMeter: '', numberMeter: '0',
isLoading: false,
isVisible: false, isVisible: false,
image: this.props.navigation.getParam('image','no-image'), image: this.props.navigation.getParam('image','no-image'),
image_send: {}, image_send: {},
image_preview: this.props.navigation.getParam('image_preview', 'no-image'),
room_id: this.props.navigation.getParam('room_id','no-id'), room_id: this.props.navigation.getParam('room_id','no-id'),
isConfirm: false isConfirm: false
}; };
@ -27,24 +24,22 @@ export default class PEAMeter extends Component {
this.onOK = this.onOK.bind(this) this.onOK = this.onOK.bind(this)
this.onPopup = this.onPopup.bind(this) this.onPopup = this.onPopup.bind(this)
this.onTakeCamera = this.onTakeCamera.bind(this) this.onTakeCamera = this.onTakeCamera.bind(this)
//this.postImageToOCR = this.postImageToOCR.bind(this) this.postImageToOCR = this.postImageToOCR.bind(this)
} }
componentDidMount = () => { componentDidMount = () => {
this.setState({ this.setState({
image_send: { image_send: {
uri: this.state.image.uri, uri: this.state.image.uri,
// type: this.state.image.mime, type: this.state.image.mime,
// name: `image_meter_${moment()}.jpg`, name: `image_meter_${moment()}.jpg`,
width: this.state.image.width,
height: this.state.image.height
} }
}/*,() => { },() => {
//this.postImageToOCR() this.postImageToOCR()
}*/) })
}; };
/*postImageToOCR(){ postImageToOCR(){
let param = { let param = {
image: this.state.image_send image: this.state.image_send
} }
@ -57,7 +52,7 @@ export default class PEAMeter extends Component {
}) })
} }
}) })
}*/ }
onTextChanged(text){ onTextChanged(text){
this.setState({ this.setState({
@ -80,8 +75,7 @@ export default class PEAMeter extends Component {
cropping: true, cropping: true,
width: 300, width: 300,
height: 100, height: 100,
includeExif: true, includeExif: true
includeBase64: true
}).then(image => { }).then(image => {
console.log('received image', image) console.log('received image', image)
let image_meter = { let image_meter = {
@ -89,19 +83,18 @@ export default class PEAMeter extends Component {
type: image.mime, type: image.mime,
name: 'image_meter.jpg', name: 'image_meter.jpg',
} }
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
this.setState({ this.setState({
image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime}, image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
images: null, images: null,
}, () => { }, () => {
this.setState({ this.setState({
image: this.state.image_url, image: this.state.image_url,
image_send: image_data image_send: image_meter
}/*,() => { },() => {
this.postImageToOCR() this.postImageToOCR()
}*/) })
}) })
}).catch(e => {}) }).catch(e => Alert.alert('Error',e))
} }
onConfirm(){ onConfirm(){
@ -109,52 +102,20 @@ export default class PEAMeter extends Component {
} }
onOK(){ onOK(){
if (!this.state.isLoading) { let param = {
this.setState({ room_id: this.state.room_id,
isLoading: true, type: 'ค่าไฟ',
isVisible: false cost: 0,
}, () => { amount: parseInt(this.state.numberMeter),
let param = { image: this.state.image_send
room_id: this.state.room_id,
type: 'ค่าไฟ',
cost: 0,
amount: parseInt(this.state.numberMeter),
image: this.state.image_send
}
//send api
postMeter(param)
.then(res => {
console.log('response post meter ------> ',res.data)
if(res.data.success) {
console.log('success >>>>>> ')
Alert.alert(t('save_success'), '', [
{
text: t('ok'),
onPress: () => {
// this.setState({ isLoading: false })
this.props.navigation.goBack()
}
}
])
} else {
console.log('unsuccess >>>>>>')
Alert.alert(t('save_fail_and_try'), res.data.message ? res.data.message : '', [
{
text: 'ok',
onPress: () => {
// this.setState({
// isLoading: false,
// isVisible: false
// })
this.props.navigation.goBack()
}
}
], { cancelable: false })
}
})
.catch(err => this.setState({ isLoading: false }))
})
} }
//send api
postMeter(param)
.then(res => {
console.log('response post meter ------> ',res.data)
this.onPopup()
this.props.navigation.goBack()
})
} }
onPopup(){ onPopup(){
@ -167,9 +128,9 @@ export default class PEAMeter extends Component {
return ( return (
<ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}> <ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}>
<View style={{flex:1}}> <View style={{flex:1}}>
<SaveViewMeter amount={this.state.numberMeter} TypeName={'ไฟฟ้า'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image_preview.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/> <SaveViewMeter amount={this.state.numberMeter} TypeName={'ไฟฟ้า'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/>
</View> </View>
<PopupMeter modalVisible={this.state.isVisible} onOk={!this.state.isLoading ? this.onOK : null} onCancel={this.onPopup}/> <PopupMeter modalVisible={this.state.isVisible} onOk={this.onOK} onCancel={this.onPopup}/>
</ImageBackground> </ImageBackground>
); );
} }

View File

@ -26,7 +26,7 @@ export default class PopupMeter extends Component {
<TouchableOpacity style={{paddingHorizontal:15,}} onPress={() => {this.props.onCancel()}}> <TouchableOpacity style={{paddingHorizontal:15,}} onPress={() => {this.props.onCancel()}}>
<Text style={{color:'#00000040',fontSize: 14,}}>Cancel</Text> <Text style={{color:'#00000040',fontSize: 14,}}>Cancel</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={{paddingHorizontal:15}} onPress={() => {this.props.onOk && this.props.onOk()}}> <TouchableOpacity style={{paddingHorizontal:15}} onPress={() => {this.props.onOk()}}>
<Text style={{color:'#2C7C0B',fontSize: 14,}}>OK</Text> <Text style={{color:'#2C7C0B',fontSize: 14,}}>OK</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>

View File

@ -20,7 +20,7 @@ export default class SaveViewMeter extends Component {
<View style={{justifyContent:'center',alignItems:'center'}}> <View style={{justifyContent:'center',alignItems:'center'}}>
<Image source={{uri:this.props.ImageUri}} resizeMode={'contain'} style={{borderRadius:5,height: 184,width:'100%'}}/> <Image source={{uri:this.props.ImageUri}} resizeMode={'contain'} style={{borderRadius:5,height: 184,width:'100%'}}/>
</View> </View>
<Text style={{color:'black',fontSize:14,textAlign:'center',marginVertical: 16,}}>ายเมอวนท {moment().format('DD/MM/YYYY HH:mm')} .</Text> <Text style={{color:'white',fontSize:14,textAlign:'center',marginVertical: 16,}}>ายเมอวนท {moment().format('DD/MM/YYYY HH:mm')} .</Text>
<TouchableOpacity style={{height: 40,width: '100%',backgroundColor:'#007AFF',justifyContent:'center',alignItems:'center',borderRadius:5,flexDirection:'row'}} <TouchableOpacity style={{height: 40,width: '100%',backgroundColor:'#007AFF',justifyContent:'center',alignItems:'center',borderRadius:5,flexDirection:'row'}}
onPress={this.props.onTakeCamera}> onPress={this.props.onTakeCamera}>
<Icon nane={'ic_outline_camera'} size={22} color={'#FFFFFF'}/> <Icon nane={'ic_outline_camera'} size={22} color={'#FFFFFF'}/>

View File

@ -1,23 +1,20 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { View, Text, Alert } from 'react-native'; import { View, Text } from 'react-native';
import ImageBackground from 'react-native-fast-image' import ImageBackground from 'react-native-fast-image'
import SaveViewMeter from './SaveViewMeter'; import SaveViewMeter from './SaveViewMeter';
import PopupMeter from './PopupMeter'; import PopupMeter from './PopupMeter';
import ImagePicker from 'react-native-image-crop-picker' import ImagePicker from 'react-native-image-crop-picker'
import {postMeter, postMeterImage} from '../../api/UserApi'; import {postMeter, postMeterImage} from '../../api/UserApi';
import moment from 'moment'; import moment from 'moment';
import {t} from "../../utils/i18n";
export default class WaterMeter extends Component { export default class WaterMeter extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
numberMeter: '', numberMeter: '0',
isLoading: false,
isVisible: false, isVisible: false,
image: this.props.navigation.getParam('image','no-image'), image: this.props.navigation.getParam('image','no-image'),
image_send: {}, image_send: {},
image_preview: this.props.navigation.getParam('image_preview', 'no-image'),
room_id: this.props.navigation.getParam('room_id','no-id'), room_id: this.props.navigation.getParam('room_id','no-id'),
isConfirm: false isConfirm: false
}; };
@ -27,23 +24,22 @@ export default class WaterMeter extends Component {
this.onOK = this.onOK.bind(this) this.onOK = this.onOK.bind(this)
this.onPopup = this.onPopup.bind(this) this.onPopup = this.onPopup.bind(this)
this.onTakeCamera = this.onTakeCamera.bind(this) this.onTakeCamera = this.onTakeCamera.bind(this)
//this.postImageToOCR = this.postImageToOCR.bind(this) this.postImageToOCR = this.postImageToOCR.bind(this)
} }
componentDidMount = () => { componentDidMount = () => {
this.setState({ this.setState({
image_send: { image_send: {
uri: this.state.image.uri, uri: this.state.image.uri,
width: this.state.image.width, type: this.state.image.mime,
height: this.state.image.height name: `image_meter_${moment()}.jpg`,
// name: `image_meter_${moment()}.jpg`,
} }
}/*,() => { },() => {
//this.postImageToOCR() this.postImageToOCR()
}*/) })
}; };
/*postImageToOCR(){ postImageToOCR(){
let param = { let param = {
image: this.state.image_send image: this.state.image_send
} }
@ -56,7 +52,7 @@ export default class WaterMeter extends Component {
}) })
} }
}) })
}*/ }
onTextChanged(text){ onTextChanged(text){
this.setState({ this.setState({
@ -79,8 +75,7 @@ export default class WaterMeter extends Component {
cropping: true, cropping: true,
width: 300, width: 300,
height: 100, height: 100,
includeExif: true, includeExif: true
includeBase64: true
}).then(image => { }).then(image => {
console.log('received image', image) console.log('received image', image)
let image_meter = { let image_meter = {
@ -88,70 +83,39 @@ export default class WaterMeter extends Component {
type: image.mime, type: image.mime,
name: 'image_meter.jpg', name: 'image_meter.jpg',
} }
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
this.setState({ this.setState({
image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime}, image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
images: null, images: null,
}, () => { }, () => {
this.setState({ this.setState({
image: this.state.image_url, image: this.state.image_url,
image_send: image_data image_send: image_meter
}/*,() => { },() => {
//this.postImageToOCR() this.postImageToOCR()
}*/) })
}) })
}).catch(e => {}) }).catch(e => Alert.alert('Error',e))
} }
onConfirm(){ onConfirm(){
this.onPopup() this.onPopup()
} }
onOK() { onOK(){
if (!this.state.isLoading) { let param = {
this.setState({ room_id: this.state.room_id,
isLoading: true, type: 'ค่าน้ำ',
isVisible: false cost: 0,
}, () => { amount: parseInt(this.state.numberMeter),
let param = { image: this.state.image_send
room_id: this.state.room_id,
type: 'ค่าน้ำ',
cost: 0,
amount: parseInt(this.state.numberMeter),
image: this.state.image_send
}
//send api
postMeter(param)
.then(res => {
console.log('response post meter ------> ',res.data)
if(res.data.success) {
Alert.alert(t('save_success'), '', [
{
text: t('ok'),
onPress: () => {
this.setState({ isLoading: false })
this.props.navigation.goBack()
}
}
])
} else {
Alert.alert(t('save_fail_and_try'), res.data.message ? res.data.message : '', [
{
text: 'ok',
onPress: () => {
this.setState({
isLoading: false,
isVisible: false
})
}
}
], { cancelable: false })
}
})
.catch(err => this.setState({ isLoading: false }))
})
} }
//send api
postMeter(param)
.then(res => {
console.log('response post meter ------> ',res.data)
this.onPopup()
this.props.navigation.goBack()
})
} }
onPopup(){ onPopup(){
@ -164,9 +128,9 @@ export default class WaterMeter extends Component {
return ( return (
<ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}> <ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}>
<View style={{flex:1,padding:16}}> <View style={{flex:1,padding:16}}>
<SaveViewMeter amount={this.state.numberMeter} TypeName={'น้ำ'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image_preview.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/> <SaveViewMeter amount={this.state.numberMeter} TypeName={'น้ำ'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/>
</View> </View>
<PopupMeter modalVisible={this.state.isVisible} onOk={!this.state.isLoading ? this.onOK : null} onCancel={this.onPopup}/> <PopupMeter modalVisible={this.state.isVisible} onOk={this.onOK} onCancel={this.onPopup}/>
</ImageBackground> </ImageBackground>
); );
} }

View File

@ -1,6 +1,6 @@
import React, { Component, Fragment } from 'react' import React, { Component, Fragment } from 'react'
import { import {
View, ScrollView, Dimensions, TouchableOpacity, StyleSheet, FlatList, RefreshControl, Animated, ActivityIndicator, Platform, Alert, Modal View, ScrollView, Dimensions, TouchableOpacity, StyleSheet, FlatList, RefreshControl, Animated, ActivityIndicator, Alert
} from 'react-native' } from 'react-native'
import Image from 'react-native-fast-image' import Image from 'react-native-fast-image'
import ImageBackground from 'react-native-fast-image' import ImageBackground from 'react-native-fast-image'
@ -11,7 +11,7 @@ import LinearGradient from 'react-native-linear-gradient'
import { BackgroundImage } from '../../components/BackgroundImage' import { BackgroundImage } from '../../components/BackgroundImage'
import Text from '../../components/Text' import Text from '../../components/Text'
import { NavigationEvents } from 'react-navigation' import { NavigationEvents } from 'react-navigation'
import {getNews, getNewsPage, getUserProfile, getNewsByProject, login, registerDevice, setPaymentLater, setFillInMeterLater, checkPaymentMeter} from '../../api/UserApi'; import { getNews, getNewsPage, getUserProfile, getNewsByProject, login } from '../../api/UserApi'
import { bindActionCreators } from 'redux' import { bindActionCreators } from 'redux'
import { import {
appSetDevice, appSetDevice,
@ -27,111 +27,13 @@ import { connect } from 'react-redux'
import moment from 'moment' import moment from 'moment'
import IndicatorLoading from '../../components/IndicatorLoading' import IndicatorLoading from '../../components/IndicatorLoading'
import { loginWithFacebook } from '../../components/FacebookUtils' import { loginWithFacebook } from '../../components/FacebookUtils'
import { signinApple } from '../../components/AppleAuth'
import parseDateLocale from '../../utils/parseDateLocale'
import { from } from 'rxjs' import { from } from 'rxjs'
//import Slideshow from 'react-native-image-slider-show'; //import Slideshow from 'react-native-image-slider-show';
import appleAuth, {
AppleButton,
} from '@invertase/react-native-apple-authentication';
import { t, locale } from '../../utils/i18n' import { t, locale } from '../../utils/i18n'
import messaging from "@react-native-firebase/messaging";
import {store} from '../../redux/store';
const { height, width } = Dimensions.get('window') const { height, width } = Dimensions.get('window')
console.disableYellowBox = true console.disableYellowBox = true
function PopupNotiElectric({isVisible, onPress, onCancel, onPressLater, pending_payment, due_at_payment}) {
return <Modal visible={isVisible} transparent={true} animationType="none" key="popup-noti-electric">
<View style={styles.popupNotiContainer}>
<View style={styles.popupNoti}>
<View style={{width: '100%', alignItems: 'center'}}>
<Icon name='ic_shop_receive' color='#FF9500' size={70} style={{marginBottom: 10, width: '100%', textAlign: 'center'}}/>
<Text style={[{color: '#FF9500', marginBottom: 10, fontSize: 16}, styles.TextFont]}>ณมยอดคางชำระเง</Text>
<View style={styles.costText}>
<Text style={[{fontSize: 25, fontWeight: '500', textAlign: 'center'}, styles.TextFont]}>{pending_payment}</Text>
<Text style={[{color: '#8A8A8F', fontSize: 18, fontWeight: '400', position: 'absolute', right: 15, bottom: 8}, styles.TextFont]}>บาท</Text>
</View>
<Text style={[{color: '#FF9500', marginBottom: 10, textAlign: 'center' , fontSize: 14}, styles.TextFont]}>{t('please_pay_within')} {moment(due_at_payment).add('543', 'y').format('DD/MM/YYYY')}</Text>
<TouchableOpacity onPress={onPress} style={{width: '100%', marginTop: 10}}>
<Badge style={styles.badgeSubmit}>
<Text style={[{color: 'white', paddingVertical: 10, fontSize: 16}, styles.TextFont]}>ชำระเงนตอนน</Text>
</Badge>
</TouchableOpacity>
<TouchableOpacity onPress={onPressLater} style={{width: '100%'}}>
<Badge style={[styles.badgeCancel, {paddingTop: 5}]}>
<Text style={[{color: 'rgba(0, 0, 0, 0.5)', fontSize: 16}, styles.TextFont]}>ภายหล</Text>
</Badge>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
}
function PopupOverDue({isVisible, onPress, onCancel, onPressLater, pending_payment}) {
return <Modal visible={isVisible} transparent={true} animationType="none">
<View style={styles.popupNotiContainer}>
<View style={styles.popupNoti}>
<View style={{width: '100%', alignItems: 'center', position: 'relative'}}>
<Icon name='ic_shop_receive' color='#FF2D55' size={70} style={{marginBottom: 10}}/>
<TouchableOpacity onPress={onPressLater} style={{position: 'absolute', right: 0, top: -10}}>
<Text style={[{color: 'rgba(0, 0, 0, 0.5)', fontSize: 20}, styles.TextFont]}>{t('close')}</Text>
</TouchableOpacity>
<Text style={[{color: '#FF2D55', marginBottom: 10, fontSize: 16}, styles.TextFont]}>หนางชำระเกนกำหนด</Text>
<View style={styles.costText}>
<Text style={[{fontSize: 25, fontWeight: '500', textAlign: 'center'}, styles.TextFont]}>{pending_payment}</Text>
<Text style={[{color: '#8A8A8F', fontSize: 18, fontWeight: '400', position: 'absolute', right: 15, bottom: 8}, styles.TextFont]}>บาท</Text>
</View>
<Text style={[{color: '#FF2D55', fontSize: 14, textAlign: 'center'}, styles.TextFont]}>ณมหนางชำระเกนกำหนดแล</Text>
{/*<Text style={[{color: '#FF2D55', fontSize: 14, textAlign: 'center'}, styles.TextFont]}>กรุณาดำเนินการชำระหนี้ตอนนี้</Text>*/}
<Text style={[{color: '#FF2D55', marginBottom: 15, fontSize: 14, textAlign: 'center'}, styles.TextFont]}>กรณาตดตอเจาหนาท</Text>
<TouchableOpacity onPress={onPress} style={{width: '100%'}}>
<Badge style={styles.badgeSubmit}>
<Text style={[{color: 'white', paddingVertical: 10, fontSize: 16}, styles.TextFont]}>{t('ok')}</Text>
</Badge>
</TouchableOpacity>
{/* <TouchableOpacity onPress={onPressLater}>
<Badge style={[styles.badgeCancel, {paddingTop: 5}]}>
<Text style={[{color: 'rgba(0, 0, 0, 0.5)', fontSize: 16}, styles.TextFont]}>ภายหล</Text>
</Badge>
</TouchableOpacity>*/}
</View>
</View>
</View>
</Modal>
}
function PopupNotiFillInMeter({isVisible, onPress, onCancel, onPressLater, notified_meter_at}) {
return <Modal visible={isVisible} transparent={true} animationType="none" key="popup-noti-meter">
<View style={styles.popupNotiContainer}>
<View style={[styles.popupNoti, {paddingHorizontal: 15}]}>
<View style={{width: '100%', alignItems: 'center'}}>
{/*<Icon name='ic_shop_receive' color='#00420A' size={60} style={{marginBottom: 10}}/>*/}
<Image source={require('../../../assets/images/meter_noti_image.png')} style={{width: 70, height: 70 }} resizeMode={'contain'}/>
<Text style={[{color: '#00420A', marginVertical: 5, fontSize: 16}, styles.TextFont]}>กรณาแนบรปและกรอกเลขมเตอรำไฟ</Text>
<Text style={[{color: '#00420A', marginVertical: 5, fontSize: 13, textAlign: 'center'}, styles.TextFont]}>ภายในวนท {notified_meter_at}</Text>
<Text style={[{color: '#00420A', marginVertical: 5, fontSize: 13, textAlign: 'center', marginBottom: 15}, styles.TextFont]}>ขออภยหากลกคาไดงขอมลเรยบรอยแล</Text>
<TouchableOpacity onPress={onPress} style={{width: '100%'}}>
<Badge style={styles.badgeSubmit}>
<Text style={[{color: 'white', paddingVertical: 10, fontSize: 16}, styles.TextFont]}>กรอกขอม</Text>
</Badge>
</TouchableOpacity>
<TouchableOpacity onPress={onPressLater}>
<Badge style={[styles.badgeCancel, {paddingTop: 5}]}>
<Text style={[{color: 'rgba(0, 0, 0, 0.5)', fontSize: 16}, styles.TextFont]}>ภายหล</Text>
</Badge>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
}
class NewsScreen extends Component { class NewsScreen extends Component {
constructor (props) { constructor (props) {
super(props) super(props)
@ -157,7 +59,7 @@ class NewsScreen extends Component {
is_new: false is_new: false
}], }],
due_at: '', due_at: '',
pending_payment: 0, pending_payment: '',
noti_count: 0, noti_count: 0,
isFirstTime: true, isFirstTime: true,
user_point: 0, user_point: 0,
@ -168,20 +70,9 @@ class NewsScreen extends Component {
scrollY: new Animated.Value(0), scrollY: new Animated.Value(0),
loadMore: false, loadMore: false,
loadPage: 1, loadPage: 1,
last_page: 1,
isLoadmore: false, isLoadmore: false,
fb_is_link: false, fb_is_link: false,
email: '', email: '',
visibleNotiElectric: false,
visibleNotiOverDue: false,
visibleNotiMeter: false,
payment_id: null,
is_notified_electric: false,
is_notified_before_due:false,
is_notified_overdue: false,
is_notified_meter: false,
notified_meter_at: moment().format('DD MMM YYYY'),
due_at_payment: moment().format('DD/MM/YYYY')
} }
this._onCarouselScroll = this._onCarouselScroll.bind(this) this._onCarouselScroll = this._onCarouselScroll.bind(this)
@ -189,51 +80,18 @@ class NewsScreen extends Component {
} }
componentDidMount () { componentDidMount () {
// this.initData() this.initData()
// this.checkNotifiedPopup()
}
checkNotifiedPopup = () => {
if (this.props.user) {
checkPaymentMeter()
.then(res => {
if (res.data && res.data.success) {
this.setState({
is_notified_electric: res.data.is_notified_electric,
is_notified_meter: res.data.is_notified_meter,
is_notified_overdue: res.data.is_notified_overdue,
notified_meter_at: res.data.notified_meter_at,
payment_id: res.data.payment_id,
pending_payment: res.data.pending_payment != null ? res.data.pending_payment : 0,
due_at_payment: res.data.payment && res.data.payment.due_at ? res.data.payment.due_at : null,
}, () => {
setTimeout(() => {
this.setState({
visibleNotiElectric: this.state.is_notified_overdue ? false : this.state.is_notified_electric && parseInt(this.state.pending_payment) > 0,
visibleNotiMeter: ((this.state.is_notified_electric && parseInt(this.state.pending_payment) > 0) || this.state.is_notified_overdue) === true ? false : this.state.is_notified_meter,
visibleNotiOverDue: this.state.is_notified_overdue,
})
}, 1000)
})
}
})
}
} }
async getUser () { async getUser () {
if (this.props.token != null) { if (this.props.token != null) {
return await getUserProfile() return await getUserProfile()
.then(async res => { .then(res => {
if (res.ok) { if (res.ok) {
console.log("News:: res.data:") console.log("News:: res.data:")
console.log(res.data) console.log(res.data)
console.log('project id >>>> ', res.data.project_id)
this.checkNotifiedPopup()
if(res.data.project_id){
await this.getAllNewsByProject(res.data.project_id)
}
this.setState({ this.setState({
pending_payment: res.data.pending_payment != null ? res.data.pending_payment : 0,
noti_count: res.data.count_noti, noti_count: res.data.count_noti,
user_point: res.data.point_balance, user_point: res.data.point_balance,
user_project_id: res.data.project_id, user_project_id: res.data.project_id,
@ -248,160 +106,101 @@ class NewsScreen extends Component {
} }
}) })
} else { } else {
//setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
isLoading: false isLoading: false
}, () => { }, () => {
this.props.appCleanUser() this.props.appCleanUser()
this.props.appCleanToken() this.props.appCleanToken()
}) })
//}, 600) }, 600)
} }
}) })
}else {
await this.getAllNewsList()
} }
return true return true
} }
async getAllNewsByProject(project_id) {
return getNewsByProject(project_id)
.then(res => {
console.log('res >>>>>>> ', res)
this.setNewsData(res)
})
}
async getAllNewsList () { async getAllNewsList () {
// return getNews() // return getNews()
return getNewsPage(this.state.loadPage) return getNewsPage(this.state.loadPage)
.then(res => { .then(res => {
this.setNewsData(res) if ((res.data.data).length > 5) {
}) var cut = []
} for (let index = 0; index < 5; index++) {
cut.push(res.data.data[index])
}
setNewsData(res) { this.setState({
if (res.data.data && (res.data.data).length > 5) { user: this.props.user,
console.log('data >>>>> ', res) news_head: cut,
var cut = [] new_all: res.data.data,
for (let index = 0; index < 5; index++) { refreshing: false,
cut.push(res.data.data[index]) isLoading: false
} })
} else {
this.setState({ this.setState({
user: this.props.user, news_head: res.data.data,
news_head: cut, new_all: res.data.data,
new_all: res.data.data, refreshing: false,
refreshing: false, isLoading: false
isLoading: false, })
last_page: res.data.last_page }
}) })
} else {
this.setState({
news_head: res.data.data,
new_all: res.data.data,
refreshing: false,
isLoading: false,
last_page: res.data.last_page
})
}
} }
initData () { initData () {
console.log('initData >>> ') this.setState({ isLoading: true })
this.setState({ Promise.all([
isLoading: true, this.getUser(),
loadPage: 1, this.getAllNewsList()
last_page: 1, ])
news_head: [{ .then(() => {
title: 'กำลังโหลดข้อมูลข่าว', let user_id = 0
content: 'กำลังโหลดข้อมูลข่าว', let user_noti_id = 0
date: 'กำลังโหลดข้อมูลข่าว', if (this.props.token != null) {
is_new: false if (this.state.isFirstTime) {
}], this.props.appSetNotification(this.state.noti_count)
new_all: [{ this.props.appSetProjectID(this.state.user_project_id)
title: 'กำลังโหลดข้อมูลข่าว', this.setState({ isFirstTime: false })
content: 'กำลังโหลดข้อมูลข่าว',
date: 'กำลังโหลดข้อมูลข่าว',
is_new: false
}],
}, () => {
Promise.all([
this.getUser(),
// this.getAllNewsList()
])
.then(() => {
let user_id = 0
let user_noti_id = 0
if (this.props.token != null) {
if (this.state.isFirstTime) {
this.props.appSetNotification(this.state.noti_count)
this.props.appSetProjectID(this.state.user_project_id)
this.setState({ isFirstTime: false })
}
} }
}
if (this.props.user && this.props.user.id) { if (this.props.user && this.props.user.id) {
user_id = this.props.user.id user_id = this.props.user.id
user_noti_id = this.props.user.id user_noti_id = this.props.user.id
} else if (this.props.device && this.props.device.customer_id) { } else if (this.props.device && this.props.device.customer_id) {
user_noti_id = this.props.device.customer_id user_noti_id = this.props.device.customer_id
} }
if (this.props.token != null && this.props.user != null) { if (this.props.token != null && this.props.user != null) {
this.setState({ this.setState({
auth: true, auth: true,
}) })
} else { } else {
this.setState({ this.setState({
auth: false auth: false
}) })
} }
this.setState({ isLoading: false }) this.setState({ isLoading: false })
}) })
.catch(() => { .catch(() => {
// console.log('catch ------------------>'); // console.log('catch ------------------>');
// this.setState({isLoading:false}) // this.setState({isLoading:false})
// this.props.appCleanUser() // this.props.appCleanUser()
// this.props.appCleanToken() // this.props.appCleanToken()
setTimeout(() => {
this.setState({
isLoading: false
}, () => {
//this.props.appCleanUser()
//this.props.appCleanToken()
})
}, 600)
// this.initData()
})
})
}
setPermission = async () => {
try {
const enabled = await messaging().hasPermission()
if (!enabled) {
await messaging().requestPermission()
}
} catch (error) {
console.log('error', error)
}
}
initNotification = async () => {
await this.setPermission()
const fcmToken = await messaging().getAPNSToken()
if (fcmToken) {
store.dispatch(appSetPushToken(fcmToken))
const resultSendDevice = await registerDevice(fcmToken)
console.log(' re sult register_device =>', resultSendDevice)
if (resultSendDevice.ok && resultSendDevice.data.success) {
store.dispatch(appSetDevice(resultSendDevice.data.device))
}
}
setTimeout(() => {
this.setState({
isLoading: false
}, () => {
this.props.appCleanUser()
this.props.appCleanToken()
})
}, 600)
this.initData()
})
} }
_onRefresh = () => { _onRefresh = () => {
@ -409,59 +208,21 @@ class NewsScreen extends Component {
refreshing: true, loadPage: 1, loadMore: false refreshing: true, loadPage: 1, loadMore: false
}, () => { }, () => {
this.initData() this.initData()
this.initNotification()
// this.checkNotifiedPopup()
}) })
} }
setPaymentLater = () => {
// setPaymentLater()
// .then(res => {
// if(res && res.data && res.data.success){
this.setState({
visibleNotiElectric: false,
visibleNotiOverDue: false
})
if(this.state.is_notified_meter === true){
this.setState({
visibleNotiMeter: true
}, () => {
setTimeout(() => {
this.forceUpdate()
}, 100)
})
}
// }
// })
}
setFillInMeterLater = () => {
// setFillInMeterLater()
// .then(res => {
// if(res && res.data && res.data.success){
this.setState({
visibleNotiMeter: false
})
// }
// })
}
renderNativeItem = ({ item }) => ( renderNativeItem = ({ item }) => (
<TouchableOpacity style={{ padding: 8, backgroundColor: '#FFFFFF33', height: 85, borderWidth: 1, borderColor: 'white', borderRadius: 5, flexDirection: 'row' }} <TouchableOpacity style={{ padding: 8, backgroundColor: '#FFFFFF33', height: 85, borderWidth: 1, borderColor: 'white', borderRadius: 5, flexDirection: 'row' }}
onPress={() => {this.props.navigation.navigate('NewsDetail', { news_id: item.id })}}> onPress={() => {this.props.navigation.navigate('NewsDetail', { news_id: item.id })}}>
<Image source={item.url ? { uri: item.url } : require('../../../assets/images/default_small.png')} defaultSource={require('../../../assets/images/default_small.png')} style={styles.image_style} resizeMode={'contain'}/> <Image source={{ uri: item.url }} defaultSource={require('../../../assets/images/default_small.png')} style={styles.image_style} resizeMode={'contain'}/>
<View style={{ flex: 1, marginLeft: 8, justifyContent: 'space-between' }}> <View style={{ flex: 1, marginLeft: 8, justifyContent: 'space-between' }}>
<Text style={{ fontSize: 14, color: 'white', width: '100%', }} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text> <Text style={{ fontSize: 14, color: 'white', width: '100%', }} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Icon name="ic_calendar_alt" size={16} color="white"/> <Icon name="ic_calendar_alt" size={16} color="white"/>
<Text style={{ flex: 1, fontSize: 12, color: 'white', marginLeft: 5 }}>{parseDateLocale(item.date)}</Text> <Text style={{ flex: 1, fontSize: 12, color: 'white', marginLeft: 5 }}>{item.date}</Text>
{
item.is_new == true &&
<View style={{ backgroundColor: '#FF9500', height: 20, paddingHorizontal: 10, borderRadius: 10, justifyContent: 'center', alignItems: 'center' }}> <View style={{ backgroundColor: '#FF9500', height: 20, paddingHorizontal: 10, borderRadius: 10, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 12, color: 'white' }}>{item.type == "promotion" ? t('latest_promotion') : t('latest_news')}</Text> <Text style={{ fontSize: 12, color: 'white' }}>{item.type == "promotion" ? t('latest_promotion') : t('latest_news')}</Text>
</View> </View>
}
</View> </View>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
@ -471,21 +232,17 @@ class NewsScreen extends Component {
return <TouchableOpacity onPress={() => { return <TouchableOpacity onPress={() => {
this.props.navigation.navigate('NewsDetail', { news_id: item.id }) this.props.navigation.navigate('NewsDetail', { news_id: item.id })
}}> }}>
<ImageBackground source={item.url ? { uri: item.url } : require('../../../assets/images/default_big.png')} onError={(e) => { this.props.source = require('../../../assets/images/default_big.png') }} style={styles.imgBg}> <ImageBackground source={{ uri: item.url }} onError={(e) => { this.props.source = require('../../../assets/images/default_big.png') }} style={styles.imgBg}>
<LinearGradient colors={['rgba(0, 0, 0, 0)', '#000000']}> <LinearGradient colors={['rgba(0, 0, 0, 0)', '#000000']}>
<View style={{ padding: 15, }}> <View style={{ padding: 15, }}>
{item.is_new == true ? {item.is_new == true ?
<View style={{ backgroundColor: '#FF9500', borderRadius: 10, height: 23, <View style={{ backgroundColor: '#FF9500', borderRadius: 10, height: 20, width: 100, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 10 }}><Text style={{ fontSize: 12, color: 'white' }}>{item.type == "promotion" ? t('latest_promotion') : t('latest_news')} </Text></View>
alignSelf: 'flex-start', alignItems: 'center', justifyContent: 'center', flexWrap: 'nowrap',
paddingHorizontal: 10 }}>
<Text style={{ fontSize: 12, width: '100%', justifyContent: 'center', alignItems: 'center', color: 'white', flexWrap: 'nowrap' }}>{item.type == "promotion" ? t('latest_promotion') : t('latest_news')} </Text>
</View>
: null } : null }
<Text style={styles.textNewsName} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text> <Text style={styles.textNewsName} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text>
<View style={{ flexDirection: 'row', marginTop: 5 }}> <View style={{ flexDirection: 'row', marginTop: 5 }}>
<Icon name="ic_calendar_alt" size={14} color="rgba(255, 255, 255, 0.65)"/> <Icon name="ic_calendar_alt" size={14} color="rgba(255, 255, 255, 0.65)"/>
<Text style={{ color: 'rgba(255, 255, 255, 0.65)', fontSize: 12, marginLeft: 5, marginTop: -1 }}> <Text style={{ color: 'rgba(255, 255, 255, 0.65)', fontSize: 12, marginLeft: 5, marginTop: -1 }}>
{parseDateLocale(item.date)} {item.date}
</Text> </Text>
</View> </View>
</View> </View>
@ -494,11 +251,21 @@ class NewsScreen extends Component {
</TouchableOpacity> </TouchableOpacity>
} }
getDueAt (date) {
let d = moment(date).format('D')
let m = moment(date).format('MM')
let y = parseInt(moment(date).format('Y')) + 543
let new_date = moment().format('DD/MM/Y')
new_date = d + '/' + m + '/' + y
return new_date
}
_onCarouselScroll (e) { _onCarouselScroll (e) {
const scrollX = e.nativeEvent.contentOffset.x const scrollX = e.nativeEvent.contentOffset.x
this.setState({ this.setState({
position: Math.ceil(scrollX / width) position: Math.ceil(scrollX / width)
}) })
// console.log(this.state.position) // console.log(this.state.position)
} }
@ -509,32 +276,41 @@ class NewsScreen extends Component {
} }
loadMoreData = async () => { loadMoreData = async () => {
if(parseInt(this.state.loadPage) < parseInt(this.state.last_page)){ const { loadMore } = this.state
this.setState({ if (loadMore) {
loadMore: true, return
isLoadmore: true,
loadPage: this.state.loadPage + 1
}, () => {
getNewsPage(this.state.loadPage)
.then(res => {
if (res.ok) {
let resData = res.data.data
let news_all = this.state.new_all
let news_arr = news_all.concat(resData)
this.setState({
new_all: news_arr,
refreshing: false,
loadMore: false,
isLoadmore: false,
last_page: res.data.last_page
})
}
})
})
} }
this.setState({ loadMore: true, isLoadmore: true })
let loadpage = this.state.loadPage + 1
/*loading - set loadMore = false when done*/ /*loading - set loadMore = false when done*/
getNewsPage(loadpage)
.then(res => {
if (res.ok) {
let resData = res.data.data
let news_arr = this.state.new_all
resData.forEach(item => {
// console.log('data >>>>>><<<< ',item);
news_arr.push(item)
})
this.setState({
loadPage: loadpage,
new_all: news_arr,
refreshing: false,
loadMore: false,
isLoadmore: false
})
if (resData.length < 10) {
this.setState({
loadMore: true
})
return
}
}
})
} }
_keyExtractorNewHead = (item, index) => 'new_head_' + index _keyExtractorNewHead = (item, index) => 'new_head_' + index
@ -550,19 +326,14 @@ class NewsScreen extends Component {
}}> }}>
<NavigationEvents <NavigationEvents
onDidFocus={() => { onDidFocus={() => {
this.setState({ this.setState({ isLoading: true })
isLoading: true let checkNav = this.props.navigation.getParam('isLogin')
}, () => {
this.initData()
// this.checkNotifiedPopup()
})
/*let checkNav = this.props.navigation.getParam('isLogin')
if (checkNav) { if (checkNav) {
this.props.navigation.setParams({ isLogin: false }) this.props.navigation.setParams({ isLogin: false })
this.initData() this.initData()
} else { } else {
this.setState({ isLoading: false }) this.setState({ isLoading: false })
}*/ }
}} }}
/> />
<BackgroundImage> <BackgroundImage>
@ -576,8 +347,7 @@ class NewsScreen extends Component {
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
scrollEventThrottle={16} scrollEventThrottle={16}
onScroll={Animated.event( onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }], [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
{useNativeDriver: false}
)} )}
onMomentumScrollEnd={({ nativeEvent }) => { onMomentumScrollEnd={({ nativeEvent }) => {
if (this.isCloseToBottom(nativeEvent)) { if (this.isCloseToBottom(nativeEvent)) {
@ -596,11 +366,7 @@ class NewsScreen extends Component {
onScroll={this._onCarouselScroll} onScroll={this._onCarouselScroll}
/> />
<View style={{ position: 'absolute', bottom: 10, width: '100%', justifyContent: 'center', flexDirection: 'row' }}> <View style={{ position: 'absolute', bottom: 10, width: '100%', justifyContent: 'center', flexDirection: 'row' }}>
{ {(this.state.news_head).map((item, i) => <View key={'news_heade_' + i} style={[{ width: 10, height: 10, borderRadius: 5, backgroundColor: this.state.position == i ? '#269A21' : 'rgba(255,255,255,0.3)', marginHorizontal: 4 }]}></View>)}
this.state.news_head ?
(this.state.news_head).map((item, i) => <View key={'news_heade_' + i} style={[{ width: 10, height: 10, borderRadius: 5, backgroundColor: this.state.position == i ? '#269A21' : 'rgba(255,255,255,0.3)', marginHorizontal: 4 }]}></View>)
: <View></View>
}
</View> </View>
</View> </View>
{this.state.auth !== null && {this.state.auth !== null &&
@ -611,9 +377,9 @@ class NewsScreen extends Component {
<View style={{ flex: 1, alignItems: 'center', padding: 10 }}> <View style={{ flex: 1, alignItems: 'center', padding: 10 }}>
<View> <View>
<Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('for_csa_customer')}</Text> <Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('for_csa_customer')}</Text>
<Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('login')} {t('to_view_outstanding_balance')}</Text> <Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('create_account')} {t('to_view_outstanding_balance')}</Text>
</View> </View>
{/*<TouchableOpacity onPress={() => { <TouchableOpacity onPress={() => {
// this.props.navigation.navigate('Register') // this.props.navigation.navigate('Register')
this.props.navigation.navigate('Terms') this.props.navigation.navigate('Terms')
}}> }}>
@ -622,8 +388,8 @@ class NewsScreen extends Component {
<Text style={{ fontSize: 16, color: 'white', padding: 5, textAlign: 'center' }}>{t('create_account')}</Text> <Text style={{ fontSize: 16, color: 'white', padding: 5, textAlign: 'center' }}>{t('create_account')}</Text>
</Badge> </Badge>
</View> </View>
</TouchableOpacity>*/} </TouchableOpacity>
{/* <Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text> */} <Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text>
<TouchableOpacity onPress={() => { this.props.navigation.navigate('Login') }}> <TouchableOpacity onPress={() => { this.props.navigation.navigate('Login') }}>
<View> <View>
<Badge style={{ backgroundColor: '#145EB3', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', marginTop: 10, height: null, width: 150 }}> <Badge style={{ backgroundColor: '#145EB3', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', marginTop: 10, height: null, width: 150 }}>
@ -631,26 +397,10 @@ class NewsScreen extends Component {
</Badge> </Badge>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
{Platform.OS == 'ios' ? <Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text> : null}
{Platform.OS == 'ios' ? <View>
<AppleButton
buttonStyle={AppleButton.Style.WHITE}
buttonType={AppleButton.Type.SIGN_IN}
style={{
width: 150,
height: 45,
marginTop: 10,
}}
onPress={ () => {signinApple(() => {
this.initData()
})
}}
/>
</View> : null}
<Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text> <Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text>
<TouchableOpacity onPress={() => { <TouchableOpacity onPress={() => {
loginWithFacebook(() => { loginWithFacebook(() => {
this.initData() this.initData()
}) })
@ -658,7 +408,7 @@ class NewsScreen extends Component {
loginWithFacebook(() => { loginWithFacebook(() => {
this.initData() this.initData()
}) })
}else }else{
Alert.alert( Alert.alert(
"", "",
"อิเมล์ "+this.state.email+" ยังไม่ได้ลงทะเบียนในระบบ กรุณาสมัครสมาชิก", "อิเมล์ "+this.state.email+" ยังไม่ได้ลงทะเบียนในระบบ กรุณาสมัครสมาชิก",
@ -685,7 +435,7 @@ class NewsScreen extends Component {
<View style={{ padding: 5 }}> <View style={{ padding: 5 }}>
<View style={[styles.row, { alignItems: 'stretch' }]}> <View style={[styles.row, { alignItems: 'stretch' }]}>
<View style={styles.custom_card}> <View style={styles.custom_card}>
<Card style={{ borderRadius: 5, backgroundColor: '#00420A', borderColor: 'rbga(0,0,0,0)', flex: 1 }}> <Card style={{ borderRadius: 5, backgroundColor: '#00420A', borderColor: 'rbga(0,0,0,0)' }}>
<BackgroundImage_RegisterForm> <BackgroundImage_RegisterForm>
<View style={{ flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 10, minHeight: 177 }}> <View style={{ flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 10, minHeight: 177 }}>
<View style={{ justifyContent: 'center', alignItems: 'center' }}> <View style={{ justifyContent: 'center', alignItems: 'center' }}>
@ -697,7 +447,7 @@ class NewsScreen extends Component {
<Text style={{ color: 'white', fontSize: 28 }}>{this.state.isBilling ? this.state.pending_payment : 'N/A'}</Text> <Text style={{ color: 'white', fontSize: 28 }}>{this.state.isBilling ? this.state.pending_payment : 'N/A'}</Text>
{/*<Text style={{ color: 'white', fontSize: 12 }}>{parseFloat(this.state.pending_payment) > 0 ?'โปรดชำระก่อนวันที่':'ยังไม่มียอดค้างชำระ'}</Text>*/} {/*<Text style={{ color: 'white', fontSize: 12 }}>{parseFloat(this.state.pending_payment) > 0 ?'โปรดชำระก่อนวันที่':'ยังไม่มียอดค้างชำระ'}</Text>*/}
<Text style={{ color: 'white', fontSize: 12, textAlign: 'center' }}>{parseFloat(this.state.pending_payment) > 0 ? t('to_view_outstanding_balance') : t('no_outstanding_balance_yet')}</Text> <Text style={{ color: 'white', fontSize: 12, textAlign: 'center' }}>{parseFloat(this.state.pending_payment) > 0 ? t('to_view_outstanding_balance') : t('no_outstanding_balance_yet')}</Text>
{this.state.due_at !== '' && <Text style={{ color: 'white', fontSize: 12 }}>{parseFloat(this.state.pending_payment) > 0 && this.state.due_at !== '' ? this.state.due_at : ''} </Text>} {this.state.due_at !== '' && <Text style={{ color: 'white', fontSize: 12 }}>{parseFloat(this.state.pending_payment) > 0 && this.state.due_at !== '' ? this.getDueAt(this.state.due_at) : ''} </Text>}
</View> </View>
<TouchableOpacity disabled={!this.state.isBilling} onPress={() => {this.props.navigation.navigate('Bill')}}> <TouchableOpacity disabled={!this.state.isBilling} onPress={() => {this.props.navigation.navigate('Bill')}}>
{/*<Badge style={{ backgroundColor: this.state.isBilling ? '#145EB3' : 'gray', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent:'center' }}><Text style={{ fontSize: 12, color: 'white' }}>ดูเพิ่มเติม</Text></Badge>*/} {/*<Badge style={{ backgroundColor: this.state.isBilling ? '#145EB3' : 'gray', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent:'center' }}><Text style={{ fontSize: 12, color: 'white' }}>ดูเพิ่มเติม</Text></Badge>*/}
@ -707,7 +457,7 @@ class NewsScreen extends Component {
</BackgroundImage_RegisterForm> </BackgroundImage_RegisterForm>
</Card> </Card>
</View> </View>
<View style={[styles.custom_card]}> <View style={[styles.custom_card, { paddingLeft: 5 }]}>
<Card title='' style={{ borderRadius: 5, backgroundColor: '#003114', borderColor: 'rbga(0,0,0,0)', flex: 1 }}> <Card title='' style={{ borderRadius: 5, backgroundColor: '#003114', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
<BackgroundImage_RegisterForm> <BackgroundImage_RegisterForm>
<View style={{ <View style={{
@ -721,14 +471,12 @@ class NewsScreen extends Component {
<Icon name='ic_star' color='white' size={24}/> <Icon name='ic_star' color='white' size={24}/>
{/*<Text style={{ color: 'white', fontSize: 14, marginTop:5 }}>คะแนนสะสม</Text>*/} {/*<Text style={{ color: 'white', fontSize: 14, marginTop:5 }}>คะแนนสะสม</Text>*/}
<Text style={{ color: 'white', fontSize: 14, marginTop: 5 }}>{t('view_points')}</Text> <Text style={{ color: 'white', fontSize: 14, marginTop: 5 }}>{t('view_points')}</Text>
<Text style={{ color: 'white', fontSize: 28 }}>{parseFloat(this.state.user_point).toLocaleString()}</Text> <Text style={{ color: 'white', fontSize: 28 }}>{this.state.user_point}</Text>
{/*<Text style={{ color: 'white', fontSize: 18 }}>พอยต์</Text>*/} {/*<Text style={{ color: 'white', fontSize: 18 }}>พอยต์</Text>*/}
<Text style={{ color: 'white', fontSize: 14 }}>{t('point')}</Text> <Text style={{ color: 'white', fontSize: 14 }}>{t('point')}</Text>
<TouchableOpacity style={{ marginTop: 5 }} <TouchableOpacity style={{ marginTop: 5 }} disabled={true} onPress={() => {}}>
onPress={() => {this.props.navigation.navigate('Redeem')}}> {/*<Badge style={{ backgroundColor: 'gray', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent:'center' }}><Text style={{ fontSize: 12, color: 'white' }}>แลกคะแนน</Text></Badge>*/}
<Badge style={{ backgroundColor: '#145EB3', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent: 'center' }}> <Badge style={{ backgroundColor: 'gray', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent: 'center' }}><Text style={{ fontSize: 12, color: 'white' }}>{t('redeem')}</Text></Badge>
<Text style={{ fontSize: 12, color: 'white' }}>{t('redeem')}</Text>
</Badge>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</BackgroundImage_RegisterForm> </BackgroundImage_RegisterForm>
@ -736,54 +484,55 @@ class NewsScreen extends Component {
</View> </View>
</View> </View>
<View style={[styles.row, { flexWrap: 'wrap', alignItems: 'stretch' }]}> <View style={[styles.row, { flexWrap: 'wrap', alignItems: 'stretch' }]}>
<View style={[styles.custom_card]}> {this.state.isMeter ?
<TouchableOpacity disabled={false} onPress={() => { <View style={[styles.custom_card]}>
this.props.navigation.navigate('Meter') <TouchableOpacity disabled={false} onPress={() => {
}} style={{ flex: 1 }}> this.props.navigation.navigate('Meter')
<Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}> }} style={{ flex: 1 }}>
<View style={{ <Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
flex: 1, <View style={{
flexDirection: 'column', flex: 1,
alignItems: 'center', flexDirection: 'column',
padding: 10, alignItems: 'center',
justifyContent: 'center' padding: 10,
}}> justifyContent: 'center'
<View style={{ alignItems: 'center' }}> }}>
<Icon name='ic_meter' color='white' size={24}/> <View style={{ alignItems: 'center' }}>
<Text style={{ color: 'white', fontSize: 14, textAlign: 'center', marginTop: 5 }}> {t('smart_meter')} </Text> <Icon name='ic_meter' color='white' size={24}/>
<Text style={{ color: 'white', fontSize: 14, textAlign: 'center', marginTop: 5 }}> {t('smart_meter')} </Text>
</View>
</View> </View>
</View> </Card>
</Card> </TouchableOpacity>
</TouchableOpacity> </View>
</View> : null}
<View style={[styles.custom_card]}> {this.state.isShipping ?
<TouchableOpacity disabled={false} onPress={() => { <View style={[styles.custom_card]}>
this.props.navigation.navigate('Object',{ <TouchableOpacity disabled={false} onPress={() => {
user:this.props.user this.props.navigation.navigate('Object')
}) }} style={{ flex: 1 }}>
}} style={{ flex: 1 }}> <Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
<Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}> <View style={{
<View style={{ flex: 1,
flex: 1, flexDirection: 'column',
flexDirection: 'column', alignItems: 'center',
alignItems: 'center', padding: 10,
padding: 10, justifyContent: 'center'
justifyContent: 'center' }}>
}}> <View style={{ alignItems: 'center' }}>
<View style={{ alignItems: 'center' }}> <Icon name='ic_cart' color='white' size={24}/>
<Icon name='ic_cart' color='white' size={24}/> <Text style={{ color: 'white', fontSize: 14, textAlign: 'center', marginTop: 5 }}>{t('mail_and_parcel')}</Text>
<Text style={{ color: 'white', fontSize: 14, textAlign: 'center', marginTop: 5 }}>{t('mail_and_parcel')}</Text> </View>
</View> </View>
</View> </Card>
</Card> </TouchableOpacity>
</TouchableOpacity> </View>
</View> : null}
<View style={[styles.custom_card]}> <View style={[styles.custom_card]}>
<TouchableOpacity disabled={false} <TouchableOpacity disabled={false}
/*onPress={() => { this.props.navigation.navigate('RepairService',{ onPress={() => { this.props.navigation.navigate('RepairService',{
user:this.props.user user:this.props.user
}) }}*/ }) }}
onPress={() => { this.props.navigation.navigate('Repair')}}
style={{ flex: 1 }}> style={{ flex: 1 }}>
<Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}> <Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
<View style={{ <View style={{
@ -834,59 +583,21 @@ class NewsScreen extends Component {
data={this.state.new_all} data={this.state.new_all}
renderItem={this.renderNativeItem} renderItem={this.renderNativeItem}
keyExtractor={this._keyExtractorNewAll} keyExtractor={this._keyExtractorNewAll}
// onEndReachedThreshold={0.01}
// onEndReached={this.loadMoreData.bind(this)}
ItemSeparatorComponent={() => { ItemSeparatorComponent={() => {
return <View style={{ width: '100%', height: 8 }}></View> return <View style={{ width: '100%', height: 8 }}></View>
}} }}
ListFooterComponent={() => { ListFooterComponent={() => {
if (!this.state.isLoadmore) return null if (!this.state.isLoadmore) return null
return (<ActivityIndicator return (<View style={{ padding: 16, flexDirection: 'row', borderRadius: 10, justifyContent: 'center', alignItems: 'center' }}>
size="large" <ActivityIndicator size="small" color="black"/>
color={'white'} <Text style={{ fontSize: 12, marginLeft: 10, color: 'black' }}>Loading...</Text>
/>) </View>)
}} }}
/> />
</View> </View>
</ScrollView> </ScrollView>
</BackgroundImage> </BackgroundImage>
<IndicatorLoading loadingVisible={this.state.isLoading}/> <IndicatorLoading loadingVisible={this.state.isLoading}/>
<PopupNotiElectric
isVisible={this.state.visibleNotiElectric}
onCancel={() => this.setState({visibleNotiElectric: false})}
onPressLater={() => this.setPaymentLater()}
pending_payment={this.state.pending_payment}
due_at_payment={this.state.due_at_payment}
onPress={() => this.setState({
visibleNotiElectric: false
}, () => {
this.props.navigation.navigate('Bill')
this.setPaymentLater()
})}/>
<PopupOverDue
isVisible={this.state.visibleNotiOverDue}
onCancel={() => this.setState({visibleNotiOverDue: false})}
onPressLater={() => this.setPaymentLater()}
pending_payment={this.state.pending_payment}
onPress={() => this.setState({
visibleNotiOverDue: false
}, () => {
// this.props.navigation.navigate('Payment', {payment_id: this.state.payment_id})
this.props.navigation.navigate('Bill')
this.setPaymentLater()
})}/>
<PopupNotiFillInMeter
isVisible={this.state.visibleNotiMeter}
onCancel={() => this.setState({visibleNotiMeter: false})}
onPressLater={() => this.setFillInMeterLater()}
notified_meter_at={this.state.notified_meter_at}
onPress={() => this.setState({
visibleNotiMeter: false
}, () => {
this.props.navigation.navigate('Meter')
this.setFillInMeterLater()
})}
/>
</LinearGradient> </LinearGradient>
) )
} }
@ -938,51 +649,6 @@ const styles = StyleSheet.create({
custom_card: { custom_card: {
width: '50%', paddingHorizontal: 5, width: '50%', paddingHorizontal: 5,
// width: '100%' // width: '100%'
},
popupNoti: {
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
marginHorizontal: 50,
paddingVertical: 20,
paddingHorizontal: 30,
maxWidth: 300,
width: '100%'
},
popupNotiContainer: {
backgroundColor: 'rgba(0,0,0,0.6)',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
width: '100%',
height: '100%',
flex: 1
},
costText: {
backgroundColor: '#EFEFF4',
alignItems: 'center',
paddingHorizontal: 20,
paddingVertical: 5,
borderRadius: 5,
width: '100%',
marginBottom: 10
},
badgeCancel: {
backgroundColor: 'white',
alignItems: 'center',
width: '100%'
},
badgeSubmit: {
backgroundColor: '#145EB3',
borderRadius: 5,
marginBottom: 10,
alignItems: 'center',
width: '100%',
height: 'auto'
},
TextFont: {
fontFamily: 'Prompt-Regular',
} }
}) })
@ -990,15 +656,5 @@ const mapDisPatchToProps = state => {
return state.app return state.app
} }
const setUser = dispatch => bindActionCreators({ const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser, appCleanToken, appCleanUser, appSetNotification, appSetProjectID }, dispatch)
appSetToken,
appSetPushToken,
appSetDevice,
appSetUser,
appCleanToken,
appCleanUser,
appSetNotification,
appSetProjectID,
setPaymentLater
}, dispatch)
export default connect(mapDisPatchToProps, setUser)(NewsScreen) export default connect(mapDisPatchToProps, setUser)(NewsScreen)

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import {View, ScrollView, StyleSheet, Linking, Button, TouchableOpacity, Alert, Platform, Modal, ImageBackground} from 'react-native'; import {View, ScrollView, StyleSheet, Linking, Button, TouchableOpacity, Alert} from 'react-native';
import Image from 'react-native-fast-image' import Image from 'react-native-fast-image'
import { WebView } from 'react-native-webview'; import { WebView } from 'react-native-webview';
import { Body, Badge, List, ListItem, Right, Title } from 'native-base' import { Body, Badge, List, ListItem, Right, Title } from 'native-base'
@ -10,12 +10,9 @@ import { BackgroundImage } from '../../components/BackgroundImage'
import { getNewsDetail } from '../../api/UserApi'; import { getNewsDetail } from '../../api/UserApi';
import IndicatorLoading from '../../components/IndicatorLoading'; import IndicatorLoading from '../../components/IndicatorLoading';
import { t } from '../../utils/i18n' import { t } from '../../utils/i18n'
import parseDateLocale from '../../utils/parseDateLocale';
import ImageView from 'react-native-image-view'; import ImageView from 'react-native-image-view';
import {NavigationActions} from "react-navigation"; import {NavigationActions} from "react-navigation";
import Config from 'src/utils/Config'
import Carousel from "../room/RoomDetail";
import {sliderWidth} from "../../styles/SliderEntry.style";
var uri = null; var uri = null;
const injectScript = ` const injectScript = `
(function () { (function () {
@ -44,11 +41,11 @@ export default class NewsDetailScreen extends Component {
}; };
/*componentWillUnmount() { componentWillUnmount() {
if(this.props && this.props.navigation && this.props.navigation.state && this.props.navigation.state.params && this.props.navigation.state.params.getNotification){ if(this.props && this.props.navigation && this.props.navigation.state && this.props.navigation.state.params && this.props.navigation.state.params.getNotification){
this.props.navigation.state.params.getNotification() this.props.navigation.state.params.getNotification()
} }
}*/ }
getNewsData(){ getNewsData(){
this.setState({ this.setState({
@ -57,34 +54,26 @@ export default class NewsDetailScreen extends Component {
getNewsDetail(this.state.news_id) getNewsDetail(this.state.news_id)
.then(res => { .then(res => {
if(res.ok){ if(res.ok){
if(res.data.data){ this.setState({
this.setState({ isLoading: false,
isLoading: false, news_detail: res.data.data
news_detail: res.data.data })
})
}else {
console.log('ถูกยกเลิกเผยแพร่ข่าว')
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว', [{
text: t('ok'),
onPress: () => {
console.log('press')
this.setState({
isLoading: false,
news_detail: {}
})
}
}])
}
}else{ }else{
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว', [{ this.setState({
text: t('ok'), isLoading: false,
onPress: () => { news_detail: [
this.setState({ {
isLoading: false, title: '',
news_detail: {} content: '',
}) style: '',
} is_new: true,
}]) date:'',
url:'',
}
],
})
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว')
// alert('ถูกยกเลิกเผยแพร่ข่าว') // alert('ถูกยกเลิกเผยแพร่ข่าว')
// this.context.router.goBack() // this.context.router.goBack()
@ -93,25 +82,6 @@ export default class NewsDetailScreen extends Component {
} }
render() { render() {
let source_webview = {};
source_webview = {
baseUrl: '',
// uri: `${Config.API_BASE_URL_POWER_CONDO_PROD}/news/${this.state.news_id}/detail`,
uri: `${Config.API_BASE_URL_POWER_CONDO_DEV}/news/${this.state.news_id}/detail`
}
// if(Platform.OS === 'android'){
// source_webview = {
// baseUrl: '',
// uri: `${Config.API_BASE_URL_POWER_CONDO_DEV}/news/${this.state.news_id}/detail`
// }
// }else {
// source_webview = {
// baseUrl: '',
// html: `${this.state.news_detail && this.state.news_detail.style ? this.state.news_detail.style : ''}<div id="content_detail"><meta charset="UTF-8"> ${this.state.news_detail && this.state.news_detail.content ? this.state.news_detail.content : ""} </div>`
// }
// }
return ( return (
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{ <LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1, flex: 1,
@ -119,36 +89,29 @@ export default class NewsDetailScreen extends Component {
height: null height: null
}}> }}>
<BackgroundImage> <BackgroundImage>
{ <ImageView
Platform.OS === 'android' && images={[{source: {uri: this.state.news_detail != null && this.state.news_detail.url }}]}
<ImageView imageIndex={0}
images={[{source: {uri: this.state.news_detail != null && this.state.news_detail.url ? this.state.news_detail.url : '' }}]} isVisible={this.state.isImageViewVisible}
imageIndex={0} animationType={'fade'}
isVisible={this.state.isImageViewVisible} />
animationType={'fade'}
onClose={() => {this.setState({isImageViewVisible: false})}}
/>
}
<View> <View>
<TouchableOpacity onPress={() => {this.setState({isImageViewVisible: true})}}> <TouchableOpacity onPress={() => {this.setState({isImageViewVisible: true})}}>
<Image source={{ uri: this.state.news_detail != null && this.state.news_detail.url ? this.state.news_detail.url : '' }} style={styles.imgBg} /> <Image source={{ uri: this.state.news_detail != null && this.state.news_detail.url }} style={styles.imgBg} />
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View style={{ backgroundColor: 'white', padding: 15 }}> <View style={{ backgroundColor: 'white', padding: 15 }}>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={{ color: '#00420A', fontSize: 16, }}>{this.state.news_detail != null && this.state.news_detail.title}</Text> <Text style={{ color: '#00420A', fontSize: 16, }}>{this.state.news_detail.title}</Text>
</View> </View>
<View style={{ flexDirection: 'row', marginTop: 5 }}> <View style={{ flexDirection: 'row', marginTop: 5 }}>
<View style={{ width: '50%', flexDirection: "row", marginTop: 5 }}> <View style={{ width: '50%', flexDirection: "row", marginTop: 5 }}>
<Icon name="ic_event_note" size={16} color="#00420A" /> <Icon name="ic_event_note" size={16} color="#00420A" />
{ <Text style={{ marginLeft: 5, color: '#00420A', fontSize: 12, }}>{this.state.news_detail.date}</Text>
this.state.news_detail &&
<Text style={{ marginLeft: 5, color: '#00420A', fontSize: 12, }}>{parseDateLocale(this.state.news_detail.date)}</Text>
}
</View> </View>
<View style={{ width: '50%', flexDirection: "row", flex: 1, justifyContent: 'flex-end' }}> <View style={{ width: '50%', flexDirection: "row", flex: 1, justifyContent: 'flex-end' }}>
{this.state.news_detail && this.state.news_detail.is_new == true ? <Badge style={{ backgroundColor: '#FF9500', borderRadius: 50, paddingLeft: 10, paddingTop: 5 }}> {this.state.news_detail.is_new == true ? <Badge style={{ backgroundColor: '#FF9500', borderRadius: 50, paddingLeft: 10, paddingTop: 5 }}>
<Text style={{ fontSize: 12, color: 'white' }}>{this.state.news_detail.type === 'promotion' ? t('latest_promotion') : t('latest_news')} </Text> <Text style={{ fontSize: 12, color: 'white' }}>{t('latest_news')} </Text>
</Badge> : null} </Badge> : null}
</View> </View>
</View> </View>
@ -164,55 +127,26 @@ export default class NewsDetailScreen extends Component {
flex: 1, flex: 1,
}} }}
originWhitelist={['*']} originWhitelist={['*']}
// source={{baseUrl: '', html: `${this.state.news_detail && this.state.news_detail.style ? this.state.news_detail.style : ''}<div id="content_detail"><meta charset="UTF-8"> ${this.state.news_detail && this.state.news_detail.content ? this.state.news_detail.content : ""} </div>` }} source={{ baseUrl: '', html: `${this.state.news_detail.style}<div id="content_detail"><meta charset="UTF-8">`+this.state.news_detail.content+'</div>' }}
source={source_webview}
ref={(ref) => { this.webview = ref; }} ref={(ref) => { this.webview = ref; }}
javaScriptEnabled={true} javaScriptEnabled={true}
domStorageEnabled={true} domStorageEnabled={true}
onMessage={(event) => { // onShouldStartLoadWithRequest={(navState)=>{ //open external browser for android
if(event.nativeEvent.data){ // console.log('onShouldStartLoadWithRequest >>>>>> ',navState);
let data = JSON.parse(event.nativeEvent.data); // Linking.openURL(navState.url)
if(data.video_id){ // return false;
Linking.openURL(`https://youtube.com/embed/${data.video_id}`); // }}
}
}
}}
/*onNavigationStateChange={(event) => { onNavigationStateChange={(event) => {
console.log('onNavigationStateChange >>>>>> ',event); console.log('onNavigationStateChange >>>>>> ',event);
if (event.url.startsWith("http")) { if (event.url.startsWith("http")) {
this.webview.stopLoading(); this.webview.stopLoading();
this.webview.goBack(); this.webview.goBack();
Linking.openURL(event.url); Linking.openURL(event.url);
} }
}}*/ }}
/> />
</BackgroundImage> </BackgroundImage>
{
Platform.OS === 'ios' &&
<Modal animationType="none"
transparent={true}
visible={this.state.isImageViewVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={{flex:1,backgroundColor: 'rgba(0,0,0,.9)', justifyContent: 'center', alignItems: 'center', width: '100%'}}>
<TouchableOpacity style={{height: 80,width: 80, position: 'absolute', zIndex: 1000, right: -25, top: '6%'}}
onPress={() => {this.setState({isImageViewVisible:false})}}
>
<Icon name='ic_add' size={36} color='white' style={{transform:[{rotate:'45deg'}]}}/>
</TouchableOpacity>
<View style={{width: '90%', justifyContent: 'center', height: '100%'}}>
<Image source={{ uri: this.state.news_detail != null && this.state.news_detail.url ? this.state.news_detail.url : '' }}
style={{flex: 1}}
resizeMode={'contain'}
/>
</View>
</View>
</Modal>
}
<IndicatorLoading loadingVisible={this.state.isLoading}/> <IndicatorLoading loadingVisible={this.state.isLoading}/>
</LinearGradient> </LinearGradient>
) )
@ -233,11 +167,5 @@ const styles = StyleSheet.create({
textAlign: 'center', textAlign: 'center',
fontSize: 12 fontSize: 12
},
backgroundImage: {
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
} }
}) })

View File

@ -1,5 +1,5 @@
import React, {Component} from 'react' import React, {Component} from 'react'
import {FlatList, View, TouchableOpacity, RefreshControl, ScrollView, ActivityIndicator, SafeAreaView} from 'react-native' import {FlatList, View, TouchableOpacity, RefreshControl, ScrollView, ActivityIndicator} from 'react-native'
import Image from 'react-native-fast-image' import Image from 'react-native-fast-image'
import {BackgroundImage} from '../../components/BackgroundImage' import {BackgroundImage} from '../../components/BackgroundImage'
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
@ -8,9 +8,8 @@ import { get_notification, news, read_notification} from '../../api/UserApi'
import {bindActionCreators} from 'redux' import {bindActionCreators} from 'redux'
import {appSetNotification} from '../../redux/app/action' import {appSetNotification} from '../../redux/app/action'
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import moment from "moment";
import { t } from '../../utils/i18n'; import { t } from '../../utils/i18n';
import parseDateLocale from '../../utils/parseDateLocale';
import { NavigationEvents } from "react-navigation";
const injectScript = ` const injectScript = `
(function () { (function () {
@ -34,137 +33,9 @@ class NotificationScreen extends Component {
} }
_set_read(item) { _set_read(item) {
switch (item.source_type) { read_notification(item.id).then(res => {
case 'payment_success': console.log('read noti => ', res.data.message)
case 'update_app': })
return false;
default:
read_notification(item.id).then(res => {
this.navigateNotification(item)
})
}
}
getContentId(item) {
let data = item.data;
let dataJson = JSON.parse(data);
if(dataJson.id){
return dataJson.id;
}else {
return null;
}
}
navigateNotification = (item) => {
switch (item.source_type) {
case 'news':
case 'general':
case 'promotion':
this.props.navigation.navigate('NewsDetail', {
news_id: item.source_id,
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
});
break;
case 'parcels':
if(item.parcel_status === 'PENDING'){
this.props.navigation.navigate('ObjectDetail', {
object_id: item.source_id,
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
})
}else {
this.props.navigation.navigate('Object', {
user: this.props.user,
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
})
}
break;
case 'message':
this.props.navigation.navigate('Question', {
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
});
break;
case 'meter':
this.props.navigation.navigate('Meter', {
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
});
break;
case 'invoice':
case 'invoice_overdue':
this.props.navigation.navigate('Payment', {
payment_id: this.getContentId(item),
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
});
break;
case 'repair':
case 'effect_repair':
case 'effect_responsible':
case 'edit_repair':
case 'appointment_repair':
case 'cancel_repair':
case 'success_repair':
case 'renew_appointment':
this.props.navigation.navigate('RepairHistoryDetail', {
repair_id: this.getContentId(item),
type: item.source_type,
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
})
break;
case 'request_contact':
this.props.navigation.navigate('Question', {
getNotification: () => {
this.setState({
page: 1
}, () => {
this.getNotification()
})
}
})
break;
default:
return false;
}
} }
componentDidMount() { componentDidMount() {
@ -196,13 +67,13 @@ class NotificationScreen extends Component {
// console.log('user_noti_id => ', user_noti_id) // console.log('user_noti_id => ', user_noti_id)
if(this.props.token != null){ if(this.props.token != null){
get_notification(user_noti_id, this.state.page).then(res => { get_notification(user_noti_id, 1).then(res => {
if (res.data) { if (res.data) {
this.setState({ this.setState({
new_noti: res.data.data, new_noti: res.data.data,
page: res.data.current_page, page: res.data.current_page,
refreshing: false, refreshing: false,
last_page: res.data.last_page last_page: res.data.last_page
}); });
} }
}) })
@ -259,79 +130,76 @@ class NotificationScreen extends Component {
}); });
} }
getTypeNoti(item) { getTypeNoti(source_type) {
let type = 'ข่าวใหม่'; let type = 'ข่าวใหม่';
switch (item.source_type) { switch (source_type) {
case 'news': case 'news':
case 'general':
type = t('latest_news'); type = t('latest_news');
break; break;
case 'rooms': case 'rooms':
type = t('new_room'); type = t('new_room');
break; break;
case 'parcels':
type = t('new_parcel');
break;
case 'promotion': case 'promotion':
type = t('latest_promotion'); type = t('latest_promotion');
break; break;
case 'message':
type = t('new_message');
break;
case 'invoice':
case 'invoice_overdue':
type = t('bill_payment');
break;
case 'meter':
type = t('meter_noti');
break;
case 'repair':
case 'effect_repair':
case 'effect_responsible':
case 'edit_repair':
case 'appointment_repair':
case 'request_contact':
case 'cancel_repair':
case 'success_repair':
case 'renew_appointment':
type = item.title;
break;
case 'update_app':
type = t('update_app');
break;
case 'payment_success':
type = t('payment_success');
break;
default: default:
type = ''; type = t('latest_news');
break; break;
} }
return type; return type;
} }
getStatusParcel (status) { getDateNoti(date) {
switch (status) { let d = moment(date).format('D')
case 'PENDING': let m = moment(date).format('MM')
return t('waiting_for_pickup'); let y = parseInt(moment(date).format('Y')) + 543
case 'WAIT_PICKUP': let new_month = 'ม.ค.';
return t('awaiting_payment'); let new_date = d + ' ' + new_month + ' ' + y;
case 'RECEIVE': switch (m) {
return t('paid'); case '01':
case 'OTHER': new_month = 'ม.ค.';
return t('other'); break;
case 'ERROR': case '02':
new_month = 'ก.พ.';
break;
case '03':
new_month = 'มี.ค.';
break;
case '04':
new_month = 'เม.ย.';
break;
case '05':
new_month = 'พ.ค.';
break;
case '06':
new_month = 'มิ.ย.';
break;
case '07':
new_month = 'ก.ค.';
break;
case '08':
new_month = 'ส.ค.';
break;
case '09':
new_month = 'ก.ย.';
break;
case '10':
new_month = 'ต.ค.';
break;
case '11':
new_month = 'พ.ย.';
break;
case '12':
new_month = 'ธ.ค.';
break;
default: default:
return t('contact_front_desk'); new_month = 'ม.ค.';
break;
} }
}
displayParcelContent (data) { new_date = d + ' ' + new_month + ' ' + y;
console.log('data >>> ', JSON.parse(data.data)) return new_date;
if(data.parcel_status){
return t('status') + ' : ' + this.getStatusParcel(data.parcel_status)
}
return '';
} }
renderSeparator() { renderSeparator() {
@ -350,57 +218,11 @@ class NotificationScreen extends Component {
if (!this.state.refreshing) return null; if (!this.state.refreshing) return null;
return ( return (
<ActivityIndicator <ActivityIndicator
size="large" style={{ color: '#000' }}
color={'white'}
/> />
); );
} }
getImageCover = (item) => {
if (item.image_path) {
return {uri: item.image_path};
} else {
switch (item.source_type) {
case 'invoice':
return require('../../../assets/images/invoice_icon.png');
case 'invoice_overdue':
return require('../../../assets/images/invoice_overdue_icon.png');
case 'meter':
return require('../../../assets/images/meter_icon.png');
case 'repair':
case 'effect_repair':
case 'effect_responsible':
case 'edit_repair':
case 'request_contact':
case 'cancel_repair':
case 'renew_appointment':
return require('../../../assets/images/repair_noti.png');
case 'appointment_repair':
return require('../../../assets/images/appointment_repair.png');
case 'success_repair':
return require('../../../assets/images/success_repair.png');
default:
return require('../../../assets/images/logo_5.png');
}
}
}
getContent = (item) => {
switch (item.source_type) {
// case 'parcels':
// return this.displayParcelContent(item);
case 'message':
if(item && item.source && item.source.media){
console.log('media >> ', item.source.media)
return <Image style={styles.image} source={item && item.source && item.source.media ? {uri: item.source.media} : require('../../../assets/images/default_small.png')}/>;
}else {
return item.content;
}
default:
return item.content;
}
}
_keyExtractorNewNoti = (item, index) => 'new_noti_'+index _keyExtractorNewNoti = (item, index) => 'new_noti_'+index
render() { render() {
@ -412,30 +234,17 @@ class NotificationScreen extends Component {
resizeMode: 'cover' resizeMode: 'cover'
}}> }}>
<BackgroundImage> <BackgroundImage>
{/*<ScrollView contentContainerStyle={styles.contentContainer} <ScrollView contentContainerStyle={styles.contentContainer}
refreshControl={ refreshControl={
<RefreshControl <RefreshControl
refreshing={this.state.refreshing} refreshing={this.state.refreshing}
onRefresh={this._onRefresh} onRefresh={this._onRefresh}
/> />
} }
>*/} >
<View style={styles.container}> <View style={styles.container}>
<NavigationEvents
onWillFocus={payload => {
this._onRefresh()
}}
/>
<SafeAreaView style={styles.container}>
<FlatList <FlatList
data={this.state.new_noti} data={this.state.new_noti}
refreshing={true}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
/>
}
keyExtractor={this._keyExtractorNewNoti} keyExtractor={this._keyExtractorNewNoti}
ListEmptyComponent={() => ListEmptyComponent={() =>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', margin: 16,padding:16,borderRadius:5,backgroundColor:'white'}}> <View style={{flex: 1, alignItems: 'center', justifyContent: 'center', margin: 16,padding:16,borderRadius:5,backgroundColor:'white'}}>
@ -444,50 +253,48 @@ class NotificationScreen extends Component {
} }
ItemSeparatorComponent={this.renderSeparator} ItemSeparatorComponent={this.renderSeparator}
ListFooterComponent={this.renderFooter.bind(this)} ListFooterComponent={this.renderFooter.bind(this)}
onEndReachedThreshold={0.01}
onEndReached={this.loadMoreNoti.bind(this)}
renderItem={({item, rowData, index}) => renderItem={({item, rowData, index}) =>
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
this._set_read(item) this._set_read(item),
/*this.props.navigation.navigate('NewsDetail', { this.props.navigation.navigate('NewsDetail', {
news_id: item.source_id, news_id: item.source_id,
getNotification: () => this.getNotification() getNotification: () => this.getNotification()
})*/ })
}} }}
key={index} key={index}
delayPressIn={50} delayPressIn={50}
activeOpacity={0.8} activeOpacity={0.8}
style={[ item && item.is_read === false ? styles.isReadFalse : styles.isReadTrue]} style={[item.is_read === false ? styles.isReadFalse : styles.isReadTrue]}
> >
<View style={styles.viewimages} key={index}> <View style={styles.viewimages} key={index}>
<Image style={styles.image} //source={{uri: rowData.image}} <Image style={styles.image} //source={{uri: rowData.image}}
source={this.getImageCover(item)} source={item.url ? {uri: item.url} : require('../../../assets/images/news_test.png')}
defaultSource={require('../../../assets/images/default_small.png')} defaultSource={require('../../../assets/images/default_small.png')}
/> />
<View style={styles.viewcontainer}> <View style={styles.viewcontainer}>
<Text style={{fontSize: 14, color: '#145EB3', marginBottom: 3,}}> <Text style={{fontSize: 14, color: '#145EB3', marginBottom: 3,}}>
{/*{this.getTypeNoti(item.source_type)}*/} {/*{this.getTypeNoti(item.source_type)}*/}
{ {
item && item.source_type && this.getTypeNoti(item) item.source &&
item.source.content_type &&
item.source.content_type == 'general' ? t('latest_news') : t('latest_promotion')
} }
</Text> </Text>
<Text <Text numberOfLines={2} style={{fontSize: 14, color: 'black', marginBottom: 3,}}>
numberOfLines={item.source_type === 'payment_success' ? 0 : 3} {item.title}
style={{fontSize: 14, color: 'black', marginBottom: 3,}}>
{this.getContent(item)}
</Text> </Text>
<Text style={{fontSize: 10, color: 'rgba(0, 0, 0, 0.5)',}}> <Text style={{fontSize: 10, color: 'rgba(0, 0, 0, 0.5)',}}>
{ item && item.notified_at && parseDateLocale(item.notified_at, 'D MMM Y, HH:mm')} {this.getDateNoti(item.notified_at)}
</Text> </Text>
</View> </View>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
} }
/> />
</SafeAreaView> </View>
</View> </ScrollView>
{/*</ScrollView>*/}
</BackgroundImage> </BackgroundImage>
</LinearGradient> </LinearGradient>
) )

View File

@ -4,7 +4,7 @@ import Image from 'react-native-fast-image'
import { FlatList } from 'react-native-gesture-handler'; import { FlatList } from 'react-native-gesture-handler';
import Text from '../../components/Text'; import Text from '../../components/Text';
import Icon from '../../components/Icon' import Icon from '../../components/Icon'
import {getObjectMessage, getRoomParcel} from '../../api/UserApi' import {getObjectMessage} from '../../api/UserApi'
import moment from 'moment'; import moment from 'moment';
import IndicatorLoading from '../../components/IndicatorLoading'; import IndicatorLoading from '../../components/IndicatorLoading';
import { NavigationEvents } from 'react-navigation' import { NavigationEvents } from 'react-navigation'
@ -18,9 +18,7 @@ export default class MessageObject extends Component {
this.state = { this.state = {
isRefreshing: false, isRefreshing: false,
isLoading: true, isLoading: true,
message_list:[], message_list:[]
users:[],
roomIds:[],
}; };
this.statusText = this.statusText.bind(this) this.statusText = this.statusText.bind(this)
@ -29,55 +27,23 @@ export default class MessageObject extends Component {
componentDidMount() { componentDidMount() {
// this.getObject() // this.getObject()
const { navigation } = this.props
const users_state = navigation.getParam('user', 'NO ITEM')
this.state.users = users_state
this.state.roomIds = new Array()
if(users_state){
let rooms = users_state.room ? users_state.room : null
let rooms_list = rooms != null ? rooms.split(",") : []
var arrayLength = rooms_list.length;
let self = this;
for (var i = 0; i < arrayLength; i++) {
getRoomParcel(rooms_list[i])
.then(res => {
if(res.ok){
let result_data = new Array()
result_data = res.data.data
self.state.roomIds.push(result_data.id)
}
})
}
}
} }
getObject(){ getObject(){
this.setState({ this.setState({
isLoading: true isLoading: true
}, () => { })
getObjectMessage() getObjectMessage()
.then(res => { .then(res => {
if(res.ok && res.data){ if(res.ok){
// let parcel_data = new Array() this.setState({
// parcel_data=res.data.data message_list: res.data.data,
// var roomIds = this.state.roomIds
// var filteredArray = new Array()
// if(roomIds.length > 0){
// filteredArray = parcel_data.filter(function(itm){
// return roomIds.indexOf(itm.room_id) > -1;
// })
this.setState({
message_list: res.data.data,
})
}
}) })
}
this.setState({ this.setState({
isLoading: false isLoading: false
}) })
}) })
} }
statusColor(status){ statusColor(status){
@ -103,8 +69,6 @@ export default class MessageObject extends Component {
return t('awaiting_payment') return t('awaiting_payment')
case 'RECEIVE': case 'RECEIVE':
return t('paid') return t('paid')
case 'OTHER':
return t('other')
case 'ERROR': case 'ERROR':
default: default:
return t('contact_front_desk') return t('contact_front_desk')
@ -115,8 +79,8 @@ export default class MessageObject extends Component {
_renderItem = ({item,index}) => ( _renderItem = ({item,index}) => (
<TouchableOpacity onPress={() => {this.props.navigation.navigate('ObjectDetail',{object_id: item.id})}} <TouchableOpacity onPress={() => {this.props.navigation.navigate('ObjectDetail',{object_id: item.id})}}
disabled={item.status == 'PENDING' || item.status === 'wait_customer_code' ? false : true} disabled={item.status == 'PENDING' ? false : true}
style={{opacity:item.status == 'PENDING' ? 0.5 : 1}}> style={{opacity:item.status == 'PENDING' ? 1 : 0.5}}>
<View style={{paddingHorizontal:16,height: 88,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}> <View style={{paddingHorizontal:16,height: 88,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}>
<View style={{flex:1,flexDirection:'row',alignItems:'center'}}> <View style={{flex:1,flexDirection:'row',alignItems:'center'}}>
<View style={{height: 64,width: 64,justifyContent:'center',marginRight:8}}> <View style={{height: 64,width: 64,justifyContent:'center',marginRight:8}}>
@ -125,19 +89,11 @@ export default class MessageObject extends Component {
<View style={{flex:1,justifyContent:'center'}}> <View style={{flex:1,justifyContent:'center'}}>
<View style={{flexDirection:'row',justifyContent:'space-between'}}> <View style={{flexDirection:'row',justifyContent:'space-between'}}>
<Text style={styles.textTitle} numberOfLines={1}>{item.parcel_name}</Text> <Text style={styles.textTitle} numberOfLines={1}>{item.parcel_name}</Text>
<Text> <Text>{item.code != null && t('confirmation_code')}</Text>
{((item.code != null) && (item.status != 'PENDING' && item.status != 'OTHER' && item.status != 'ERROR') ) ? t('confirmation_code'): '' }
</Text>
</View> </View>
<View style={{flexDirection:'row',justifyContent:'space-between'}}> <View style={{flexDirection:'row',justifyContent:'space-between'}}>
<Text style={styles.textTitle} numberOfLines={1}>{t('consignee')} : { item.customer_name ? item.customer_name.length > 22 ? item.customer_name.substring(0, 22) + '...' : item.customer_name : "" }</Text> <Text style={styles.textTitle} numberOfLines={1}>{t('consignee')} : { item.customer ? item.customer.name : "" }</Text>
<Text style={{fontWeight: 'bold',fontSize: 18}}> <Text style={{fontWeight: 'bold',fontSize: 18}}>{item.code != null && item.code}</Text>
{((item.code != null)&&(item.status != 'PENDING' && item.status != 'OTHER' && item.status != 'ERROR')) ? item.code: '' }
</Text>
</View> </View>
<View style={{flexDirection:'row',justifyContent:'space-between'}}> <View style={{flexDirection:'row',justifyContent:'space-between'}}>
<View style={{justifyContent:'center',alignItems:'center',flexDirection:'row'}}> <View style={{justifyContent:'center',alignItems:'center',flexDirection:'row'}}>

View File

@ -24,12 +24,6 @@ export default class MessageObjectDetail extends Component {
this.getObjectDetail() this.getObjectDetail()
} }
componentWillUnmount() {
if(this.props && this.props.navigation && this.props.navigation.state && this.props.navigation.state.params && this.props.navigation.state.params.getNotification){
this.props.navigation.state.params.getNotification()
}
}
getObjectDetail(){ getObjectDetail(){
getObjectMessageByID(this.state.object_id) getObjectMessageByID(this.state.object_id)
.then(res => { .then(res => {
@ -94,7 +88,7 @@ export default class MessageObjectDetail extends Component {
</View> </View>
<View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/> <View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/>
<Text style={styles.textTitle}></Text> <Text style={styles.textTitle}></Text>
<Text style={styles.textBaclk}>{this.state.object_data.customer_name != null && this.state.object_data.customer_name}</Text> <Text style={styles.textBaclk}>{this.state.object_data.customer != null && this.state.object_data.customer.name}</Text>
{/*<View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/> {/*<View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/>
<View style={{flexDirection:'row',justifyContent:'space-between'}}> <View style={{flexDirection:'row',justifyContent:'space-between'}}>
<View> <View>

View File

@ -4,48 +4,33 @@ import Text from '../../components/Text';
import Signature from 'react-native-signature-canvas'; import Signature from 'react-native-signature-canvas';
import {postSignatureImage} from '../../api/UserApi'; import {postSignatureImage} from '../../api/UserApi';
import { t } from '../../utils/i18n'; import { t } from '../../utils/i18n';
import SignaturePad from 'react-native-signature-pad';
export default class SignaturePadScreen extends Component { export default class SignaturePadScreen extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
signature: null, signature: null,
object_id: this.props.navigation.getParam('object_id','no-id'), object_id: this.props.navigation.getParam('object_id','no-id')
keySign: 1
}; };
this.signPad = React.createRef();
} }
handleSignature = signature => { handleSignature = signature => {
if(signature === '' || !signature){ let param = {
Alert.alert(null, t('please_sign'), [{text: 'ok'}]) id: this.state.object_id,
}else { image: signature
let param = {
id: this.state.object_id,
image: signature
}
console.log('-----------> handle signature', signature);
this.setState({ signature },() => {
postSignatureImage(param)
.then(res => {
if(res.ok){
Alert.alert(null,t('save_success'),[{text: t('ok')}])
this.props.navigation.navigate('Object')
}else{
Alert.alert(null,t('save_fail_and_try'),[{text: t('ok')}])
}
})
});
} }
console.log('-----------> handle signature')
}; this.setState({ signature },() => {
postSignatureImage(param)
clearSignPad = () => { .then(res => {
this.setState({ if(res.ok){
keySign: this.state.keySign + 1 Alert.alert(null,'บันทึกสำเร็จ',[{text: t('ok')}])
}) this.props.navigation.navigate('Object')
}else{
Alert.alert(null,'บันทึกไม่สำเร็จ กรุณาลองอีกครั้ง',[{text: t('ok')}])
}
})
});
}; };
render() { render() {
@ -54,7 +39,6 @@ export default class SignaturePadScreen extends Component {
background-color: #269A21; background-color: #269A21;
color: #FFF; color: #FFF;
}`; }`;
return ( return (
<View style={{flex:1}}> <View style={{flex:1}}>
{/*image show signature when save*/} {/*image show signature when save*/}
@ -67,31 +51,18 @@ export default class SignaturePadScreen extends Component {
/> />
) : null} ) : null}
</View>*/} </View>*/}
{/*<Signature*/} <Signature
{/*ref={(c) => { this._signature = c }}*/} ref={(c) => { this._signature = c }}
{/*onOK={this.handleSignature}*/} onOK={this.handleSignature}
{/*descriptionText="ลายเซ็น"*/} descriptionText="ลายเซ็น"
{/*clearText="ล้าง"*/} clearText="ล้าง"
{/*confirmText="บันทึกรูป"*/} confirmText="บันทึกรูป"
{/*webStyle={signatureStyle}*/} webStyle={signatureStyle}
{/*/>*/} />
<View style={{flex: 0.95, marginVertical: 10, marginHorizontal: 15, borderWidth: 1, borderColor: '#e8e8e8'}}> {/*<TouchableOpacity style={{margin:16,height: 40,backgroundColor:'#269A21',justifyContent:'center',alignItems:'center',borderRadius:5}}*/}
<SignaturePad ref={this.signPad} key={this.state.keySign}/> {/*onPress={() => {this._signature.onOK()}}>*/}
</View> {/*<Text style={{color:'white'}}>ยืนยัน</Text>*/}
<View style={{flex: 0.05, flexDirection: 'row', alignItems: 'center', marginBottom: 15, marginHorizontal: 15, justifyContent: 'space-between'}}> {/*</TouchableOpacity>*/}
<TouchableOpacity style={{backgroundColor:'#269A21',borderRadius:5, marginRight: 10, justifyContent: 'center', alignItems: 'center', paddingVertical: 5, paddingHorizontal: 35}}
onPress={() => { this.clearSignPad() }}>
<Text style={{color:'white'}}>{t('clear_signature')}</Text>
</TouchableOpacity>
<Text style={{ opacity: 0.4 }}>{t('signature')}</Text>
<TouchableOpacity style={{backgroundColor:'#269A21',borderRadius:5, marginLeft: 10, justifyContent: 'center', alignItems: 'center', paddingVertical: 5, paddingHorizontal: 20}}
onPress={() => { this.handleSignature(this.signPad.current.state.base64DataUrl) }}>
<Text style={{color:'white'}}>{t('save_signature')}</Text>
</TouchableOpacity>
</View>
</View> </View>
); );
} }

View File

@ -2,12 +2,12 @@ import React, { Component } from 'react'
import { import {
View, View,
ScrollView, ScrollView,
Image,
TouchableOpacity, TouchableOpacity,
Platform, Platform,
KeyboardAvoidingView, KeyboardAvoidingView,
Alert Alert
} from 'react-native' } from 'react-native'
import Image from 'react-native-fast-image'
import Icon from '../../components/Icon' import Icon from '../../components/Icon'
import { Picker } from 'native-base' import { Picker } from 'native-base'
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm' import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
@ -56,42 +56,31 @@ class EditProfileScreen extends Component {
componentDidMount () { componentDidMount () {
const { navigation } = this.props const { navigation } = this.props
const users_state = navigation.getParam('user', 'NO ITEM') const users_state = navigation.getParam('user', 'NO ITEM')
const image = navigation.getParam('image', 'NO ITEM')
console.log("defaultImage",image);
if(image != null ){
this.setState({
image_url :image
})
}
// console.log('check user state ----------- ',users_state) // console.log('check user state ----------- ',users_state)
if(users_state.gender == null || users_state.gender == 'null'){ if(users_state.gender == null || users_state.gender == 'null'){
console.log('NULL'); console.log('NULL');
// this.state.user.show_birth_date = users_state.birth_date;
this.setState({ this.setState({
user: { user: {
gender: 'male', gender: 'male',
name: users_state.name, ...users_state
...users_state,
} }
}) })
}else{ }else{
console.log('NOT NULL'); console.log('NOT NULL');
this.setState({ this.setState({
user: { user: users_state
...users_state,
name: users_state.name
}
}) })
} }
// this.getProjectList() this.getProjectList()
} }
getProjectList() { getProjectList() {
project() project()
.then(res => { .then(res => {
if (res.ok && res.data && res.data.data) { if (res.ok) {
this.setState({ return this.setState({
project_list: res.data.data, project_list: res.data.data,
selected_project: res.data.data[0].id selected_project: res.data.data[0].id
}) })
@ -111,50 +100,23 @@ class EditProfileScreen extends Component {
} }
edit_profile () { edit_profile () {
// console.log('send user data for edit ----------> ',this.state.user);
if(this.state.user.password != null || this.state.user.password != ''){ if(this.state.user.password != null || this.state.user.password != ''){
if(this.state.user.password === this.state.user.confirm_password){ if(this.state.user.password === this.state.user.confirm_password){
edit_profile(this.state.user) edit_profile(this.state.user).then(res => res.data)
.then(res => { .then(res => {
if(res.ok){ this.props.appSetUser(res)
this.props.appSetUser(res.data) this.props.navigation.navigate('Profile')
Alert.alert(t('save_success'), '', [{ })
text: 'ok',
onPress: () => {
this.props.navigation.navigate('Profile')
}
}])
}else {
Alert.alert(t('save_fail_and_try'), '', [{
text: 'ok',
onPress: () => {
this.props.navigation.navigate('Profile')
}
}])
}
})
}else{ }else{
Alert.alert('รหัสผ่านไม่ถูกต้อง',`รหัสผ่านใหม่ไม่ตรงกับรหัสยืนยัน\nกรุณาลองอีกครั้ง`) Alert.alert('รหัสผ่านไม่ถูกต้อง',`รหัสผ่านใหม่ไม่ตรงกับรหัสยืนยัน\nกรุณาลองอีกครั้ง`)
} }
}else{ }else{
edit_profile(this.state.user) edit_profile(this.state.user).then(res => res.data)
.then(res => { .then(res => {
if(res.ok){ this.props.appSetUser(res)
this.props.appSetUser(res.data) this.props.navigation.navigate('Profile')
Alert.alert(t('save_success'), '', [{ })
text: 'ok',
onPress: () => {
this.props.navigation.navigate('Profile')
}
}])
}else {
Alert.alert(t('save_fail_and_try'), '', [{
text: 'ok',
onPress: () => {
this.props.navigation.navigate('Profile')
}
}])
}
})
} }
} }
@ -165,24 +127,21 @@ class EditProfileScreen extends Component {
cropping: true, cropping: true,
includeBase64: true includeBase64: true
}).then(image => { }).then(image => {
console.log('received base64 image', image) // console.log('received base64 image', image)
let image_profile = { let image_profile = {
uri: image.path, uri: image.path,
type: image.mime, type: image.mime,
name: 'image_profile.jpg', name: 'image_profile.jpg',
} }
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
this.setState({ this.setState({
image_url: image_profile, image_url: { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height },
images: null, images: null,
user: { user: {
...this.state.user, ...this.state.user,
profile_image_id: image_profile, profile_image_id: image_profile
profile_image: image_data
} }
}) })
}) }).catch(e => alert(e))
} }
onTakeCamera () { onTakeCamera () {
@ -190,12 +149,9 @@ class EditProfileScreen extends Component {
cropping: true, cropping: true,
width: 300, width: 300,
height: 300, height: 300,
includeExif: true, includeExif: true
includeBase64: true
}).then(image => { }).then(image => {
console.log('received image', image) // console.log('received image', image)
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
let image_profile = { let image_profile = {
uri: image.path, uri: image.path,
type: image.mime, type: image.mime,
@ -206,11 +162,10 @@ class EditProfileScreen extends Component {
images: null, images: null,
user: { user: {
...this.state.user, ...this.state.user,
profile_image_id: image_profile, profile_image_id: image_profile
profile_image: image_data
} }
}) })
}) }).catch(e => alert(e))
} }
render () { render () {
@ -218,65 +173,64 @@ class EditProfileScreen extends Component {
const users = navigation.getParam('user', 'NO ITEM') const users = navigation.getParam('user', 'NO ITEM')
// console.log('users :', users); // console.log('users :', users);
return ( return (
<KeyboardAvoidingView style={{flex:1}} <View style={{ flex: 1, backgroundColor: '#00420A' }}>
keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0} <KeyboardAvoidingView style={{flex:1}} keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0} behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
behavior={Platform.OS == 'ios' ? 'padding' : ''}
ref={(view) => {this.scrollView = view;}}
>
<View style={{ flex: 1, backgroundColor: '#00420A'}}>
<BackgroundImage_RegisterForm> <BackgroundImage_RegisterForm>
<ScrollView style={{ flex: 1, height: '100%' }}> <ScrollView style={{ flexDirection: 'column' }}>
<View style={{ flexDirection: 'column', flex: 1}}> <LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
<View> flex: 1,
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{ width: null,
// flex: 1, height: null,
width: null, resizeMode: 'cover'
height: null, }}>
resizeMode: 'cover' <View style={{ flex: 1, paddingVertical: 20, alignItems: 'center' }}>
}}> <View style={{ width: '30%' }}>
<View style={{ paddingVertical: 20, alignItems: 'center' }}> <TouchableOpacity
<View> style={{
<TouchableOpacity backgroundColor: '#FFF',
style={{ borderRadius: 50, padding: 5,
backgroundColor: '#FFF', justifyContent: 'center',
borderRadius: 50, padding: 5, alignItems: 'center',
justifyContent: 'center', position: 'absolute',
alignItems: 'center', right: '-5%',
position: 'absolute', top: '0%',
right: '0%', zIndex: 1
top: '0%', }}
zIndex: 1 onPress={() => {
}} // this.onImagePick()
onPress={() => { ActionSheet.showActionSheetWithOptions({
// this.onImagePick() options: ACTIONSHEET_BUTTONS,
ActionSheet.showActionSheetWithOptions({ cancelButtonIndex: CANCEL_INDEX,
options: ACTIONSHEET_BUTTONS, // destructiveButtonIndex: DESTRUCTIVE_INDEX,
cancelButtonIndex: CANCEL_INDEX, // tintColor: 'blue'
// destructiveButtonIndex: DESTRUCTIVE_INDEX, },
// tintColor: 'blue' (buttonIndex) => {
}, // console.log('button clicked :', buttonIndex)
(buttonIndex) => { if (buttonIndex == 0) {
// console.log('button clicked :', buttonIndex) this.onTakeCamera()
if (buttonIndex == 0) { } else if (buttonIndex == 1) {
this.onTakeCamera() this.onImagePick()
} else if (buttonIndex == 1) { }
this.onImagePick() })
} }}>
}) <Icon name={'ic_outline_camera'} size={20} color={'#8BC34A'}/>
}}> </TouchableOpacity>
<Icon name={'ic_outline_camera'} size={20} color={'#8BC34A'}/> <Image
</TouchableOpacity> style={{
<Image width: 120,
style={{width: 120, height: 120, borderRadius: 60, borderColor: 'white', borderWidth: 2}} height: 120,
source={{ uri: this.state.image_url && this.state.image_url.uri ? this.state.image_url.uri : ''}} borderRadius: 60,
/> borderColor: 'white',
</View> borderWidth: 2
</View> }}
</LinearGradient> source={this.state.image_url}
/>
</View>
</View> </View>
</LinearGradient>
<View style={{ flexDirection: 'column' , padding: 15, paddingTop: 5, paddingBottom: 0,}}> <View style={{ flex: 1, height: '100%' }}>
<View> <View style={{ flex: 1 }}>
<View style={[styles.form]}>
<Text style={styles.headerTitle}>{t('profile')}</Text> <Text style={styles.headerTitle}>{t('profile')}</Text>
<View style={styles.row}> <View style={styles.row}>
<CustomInput <CustomInput
@ -289,8 +243,7 @@ class EditProfileScreen extends Component {
this.setState({ this.setState({
user: { user: {
...this.state.user, ...this.state.user,
name: text, name: text
name_th: text
} }
}) })
}}/> }}/>
@ -311,9 +264,111 @@ class EditProfileScreen extends Component {
}) })
}}/> }}/>
</View> </View>
{/*<View style={styles.row}> <View style={styles.row}>
<View style={styles.row_grow_first}> <View style={styles.row_grow_first}>
<View <View
style={{
flexGrow: 1,
flexDirection: 'row',
height: 40,
maxHeight: 48,
minHeight: 40,
paddingHorizontal: 5,
backgroundColor: 'rgba(255,255,255,0.3)',
borderRadius: 30
}}
>
<View
style={{
justifyContent: 'center',
paddingLeft: 5,
paddingRight: 5
}}
>
<Text
style={{
color: 'white'
}}
>
{t('gender')}
</Text>
</View>
<View style={{ flex: 1,alignItems: Platform.OS == 'ios' ? 'flex-end' : 'stretch'}}>
<Picker
mode="dropdown"
style={{
height: 40,
color: 'white',
}}
textStyle={{color:'white',fontFamily: 'Prompt-Regular',fontSize:14,textAlign:'right'}}
itemStyle={{color:'white',fontFamily: 'Prompt-Regular',fontSize:14}}
itemTextStyle={{color:'black',fontFamily: 'Prompt-Regular',fontSize:14}}
labelName={t('gender')}
placeholder={t('male') +"/"+ t('female')}
selectedValue={this.state.user.gender}
onValueChange={e => {
// console.log('check gender +++++++++++++++ ',e);
this.setState({
user: {
...this.state.user,
gender: e
}
})
}}
>
<Picker.Item label={t('male')} value="male"/>
<Picker.Item label={t('female')} value="female"/>
</Picker>
</View>
</View>
</View>
</View>
<View style={styles.row}>
<View style={styles.row_grow}>
<CustomDatePicker titleText={t('birth_date')} dateText={moment(this.state.user.birth_date).format('YYYY-MM-DD')} handleDate={(data) => {
this.setState({
user: {
...this.state.user,
birth_date: moment(data).format('YYYY-MM-DD')
}
})}}/>
</View>
</View>
<View style={styles.row}>
<CustomInput
style={styles.register_input}
labelColor={'white'}
placeholderTextColor={'white'}
labelName={t('citizen_id')}
value={this.state.user.tax_id}
onChangeText={(text) => {
this.setState({
user: {
...this.state.user,
tax_id: text
}
})
}}/>
</View>
<View style={styles.row}>
<CustomInput
style={styles.register_input}
labelColor={'white'}
placeholderTextColor={'white'}
labelName={t('phone')}
value={this.state.user.mobile}
onChangeText={(text) => {
this.setState({
user: {
...this.state.user,
mobile: text
}
})
}}/>
</View>
<Text style={styles.headerTitle}>{t('accom_info')}</Text>
<View style={styles.row}>
<View
style={{ style={{
flexGrow: 1, flexGrow: 1,
flexDirection: 'row', flexDirection: 'row',
@ -337,214 +392,114 @@ class EditProfileScreen extends Component {
color: 'white' color: 'white'
}} }}
> >
{t('gender')} {t('project')}
</Text> </Text>
</View> </View>
<View style={{ flex: 1,alignItems: Platform.OS == 'ios' ? 'flex-end' : 'stretch'}}> <View style={{ flex: 1 }}>
<Picker <Picker
mode="dropdown"
style={{ style={{
height: 40,
color: 'white', color: 'white',
height: 40,
}} }}
textStyle={{color:'white',fontFamily: 'Prompt-Regular',fontSize:14,textAlign:'right'}} textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}}
itemStyle={{color:'white',fontFamily: 'Prompt-Regular',fontSize:14}} labelName={t('project')}
itemTextStyle={{color:'black',fontFamily: 'Prompt-Regular',fontSize:14}} placeholder={t('choose_project')}
labelName={t('gender')} selectedValue={this.state.project_item}
placeholder={t('male') +"/"+ t('female')}
selectedValue={this.state.user.gender}
onValueChange={e => { onValueChange={e => {
// console.log('check gender +++++++++++++++ ',e); // console.log('@@@@@@ project selected --------> ',e);
this.setState({ this.setState({
project_name: e.name,
project_item:e,
selected_project: e.id,
user: { user: {
...this.state.user, ...this.state.user,
gender: e project: e.code,
} },
}, () => {
this.getBuildingList()
}) })
}} }}
> >
<Picker.Item label={t('male')} value="male"/> {this.state.project_list.map((item,index) => {
<Picker.Item label={t('female')} value="female"/> return <Picker.Item label={item.name} value={item} key={'project_'+index}/>
})}
</Picker> </Picker>
</View> </View>
</View> </View>
</View> </View>
</View>*/}
{/*<View style={styles.row}>
<View style={styles.row_grow}>
<CustomDatePicker titleText={t('birth_date')} dateText={moment(this.state.user.show_birth_date).add(543, 'years').format('DD-MM-YYYY')} handleDate={(data) => {
this.setState({
user: {
...this.state.user,
birth_date: moment(data).format('YYYY-MM-DD'),
show_birth_date: moment(data).format('YYYY-MM-DD')
}
})}}/>
</View>
</View>*/}
{/*<View style={styles.row}>
<CustomInput
style={styles.register_input}
labelColor={'white'}
placeholderTextColor={'white'}
labelName={t('citizen_id')}
value={this.state.user.tax_id}
onChangeText={(text) => {
this.setState({
user: {
...this.state.user,
tax_id: text
}
})
}}/>
</View>*/}
<View style={styles.row}> <View style={styles.row}>
<CustomInput
style={styles.register_input}
labelColor={'white'}
placeholderTextColor={'white'}
labelName={t('phone')}
value={this.state.user.mobile}
onChangeText={(text) => {
this.setState({
user: {
...this.state.user,
mobile: text
}
})
}}/>
</View>
{/*<Text style={styles.headerTitle}>{t('accom_info')}</Text>*/}
{/*<View style={styles.row}>
<View <View
style={{
flexGrow: 1,
flexDirection: 'row',
height: 40,
maxHeight: 48,
minHeight: 40,
paddingHorizontal: 5,
backgroundColor: 'rgba(255,255,255,0.3)',
borderRadius: 30
}}
>
<View
style={{ style={{
justifyContent: 'center', flexGrow: 1,
paddingLeft: 5, flexDirection: 'row',
paddingRight: 5 height: 40,
}} maxHeight: 48,
> minHeight: 40,
<Text paddingHorizontal: 5,
style={{ backgroundColor: 'rgba(255,255,255,0.3)',
color: 'white' borderRadius: 30
}}
>
{t('project')}
</Text>
</View>
<View style={{ flex: 1 }}>
<Picker
style={{
color: 'white',
height: 40,
}}
textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}}
labelName={t('project')}
placeholder={t('choose_project')}
selectedValue={this.state.project_item}
onValueChange={e => {
// console.log('@@@@@@ project selected --------> ',e);
this.setState({
project_name: e.name,
project_item:e,
selected_project: e.id,
user: {
...this.state.user,
project: e.code,
},
}, () => {
this.getBuildingList()
})
}}
>
{this.state.project_list.map((item,index) => {
return <Picker.Item label={item.name} value={item} key={'project_'+index}/>
})}
</Picker>
</View>
</View>
</View>*/}
{/*<View style={styles.row}>
<View
style={{
flexGrow: 1,
flexDirection: 'row',
height: 40,
maxHeight: 48,
minHeight: 40,
paddingHorizontal: 5,
backgroundColor: 'rgba(255,255,255,0.3)',
borderRadius: 30
}}>
<View
style={{
justifyContent: 'center',
paddingLeft: 5,
paddingRight: 5
}}> }}>
<Text <View
style={{ style={{
color: 'white' justifyContent: 'center',
paddingLeft: 5,
paddingRight: 5
}}> }}>
{t('building')} <Text
</Text> style={{
color: 'white'
}}>
{t('building')}
</Text>
</View>
<View style={{ flex: 1 }}>
<Picker
// mode="dropdown"
style={{
color: 'white',
height: 40,
}}
textStyle={{
color: 'white',
fontFamily: 'Prompt-Regular'
}}
textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}}
labelName={t('building')}
placeholder={t('choose_project')}
selectedValue={this.state.user.building != null && this.state.user.building}
onValueChange={e => {
this.setState({
user: {
...this.state.user,
building: e
}
})
}}>
{this.state.building_list.length > 0 && this.state.building_list.map((item,index) => {
return <Picker.Item label={item.room_build} value={item.room_build} key={'building_'+index}/>
})}
</Picker>
</View>
</View> </View>
<View style={{ flex: 1 }}> <View style={styles.row_grow}>
<Picker <CustomInput
// mode="dropdown" style={styles.register_input}
style={{ labelColor={'white'}
color: 'white', placeholderTextColor={'white'}
height: 40, labelName={t('room2')}
}} placeholder={t('room_no')}
textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}} placeholderTextColor={'#FFFFFF40'}
labelName={t('building')} value={this.state.user.room}
placeholder={t('choose_project')} onChangeText={(text) => {
selectedValue={this.state.user.building != null && this.state.user.building}
onValueChange={e => {
this.setState({ this.setState({
user: { user: {
...this.state.user, ...this.state.user,
building: e room: text
} }
}) })
}}> }}/>
{this.state.building_list.map((item,index) => {
return <Picker.Item label={item.room_build} value={item.room_build} key={'building_'+index}/>
})}
</Picker>
</View> </View>
</View> </View>
<View style={styles.row_grow}>
<CustomInput
style={styles.register_input}
labelColor={'white'}
placeholderTextColor={'white'}
labelName={t('room2')}
placeholder={t('room_no')}
placeholderTextColor={'#FFFFFF40'}
value={this.state.user.room}
onChangeText={(text) => {
this.setState({
user: {
...this.state.user,
room: text
}
})
}}/>
</View>
</View>*/}
<Text style={styles.headerTitle}>{t('change_password')}</Text> <Text style={styles.headerTitle}>{t('change_password')}</Text>
<View> <View>
<View style={styles.row}> <View style={styles.row}>
@ -585,14 +540,11 @@ class EditProfileScreen extends Component {
}}/> }}/>
</View> </View>
</View> </View>
</View>
<View>
<View style={styles.buttons}> <View style={styles.buttons}>
<View style={styles.row_grow}> <View style={styles.row_grow}>
<CustomButton style={styles.btn_next_register} title={t('complete')} <CustomButton style={styles.btn_next_register} title={t('complete')}
sizeText={14} sizeText={14}
onPress={this.edit_profile} onPress={this.edit_profile}
/> />
</View> </View>
</View> </View>
@ -601,8 +553,8 @@ class EditProfileScreen extends Component {
</View> </View>
</ScrollView> </ScrollView>
</BackgroundImage_RegisterForm> </BackgroundImage_RegisterForm>
</KeyboardAvoidingView>
</View> </View>
</KeyboardAvoidingView>
) )
} }
} }
@ -657,10 +609,10 @@ const styles = {
backgroundColor: 'rgba(255,255,255,0.3)', backgroundColor: 'rgba(255,255,255,0.3)',
borderRadius: 30, borderRadius: 30,
} }
}; }
const mapDisPatchToProps = state => { const mapDisPatchToProps = state => {
return state.app return state.app
}; }
const setUser = dispatch => bindActionCreators({ appSetDevice, appSetUser, appCleanUser }, dispatch) const setUser = dispatch => bindActionCreators({ appSetDevice, appSetUser, appCleanUser }, dispatch)
export default connect(mapDisPatchToProps, setUser)(EditProfileScreen) export default connect(mapDisPatchToProps, setUser)(EditProfileScreen)

View File

@ -23,7 +23,6 @@ class ProfileScreen extends Component {
isLoading: false, isLoading: false,
user:{}, user:{},
room:null, room:null,
profileImage: require('../../../assets/images/profile.png')
} }
this.getUserData = this.getUserData.bind(this) this.getUserData = this.getUserData.bind(this)
} }
@ -43,18 +42,10 @@ class ProfileScreen extends Component {
.then(res => { .then(res => {
// console.log('user profile -------> ',res); // console.log('user profile -------> ',res);
if(res.ok){ if(res.ok){
let image = require('../../../assets/images/profile.png')
if (res.data.user.image){
image = {
uri: res.data.user.image ? res.data.user.image.url ? res.data.user.image.url : res.data.user.image : ''
}
}
this.props.user.show_birth_date = res.data.user.birth_date
this.setState({ this.setState({
isLoading: false, isLoading: false,
user: res.data.user, user: res.data.user,
room: res.data.room && res.data.room.length > 0 ? res.data.room[0] : null, room: res.data.room
profileImage : image,
}) })
}else{ }else{
this.setState({ this.setState({
@ -64,31 +55,6 @@ class ProfileScreen extends Component {
}) })
} }
connectFBSuccess = () => {
this.state.user.fb_is_link = 't';
Alert.alert('Connect with Facebook Success', '', [
{
text: 'ok',
onPress: () => {
this.getUserData()
}
}
])
};
disConnectFBSuccess = () => {
this.state.user.fb_is_link = 'f';
this.state.user.fb_token = null;
Alert.alert('Disconnect with Facebook Success', '', [
{
text: 'ok',
onPress: () => {
this.getUserData()
}
}
])
};
refreshPage() { refreshPage() {
window.location.reload(false); window.location.reload(false);
} }
@ -103,7 +69,6 @@ class ProfileScreen extends Component {
}}> }}>
<NavigationEvents <NavigationEvents
onDidFocus={() => { onDidFocus={() => {
console.log('getUserData');
this.getUserData() this.getUserData()
}} }}
/> />
@ -115,7 +80,7 @@ class ProfileScreen extends Component {
}}> }}>
<Image <Image
style={{ width: 120, height: 120, borderRadius: 60, borderColor: 'white', borderWidth: 2 }} style={{ width: 120, height: 120, borderRadius: 60, borderColor: 'white', borderWidth: 2 }}
source={this.state.profileImage} source={require('../../../assets/images/profile.png')}
/> />
</View> </View>
<View style={{ flex: 1, padding: 15, }}> <View style={{ flex: 1, padding: 15, }}>
@ -124,7 +89,7 @@ class ProfileScreen extends Component {
<Text style={{ color: '#8BC34A', marginBottom: 10 }}>{t('profile')}</Text> <Text style={{ color: '#8BC34A', marginBottom: 10 }}>{t('profile')}</Text>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('category')}</Text> <Text style={styles.text_field_style}>{t('category')}</Text>
<Text style={styles.data_field_style}>{this.state.user.is_customer ? t('customer') : t('guest')}</Text> <Text style={styles.data_field_style}>{t('individual2')}</Text>
</View> </View>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('name')}</Text> <Text style={styles.text_field_style}>{t('name')}</Text>
@ -132,7 +97,7 @@ class ProfileScreen extends Component {
</View> </View>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('email')}</Text> <Text style={styles.text_field_style}>{t('email')}</Text>
<Text style={styles.data_field_style}>{this.state.user.email ? this.state.email : '-'}</Text> <Text style={styles.data_field_style}>{this.state.user.email}</Text>
</View> </View>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('phone2')}</Text> <Text style={styles.text_field_style}>{t('phone2')}</Text>
@ -144,11 +109,11 @@ class ProfileScreen extends Component {
</View> </View>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('gender')}</Text> <Text style={styles.text_field_style}>{t('gender')}</Text>
<Text style={styles.data_field_style}>{this.state.user.gender == "male" || this.state.user.gender == "ชาย" ? t('male') : t('female')}</Text> <Text style={styles.data_field_style}>{this.state.user.gender=="male"? t('male') : t('female')}</Text>
</View> </View>
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text style={styles.text_field_style}>{t('birth_date')}</Text> <Text style={styles.text_field_style}>{t('birth_date')}</Text>
<Text style={styles.data_field_style}>{this.state.user.birth_date ? moment(this.state.user.birth_date, 'DD-MM-YYYY').add(543, 'years').format('DD MMM YYYY') : ''}</Text> <Text style={styles.data_field_style}>{moment(this.state.user.birth_date).format('DD-MM-YYYY')}</Text>
</View> </View>
</View> </View>
{ {
@ -179,9 +144,18 @@ class ProfileScreen extends Component {
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}> <View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
<Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }} <Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }}
onPress={() => { onPress={() => {
setTimeout( () => { setTimeout( () => {
loginWithFacebook(this.connectFBSuccess) loginWithFacebook()
setTimeout( () => {
this.state.user.fb_is_link = 't'
this.props.navigation.navigate('Profile',{user:this.state.user})
Alert.alert('Connect with Facebook Success')
},4000);
},1000); },1000);
}} > }} >
<Text style={{ color: '#ffffff', fontSize: 14 }}>{t('connect_facebook')}</Text> <Text style={{ color: '#ffffff', fontSize: 14 }}>{t('connect_facebook')}</Text>
</Button> </Button>
@ -190,7 +164,18 @@ class ProfileScreen extends Component {
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}> <View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
<Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }} <Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }}
onPress={() => { onPress={() => {
disconnectWithFacebook(this.disConnectFBSuccess);
disconnectWithFacebook();
setTimeout( () => {
this.state.user.fb_is_link = 'f'
//alert("Disconnected!")
this.props.navigation.replace('Profile',{user:this.state.user})
},3000);
}} }}
> >
<Text style={{ color: '#ffffff', fontSize: 14 }}>{t('disconnect_facebook')}</Text> <Text style={{ color: '#ffffff', fontSize: 14 }}>{t('disconnect_facebook')}</Text>
@ -201,8 +186,7 @@ class ProfileScreen extends Component {
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}> <View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
<Button block style={{ backgroundColor: '#145EB3', margin:15 }} <Button block style={{ backgroundColor: '#145EB3', margin:15 }}
onPress={() => { this.props.navigation.navigate('EditProfile',{ onPress={() => { this.props.navigation.navigate('EditProfile',{
user:this.state.user, user:this.props.user
image:this.state.profileImage,
}) }}> }) }}>
<Text style={{ color: '#ffffff', fontSize: 14 }}><Icon name={'ic_edit'} size={15}/> {t('edit_profile')} </Text> <Text style={{ color: '#ffffff', fontSize: 14 }}><Icon name={'ic_edit'} size={15}/> {t('edit_profile')} </Text>
</Button> </Button>

View File

@ -1,199 +0,0 @@
import React, {Component} from 'react'
import {TouchableOpacity, View, StyleSheet, Text, ScrollView, RefreshControl, Animated, FlatList} from "react-native";
import LinearGradient from "react-native-linear-gradient";
import {BackgroundImage} from "../../components/BackgroundImage";
import IconMaterial from "react-native-vector-icons/MaterialCommunityIcons";
import Image from "react-native-fast-image";
import {NavigationEvents} from "react-navigation";
import {getListReward, getUserProfile} from "../../api/UserApi";
import {bindActionCreators} from "redux";
import {appSetUser} from "../../redux/app/action";
import {connect} from "react-redux";
import IndicatorLoading from "../../components/IndicatorLoading";
class AllRewards extends Component{
constructor(props) {
super(props);
this.state = {
isLoading: false,
refreshing: false,
all_rewards: [
/*{source: require('../../../assets/images/reward_exam1.png'), title: 'อปอปสตาร 100 บาท แถมฟรวนลดตวหน 100... ', point: '1'},
{source: require('../../../assets/images/reward_exam2.png'), title: 'Samosa หอมเครื่องเทศกรอบอร่อย 2 ชิ้น ในราคาเพียง 70 บาท', point: '2'},
{source: require('../../../assets/images/reward_exam1.png'), title: 'เหล่ามินเนียน เตรียมบุกเมเจอร์ ให้สาวกชาวแก๊งค์ให้เก็บสะสม ', point: '3'},
{source: require('../../../assets/images/reward_exam2.png'), title: 'M GEN แลก Points อร่อยคุ้มจาก แมคโดนัลด์', point: '4'},*/
],
point: 0
}
}
initData = () => {
this.setState({
isLoading: true,
refreshing: true
}, () => {
Promise.all([
this.getListReward(),
this.getUserProfile()
]).then(() => {
this.setState({
isLoading: false,
refreshing: false
})
});
})
};
async getListReward () {
let category_id = this.props.navigation && this.props.navigation.state && this.props.navigation.state.params && this.props.navigation.state.params.id ? this.props.navigation.state.params.id : ''
return await getListReward(category_id)
.then(res => {
if(res.ok){
this.setState({
all_rewards: res.data.data
})
}
})
};
async getUserProfile () {
return await getUserProfile()
.then(res => {
if(res.data && res.ok){
this.setState({
point: res.data.point_balance,
}, () => {
let user_data = this.props.user;
user_data = {
...user_data,
point: this.state.point
}
this.props.appSetUser(user_data)
})
}
});
}
_onRefresh = () => {
this.setState({
isLoading: true,
refreshing: true
}, () => {
this.initData()
})
};
_keyExtractor = (item, index) => 'reward_' + index;
renderItem = (item, index) => {
return (
<TouchableOpacity
onPress={() => this.props.navigation.navigate('RewardDetail', {id: item.id})}
style={[styles.rewardContain, {marginRight: index % 2 === 0 ? 10 : 0}, {width: index % 2 === 0 ? '48%' : '49.5%'}]}>
<View style={{flex: 0.8}}>
<Image source={{uri: item.image_reward ? item.image_reward : ''}} style={{height: '100%'}} resizeMode={'contain'} />
</View>
<View style={{flex: 0.2, padding: 8, flexDirection: 'column', justifyContent: 'center'}}>
<Text style={{fontWeight: '600', fontFamily: 'Prompt-Regular',}}>{item.name}</Text>
<Text style={{textAlign: 'right', color: '#FF6122', fontFamily: 'Prompt-Regular', fontWeight: '600'}}>{item.points_to_redeem} Point</Text>
</View>
</TouchableOpacity>
)
};
render() {
return (
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
flex: 1,
width: null,
height: null,
resizeMode: 'cover'
}}>
<NavigationEvents
onDidFocus={() => {
this.setState({
isLoading: true
}, () => {
this.initData()
})
}}
/>
<BackgroundImage>
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#FFA800', '#E46F00']}
style={styles.pointContain}
>
<Text style={styles.textStyle}>{this.state.point} Points</Text>
<IconMaterial name="star-circle-outline" color="white" size={40}/>
</LinearGradient>
<ScrollView contentContainerStyle={styles.contentContainer}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh}
/>
}
showsVerticalScrollIndicator={false}
scrollEventThrottle={16}
// onScroll={Animated.event(
// [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
// )}
>
<View style={{paddingHorizontal: 8, paddingBottom: 16}}>
<FlatList
data={this.state.all_rewards}
renderItem={({ item, index }) => this.renderItem(item, index)}
showsHorizontalScrollIndicator={false}
keyExtractor={this._keyExtractor}
numColumns={2}
extraData={this.state.all_rewards}
// onScroll={this._onCarouselScroll}
ListEmptyComponent={() =>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', margin: 16,padding:16,borderRadius:5,backgroundColor:'white'}}>
<Text style={{fontSize: 16}}>No Rewards</Text>
</View>
}
/>
</View>
</ScrollView>
</BackgroundImage>
<IndicatorLoading loadingVisible={this.state.isLoading}/>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
textStyle: {
color: 'white',
fontFamily: 'Prompt-Regular',
fontSize: 20,
textAlign: 'right',
fontWeight: '500',
marginRight: 5
},
pointContain: {
justifyContent: 'flex-end',
paddingVertical: 12,
paddingHorizontal: 5,
flexDirection: 'row',
alignItems: 'center'
},
rewardContain: {
// flex: 1,
// width: '48%',
height: 300,
backgroundColor: 'white',
borderRadius: 6,
marginTop: 16
}
});
const mapDisPatchToProps = state => {
return state.app
}
const propSet = dispatch => bindActionCreators({
appSetUser,
}, dispatch)
export default connect(mapDisPatchToProps, propSet)(AllRewards)

Some files were not shown because too many files have changed in this diff Show More