Compare commits
5 Commits
main
...
cr/powerco
| Author | SHA1 | Date | |
|---|---|---|---|
| 507a3b4ba9 | |||
| f7d378267b | |||
| 5f49b36076 | |||
| 1b38306551 | |||
| 5e0189f487 |
7
.gitignore
vendored
@ -58,3 +58,10 @@ buck-out/
|
||||
|
||||
# CocoaPods
|
||||
/ios/Pods/
|
||||
|
||||
.vscode
|
||||
.bundle
|
||||
|
||||
android/.settings
|
||||
android/app/.settings
|
||||
android/*.hprof
|
||||
|
||||
46
App.js
@ -7,21 +7,22 @@
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import { Platform, StyleSheet, Text, StatusBar, TouchableOpacity, View } from 'react-native'
|
||||
import { StatusBar, StyleSheet, Text, TouchableOpacity } from 'react-native'
|
||||
import MainNav from './src/navigation/MainNav'
|
||||
import firebase, { Notification } from 'react-native-firebase'
|
||||
import { store, persistor } from './src/redux/store'
|
||||
import messaging from "@react-native-firebase/messaging"
|
||||
import { persistor, store } from './src/redux/store'
|
||||
import { Provider } from 'react-redux'
|
||||
import { registerDevice, testConnect ,news} from './src/api/UserApi'
|
||||
import { appSetPushToken, appSetDevice, appCleanDevice,appSetNotification } from './src/redux/app/action'
|
||||
import { setLanguage, setStore as setApiStore, setToken } from 'src/api/api'
|
||||
import { registerDevice } from './src/api/UserApi'
|
||||
import { appSetDevice, appSetPushToken } from './src/redux/app/action'
|
||||
import { setLanguage, setToken } from 'src/api/api'
|
||||
import { PersistGate } from 'redux-persist/integration/react'
|
||||
import { create } from 'apisauce'
|
||||
import Toast from 'react-native-toast-message'
|
||||
|
||||
import SplashScreen from 'react-native-splash-screen'
|
||||
import { setBaseUrlByServerMode } from './src/api/api'
|
||||
|
||||
Text.defaultProps = Text.defaultProps || {};
|
||||
Text.defaultProps.allowFontScaling = false;
|
||||
Text.defaultProps = Text.defaultProps || {}
|
||||
Text.defaultProps.allowFontScaling = false
|
||||
|
||||
if (TouchableOpacity.defaultProps == null) TouchableOpacity.defaultProps = {}
|
||||
TouchableOpacity.defaultProps.activeOpacity = 0.7
|
||||
@ -29,7 +30,7 @@ TouchableOpacity.defaultProps.activeOpacity = 0.7
|
||||
// setApiStore(store)
|
||||
class App extends Component {
|
||||
|
||||
constructor(props) {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this._setDataFromInitState = this._setDataFromInitState.bind(this)
|
||||
}
|
||||
@ -37,15 +38,15 @@ class App extends Component {
|
||||
componentDidMount = () => {
|
||||
SplashScreen.hide()
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
initNotification = async () => {
|
||||
await this.setPermission()
|
||||
const fcmToken = await firebase.messaging().getToken()
|
||||
const fcmToken = await messaging().getAPNSToken();
|
||||
if (fcmToken) {
|
||||
store.dispatch(appSetPushToken(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) {
|
||||
store.dispatch(appSetDevice(resultSendDevice.data.device))
|
||||
}
|
||||
@ -55,23 +56,27 @@ class App extends Component {
|
||||
|
||||
setPermission = async () => {
|
||||
try {
|
||||
const enabled = await firebase.messaging().hasPermission()
|
||||
await messaging().registerDeviceForRemoteMessages();
|
||||
const authStatus = await messaging().requestPermission();
|
||||
const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL;
|
||||
if (!enabled) {
|
||||
await firebase.messaging().requestPermission()
|
||||
await messaging().requestPermission()
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('error', error)
|
||||
}
|
||||
}
|
||||
|
||||
_setDataFromInitState() {
|
||||
_setDataFromInitState () {
|
||||
const appState = store.getState().app
|
||||
let device = appState.device;
|
||||
let device = appState.device
|
||||
|
||||
setBaseUrlByServerMode(appState.server_mode)
|
||||
|
||||
if (appState.token) {
|
||||
setToken(appState.token)
|
||||
}
|
||||
if(appState.lang){
|
||||
if (appState.lang) {
|
||||
setLanguage(appState.lang)
|
||||
}
|
||||
|
||||
@ -83,14 +88,15 @@ class App extends Component {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
render () {
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<PersistGate persistor={persistor} loading={null} onBeforeLift={this._setDataFromInitState}>
|
||||
<StatusBar barStyle="light-content"/>
|
||||
<MainNav />
|
||||
<MainNav/>
|
||||
</PersistGate>
|
||||
<Toast />
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>csareactrn60</name>
|
||||
<name>charoensin</name>
|
||||
<comment>Project android created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
@ -14,4 +14,15 @@
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</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>
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<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.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
||||
@ -20,4 +20,15 @@
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</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>
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
connection.project.dir=..
|
||||
eclipse.preferences.version=1
|
||||
@ -131,9 +131,11 @@ android {
|
||||
applicationId "th.co.csasset.mobile"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 60
|
||||
versionName "2.12"
|
||||
versionCode 84
|
||||
versionName "2.33"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
missingDimensionStrategy 'react-native-camera', 'general'
|
||||
multiDexEnabled true
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
@ -208,7 +210,10 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
// def multidex_version = "2.0.1"
|
||||
dependencies {
|
||||
implementation project(':react-native-permissions')
|
||||
implementation project(':react-native-camera')
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
if (enableHermes) {
|
||||
@ -223,6 +228,7 @@ dependencies {
|
||||
implementation "com.google.firebase:firebase-core:16.0.9"
|
||||
implementation "com.google.firebase:firebase-config:17.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)'
|
||||
}
|
||||
|
||||
42
android/app/google-services-backup.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
@ -1,39 +1,45 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "300814322402",
|
||||
"firebase_url": "https://charoensin-ec628.firebaseio.com",
|
||||
"project_id": "charoensin-ec628",
|
||||
"storage_bucket": "charoensin-ec628.appspot.com"
|
||||
"project_number": "468878476620",
|
||||
"firebase_url": "https://csasset-mobile.firebaseio.com",
|
||||
"project_id": "csasset-mobile",
|
||||
"storage_bucket": "csasset-mobile.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:300814322402:android:61e2ca18a6ba4174",
|
||||
"mobilesdk_app_id": "1:468878476620:android:61e2ca18a6ba4174",
|
||||
"android_client_info": {
|
||||
"package_name": "th.co.csasset.mobile"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "300814322402-82gqcb4dte5m2tv1dr2imsf0u7regk87.apps.googleusercontent.com",
|
||||
"client_id": "468878476620-v3rqr1b2bta862r6q974csuc3rq917ni.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAIXzIwPy-023B3sbDQv42LaxXaSnJcWmU"
|
||||
"current_key": "AIzaSyB7o8KiFwABvfyYubdWTcjpm3Y6ciCrO1I"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
android/app/release/app-release.apk
Normal file
18
android/app/release/output-metadata.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="th.co.csasset.mobile">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
@ -16,25 +17,32 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme"
|
||||
android:hardwareAccelerated="false"
|
||||
android:hardwareAccelerated="true"
|
||||
android:largeHeap="true">
|
||||
<!-- android:usesCleartextTraffic="true" -->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action
|
||||
android:name="android.intent.action.MAIN"
|
||||
android:exported="true"/>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<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>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
|
||||
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
|
||||
</intent-filter>
|
||||
|
||||
@ -9,15 +9,17 @@ import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
//import com.facebook.reactnative.androidsdk.BuildConfig;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.learnium.RNDeviceInfo.RNDeviceInfo;
|
||||
|
||||
import com.reactnativecommunity.cameraroll.CameraRollPackage;
|
||||
import org.reactnative.camera.RNCameraPackage;
|
||||
|
||||
// Firebase
|
||||
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
|
||||
import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
|
||||
import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage;
|
||||
//import io.invertase.firebase.messaging.ReactNativeFirebaseMessagingPackage;
|
||||
//import io.invertase.firebase.notifications.RNFirebaseNotificationsPackage;
|
||||
//import io.invertase.firebase.config.RNFirebaseRemoteConfigPackage;
|
||||
|
||||
import com.facebook.reactnative.androidsdk.FBSDKPackage;
|
||||
|
||||
@ -37,9 +39,10 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
packages.add(new RNFirebaseNotificationsPackage());
|
||||
packages.add(new RNFirebaseMessagingPackage());
|
||||
packages.add(new RNFirebaseRemoteConfigPackage());
|
||||
// packages.add(new RNFirebaseNotificationsPackage());
|
||||
// packages.add(new ReactNativeFirebaseMessagingPackage());
|
||||
// packages.add(new RNFirebaseRemoteConfigPackage());
|
||||
// packages.add(new RNCameraPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
|
||||
36
android/app/src/main/res/drawable/rn_edit_text_material.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<?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>
|
||||
20
android/app/src/release/java/ReactNativeFlipper.java
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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.
|
||||
}
|
||||
}
|
||||
@ -4,26 +4,30 @@ buildscript {
|
||||
ext {
|
||||
googlePlayServiceVersion = "17.0.0"
|
||||
buildToolsVersion = "28.0.3"
|
||||
kotlinVersion = "1.5.20"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 28
|
||||
targetSdkVersion = 28
|
||||
compileSdkVersion = 31
|
||||
targetSdkVersion = 31
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
// jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:3.4.1")
|
||||
classpath 'com.google.gms:google-services:4.2.0'
|
||||
classpath('com.android.tools.build:gradle:4.2.2')
|
||||
classpath('com.google.gms:google-services:4.3.14')
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// 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 {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
@ -35,9 +39,14 @@ allprojects {
|
||||
}
|
||||
|
||||
google()
|
||||
jcenter()
|
||||
// jcenter()
|
||||
|
||||
maven { url 'https://maven.google.com' }
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +1,20 @@
|
||||
# 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
|
||||
## For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
#
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
#
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# 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
|
||||
# org.gradle.parallel=true
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
#Fri Apr 07 15:17:20 ICT 2023
|
||||
MYAPP_RELEASE_STORE_FILE=charoensin.release.keystore
|
||||
MYAPP_RELEASE_KEY_ALIAS=charoensin
|
||||
MYAPP_RELEASE_STORE_PASSWORD=aabbccddee
|
||||
MYAPP_RELEASE_KEY_PASSWORD=aabbccddee
|
||||
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
MYAPP_RELEASE_STORE_PASSWORD=aabbccddee
|
||||
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
@ -1,5 +1,7 @@
|
||||
#Fri Jan 13 09:46:32 ICT 2023
|
||||
networkTimeout=10000
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
288
android/gradlew
vendored
@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# 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
|
||||
# https://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,
|
||||
@ -17,78 +17,113 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# 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
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
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.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
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.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@ -105,84 +140,105 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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
|
||||
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" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
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
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
# 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.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# 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" )
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
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
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
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" "$@"
|
||||
|
||||
40
android/gradlew.bat
vendored
@ -5,7 +5,7 @@
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@ -25,10 +25,14 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
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.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@ -37,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@ -51,7 +55,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@ -61,38 +65,26 @@ echo location of your Java installation.
|
||||
|
||||
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
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
@ -1,4 +1,20 @@
|
||||
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'
|
||||
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
|
||||
include ':react-native-fbsdk'
|
||||
|
||||
BIN
assets/images/appointment_repair.png
Normal file
|
After Width: | Height: | Size: 579 B |
BIN
assets/images/discount_coupon.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/discount_product.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/images/discount_redeem.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
assets/images/discount_rent.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/images/invoice_icon.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
assets/images/invoice_overdue_icon.png
Normal file
|
After Width: | Height: | Size: 702 B |
BIN
assets/images/logo_5.png
Normal file
|
After Width: | Height: | Size: 549 KiB |
BIN
assets/images/meter_icon.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/meter_noti_image.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/images/radio_button.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
assets/images/radio_button_checked.png
Normal file
|
After Width: | Height: | Size: 575 B |
BIN
assets/images/repair_noti.png
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
assets/images/reward_exam1.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
assets/images/reward_exam2.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
assets/images/star_grey.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/star_rating.png
Normal file
|
After Width: | Height: | Size: 590 B |
BIN
assets/images/star_yellow.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
assets/images/success_repair.png
Normal file
|
After Width: | Height: | Size: 669 B |
@ -1,3 +1,9 @@
|
||||
export default {
|
||||
API_BASE_URL: 'https://app.csasset.co.th/mobile',
|
||||
API_BASE_URL_PROD: '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'
|
||||
}
|
||||
|
||||
11
firebase.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
3
ios/Gemfile
Normal file
@ -0,0 +1,3 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "fastlane"
|
||||
44
ios/Podfile
@ -1,6 +1,8 @@
|
||||
platform :ios, '9.0'
|
||||
platform :ios, '13.0'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
xcodeproj 'csareactrn60'
|
||||
|
||||
target 'csareactrn60' do
|
||||
# Pods for csareactrn60
|
||||
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
@ -26,7 +28,7 @@ target 'csareactrn60' do
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'React-callinvoker', :path => "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
|
||||
@ -37,15 +39,47 @@ target 'csareactrn60' do
|
||||
pod 'react-native-fbsdk', :path => '../node_modules/react-native-fbsdk'
|
||||
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 'FBSDKLoginKit'
|
||||
pod 'FBSDKShareKit'
|
||||
|
||||
#Firebase
|
||||
pod 'Firebase/Messaging', '~> 6.8.0'
|
||||
|
||||
pod 'react-native-view-shot', :path => '../node_modules/react-native-view-shot'
|
||||
pod 'RNImageCropPicker', :path => '../node_modules/react-native-image-crop-picker'
|
||||
|
||||
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
|
||||
|
||||
917
ios/Podfile.lock
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
LastUpgradeVersion = "1120"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
@ -55,6 +55,15 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
|
||||
BuildableName = "csareactrn60-tvOS.app"
|
||||
BlueprintName = "csareactrn60-tvOS"
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@ -67,17 +76,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7"
|
||||
BuildableName = "csareactrn60-tvOS.app"
|
||||
BlueprintName = "csareactrn60-tvOS"
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@ -99,8 +97,6 @@
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0940"
|
||||
LastUpgradeVersion = "1120"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
@ -55,6 +55,15 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "csareactrn60.app"
|
||||
BlueprintName = "csareactrn60"
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@ -67,17 +76,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "csareactrn60.app"
|
||||
BlueprintName = "csareactrn60"
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@ -99,8 +97,6 @@
|
||||
ReferencedContainer = "container:csareactrn60.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@ -69,6 +69,20 @@
|
||||
<string>Choose a picture for user profile image or save image.</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<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>
|
||||
<array>
|
||||
<string>arial.ttf</string>
|
||||
|
||||
@ -4,5 +4,9 @@
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.applesignin</key>
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
8
ios/fastlane/Appfile
Normal file
@ -0,0 +1,8 @@
|
||||
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
|
||||
27
ios/fastlane/Fastfile
Normal file
@ -0,0 +1,27 @@
|
||||
# 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
|
||||
35
package.json
@ -9,7 +9,9 @@
|
||||
"postinstall": "sh ./fix.sh",
|
||||
"prod-android": "cd android && ./gradlew assembleRelease",
|
||||
"run-android": "react-native run-android",
|
||||
"run-ios": "react-native run-ios --simulator \"iPhone 11\""
|
||||
"run-ios": "react-native run-ios --simulator \"iPhone 14 Pro Max\"",
|
||||
"run-device": "react-native run-ios --device",
|
||||
"ios": "react-native run-ios --simulator \"iPhone 14 Pro Max\""
|
||||
},
|
||||
"rnpm": {
|
||||
"assets": [
|
||||
@ -18,51 +20,66 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@invertase/react-native-apple-authentication": "^1.1.2",
|
||||
"@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",
|
||||
"deprecated-react-native-listview": "^0.0.5",
|
||||
"i18n-js": "^3.5.1",
|
||||
"intl": "^1.2.5",
|
||||
"jetifier": "^2.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"native-base": "^2.13.8",
|
||||
"react": "16.9.0",
|
||||
"react-native": "0.61.5",
|
||||
"react-native": "^0.63",
|
||||
"react-native-action-sheet": "^2.2.0",
|
||||
"react-native-appearance": "^0.2.2",
|
||||
"react-native-camera": "^4.2.1",
|
||||
"react-native-countdown-component": "^2.7.1",
|
||||
"react-native-device-info": "^5.5.7",
|
||||
"react-native-dropdown-picker": "^5.4.6",
|
||||
"react-native-easy-grid": "^0.2.2",
|
||||
"react-native-elastic-image-slider": "^1.0.0",
|
||||
"react-native-elements": "^1.2.0",
|
||||
"react-native-fast-image": "^8.1.5",
|
||||
"react-native-fbsdk": "^1.1.2",
|
||||
"react-native-firebase": "^5.5.6",
|
||||
"react-native-gesture-handler": "^1.4.1",
|
||||
"react-native-hyperlink": "^0.0.16",
|
||||
"react-native-image-crop-picker": "0.25.3",
|
||||
"react-native-image-crop-picker": "^0.32.2",
|
||||
"react-native-image-slider-show": "^1.0.3",
|
||||
"react-native-image-slideshow": "^1.0.1",
|
||||
"react-native-image-view": "^2.1.5",
|
||||
"react-native-linear-gradient": "^2.5.6",
|
||||
"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-qrcode": "^0.2.7",
|
||||
"react-native-qrcode-scanner": "^1.5.5",
|
||||
"react-native-qrcode-svg": "^5.2.0",
|
||||
"react-native-render-html": "^4.1.2",
|
||||
"react-native-screens": "^2.7.0",
|
||||
"react-native-searchable-dropdown": "^1.1.1",
|
||||
"react-native-signature-canvas": "^2.4.0",
|
||||
"react-native-signature-canvas": "^4.4.1",
|
||||
"react-native-signature-pad": "^0.1.0",
|
||||
"react-native-snap-carousel": "^3.8.0",
|
||||
"react-native-splash-screen": "^3.2.0",
|
||||
"react-native-svg": "^9.9.3",
|
||||
"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-view-shot": "^3.0.2",
|
||||
"react-native-webview": "^9.4.0",
|
||||
"react-native-webview": "^11.23.0",
|
||||
"react-navigation": "^3.3.0",
|
||||
"react-redux": "^7.1.1",
|
||||
"react-select2-native": "^1.3.0",
|
||||
"redux": "^4.0.4",
|
||||
"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": {
|
||||
"@babel/core": "^7.6.0",
|
||||
@ -71,7 +88,7 @@
|
||||
"babel-jest": "^24.9.0",
|
||||
"eslint": "^6.3.0",
|
||||
"jest": "^24.9.0",
|
||||
"metro-react-native-babel-preset": "^0.56.0",
|
||||
"metro-react-native-babel-preset": "^0.59.0",
|
||||
"react-test-renderer": "16.8.6"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
@ -2,9 +2,11 @@ import Api from './api'
|
||||
import { Platform } from 'react-native'
|
||||
import Config from 'src/utils/Config'
|
||||
import DeviceInfo from 'react-native-device-info'
|
||||
import ApiPowerCondo from "./apiPowerCondo";
|
||||
import moment from "moment";
|
||||
|
||||
export const getUserProfile = () => {
|
||||
return Api.get('/me');
|
||||
return Api.get('/mobile/me');
|
||||
}
|
||||
|
||||
export const testConnect = () => {
|
||||
@ -12,7 +14,7 @@ export const testConnect = () => {
|
||||
}
|
||||
|
||||
export const registerDevice = (pushToken) => {
|
||||
return Api.post('/register/device', {
|
||||
return Api.post('/mobile/register/device', {
|
||||
push_token: pushToken,
|
||||
uid: DeviceInfo.getUniqueId(),
|
||||
brand: DeviceInfo.getBrand(),
|
||||
@ -21,43 +23,56 @@ export const registerDevice = (pushToken) => {
|
||||
}
|
||||
|
||||
export const register = (user) => {
|
||||
return Api.post('/register',
|
||||
user
|
||||
);
|
||||
const formData = new FormData()
|
||||
for (let k in user) {
|
||||
formData.append(k, user[k])
|
||||
}
|
||||
return Api.post('/register', formData );
|
||||
}
|
||||
|
||||
export const login = (params) => {
|
||||
return Api.post('/login',
|
||||
params = {
|
||||
...params,
|
||||
uid: DeviceInfo.getUniqueId(),
|
||||
brand: DeviceInfo.getBrand(),
|
||||
model: DeviceInfo.getModel()
|
||||
}
|
||||
|
||||
return Api.post('/api/login',
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
export const logout = () => {
|
||||
return Api.post('/api/logout');
|
||||
}
|
||||
|
||||
export const dashboard = (params) => {
|
||||
return Api.get('/me/dashboard');
|
||||
return Api.get('/mobile/me/dashboard');
|
||||
}
|
||||
|
||||
export const getNews = (params) => {
|
||||
return Api.get('/news');
|
||||
return Api.get('/mobile/news');
|
||||
}
|
||||
|
||||
export const getNewsPage = (page = 1) => {
|
||||
return Api.get('/news?page='+page);
|
||||
return Api.get('/mobile/news?page='+page);
|
||||
}
|
||||
|
||||
export const getNewsDetail = (news_id) => {
|
||||
return Api.get('/news/'+news_id);
|
||||
return Api.get('/mobile/news/'+news_id);
|
||||
}
|
||||
|
||||
export const getNewsByProject = (project_id) => {
|
||||
return Api.get('/news_projects/'+project_id);
|
||||
return Api.get('/mobile/news-projects/'+project_id);
|
||||
}
|
||||
|
||||
export const project = (keyword) => {
|
||||
return Api.get('/project');
|
||||
return Api.get('/mobile/project');
|
||||
}
|
||||
|
||||
export const getBuildingByProjectId = (project_id) => {
|
||||
return Api.get(`/project/${project_id}/building`);
|
||||
return Api.get(`/mobile/project/${project_id}/building`);
|
||||
}
|
||||
|
||||
export const room = (project_id) => {
|
||||
@ -71,13 +86,13 @@ export const roomdetail = (room_id) => {
|
||||
}
|
||||
|
||||
export const payment = (user_id) => {
|
||||
return Api.get('/payment', {
|
||||
return Api.get('/mobile/me/invoice', {
|
||||
user_id: user_id
|
||||
});
|
||||
}
|
||||
|
||||
export const payment_detail = (payments_id) => {
|
||||
return Api.get('/payment/'+payments_id);
|
||||
return Api.get('/mobile/payment/'+payments_id);
|
||||
}
|
||||
|
||||
export const total_payment = (user_id) => {
|
||||
@ -85,51 +100,52 @@ export const total_payment = (user_id) => {
|
||||
}
|
||||
|
||||
export const edit_profile = (user) => {
|
||||
const formData = new FormData()
|
||||
for (let k in user) {
|
||||
formData.append(k, user[k])
|
||||
}
|
||||
return Api.post('/me/profile', formData );
|
||||
// const formData = new FormData()
|
||||
// for (let k in user) {
|
||||
// formData.append(k, user[k])
|
||||
// }
|
||||
// let formDataParts = formData._parts ? formData._parts : formData;
|
||||
return Api.post('/mobile/me/profile', user );
|
||||
}
|
||||
|
||||
export const get_notification = (user_id, page) => {
|
||||
return Api.get('/notification', {
|
||||
return Api.get('/mobile/notification', {
|
||||
user_id: user_id,
|
||||
page: page
|
||||
})
|
||||
}
|
||||
|
||||
export const read_notification = (noti_id) => {
|
||||
return Api.post('/notification',{noti_id: noti_id})
|
||||
return Api.post('/mobile/notification',{noti_id: noti_id})
|
||||
}
|
||||
|
||||
export const count_notification = (user_id) => {
|
||||
return Api.get('/notification/count', {
|
||||
return Api.get('/mobile/notification/count', {
|
||||
user_id: user_id
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export const getSubscription = (customer_id,type) => {
|
||||
return Api.get('/subscription', {
|
||||
return Api.get('/mobile/subscription', {
|
||||
customer_id: customer_id,
|
||||
type: type,
|
||||
})
|
||||
}
|
||||
|
||||
export const postSubscription = (customer_id,type) => {
|
||||
return Api.post('/subscription', {
|
||||
return Api.post('/mobile/subscription', {
|
||||
customer_id: customer_id,
|
||||
type: type,
|
||||
})
|
||||
}
|
||||
|
||||
export const getProductList = () => {
|
||||
return Api.get('/product');
|
||||
return Api.get('/mobile/product');
|
||||
}
|
||||
|
||||
export const getProductDetail = (product_id) => {
|
||||
return Api.get('/product/'+product_id);
|
||||
return Api.get('/mobile/product/'+product_id);
|
||||
}
|
||||
|
||||
export const getServices = () => {
|
||||
@ -148,8 +164,8 @@ export const getRepairList = (service_id) => {
|
||||
return Api.get('/repair');
|
||||
}
|
||||
|
||||
export const getRepairById = (repair_id) => {
|
||||
return Api.get('/repair/'+repair_id);
|
||||
export const getRepairById = (repair_id, type = '') => {
|
||||
return Api.get(`/repair/${repair_id}?self_room=${(type === 'effect_responsible' ? 'true' : 'false')}`);
|
||||
}
|
||||
|
||||
export const postRepair = (param) => {
|
||||
@ -166,7 +182,8 @@ export const postSuggestion = (params) => {
|
||||
for (let k in params) {
|
||||
formData.append(k, params[k])
|
||||
}
|
||||
return Api.post('/suggestion',formData)
|
||||
let newFormData = formData._parts ? formData._parts : formData;
|
||||
return Api.post('/mobile/suggestion', newFormData)
|
||||
}
|
||||
|
||||
export const postSuggestionLogin = (params) => {
|
||||
@ -174,22 +191,22 @@ export const postSuggestionLogin = (params) => {
|
||||
for (let k in params) {
|
||||
formData.append(k, params[k])
|
||||
}
|
||||
return Api.post('/service_suggestion',formData)
|
||||
return Api.post('/mobile/service-suggestion',formData)
|
||||
}
|
||||
|
||||
|
||||
//Question & Answer
|
||||
export const getConversation = () => {
|
||||
return Api.get('/conversation');
|
||||
return Api.get('/mobile/conversation');
|
||||
}
|
||||
|
||||
export const postConversation = (param) => {
|
||||
return Api.post('/conversation/messages',param);
|
||||
return Api.post('/mobile/conversation/messages',param);
|
||||
}
|
||||
|
||||
//Object & Message
|
||||
export const getObjectMessage = () => {
|
||||
return Api.get('/parcel');
|
||||
return Api.get('/mobile/parcel');
|
||||
}
|
||||
|
||||
export const postSignatureImage = (params) => {
|
||||
@ -197,29 +214,29 @@ export const postSignatureImage = (params) => {
|
||||
for (let k in params) {
|
||||
formData.append(k, params[k])
|
||||
}
|
||||
return Api.post('/parcel',formData);
|
||||
return Api.post('/mobile/parcel',formData);
|
||||
}
|
||||
|
||||
export const getObjectMessageByID = (id) => {
|
||||
return Api.get(`/parcel/${id}`);
|
||||
return Api.get(`/mobile/parcel/${id}`);
|
||||
}
|
||||
|
||||
//Meter
|
||||
export const getMeterList = () => {
|
||||
return Api.get('/meter');
|
||||
return Api.get('/mobile/meter');
|
||||
}
|
||||
|
||||
export const getRoomSlideList = (roon_id) => {
|
||||
return Api.get('/meter?room_id='+roon_id);
|
||||
return Api.get('/mobile/meter?room_id='+roon_id);
|
||||
}
|
||||
|
||||
export const postMeter = (params) => {
|
||||
const formData = new FormData()
|
||||
for (let k in params) {
|
||||
formData.append(k, params[k])
|
||||
}
|
||||
// const formData = new FormData()
|
||||
// for (let k in params) {
|
||||
// formData.append(k, params[k])
|
||||
// }
|
||||
|
||||
return Api.post('/meter',formData);
|
||||
return Api.post('/mobile/meter',params);
|
||||
}
|
||||
|
||||
export const postMeterImage = (params) => {
|
||||
@ -228,7 +245,7 @@ export const postMeterImage = (params) => {
|
||||
formData.append(k, params[k])
|
||||
}
|
||||
|
||||
return Api.post('/ocr',formData);
|
||||
return Api.post('/mobile/ocr',formData);
|
||||
}
|
||||
|
||||
export const disconnectFacebook = (user) => {
|
||||
@ -236,3 +253,126 @@ export const disconnectFacebook = (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')
|
||||
}
|
||||
@ -1,8 +1,7 @@
|
||||
import { create } from 'apisauce'
|
||||
import Config from 'src/utils/Config'
|
||||
import DeviceInfo from 'react-native-device-info'
|
||||
import { Alert, NetInfo, Platform } from 'react-native'
|
||||
import NavigationService from 'src/utils/NavigationService'
|
||||
import { Alert, Platform } from 'react-native'
|
||||
|
||||
// import { strings as t } from '../i18n'
|
||||
// import { userLogout } from 'src/redux/app/action'
|
||||
@ -11,15 +10,26 @@ import NavigationService from 'src/utils/NavigationService'
|
||||
let store
|
||||
|
||||
const Api = create({
|
||||
baseURL: Config.API_BASE_URL,
|
||||
// baseURL: Config.API_BASE_URL_PROD,
|
||||
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'
|
||||
}
|
||||
})
|
||||
|
||||
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 => {
|
||||
Api.setHeader('X-Device-Name', name)
|
||||
})
|
||||
@ -29,11 +39,11 @@ Api.addRequestTransform(request => {
|
||||
})
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Api.addRequestTransform(request => {
|
||||
console.info('--> [' + request.method + '] ' + Api.getBaseURL() + request.url,request.params, request.data)
|
||||
console.info('header --' + request.url +' -- ', request.headers)
|
||||
console.info('--> [' + request.method + '] ' + Api.getBaseURL() + request.url, request.params, request.data)
|
||||
console.info('header --' + request.url + ' -- ', request.headers)
|
||||
})
|
||||
Api.addMonitor(response => {
|
||||
console.info('<-- ' + response.status + ' --- ' + response.config.url,response)
|
||||
console.info('<-- ' + response.status + ' --- ' + response.config.url, response)
|
||||
})
|
||||
}
|
||||
|
||||
@ -49,8 +59,7 @@ Api.addMonitor(response => {
|
||||
case 'SERVER_ERROR':
|
||||
case 'CANCEL_ERROR':
|
||||
case 'CLIENT_ERROR': // 4XX
|
||||
if (response.status === 401) {
|
||||
// store.dispatch(userLogout)
|
||||
/*if (response.status === 401) {
|
||||
Alert.alert('Session timeout', 'Please login again to continue using application', [
|
||||
{
|
||||
text: 'ok',
|
||||
@ -58,20 +67,20 @@ Api.addMonitor(response => {
|
||||
// NavigationService.navigate('AppLoading')
|
||||
}
|
||||
}
|
||||
], {cancelable: false})
|
||||
], { cancelable: false })
|
||||
return
|
||||
}
|
||||
}*/
|
||||
// Alert.alert(null, 'error_getting_data', [{text: 'ok'}])
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export function setStore(reduxStore) {
|
||||
export function setStore (reduxStore) {
|
||||
store = reduxStore
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
export function setToken (token) {
|
||||
Api.setHeader('Authorization', 'Bearer ' + token)
|
||||
}
|
||||
|
||||
@ -79,11 +88,11 @@ export function setLanguage (languageCode) {
|
||||
Api.setHeader('language', languageCode)
|
||||
}
|
||||
|
||||
export function clearToken() {
|
||||
export function clearToken () {
|
||||
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-Longitude', lng.toString() || '0.0')
|
||||
}
|
||||
|
||||
68
src/api/apiPowerCondo.js
Normal file
@ -0,0 +1,68 @@
|
||||
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
|
||||
83
src/components/AppleAuth.js
Normal file
@ -0,0 +1,83 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react'
|
||||
import { TextInput, View } from 'react-native'
|
||||
import Icon from 'src/components/Icon'
|
||||
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome'
|
||||
import Text from 'src/components/Text';
|
||||
export class CustomInput extends Component {
|
||||
|
||||
@ -8,10 +9,30 @@ export class CustomInput extends Component {
|
||||
let props = this.props
|
||||
return (
|
||||
<View style={[styles.container, props.style]}>
|
||||
{props.iconName && <View style={styles.icon}>
|
||||
{/* {
|
||||
props.iconType === 'fontAwesome' ?
|
||||
props.iconName && <View style={styles.icon}>
|
||||
<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}>
|
||||
<Text style={{ color: props.labelColor || 'rgba(0, 0, 0, 0.5)' }}>{props.labelName}</Text>
|
||||
</View>
|
||||
@ -20,10 +41,12 @@ export class CustomInput extends Component {
|
||||
<View style={{ flex: 1 , justifyContent:'center'}}>
|
||||
<TextInput
|
||||
{...props}
|
||||
style={{ padding: 7, textAlign: 'right', color: props.afterInput || 'white', fontFamily: 'Prompt-Regular' }}
|
||||
style={{ padding: 7, textAlign: 'right', color: props.afterInput || 'white', fontFamily: 'Prompt-Regular', ...props.textInputStyles }}
|
||||
secureTextEntry={props.secureTextEntry}
|
||||
textAlign={props.inputTextAlign || 'right'}
|
||||
placeholder={props.placeholder} value={props.value} />
|
||||
placeholder={props.placeholder}
|
||||
value={props.value}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@ -5,6 +5,7 @@ import { login, disconnectFacebook } from '../api/UserApi'
|
||||
import { store } from '../redux/store'
|
||||
import { Alert } from 'react-native'
|
||||
import NavigationService from '../utils/NavigationService';
|
||||
import messaging from "@react-native-firebase/messaging";
|
||||
|
||||
|
||||
let requestManager = new GraphRequestManager();
|
||||
@ -33,10 +34,22 @@ export function loginWithFacebook(onSuccess){
|
||||
);
|
||||
}
|
||||
|
||||
function loginAccessTokenToServer(accessToken,onSuccess){
|
||||
async function loginAccessTokenToServer(accessToken,onSuccess){
|
||||
const fcm = messaging();
|
||||
if (!await fcm.hasPermission()) {
|
||||
try {
|
||||
await messaging().requestPermission();
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
const fcmToken = await messaging().getAPNSToken();
|
||||
|
||||
let params = {
|
||||
access_token: accessToken,
|
||||
fcm_token: fcmToken
|
||||
}
|
||||
|
||||
login(params)
|
||||
.then(async (res) => {
|
||||
if(res.status == 500){
|
||||
@ -66,13 +79,15 @@ export function logoutFacebook() {
|
||||
|
||||
|
||||
export function disconnectWithFacebook(onSuccess){
|
||||
|
||||
AccessToken.getCurrentAccessToken().then(
|
||||
(data) => {
|
||||
AccessToken.getCurrentAccessToken()
|
||||
.then((data) => {
|
||||
console.log("AccessToken.getCurrentAccessToken():")
|
||||
console.log(data)
|
||||
|
||||
const accessToken = data.accessToken.toString()
|
||||
let accessToken = null;
|
||||
if(data && data.accessToken){
|
||||
accessToken = data.accessToken.toString();
|
||||
}
|
||||
//console.log("accessToken:")
|
||||
//console.log(accessToken)
|
||||
|
||||
@ -91,20 +106,7 @@ export function disconnectWithFacebook(onSuccess){
|
||||
}
|
||||
|
||||
if (res.ok) {
|
||||
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()
|
||||
// }
|
||||
onSuccess && onSuccess();
|
||||
} else {
|
||||
if(res.data.msg != null){
|
||||
Alert.alert('',res.data.msg)
|
||||
|
||||
53
src/components/Popup.js
Normal file
@ -0,0 +1,53 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { switchLanguage } from 'src/utils/i18n'
|
||||
import { setLanguage } from '../../api/api'
|
||||
import { setBaseUrlByServerMode, setLanguage } from '../../api/api'
|
||||
|
||||
// action type
|
||||
export const ACTION_APP_SET_TOKEN = 'APP_SET_TOKEN'
|
||||
@ -14,9 +14,12 @@ 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_CLEAN_PROJECT_ID = 'ACTION_APP_CLEAN_PROJECT_ID'
|
||||
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
|
||||
export function appSetToken (token) {
|
||||
console.log('token appSetToken >>>>>>>>>>>>>>> ', token)
|
||||
return {
|
||||
type: ACTION_APP_SET_TOKEN,
|
||||
token
|
||||
@ -97,3 +100,18 @@ export function appSetLanguage (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
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import {
|
||||
ACTION_APP_SET_PROJECT_ID,
|
||||
ACTION_APP_CLEAN_PROJECT_ID,
|
||||
ACTION_APP_SET_LANGUAGE,
|
||||
ACTION_APP_SET_SERVER_MODE,
|
||||
ACTION_SET_POPUP_NOTIFICATION
|
||||
} from './action'
|
||||
|
||||
const initialState = {
|
||||
@ -21,34 +23,39 @@ const initialState = {
|
||||
notification: null,
|
||||
project_id: null,
|
||||
lang: null,
|
||||
};
|
||||
server_mode: 'production',
|
||||
}
|
||||
|
||||
export default function (state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case ACTION_APP_SET_LANGUAGE:
|
||||
return { ...state, lang: action.lang }
|
||||
case ACTION_APP_SET_TOKEN:
|
||||
return { ...state, token: action.token };
|
||||
return { ...state, token: action.token }
|
||||
case ACTION_APP_CLEAN_TOKEN:
|
||||
return { ...state, token: null };
|
||||
return { ...state, token: null }
|
||||
case ACTION_APP_SET_PUSH_TOKEN:
|
||||
return { ...state, push_token: action.pushToken };
|
||||
return { ...state, push_token: action.pushToken }
|
||||
case ACTION_APP_SET_DEVICE:
|
||||
return { ...state, device: action.device };
|
||||
return { ...state, device: action.device }
|
||||
case ACTION_APP_CLEAN_DEVICE:
|
||||
return { ...state, device: null };
|
||||
return { ...state, device: null }
|
||||
case ACTION_APP_SET_USER:
|
||||
return { ...state, user: action.user };
|
||||
return { ...state, user: action.user }
|
||||
case ACTION_APP_CLEAN_USER:
|
||||
return { ...state, user: null };
|
||||
return { ...state, user: null }
|
||||
case ACTION_APP_SET_NOTIFICATION:
|
||||
return { ...state, count_noti: action.count_noti };
|
||||
return { ...state, count_noti: action.count_noti }
|
||||
case ACTION_APP_CHANGE_NOTIFICATION:
|
||||
return { ...state, notification: action.notification };
|
||||
return { ...state, notification: action.notification }
|
||||
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:
|
||||
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:
|
||||
return state
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { Component } from 'react'
|
||||
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 { View } from 'react-native'
|
||||
import { switchLanguage } from '../../utils/i18n'
|
||||
@ -24,7 +24,8 @@ class AppLoading extends Component {
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
lang: state.app.lang
|
||||
lang: state.app.lang,
|
||||
user: state.app.user
|
||||
}
|
||||
}
|
||||
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser }, dispatch)
|
||||
|
||||
@ -5,6 +5,7 @@ import { useDispatch } from 'react-redux'
|
||||
import { appSetLanguage } from '../../redux/app/action'
|
||||
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import {setLanguage} from "../../api/UserApi";
|
||||
|
||||
const languages = [
|
||||
{ code: 'th', name: 'ภาษาไทย' },
|
||||
@ -18,7 +19,18 @@ export default function ({ navigation }) {
|
||||
|
||||
function selectLanguage (code) {
|
||||
dispatch(appSetLanguage(code))
|
||||
if(code === 'th'){
|
||||
code = 'th_TH';
|
||||
}
|
||||
|
||||
setLanguage(code)
|
||||
.then(res => {
|
||||
if(res.success){
|
||||
navigation.navigate('HomeScreen')
|
||||
}else{
|
||||
navigation.navigate('HomeScreen')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return <LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
|
||||
|
||||
@ -24,7 +24,8 @@ import {appSetDevice, appSetPushToken, appSetToken, appSetUser} from "../../redu
|
||||
import moment from "moment";
|
||||
import IndicatorLoading from '../../components/IndicatorLoading';
|
||||
import { t } from 'src/utils/i18n'
|
||||
|
||||
import parseDateLocale from 'src/utils/parseDateLocale';
|
||||
import { NavigationEvents } from 'react-navigation'
|
||||
const { height, width } = Dimensions.get('window')
|
||||
|
||||
function ItemOrder({title,cost,description,type}){
|
||||
@ -98,9 +99,7 @@ class BillScreen extends Component {
|
||||
this.checkstatusBill = this.checkstatusBill.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({isLoading: true})
|
||||
if(this.props.user){
|
||||
getData = () => {
|
||||
payment(this.props.user.id)
|
||||
.then(res => {
|
||||
if(res.ok){
|
||||
@ -156,7 +155,10 @@ class BillScreen extends Component {
|
||||
|
||||
|
||||
let date_now = moment()
|
||||
let findTimeout = array_payment.find((item) => {return moment(item.due_at) == date_now})
|
||||
let findTimeout = array_payment.find((item) => {
|
||||
console.log('item >>> ',item)
|
||||
return moment(item.due_at) == date_now
|
||||
})
|
||||
//check bill timeout
|
||||
if(findTimeout !== undefined){
|
||||
this.setState({
|
||||
@ -181,65 +183,61 @@ 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 = [];
|
||||
|
||||
getMonth(period_month){
|
||||
let new_month = 'มกราคม'
|
||||
switch (period_month) {
|
||||
case '01':
|
||||
new_month = 'มกราคม';
|
||||
break;
|
||||
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:
|
||||
new_month = 'มกราคม';
|
||||
break;
|
||||
}
|
||||
// if(Object.keys(sum_cost_room).length > 0) {
|
||||
// Object.keys(sum_cost_room).map((sum_cost) => {
|
||||
// sum_payment.push({
|
||||
// total_cost : sum_cost_room[sum_cost].total_cost,
|
||||
// room: sum_cost_room[sum_cost].room,
|
||||
// room_id: sum_cost_room[sum_cost].room_id,
|
||||
// project: sum_cost_room[sum_cost].project,
|
||||
// due_at: sum_cost_room[sum_cost].due_at,
|
||||
// }
|
||||
// )
|
||||
// room_number_array.push(sum_cost_room[sum_cost].room_id)
|
||||
// })
|
||||
|
||||
return new_month;
|
||||
// let first_room = room_number_array && room_number_array.length > 0 && room_number_array[0];
|
||||
// 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) {
|
||||
let period_month = moment(period, "MM/Y").format('MM');
|
||||
let period_year = parseInt(moment(period, "MM/Y").format('Y')) + 543;
|
||||
let new_month = 'มกราคม';
|
||||
let new_period = new_month + ' ' + period_year;
|
||||
|
||||
new_month = this.getMonth(period_month)
|
||||
|
||||
new_period = new_month + ' ' + period_year;
|
||||
let period_month = moment(period, "MM/Y").format('MMMM');
|
||||
let period_year = parseInt(moment(period, "MM/Y").locale('en').format('Y'));
|
||||
let new_month = '';
|
||||
let new_period = period_month + ' ' + period_year;
|
||||
return new_period;
|
||||
}
|
||||
|
||||
@ -254,7 +252,7 @@ class BillScreen extends Component {
|
||||
return true
|
||||
}
|
||||
|
||||
checkstatusBill(data,boolDate){
|
||||
checkstatusBill(data, isOverdue){
|
||||
if(data.status == 'paid'){
|
||||
return <TouchableOpacity style={{backgroundColor:data.status === 'pending' ? '#145EB3' : 'white',
|
||||
height: 32,width: 103,justifyContent:'center',alignItems:'center',borderRadius:5,
|
||||
@ -263,13 +261,13 @@ class BillScreen extends Component {
|
||||
disabled={data.status === 'pending' ? false : true}
|
||||
onPress={() => {
|
||||
this.state.isCanPay ?
|
||||
data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
|
||||
data.status === 'pending' && this.props.navigation.navigate('PaymentDetail',{payment_id:data.payment_id})
|
||||
: 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>
|
||||
}else{
|
||||
if(!boolDate){
|
||||
if(isOverdue){
|
||||
return <View>
|
||||
<Text style={{ color: 'red',borderWidth:1,borderColor:'#00000040',borderRadius:5,paddingHorizontal:6}}>{'เกินกำหนดชำระ'}</Text>
|
||||
</View>
|
||||
@ -281,10 +279,10 @@ class BillScreen extends Component {
|
||||
disabled={data.status === 'pending' ? false : true}
|
||||
onPress={() => {
|
||||
this.state.isCanPay ?
|
||||
data.status === 'pending' && this.props.navigation.navigate('Payment',{payment_id:data.id})
|
||||
data.status === 'pending' && this.props.navigation.navigate('PaymentDetail',{payment_id:data.payment_id})
|
||||
: 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>
|
||||
}
|
||||
}
|
||||
@ -292,19 +290,39 @@ class BillScreen extends Component {
|
||||
|
||||
_renderHeader(data, expanded) {
|
||||
// if(data.room_id == this.state.sum_payment[this.state.activePage].room.id){
|
||||
let checkBool = this.checkDueDate(data.due_at == null || data.due_at == undefined ? moment() : data.due_at)
|
||||
let checkBool = this.checkDueDate(data.due_date == null || data.due_date == undefined ? moment() : data.due_date)
|
||||
return (
|
||||
<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}}>
|
||||
<Text>{t('month')} {this.getTitle(data.period)}</Text>
|
||||
{/*<Text>{t('month')} {parseDateLocale(moment(data.period, 'MM/Y'), 'MMMM Y')}</Text>*/}
|
||||
<Text>{t('payment_no')} : {data.invoice_code}</Text>
|
||||
<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>}
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
this.checkstatusBill(data,checkBool)
|
||||
}
|
||||
{/*{
|
||||
this.checkstatusBill(data, data.is_overdue)
|
||||
}*/}
|
||||
|
||||
<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 ?
|
||||
data.enable_qr &&
|
||||
@ -331,51 +349,51 @@ class BillScreen extends Component {
|
||||
}
|
||||
|
||||
_renderContent(data) {
|
||||
let water_cost = 0;
|
||||
let electrict_cost = 0;
|
||||
let room_cost = 0;
|
||||
let service_cost = 0;
|
||||
let date_payment = '';
|
||||
let extra_info = '';
|
||||
let d = moment(data.created_at).format('D')
|
||||
let m = moment(data.created_at).format('MM')
|
||||
let y = parseInt(moment(data.created_at).format('Y')) + 543
|
||||
date_payment = d + ' ' + this.getMonth(m) + ' ' + y
|
||||
// let water_cost = 0;
|
||||
// let electrict_cost = 0;
|
||||
// let room_cost = 0;
|
||||
// let service_cost = 0;
|
||||
// let date_payment = '';
|
||||
// let extra_info = '';
|
||||
// let d = moment(data.created_at).format('D')
|
||||
// let m = moment(data.created_at).format('MM')
|
||||
// let y = parseInt(moment(data.created_at).format('Y')) + 543
|
||||
//date_payment = d + ' ' + this.getMonth(m) + ' ' + y
|
||||
|
||||
let descriptionRoom = '-'
|
||||
let descriptionWater = '-'
|
||||
let descriptionElec = '-'
|
||||
let descriptionService = '-'
|
||||
// let descriptionRoom = '-'
|
||||
// let descriptionWater = '-'
|
||||
// let descriptionElec = '-'
|
||||
// let descriptionService = '-'
|
||||
|
||||
// console.log('check data ----------> ',data)
|
||||
|
||||
if(data.details){
|
||||
data.details.map((det) => {
|
||||
if(det.sequence === 1){
|
||||
room_cost = det.cost
|
||||
room_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
descriptionRoom = det.descript == '' ? '-' : det.descript
|
||||
}
|
||||
// if(data.details){
|
||||
// data.details.map((det) => {
|
||||
// if(det.sequence === 1){
|
||||
// room_cost = det.cost
|
||||
// room_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
// descriptionRoom = det.descript == '' ? '-' : det.descript
|
||||
// }
|
||||
|
||||
if(det.sequence === 2){
|
||||
water_cost = det.cost
|
||||
water_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
descriptionWater = det.descript == '' ? '-' : det.descript
|
||||
}
|
||||
// if(det.sequence === 2){
|
||||
// water_cost = det.cost
|
||||
// water_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
// descriptionWater = det.descript == '' ? '-' : det.descript
|
||||
// }
|
||||
|
||||
if(det.sequence === 3){
|
||||
electrict_cost = det.cost
|
||||
electrict_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
descriptionElec = det.descript == '' ? '-' : det.descript
|
||||
}
|
||||
// if(det.sequence === 3){
|
||||
// electrict_cost = det.cost
|
||||
// electrict_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
// descriptionElec = det.descript == '' ? '-' : det.descript
|
||||
// }
|
||||
|
||||
if(det.sequence === 4){
|
||||
service_cost = det.cost
|
||||
service_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
descriptionService = det.descript == '' ? '-' : det.descript
|
||||
}
|
||||
})
|
||||
}
|
||||
// if(det.sequence === 4){
|
||||
// service_cost = det.cost
|
||||
// service_extra_info = det.extra_info != null ? det.extra_info : ''
|
||||
// descriptionService = det.descript == '' ? '-' : det.descript
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
return (
|
||||
<View>
|
||||
@ -462,7 +480,7 @@ class BillScreen extends Component {
|
||||
item.due_at !== null
|
||||
? (
|
||||
<View style={{height:24,backgroundColor: '#FF2D55',justifyContent:'center',alignItems:'center'}}>
|
||||
<Text style={{ fontSize: 12, color: 'white'}}>{t('please_pay_before')} {this.getDueDate(item.due_at)}</Text>
|
||||
<Text style={{ fontSize: 12, color: 'white'}}>{t('please_pay_within')} {this.getDueDate(item.due_at)}</Text>
|
||||
</View>
|
||||
)
|
||||
: null
|
||||
@ -490,11 +508,12 @@ class BillScreen extends Component {
|
||||
roomFilter(index){
|
||||
let payment_exits = this.state.all_payment;
|
||||
let another_room = this.state.room_number_array[index];
|
||||
let payment_array = payment_exits.filter((obj)=>{
|
||||
return Object.keys(obj).reduce((acc, curr)=>{
|
||||
return obj.room_id === another_room
|
||||
}, false);
|
||||
});
|
||||
let payment_array = [];
|
||||
if(payment_exits && payment_exits.length > 0){
|
||||
payment_array = payment_exits.filter((payment) => {
|
||||
return payment.room_id === another_room;
|
||||
})
|
||||
}
|
||||
this.state.payment = payment_array;
|
||||
}
|
||||
|
||||
@ -504,6 +523,15 @@ class BillScreen extends Component {
|
||||
return (
|
||||
<SafeAreaView style={{flex: 1}}>
|
||||
<ScrollView contentContainerStyle={styles.contentContainer}>
|
||||
<NavigationEvents
|
||||
onDidFocus={() => {
|
||||
this.setState({
|
||||
isLoading: true
|
||||
}, () => {
|
||||
this.getData()
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<View style={{ alignItems: 'center'}}>
|
||||
{
|
||||
this.state.sum_payment.length == 0 &&
|
||||
@ -528,7 +556,7 @@ class BillScreen extends Component {
|
||||
<View style={{flex:1}}>
|
||||
<Accordion
|
||||
dataArray={ this.state.payment }
|
||||
expanded={this.state.payment.length - 1}
|
||||
expanded={this.state.payment && this.state.payment.length > 0 ? this.state.payment.length - 1 : []}
|
||||
renderHeader={(data, expanded) => { return this._renderHeader(data, expanded) }}
|
||||
renderContent={(data) => { return this._renderContent(data) }} />
|
||||
</View>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import {ScrollView, StyleSheet, Image, TouchableOpacity, Alert, PermissionsAndroid, ImageBackground, Platform} from "react-native";
|
||||
import {ScrollView, StyleSheet, TouchableOpacity, Alert, PermissionsAndroid, ImageBackground, Platform} from "react-native";
|
||||
import CameraRoll from "@react-native-community/cameraroll";
|
||||
import {View} from "native-base";
|
||||
import Text from '../../components/Text';
|
||||
@ -8,6 +8,7 @@ import ViewShot, { captureRef } from "react-native-view-shot";
|
||||
import IndicatorLoading from '../../components/IndicatorLoading';
|
||||
import QRCode from 'react-native-qrcode-svg';
|
||||
import { t } from '../../utils/i18n';
|
||||
import Image from 'react-native-fast-image'
|
||||
|
||||
class PaymentScreen extends Component {
|
||||
constructor(props) {
|
||||
@ -26,11 +27,24 @@ class PaymentScreen extends Component {
|
||||
this.setState({isLoading:true})
|
||||
payment_detail(this.state.payment_id)
|
||||
.then( res => {
|
||||
if(res.data && res.data.success){
|
||||
this.setState({
|
||||
payment_data: res.data
|
||||
},() => {
|
||||
this.setState({isLoading: false})
|
||||
})
|
||||
}else {
|
||||
Alert.alert(res.data.message, '', [{
|
||||
text: 'ok',
|
||||
onPress: () => {
|
||||
this.setState({
|
||||
isLoading: false
|
||||
}, () => {
|
||||
this.props.navigation.goBack()
|
||||
})
|
||||
}
|
||||
}])
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
@ -81,16 +95,16 @@ class PaymentScreen extends Component {
|
||||
render(){
|
||||
return(
|
||||
<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}>
|
||||
<View style={{flex: 1}}>
|
||||
<View style={{ alignItems: 'center', padding:20}}>
|
||||
<ViewShot style={{width: '100%',alignItems:'center'}} options={{format: "jpg", quality: 1}} ref={ref => this.viewshot = ref}>
|
||||
<View style={{backgroundColor:'white', borderRadius:10,width: '90%',alignItems:'center'}}>
|
||||
<View style={{width: '100%',backgroundColor:'#29558D',height: 55,borderTopLeftRadius:10,borderTopEndRadius:10,alignItems:'center',justifyContent:'center'}}>
|
||||
<View style={styles.QrContainer}>
|
||||
<View style={styles.headerQr}>
|
||||
<Image source={require('../../../assets/images/icon_payment.png')} style={{height: 40}} resizeMode={'contain'}/>
|
||||
</View>
|
||||
<Image source={require('../../../assets/images/icon_promptpay.png')} style={{height: 24,marginVertical: 18}} resizeMode={'contain'}/>
|
||||
<Text style={{fontSize: 18,color:'#00420A'}}>{t('scan_to_pay')}</Text>
|
||||
<Image source={require('../../../assets/images/icon_promptpay.png')} style={{height: 35, marginVertical: 18}} resizeMode={'contain'}/>
|
||||
<Text style={{fontSize: 18,color:'#00420A', textAlign: 'center'}}>{t('scan_to_pay')}</Text>
|
||||
<View style={{flex: 0.9, alignItems: 'center'}}>
|
||||
{/* <Image source={{uri: this.state.payment_data.qr}} style={{flex: 1}} resizeMode="contain"/> */}
|
||||
<View style={{paddingVertical:10}}>
|
||||
<QRCode
|
||||
value={this.state.payment_data.qr}
|
||||
@ -98,6 +112,7 @@ class PaymentScreen extends Component {
|
||||
color='black'
|
||||
backgroundColor='white'/>
|
||||
</View>
|
||||
<View style={{alignItems: 'center'}}>
|
||||
<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: 10,color:'#00000080'}}>{t('ref_no')}: { this.state.payment_data.payment != null && this.state.payment_data.payment.reference}</Text>
|
||||
@ -108,15 +123,17 @@ class PaymentScreen extends Component {
|
||||
<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>
|
||||
</View>
|
||||
</ViewShot>
|
||||
</View>
|
||||
<View style={{alignItems: 'center', paddingHorizontal:20}}>
|
||||
<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>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</ViewShot>
|
||||
|
||||
<View style={{flex: 0.1, justifyContent: 'center'}}>
|
||||
<TouchableOpacity style={{backgroundColor:'#269A21',height: 40,justifyContent:'center',alignItems:'center',borderRadius:5, marginHorizontal: 20}}
|
||||
onPress={this.snapScreen}>
|
||||
<Text style={{color:'white',fontSize:14}}>{t('save')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<IndicatorLoading loadingVisible={this.state.isLoading}/>
|
||||
</ImageBackground>
|
||||
)
|
||||
@ -133,11 +150,24 @@ const styles = StyleSheet.create({
|
||||
alignItems: 'center'
|
||||
},
|
||||
contentContainer: {
|
||||
paddingVertical: 0,
|
||||
flex:1
|
||||
flex:1,
|
||||
padding: 20
|
||||
},
|
||||
colorTextPayment: {
|
||||
color: '#7CBB33'
|
||||
},
|
||||
QrContainer: {
|
||||
flex: 1,
|
||||
backgroundColor:'white',
|
||||
borderRadius:10
|
||||
},
|
||||
headerQr: {
|
||||
width: '100%',
|
||||
backgroundColor:'#29558D',
|
||||
height: 55,
|
||||
borderTopLeftRadius:10,
|
||||
borderTopEndRadius:10,
|
||||
justifyContent:'center'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
197
src/screens/bill/PaymentConfirm.js
Normal file
@ -0,0 +1,197 @@
|
||||
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;
|
||||
381
src/screens/bill/PaymentDetail.js
Normal file
@ -0,0 +1,381 @@
|
||||
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;
|
||||
169
src/screens/forget_password/ForgetPasswordScreen.js
Normal file
@ -0,0 +1,169 @@
|
||||
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;
|
||||
84
src/screens/forget_password/PasswordCode.js
Normal file
@ -0,0 +1,84 @@
|
||||
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;
|
||||
221
src/screens/forget_password/VerifyOTP.js
Normal file
@ -0,0 +1,221 @@
|
||||
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
|
||||
@ -1,20 +1,21 @@
|
||||
import React, { Component } from 'react'
|
||||
import React, {Component, useCallback} from 'react';
|
||||
import { TouchableOpacity, View, Alert, ScrollView, SafeAreaView, KeyboardAvoidingView, Platform } from 'react-native'
|
||||
import Image from 'react-native-fast-image'
|
||||
import GetWidthHeightDevice from '../../components/GetWidthHeightDevice'
|
||||
import { CustomButton } from '../../components/CustomButton'
|
||||
import { CustomInput } from '../../components/CustomInput'
|
||||
import { login } from '../../api/UserApi'
|
||||
import {login, payment} from '../../api/UserApi'
|
||||
import { setToken } from '../../api/api'
|
||||
import { BackgroundImage } from '../../components/BackgroundImage'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import Text from '../../components/Text'
|
||||
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 IndicatorLoading from '../../components/IndicatorLoading';
|
||||
import { locale, t } from '../../utils/i18n'
|
||||
|
||||
import moment from "moment";
|
||||
import messaging from "@react-native-firebase/messaging";
|
||||
|
||||
class LoginScreen extends Component {
|
||||
|
||||
@ -22,35 +23,64 @@ class LoginScreen extends Component {
|
||||
super(props)
|
||||
this.state = {
|
||||
isLoading: false,
|
||||
username: null,
|
||||
password: null,
|
||||
username: '0935697758',
|
||||
password: '123456',
|
||||
payment: [],
|
||||
sum_payment: [],
|
||||
all_payment : [],
|
||||
room_number_array : [],
|
||||
}
|
||||
this._login = this._login.bind(this)
|
||||
}
|
||||
|
||||
_login() {
|
||||
async _login () {
|
||||
if (this.state.username && this.state.password) {
|
||||
|
||||
var regex = /^\d+$/;
|
||||
|
||||
if (regex.test(this.state.username) === true) {
|
||||
let params = {
|
||||
mobile: this.state.username,
|
||||
password: this.state.password
|
||||
console.log('true')
|
||||
|
||||
const fcm = messaging()
|
||||
if (!await fcm.hasPermission()) {
|
||||
try {
|
||||
await messaging().requestPermission()
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
const fcmToken = await messaging().getAPNSToken();
|
||||
|
||||
let params = {
|
||||
// mobile: this.state.username,
|
||||
username: this.state.username,
|
||||
password: this.state.password,
|
||||
fcm_token: fcmToken
|
||||
}
|
||||
|
||||
console.log('params >> ', params)
|
||||
console.log('fcmToken >>>>>>>>>>>>>>>>>>>>>>>>> ', fcmToken)
|
||||
this.setState({isLoading:true})
|
||||
login(params)
|
||||
.then((res) => {
|
||||
if (res.ok) {
|
||||
if (res.data.token) {
|
||||
setToken(res.data.token)
|
||||
this.props.appSetToken(res.data.token)
|
||||
this.props.appSetUser(res.data.user)
|
||||
setTimeout(() => {
|
||||
this.setState({isLoading:false},() => {
|
||||
console.log('data >>>>> ', res.data)
|
||||
if (res.data.access_token) {
|
||||
// setToken(res.data.token)
|
||||
// this.props.appSetToken(res.data.token)
|
||||
setToken(res.data.access_token)
|
||||
this.props.appSetToken(res.data.access_token)
|
||||
this.props.navigation.navigate('HomeScreen',{isLogin:true})
|
||||
})
|
||||
}, 300);
|
||||
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(() => {
|
||||
@ -65,7 +95,7 @@ class LoginScreen extends Component {
|
||||
} else {
|
||||
Alert.alert(null, 'กรุณากรอกข้อมูลให้ครบถ้วน')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
@ -137,6 +167,11 @@ class LoginScreen extends Component {
|
||||
}}
|
||||
style={styles.form_input} />
|
||||
</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 }]}>
|
||||
<CustomButton
|
||||
colorText={'#2470A1'}
|
||||
@ -149,14 +184,14 @@ class LoginScreen extends Component {
|
||||
//onPress={() => { this.props.navigation.navigate('HomeScreen') }}
|
||||
/>
|
||||
</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' }]}>
|
||||
<Text style={{ color: '#FFF', fontSize: 15,/* fontFamily: 'Prompt-Regular', */ }}> {t('not_a_member')} </Text>
|
||||
<Text style={{ color: '#FFF', fontSize: 15}}> {t('not_a_member')} </Text>
|
||||
<TouchableOpacity onPress={() => { this.props.navigation.navigate('Register') }}>
|
||||
<Text style={{ color: '#FFF', fontSize: 15, fontFamily: 'Prompt-Bold' }}> {t('create_account')} </Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View> */}
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@ -26,15 +26,24 @@ class RegisterScreen extends Component {
|
||||
_onNextStep = async () => {
|
||||
var regex = /^\d+$/;
|
||||
|
||||
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) {
|
||||
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 (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.navigation.navigate('RegisterFormLogin');
|
||||
} else {
|
||||
Alert.alert(null, 'ท่านกรอกรูปแบบโทรศัพท์ไม่ถูกต้อง')
|
||||
}
|
||||
} else {
|
||||
Alert.alert(null, 'รหัสผ่านไม่ตรงกัน')
|
||||
if(!this.state.user.mobile){
|
||||
Alert.alert(null, 'กรุณากรอกเบอร์โทรศัพท์')
|
||||
} else if(!this.state.user.password){
|
||||
Alert.alert(null, 'กรุณากรอกรหัสผ่าน')
|
||||
} else if(!this.state.user.password_confirm){
|
||||
Alert.alert(null, 'กรุณากรอกยืนยันรหัสผ่าน')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Alert, ScrollView, TouchableOpacity, View, Platform, KeyboardAvoidingView } from 'react-native'
|
||||
import React, {Component} from 'react'
|
||||
import {Alert, ScrollView, TouchableOpacity, View, Platform, KeyboardAvoidingView} from 'react-native'
|
||||
import Image from 'react-native-fast-image'
|
||||
import { CustomStepIndicator } from '../../components/StepIndicator'
|
||||
import { CustomInput } from '../../components/CustomInput'
|
||||
import { CustomButton } from '../../components/CustomButton'
|
||||
import {CustomStepIndicator} from '../../components/StepIndicator'
|
||||
import {CustomInput} from '../../components/CustomInput'
|
||||
import {CustomButton} from '../../components/CustomButton'
|
||||
import Icon from 'src/components/Icon'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { appSetUser } from '../../redux/app/action'
|
||||
import { connect } from 'react-redux'
|
||||
import { Picker } from 'native-base'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {appSetUser} from '../../redux/app/action'
|
||||
import {connect} from 'react-redux'
|
||||
import DropDownPicker from 'react-native-dropdown-picker'
|
||||
import moment from 'moment'
|
||||
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
|
||||
import {BackgroundImage_RegisterForm} from '../../components/BackgroundImage_RegisterForm'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import Text from '../../components/Text'
|
||||
import { getBuildingByProjectId, project } from '../../api/UserApi'
|
||||
import {getBuildingByProjectId, project} from '../../api/UserApi'
|
||||
import ImagePicker from 'react-native-image-crop-picker'
|
||||
import ActionSheet from 'react-native-action-sheet'
|
||||
import CustomDatePicker from '../room/CustomDatePicker';
|
||||
import { t } from '../../utils/i18n'
|
||||
import {t} from '../../utils/i18n'
|
||||
|
||||
let ACTIONSHEET_BUTTONS = [
|
||||
'ถ่ายรูป',
|
||||
@ -27,6 +27,39 @@ let ACTIONSHEET_BUTTONS = [
|
||||
|
||||
let CANCEL_INDEX = 2
|
||||
|
||||
const DropdownSelection = (props) => {
|
||||
return (
|
||||
<View>
|
||||
<DropDownPicker
|
||||
style={{
|
||||
borderColor: '1px solid rgba(0, 0, 0, 0.25)',
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: 'transparent',
|
||||
marginTop: -6,
|
||||
}}
|
||||
placeholderStyle={{
|
||||
color: "#FFFFFF40"
|
||||
}}
|
||||
dropDownContainerStyle={{
|
||||
borderColor: '1px solid rgba(0, 0, 0, 0.25)',
|
||||
fontFamily: 'Prompt-Regular'
|
||||
}}
|
||||
textStyle={{
|
||||
color: 'white',
|
||||
fontFamily: 'Prompt-Regular',
|
||||
fontSize: 14
|
||||
}}
|
||||
translation={{
|
||||
NOTHING_TO_SHOW: "ไม่มีรายการข้อมูล"
|
||||
}}
|
||||
listMode='MODAL'
|
||||
showArrowIcon={false}
|
||||
{...props}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
class RegisterFormLoginScreen extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
@ -35,12 +68,16 @@ class RegisterFormLoginScreen extends Component {
|
||||
project_list: [],
|
||||
building_list: [],
|
||||
selected_project: 0,
|
||||
project_name:t('choose_project'),
|
||||
project_name: t('choose_project'),
|
||||
image_url: require('../../../assets/images/profile.png'),
|
||||
enableSummit: false,
|
||||
checkFullname: false,
|
||||
checkCitizenID: false,
|
||||
checkBirthDate: null
|
||||
checkBirthDate: null,
|
||||
checkRoomNo: false,
|
||||
is_customer: true,
|
||||
openProject: false,
|
||||
openBuilding: false
|
||||
}
|
||||
this._onNextStep = this._onNextStep.bind()
|
||||
this.onImagePick = this.onImagePick.bind(this)
|
||||
@ -52,7 +89,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
this.setDefaultUserData()
|
||||
}
|
||||
|
||||
setDefaultUserData(){
|
||||
setDefaultUserData() {
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
@ -65,9 +102,21 @@ class RegisterFormLoginScreen extends Component {
|
||||
project()
|
||||
.then(res => {
|
||||
if (res.ok) {
|
||||
return this.setState({
|
||||
project_list: res.data.data,
|
||||
selected_project: res.data.data[0].id
|
||||
console.log('data >>> ', res.data)
|
||||
let project_list = res.data.data.map((data) => {
|
||||
return {
|
||||
...data,
|
||||
value: data.id,
|
||||
label: this.props.lang === 'th' ? data.name_th : data.name_en,
|
||||
labelStyle: {
|
||||
color: 'black'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.setState({
|
||||
project_list,
|
||||
// selected_project: res.data.data[0].id
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -81,11 +130,21 @@ class RegisterFormLoginScreen extends Component {
|
||||
.then(res => {
|
||||
// console.log('-------------------> ', res)
|
||||
if (res.ok) {
|
||||
let building_list = res.data.data.map((data) => {
|
||||
return {
|
||||
...data,
|
||||
value: data.room_build,
|
||||
label: data.room_build,
|
||||
labelStyle: {
|
||||
color: 'black'
|
||||
}
|
||||
}
|
||||
})
|
||||
this.setState({
|
||||
building_list: res.data.data,
|
||||
building_list,
|
||||
user: { //set default building index 0
|
||||
...this.state.user,
|
||||
building: res.data.data[0].room_build
|
||||
// building: res.data.data[0].room_build
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -94,7 +153,14 @@ class RegisterFormLoginScreen extends Component {
|
||||
|
||||
_onNextStep = async () => {
|
||||
// if (this.state.user.email && this.state.user.mobile) {
|
||||
if (this.state.user.mobile && this.state.user.tax_id && this.state.user.name && this.state.user.birth_date) {
|
||||
// let tax_id = this.state.user && this.state.user.tax_id
|
||||
// if(!tax_id && !this.state.is_customer){
|
||||
// tax_id = (Math.floor(1000000000000 + Math.random() * 9000000000000)).toString();
|
||||
// }
|
||||
if (this.state.user.mobile
|
||||
// && this.state.is_customer && this.state.user.tax_id && (this.state.user.tax_id.toString()).length > 0
|
||||
// && tax_id.length > 0
|
||||
&& this.state.user.name) {
|
||||
/*var email_validate = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
if (email_validate.test(this.state.user.email) === true) {
|
||||
this.props.appSetUser(this.state.user)
|
||||
@ -102,16 +168,26 @@ class RegisterFormLoginScreen extends Component {
|
||||
} else {
|
||||
Alert.alert(null, 'ท่านกรอกรูปแบบอีเมลไม่ถูกต้อง')
|
||||
}*/
|
||||
console.log('check user data next <<<<<<<< ',this.state.user);
|
||||
console.log('check user data next <<<<<<<< ', this.state.user);
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
// tax_id: !this.state.is_customer ? Math.floor(1000000000000 + Math.random() * 9000000000000) : this.state.user.tax_id,
|
||||
// is_customer: this.state.is_customer
|
||||
}
|
||||
}, () => {
|
||||
// console.log('user >>> ', this.state.user)
|
||||
this.props.appSetUser(this.state.user)
|
||||
// next page !!
|
||||
this.props.navigation.navigate('RegisterProfile')
|
||||
this.props.navigation.navigate('RegisterProfile', {image_url: this.state.image_url})
|
||||
})
|
||||
} else {
|
||||
console.log('กรุณากรอกข้อมูลให้ครบถ้วน')
|
||||
Alert.alert(null, 'กรุณากรอกข้อมูลให้ครบถ้วน')
|
||||
}
|
||||
}
|
||||
|
||||
onImagePick () {
|
||||
onImagePick() {
|
||||
ImagePicker.openPicker({
|
||||
width: 300,
|
||||
height: 300,
|
||||
@ -125,7 +201,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
name: 'image_profile.jpg',
|
||||
}
|
||||
this.setState({
|
||||
image_url: { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height },
|
||||
image_url: {uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height},
|
||||
images: null,
|
||||
user: {
|
||||
...this.state.user,
|
||||
@ -135,7 +211,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
}).catch(e => alert(e))
|
||||
}
|
||||
|
||||
onTakeCamera () {
|
||||
onTakeCamera() {
|
||||
ImagePicker.openCamera({
|
||||
cropping: true,
|
||||
width: 300,
|
||||
@ -149,7 +225,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
name: 'image_profile.jpg',
|
||||
}
|
||||
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,
|
||||
user: {
|
||||
...this.state.user,
|
||||
@ -159,27 +235,49 @@ class RegisterFormLoginScreen extends Component {
|
||||
}).catch(e => alert(e))
|
||||
}
|
||||
|
||||
handleRequired = (e,type) => {
|
||||
validateNextStepBtn(){
|
||||
if (this.state.checkFullname.length > 0 && this.state.user.project && this.state.user.building && this.state.checkRoomNo.length > 0) {
|
||||
this.setState({
|
||||
enableSummit: true
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
enableSummit: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleRequired = (e, type) => {
|
||||
// e = value
|
||||
console.log(type + " : ", e);
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case 'fullname':
|
||||
// code block
|
||||
this.setState(() => ({ ['checkFullname']: e }));
|
||||
this.setState(() => ({['checkFullname']: e}), () => {
|
||||
this.validateNextStepBtn()
|
||||
});
|
||||
break;
|
||||
case 'citizen_id':
|
||||
this.setState(() => ({ ['checkCitizenID']: e }));
|
||||
case 'room':
|
||||
// code block
|
||||
this.setState(() => ({['checkRoomNo']: e}), () => {
|
||||
this.validateNextStepBtn()
|
||||
});
|
||||
break;
|
||||
/*case 'citizen_id':
|
||||
this.setState(() => ({['checkCitizenID']: e}));
|
||||
break;*/
|
||||
default:
|
||||
this.validateNextStepBtn()
|
||||
// code block
|
||||
}
|
||||
|
||||
// console.log(this.state.user.birth_date);
|
||||
// check all
|
||||
if(this.state.checkFullname.length >= 1 && this.state.checkCitizenID.length >= 1 && typeof this.state.user.birth_date != 'undefined'){
|
||||
this.setState(() => ({ ['enableSummit']: true }));
|
||||
}
|
||||
|
||||
setOpen = (open, key) => {
|
||||
this.setState({
|
||||
[key]: open
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -193,9 +291,9 @@ class RegisterFormLoginScreen extends Component {
|
||||
resizeMode: 'cover'
|
||||
}}
|
||||
>
|
||||
<KeyboardAvoidingView style={{flex:1}} keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0} behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
|
||||
<KeyboardAvoidingView style={{flex: 1}} keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0} behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
|
||||
<BackgroundImage_RegisterForm>
|
||||
<ScrollView showsVerticalScrollIndicator={false} style={{ flex: 1 }}>
|
||||
<ScrollView showsVerticalScrollIndicator={false} style={{flex: 1}}>
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.step_indicator]}>
|
||||
<CustomStepIndicator
|
||||
@ -206,6 +304,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
<View style={styles.logo}>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexGrow: 1,
|
||||
backgroundColor: '#3AA40C',
|
||||
alignItems: 'center',
|
||||
@ -261,7 +360,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
</View>
|
||||
{/*<Text> LOGO </Text>*/}
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={{flex: 1}}>
|
||||
<View style={[styles.form]}>
|
||||
<Text style={styles.headerTitle}> {t('profile')} </Text>
|
||||
<View style={styles.row}>
|
||||
@ -281,7 +380,17 @@ class RegisterFormLoginScreen extends Component {
|
||||
}
|
||||
})
|
||||
}}
|
||||
onChangeText={(evt) => this.handleRequired(evt, "fullname")}
|
||||
value={this.state.user.name}
|
||||
onChangeText={(evt) => {
|
||||
this.handleRequired(evt, "fullname")
|
||||
this.setState({
|
||||
user:{
|
||||
...this.state.user,
|
||||
name: evt.replace(/\u0020/, '\u00a0')
|
||||
|
||||
}
|
||||
})
|
||||
}}
|
||||
placeholder={t('specific_fullname')}
|
||||
placeholderTextColor={'#FFFFFF40'}
|
||||
/>
|
||||
@ -309,7 +418,7 @@ class RegisterFormLoginScreen extends Component {
|
||||
placeholderTextColor={'#FFFFFF40'}
|
||||
/>
|
||||
</View> */}
|
||||
<View style={styles.row}>
|
||||
{/*<View style={styles.row}>
|
||||
<View style={styles.row_grow_first}>
|
||||
<View
|
||||
style={{
|
||||
@ -359,9 +468,9 @@ class RegisterFormLoginScreen extends Component {
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>*/}
|
||||
{/* /// */}
|
||||
<View style={styles.row}>
|
||||
{/*<View style={styles.row}>
|
||||
<View style={styles.row_grow}>
|
||||
<CustomDatePicker titleText={t('birth_date')} dateText={this.state.user.text_birth} maxDate={new Date()} handleDate={(data) => {
|
||||
this.setState({
|
||||
@ -371,32 +480,12 @@ class RegisterFormLoginScreen extends Component {
|
||||
birth_date_show: moment(data).format('MM/DD/YYYY'),
|
||||
text_birth: moment(data).add(543, 'years').format('DD-MM-YYYY')
|
||||
}
|
||||
})
|
||||
}, () => {
|
||||
this.handleRequired(data, "birth_date");
|
||||
})
|
||||
}}/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<CustomInput
|
||||
maxLength={13}
|
||||
style={styles.register_input}
|
||||
labelColor={'white'}
|
||||
placeholderTextColor={'white'}
|
||||
labelName={t('citizen_id')}
|
||||
onEndEditing={e => {
|
||||
let input = e.nativeEvent.text
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
tax_id: input
|
||||
}
|
||||
})
|
||||
}}
|
||||
onChangeText={(evt) => this.handleRequired(evt, "citizen_id")}
|
||||
placeholder={t('citizen_id_13')}
|
||||
placeholderTextColor={'#FFFFFF40'}
|
||||
/>
|
||||
</View>
|
||||
</View>*/}
|
||||
<View style={styles.row}>
|
||||
<CustomInput
|
||||
maxLength={10}
|
||||
@ -420,6 +509,74 @@ class RegisterFormLoginScreen extends Component {
|
||||
value={this.state.user.mobile || ''}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/*<View style={styles.userTypeContainer}>
|
||||
<TouchableOpacity style={styles.radioInput}
|
||||
onPress={() => {this.setState({
|
||||
is_customer: true }, () => {
|
||||
this.handleRequired(this.state.is_customer, "user_type");
|
||||
})
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.state.is_customer ?
|
||||
<Image source={require('../../../assets/images/radio_button_checked.png')} style={{width: 20, height: 20, marginRight: 5}} />
|
||||
: <Image source={require('../../../assets/images/radio_button.png')} style={{width: 20, height: 20, marginRight: 5}} />
|
||||
}
|
||||
|
||||
<Text style={{color: 'white'}}>{t('customer')}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.radioInput}
|
||||
onPress={() => {
|
||||
this.setState({
|
||||
is_customer: false,
|
||||
user: {
|
||||
...this.state.user,
|
||||
tax_id: '',
|
||||
building: '',
|
||||
room: ''
|
||||
},
|
||||
checkCitizenID: false
|
||||
}, () => {
|
||||
this.handleRequired(this.state.is_customer, "user_type");
|
||||
})
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.state.is_customer ?
|
||||
<Image source={require('../../../assets/images/radio_button.png')} style={{width: 20, height: 20, marginRight: 5}} />
|
||||
: <Image source={require('../../../assets/images/radio_button_checked.png')} style={{width: 20, height: 20, marginRight: 5}} />
|
||||
}
|
||||
<Text style={{color: 'white'}}>{t('guest')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>*/}
|
||||
|
||||
{/*{
|
||||
this.state.is_customer &&
|
||||
<View style={styles.row}>
|
||||
<CustomInput
|
||||
maxLength={13}
|
||||
style={styles.register_input}
|
||||
labelColor={'white'}
|
||||
placeholderTextColor={'white'}
|
||||
labelName={t('citizen_id')}
|
||||
onEndEditing={e => {
|
||||
let input = e.nativeEvent.text
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
tax_id: input
|
||||
}
|
||||
})
|
||||
}}
|
||||
onChangeText={(evt) => this.handleRequired(evt, "citizen_id")}
|
||||
placeholder={t('citizen_id_13')}
|
||||
placeholderTextColor={'#FFFFFF40'}
|
||||
/>
|
||||
</View>
|
||||
}*/}
|
||||
|
||||
<Text style={styles.headerTitle}> {t('accom_info')} </Text>
|
||||
<View style={styles.row}>
|
||||
<View
|
||||
@ -448,43 +605,36 @@ class RegisterFormLoginScreen extends Component {
|
||||
{t('project')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Picker
|
||||
// mode="dropdown"
|
||||
style={{
|
||||
height: 40,
|
||||
color:'white'
|
||||
}}
|
||||
textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}}
|
||||
labelName={t('project')}
|
||||
<View style={{flex: 1}}>
|
||||
<DropdownSelection
|
||||
open={this.state.openProject}
|
||||
items={this.state.project_list}
|
||||
value={this.state.selected_project}
|
||||
setOpen={(open) => this.setOpen(open, 'openProject')}
|
||||
placeholder={t('choose_project')}
|
||||
placeholderStyle={{color:'#FFFFFF40'}}
|
||||
selectedValue={this.state.project_item}
|
||||
onValueChange={e => {
|
||||
// console.log('@@@@@@ project selected --------> ',e);
|
||||
onSelectItem={(e) => {
|
||||
this.setState({
|
||||
project_name: e.name,
|
||||
project_name: e.label,
|
||||
project_item: e,
|
||||
selected_project: e.id,
|
||||
user: {
|
||||
...this.state.user,
|
||||
project: e.code,
|
||||
project_name : e.name
|
||||
project_name: this.props.lang === 'th' ? e.name_th : e.name_en
|
||||
},
|
||||
}, () => {
|
||||
// console.log('check project selected --------> ',this.state.project_name);
|
||||
console.log('check project selected --------> ',this.state.project_name);
|
||||
this.handleRequired(e, "project")
|
||||
this.getBuildingList()
|
||||
})
|
||||
}}
|
||||
>
|
||||
{this.state.project_list.map((item) => {
|
||||
return <Picker.Item label={item.name} value={item} key={'project_'+item}/>
|
||||
})}
|
||||
</Picker>
|
||||
/>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
this.state.is_customer &&
|
||||
<View style={styles.row}>
|
||||
<View
|
||||
style={{
|
||||
@ -514,31 +664,25 @@ class RegisterFormLoginScreen extends Component {
|
||||
{t('building')}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Picker
|
||||
// mode="dropdown"
|
||||
style={{
|
||||
height: 40,
|
||||
color:'white'
|
||||
}}
|
||||
textStyle={{color:'white',fontFamily:'Prompt-Regular',fontSize:14}}
|
||||
labelName={t('building')}
|
||||
placeholder={'เลือกอาคาร'}
|
||||
placeholderStyle={{color:'#FFFFFF40'}}
|
||||
selectedValue={this.state.user.building}
|
||||
onValueChange={e => {
|
||||
<View style={{flex: 1}}>
|
||||
<DropdownSelection
|
||||
open={this.state.openBuilding}
|
||||
items={this.state.building_list}
|
||||
value={this.state.user && this.state.user.building}
|
||||
setOpen={(open) => this.setOpen(open, 'openBuilding')}
|
||||
placeholder='เลือกอาคาร'
|
||||
onSelectItem={(e) => {
|
||||
console.log('e >>>>>> ', e)
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
building: e
|
||||
building: e.value
|
||||
}
|
||||
}, () => {
|
||||
this.handleRequired(e, "building")
|
||||
})
|
||||
}}
|
||||
>
|
||||
{this.state.building_list.map((item) => {
|
||||
return <Picker.Item label={item.room_build} value={item.room_build} key={'building_'+item.room_build}/>
|
||||
})}
|
||||
</Picker>
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.row_grow}>
|
||||
@ -549,13 +693,15 @@ class RegisterFormLoginScreen extends Component {
|
||||
placeholderTextColor={'white'}
|
||||
//New Code style
|
||||
labelName={t('room2')}
|
||||
onEndEditing={e => {
|
||||
let input = e.nativeEvent.text
|
||||
onChangeText={e => {
|
||||
// let input = e.nativeEvent.text
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
room: input
|
||||
room: e
|
||||
}
|
||||
}, () => {
|
||||
this.handleRequired(e, "room")
|
||||
})
|
||||
}}
|
||||
placeholder={t('room_no')}
|
||||
@ -563,11 +709,25 @@ class RegisterFormLoginScreen extends Component {
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.buttons}>
|
||||
}
|
||||
|
||||
<View style={[styles.buttons, {display: this.state.enableSummit ? 'none' : 'flex'}]}>
|
||||
<View style={styles.row_grow}>
|
||||
<CustomButton
|
||||
// disabled="true"
|
||||
style={ this.state.enableSummit ? [styles.btn_next_register , styles.enableNext]: [styles.btn_next_register , styles.disableNext] } // enableNext
|
||||
style={styles.disableNext} // enableNext
|
||||
title={t('next')}
|
||||
sizeText={14}
|
||||
// onPress={this._onNextStep}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[styles.buttons, {display: this.state.enableSummit ? 'flex' : 'none'}]}>
|
||||
<View style={styles.row_grow}>
|
||||
<CustomButton
|
||||
// disabled="true"
|
||||
style={styles.enableNext} // enableNext
|
||||
title={t('next')}
|
||||
sizeText={14}
|
||||
onPress={this._onNextStep}
|
||||
@ -592,6 +752,7 @@ const styles = {
|
||||
flexDirection: 'column'
|
||||
},
|
||||
logo: {
|
||||
flex: 1,
|
||||
backgroundColor: '#3AA40C',
|
||||
height: '20%',
|
||||
flexDirection: 'row',
|
||||
@ -613,7 +774,8 @@ const styles = {
|
||||
paddingBottom: 0
|
||||
},
|
||||
step_indicator: {
|
||||
backgroundColor: '#3AA40C'
|
||||
backgroundColor: '#3AA40C',
|
||||
flex: 1
|
||||
},
|
||||
buttons: {
|
||||
flexDirection: 'row',
|
||||
@ -642,22 +804,50 @@ const styles = {
|
||||
fontFamily: 'Prompt-Regular',
|
||||
borderRadius: 30
|
||||
},
|
||||
disableNext :{
|
||||
disableNext: {
|
||||
opacity: 0.65,
|
||||
cursor: "not-allowed",
|
||||
backgroundColor: '#AAAAAA'
|
||||
},
|
||||
enableNext :{
|
||||
enableNext: {
|
||||
opacity: 1,
|
||||
color: '#FFFFFF',
|
||||
backgroundColor: '#145EB3'
|
||||
}
|
||||
},
|
||||
userTypeContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
paddingTop: 5,
|
||||
paddingBottom: 10
|
||||
},
|
||||
radioInput: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
custom_button_container: {
|
||||
// flex:1,
|
||||
// flexDirection: 'row',
|
||||
height: 35,
|
||||
abckgroundColor: '#FF9500',
|
||||
borderRadius: 5,
|
||||
width: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
icon: {
|
||||
justifyContent: 'center',
|
||||
// alignItems: '',
|
||||
// flex: 1,
|
||||
paddingLeft: 5,
|
||||
paddingRight: 5
|
||||
},
|
||||
}
|
||||
|
||||
const mapDisPatchToProps = state => {
|
||||
return state.app
|
||||
}
|
||||
const setUser = dispatch => bindActionCreators({ appSetUser }, dispatch)
|
||||
const setUser = dispatch => bindActionCreators({appSetUser}, dispatch)
|
||||
export default connect(
|
||||
mapDisPatchToProps,
|
||||
setUser
|
||||
|
||||
@ -5,14 +5,15 @@ import { CustomStepIndicator } from '../../components/StepIndicator'
|
||||
import GetWidthHeightDevice from '../../components/GetWidthHeightDevice'
|
||||
import { CustomButton } from '../../components/CustomButton'
|
||||
import { connect } from 'react-redux'
|
||||
import { register, registerDevice, testConnect } from '../../api/UserApi'
|
||||
import {checkPaymentMeter, register, registerDevice, testConnect} from '../../api/UserApi'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import { appSetDevice, appSetPushToken, appSetToken, appSetUser } from '../../redux/app/action'
|
||||
import firebase, { Notification } from 'react-native-firebase'
|
||||
import {appSetDevice, appSetPushToken, appSetToken, appSetUser, setPopupNotification} from '../../redux/app/action'
|
||||
import messaging from "@react-native-firebase/messaging";
|
||||
import moment from 'moment'
|
||||
import { setToken } from '../../api/api'
|
||||
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import Text from '../../components/Text';
|
||||
import { t } from '../../utils/i18n'
|
||||
|
||||
@ -23,7 +24,8 @@ class RegisterProfileScreen extends Component {
|
||||
|
||||
this.state = {
|
||||
auth: false,
|
||||
disableButton: false
|
||||
disableButton: false,
|
||||
image_url: require('../../../assets/images/profile.png'),
|
||||
}
|
||||
|
||||
this._register = this._register.bind(this);
|
||||
@ -36,27 +38,31 @@ class RegisterProfileScreen extends Component {
|
||||
if (!this.props.push_token) {
|
||||
this.initNotification();
|
||||
}
|
||||
|
||||
this.setState({
|
||||
image_url: this.props.navigation.getParam('image_url', require('../../../assets/images/profile.png'))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
initNotification = async () => {
|
||||
await this.setPermission()
|
||||
const fcmToken = await firebase.messaging().getToken()
|
||||
const fcmToken = await messaging().getToken()
|
||||
console.log('fcmToken', fcmToken)
|
||||
if (fcmToken) {
|
||||
this.props.appSetPushToken(fcmToken)
|
||||
console.log('fcmToken', this.props)
|
||||
|
||||
} else {
|
||||
Alert.alert(null, 'Cannot get push token.', [{ text: 'ok' }])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setPermission = async () => {
|
||||
try {
|
||||
const enabled = await firebase.messaging().hasPermission()
|
||||
const enabled = await messaging().hasPermission()
|
||||
if (!enabled) {
|
||||
await firebase.messaging().requestPermission()
|
||||
await messaging().requestPermission()
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('error', error)
|
||||
@ -72,14 +78,22 @@ class RegisterProfileScreen extends Component {
|
||||
this.props.appSetDevice(resultSendDevice.data.device)
|
||||
}
|
||||
}
|
||||
if (!this.props.device || !this.props.push_token) {
|
||||
|
||||
let systemName = DeviceInfo.getSystemName();
|
||||
let deviceId = null
|
||||
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({
|
||||
...this.props.user,
|
||||
device_id: this.props.device.id
|
||||
device_id: deviceId,
|
||||
name: this.props.user.name.replace(/\u00a0/g, /\u0020/),
|
||||
fcm_token: this.props.push_token
|
||||
}).then(
|
||||
(res) => {
|
||||
if (res.ok && res.data.success) {
|
||||
@ -89,8 +103,40 @@ class RegisterProfileScreen extends Component {
|
||||
this.props.appSetUser(res.data.customer)
|
||||
this.props.appSetToken(res.data.token)
|
||||
setToken(token)
|
||||
Alert.alert(null, t('register_success'), [{ text: t('ok') }])
|
||||
this.props.navigation.navigate('HomeScreen')
|
||||
|
||||
Alert.alert(
|
||||
'',
|
||||
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 {
|
||||
this.props.appSetUser(null)
|
||||
@ -125,7 +171,7 @@ class RegisterProfileScreen extends Component {
|
||||
}}>
|
||||
<Image
|
||||
style={{ width: 100, height: 100, borderRadius: 50, borderColor: 'white', borderWidth: 2 }}
|
||||
source={require('../../../assets/images/profile.png')}
|
||||
source={this.state.image_url}
|
||||
/>
|
||||
</View>
|
||||
{/*<Text> LOGO </Text>*/}
|
||||
@ -138,10 +184,10 @@ class RegisterProfileScreen extends Component {
|
||||
<View style={[styles.table]}>
|
||||
|
||||
<View style={styles.row_title}>
|
||||
<Text style={styles.title_data}> ชื่อ </Text>
|
||||
<Text style={styles.title_data}> {t('name')} </Text>
|
||||
{/* <Text style={styles.title_data}> อีเมล </Text> */}
|
||||
<Text style={styles.title_data}> {t('gender')} </Text>
|
||||
<Text style={styles.title_data}> {t('birth_date')} </Text>
|
||||
{/*<Text style={styles.title_data}> {t('gender')} </Text>*/}
|
||||
{/*<Text style={styles.title_data}> {t('birth_date')} </Text>*/}
|
||||
<Text style={styles.title_data}> {t('phone2')} </Text>
|
||||
</View>
|
||||
{
|
||||
@ -149,8 +195,8 @@ class RegisterProfileScreen extends Component {
|
||||
<View style={styles.row_data}>
|
||||
<Text style={styles.detail_data}> {user.name} </Text>
|
||||
{/* <Text style={styles.detail_data}> {user.email} </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}> {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}> {user.mobile} </Text>
|
||||
</View>
|
||||
}
|
||||
@ -276,5 +322,5 @@ const styles = {
|
||||
const mapDisPatchToProps = state => {
|
||||
return state.app
|
||||
}
|
||||
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser }, dispatch)
|
||||
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser, setPopupNotification }, dispatch)
|
||||
export default connect(mapDisPatchToProps, setUser)(RegisterProfileScreen)
|
||||
|
||||
@ -4,14 +4,25 @@ import Text from '../../components/Text';
|
||||
import { Badge } from 'native-base'
|
||||
import { WebView } from 'react-native-webview';
|
||||
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";
|
||||
|
||||
export default class TermsAndCondition extends Component {
|
||||
class TermsAndCondition extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
currentLocale: 'th'
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.setState({
|
||||
currentLocale : I18n.currentLocale()
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={{flex:1}}>
|
||||
@ -26,7 +37,8 @@ export default class TermsAndCondition extends Component {
|
||||
flex: 1,
|
||||
}}
|
||||
originWhitelist={['*']}
|
||||
source={{ uri: 'https://www.csasset.co.th/Privacy-Policy-TH.htm'}}
|
||||
// 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={ this.state.currentLocale === 'th' ? { uri: 'https://powercondo.csasset.co.th/privacy-policy-new'} : {uri: 'https://powercondo.csasset.co.th/privacy-policy-en'}}
|
||||
javaScriptEnabled={true}
|
||||
domStorageEnabled={true}
|
||||
onNavigationStateChange={(event) => {
|
||||
@ -41,6 +53,7 @@ export default class TermsAndCondition extends Component {
|
||||
</View>
|
||||
<View style={{flexDirection:'row',justifyContent:'space-around',height:60}}>
|
||||
<TouchableOpacity onPress={() => {
|
||||
this.props. appCleanUser();
|
||||
this.props.navigation.goBack()
|
||||
}}>
|
||||
<View>
|
||||
@ -64,3 +77,6 @@ export default class TermsAndCondition extends Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const clearUser = dispatch => bindActionCreators({appCleanUser}, dispatch);
|
||||
export default connect(null, clearUser)(TermsAndCondition);
|
||||
|
||||
@ -32,6 +32,12 @@ export default class Meter extends Component {
|
||||
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(){
|
||||
this.setState({
|
||||
isLoading: true
|
||||
@ -71,7 +77,8 @@ export default class Meter extends Component {
|
||||
cropping: true,
|
||||
width: 300,
|
||||
height: 100,
|
||||
includeExif: true
|
||||
includeExif: true,
|
||||
includeBase64: true
|
||||
}).then(image => {
|
||||
console.log('received image', image)
|
||||
let image_meter = {
|
||||
@ -79,13 +86,15 @@ export default class Meter extends Component {
|
||||
type: image.mime,
|
||||
name: 'image_meter.jpg',
|
||||
}
|
||||
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height};
|
||||
this.setState({
|
||||
image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
|
||||
image_url: image_data,
|
||||
images: null,
|
||||
image_preview: image_meter
|
||||
}, () => {
|
||||
this.selectedImage(this.state.image_url)
|
||||
})
|
||||
}).catch(e => alert(e))
|
||||
}).catch(e => {})
|
||||
}
|
||||
|
||||
selectedImage(image_meter){
|
||||
@ -94,9 +103,9 @@ export default class Meter extends Component {
|
||||
},() => {
|
||||
console.log('selected image ',this.state.image_selected)
|
||||
if(this.state.selected_type == 'pea'){
|
||||
this.props.navigation.navigate('PEAMeter',{image: this.state.image_selected,room_id: this.state.room_list[this.state.room_snap_index].id})
|
||||
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})
|
||||
}else{
|
||||
this.props.navigation.navigate('WaterMeter',{image: this.state.image_selected,room_id: this.state.room_list[this.state.room_snap_index].id})
|
||||
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})
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -104,7 +113,7 @@ export default class Meter extends Component {
|
||||
_keyExtractor = (item, index) => 'meter_room_'+index;
|
||||
|
||||
_renderItem = ({item}) => (
|
||||
<LinearGradient colors={['#4BAF3B', '#0E5E29']} style={{ height: 120, borderColor: 'white', borderRadius: 5, height: 120,paddingBottom:10, justifyContent:'space-between'}}>
|
||||
<LinearGradient colors={['#4BAF3B', '#0E5E29']} style={{ borderColor: 'white', borderRadius: 5, height: 120,paddingBottom:10, justifyContent:'space-between'}}>
|
||||
<View style={{ justifyContent: 'center',padding:16 }}>
|
||||
<Text style={{ color: 'white', fontSize: 16 }}>{item.name}</Text>
|
||||
<Text style={{ color: 'white', fontSize: 16 }}>{item.project_name}</Text>
|
||||
@ -129,7 +138,7 @@ export default class Meter extends Component {
|
||||
<View style={{paddingHorizontal:16,height: 96,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}>
|
||||
<View style={{flex:1,flexDirection:'row'}}>
|
||||
<View style={{height: 96,justifyContent:'center',marginRight:16}}>
|
||||
<Image source={{uri:item.media.url}} style={{height: 64,width: 64,}} resizeMode={'contain'}/>
|
||||
<Image source={{uri:item.image_meter}} style={{height: 64,width: 64,}} resizeMode={'contain'}/>
|
||||
</View>
|
||||
<View style={{flex:1,justifyContent:'center'}}>
|
||||
<View style={styles.viewTextFlatlist}>
|
||||
|
||||
@ -6,15 +6,18 @@ import PopupMeter from './PopupMeter';
|
||||
import ImagePicker from 'react-native-image-crop-picker'
|
||||
import {postMeter, postMeterImage} from '../../api/UserApi';
|
||||
import moment from 'moment';
|
||||
import { t } from '../../utils/i18n'
|
||||
|
||||
export default class PEAMeter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
numberMeter: '0',
|
||||
numberMeter: '',
|
||||
isLoading: false,
|
||||
isVisible: false,
|
||||
image: this.props.navigation.getParam('image','no-image'),
|
||||
image_send: {},
|
||||
image_preview: this.props.navigation.getParam('image_preview', 'no-image'),
|
||||
room_id: this.props.navigation.getParam('room_id','no-id'),
|
||||
isConfirm: false
|
||||
};
|
||||
@ -24,22 +27,24 @@ export default class PEAMeter extends Component {
|
||||
this.onOK = this.onOK.bind(this)
|
||||
this.onPopup = this.onPopup.bind(this)
|
||||
this.onTakeCamera = this.onTakeCamera.bind(this)
|
||||
this.postImageToOCR = this.postImageToOCR.bind(this)
|
||||
//this.postImageToOCR = this.postImageToOCR.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.setState({
|
||||
image_send: {
|
||||
uri: this.state.image.uri,
|
||||
type: this.state.image.mime,
|
||||
name: `image_meter_${moment()}.jpg`,
|
||||
// type: this.state.image.mime,
|
||||
// name: `image_meter_${moment()}.jpg`,
|
||||
width: this.state.image.width,
|
||||
height: this.state.image.height
|
||||
}
|
||||
},() => {
|
||||
this.postImageToOCR()
|
||||
})
|
||||
}/*,() => {
|
||||
//this.postImageToOCR()
|
||||
}*/)
|
||||
};
|
||||
|
||||
postImageToOCR(){
|
||||
/*postImageToOCR(){
|
||||
let param = {
|
||||
image: this.state.image_send
|
||||
}
|
||||
@ -52,7 +57,7 @@ export default class PEAMeter extends Component {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
onTextChanged(text){
|
||||
this.setState({
|
||||
@ -75,7 +80,8 @@ export default class PEAMeter extends Component {
|
||||
cropping: true,
|
||||
width: 300,
|
||||
height: 100,
|
||||
includeExif: true
|
||||
includeExif: true,
|
||||
includeBase64: true
|
||||
}).then(image => {
|
||||
console.log('received image', image)
|
||||
let image_meter = {
|
||||
@ -83,18 +89,19 @@ export default class PEAMeter extends Component {
|
||||
type: image.mime,
|
||||
name: 'image_meter.jpg',
|
||||
}
|
||||
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
|
||||
this.setState({
|
||||
image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
|
||||
images: null,
|
||||
}, () => {
|
||||
this.setState({
|
||||
image: this.state.image_url,
|
||||
image_send: image_meter
|
||||
},() => {
|
||||
image_send: image_data
|
||||
}/*,() => {
|
||||
this.postImageToOCR()
|
||||
}*/)
|
||||
})
|
||||
})
|
||||
}).catch(e => Alert.alert('Error',e))
|
||||
}).catch(e => {})
|
||||
}
|
||||
|
||||
onConfirm(){
|
||||
@ -102,6 +109,11 @@ export default class PEAMeter extends Component {
|
||||
}
|
||||
|
||||
onOK(){
|
||||
if (!this.state.isLoading) {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isVisible: false
|
||||
}, () => {
|
||||
let param = {
|
||||
room_id: this.state.room_id,
|
||||
type: 'ค่าไฟ',
|
||||
@ -113,9 +125,36 @@ export default class PEAMeter extends Component {
|
||||
postMeter(param)
|
||||
.then(res => {
|
||||
console.log('response post meter ------> ',res.data)
|
||||
this.onPopup()
|
||||
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 }))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onPopup(){
|
||||
@ -128,9 +167,9 @@ export default class PEAMeter extends Component {
|
||||
return (
|
||||
<ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}>
|
||||
<View style={{flex:1}}>
|
||||
<SaveViewMeter amount={this.state.numberMeter} TypeName={'ไฟฟ้า'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/>
|
||||
<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}/>
|
||||
</View>
|
||||
<PopupMeter modalVisible={this.state.isVisible} onOk={this.onOK} onCancel={this.onPopup}/>
|
||||
<PopupMeter modalVisible={this.state.isVisible} onOk={!this.state.isLoading ? this.onOK : null} onCancel={this.onPopup}/>
|
||||
</ImageBackground>
|
||||
);
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ export default class PopupMeter extends Component {
|
||||
<TouchableOpacity style={{paddingHorizontal:15,}} onPress={() => {this.props.onCancel()}}>
|
||||
<Text style={{color:'#00000040',fontSize: 14,}}>Cancel</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={{paddingHorizontal:15}} onPress={() => {this.props.onOk()}}>
|
||||
<TouchableOpacity style={{paddingHorizontal:15}} onPress={() => {this.props.onOk && this.props.onOk()}}>
|
||||
<Text style={{color:'#2C7C0B',fontSize: 14,}}>OK</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@ -20,7 +20,7 @@ export default class SaveViewMeter extends Component {
|
||||
<View style={{justifyContent:'center',alignItems:'center'}}>
|
||||
<Image source={{uri:this.props.ImageUri}} resizeMode={'contain'} style={{borderRadius:5,height: 184,width:'100%'}}/>
|
||||
</View>
|
||||
<Text style={{color:'white',fontSize:14,textAlign:'center',marginVertical: 16,}}>ถ่ายเมื่อวันที่ {moment().format('DD/MM/YYYY HH:mm')} น.</Text>
|
||||
<Text style={{color:'black',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'}}
|
||||
onPress={this.props.onTakeCamera}>
|
||||
<Icon nane={'ic_outline_camera'} size={22} color={'#FFFFFF'}/>
|
||||
|
||||
@ -1,20 +1,23 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
import { View, Text, Alert } from 'react-native';
|
||||
import ImageBackground from 'react-native-fast-image'
|
||||
import SaveViewMeter from './SaveViewMeter';
|
||||
import PopupMeter from './PopupMeter';
|
||||
import ImagePicker from 'react-native-image-crop-picker'
|
||||
import {postMeter, postMeterImage} from '../../api/UserApi';
|
||||
import moment from 'moment';
|
||||
import {t} from "../../utils/i18n";
|
||||
|
||||
export default class WaterMeter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
numberMeter: '0',
|
||||
numberMeter: '',
|
||||
isLoading: false,
|
||||
isVisible: false,
|
||||
image: this.props.navigation.getParam('image','no-image'),
|
||||
image_send: {},
|
||||
image_preview: this.props.navigation.getParam('image_preview', 'no-image'),
|
||||
room_id: this.props.navigation.getParam('room_id','no-id'),
|
||||
isConfirm: false
|
||||
};
|
||||
@ -24,22 +27,23 @@ export default class WaterMeter extends Component {
|
||||
this.onOK = this.onOK.bind(this)
|
||||
this.onPopup = this.onPopup.bind(this)
|
||||
this.onTakeCamera = this.onTakeCamera.bind(this)
|
||||
this.postImageToOCR = this.postImageToOCR.bind(this)
|
||||
//this.postImageToOCR = this.postImageToOCR.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.setState({
|
||||
image_send: {
|
||||
uri: this.state.image.uri,
|
||||
type: this.state.image.mime,
|
||||
name: `image_meter_${moment()}.jpg`,
|
||||
width: this.state.image.width,
|
||||
height: this.state.image.height
|
||||
// name: `image_meter_${moment()}.jpg`,
|
||||
}
|
||||
},() => {
|
||||
this.postImageToOCR()
|
||||
})
|
||||
}/*,() => {
|
||||
//this.postImageToOCR()
|
||||
}*/)
|
||||
};
|
||||
|
||||
postImageToOCR(){
|
||||
/*postImageToOCR(){
|
||||
let param = {
|
||||
image: this.state.image_send
|
||||
}
|
||||
@ -52,7 +56,7 @@ export default class WaterMeter extends Component {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}*/
|
||||
|
||||
onTextChanged(text){
|
||||
this.setState({
|
||||
@ -75,7 +79,8 @@ export default class WaterMeter extends Component {
|
||||
cropping: true,
|
||||
width: 300,
|
||||
height: 100,
|
||||
includeExif: true
|
||||
includeExif: true,
|
||||
includeBase64: true
|
||||
}).then(image => {
|
||||
console.log('received image', image)
|
||||
let image_meter = {
|
||||
@ -83,25 +88,32 @@ export default class WaterMeter extends Component {
|
||||
type: image.mime,
|
||||
name: 'image_meter.jpg',
|
||||
}
|
||||
|
||||
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
|
||||
this.setState({
|
||||
image_url: {uri: image.path, width: image.width, height: image.height, mime: image.mime},
|
||||
images: null,
|
||||
}, () => {
|
||||
this.setState({
|
||||
image: this.state.image_url,
|
||||
image_send: image_meter
|
||||
},() => {
|
||||
this.postImageToOCR()
|
||||
image_send: image_data
|
||||
}/*,() => {
|
||||
//this.postImageToOCR()
|
||||
}*/)
|
||||
})
|
||||
})
|
||||
}).catch(e => Alert.alert('Error',e))
|
||||
}).catch(e => {})
|
||||
}
|
||||
|
||||
onConfirm(){
|
||||
this.onPopup()
|
||||
}
|
||||
|
||||
onOK(){
|
||||
onOK() {
|
||||
if (!this.state.isLoading) {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
isVisible: false
|
||||
}, () => {
|
||||
let param = {
|
||||
room_id: this.state.room_id,
|
||||
type: 'ค่าน้ำ',
|
||||
@ -113,10 +125,34 @@ export default class WaterMeter extends Component {
|
||||
postMeter(param)
|
||||
.then(res => {
|
||||
console.log('response post meter ------> ',res.data)
|
||||
this.onPopup()
|
||||
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 }))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onPopup(){
|
||||
this.setState({
|
||||
@ -128,9 +164,9 @@ export default class WaterMeter extends Component {
|
||||
return (
|
||||
<ImageBackground source={require('../../../assets/images/tree2.png')} style={{flex:1,backgroundColor:'#EEFFD7',paddingTop:16}}>
|
||||
<View style={{flex:1,padding:16}}>
|
||||
<SaveViewMeter amount={this.state.numberMeter} TypeName={'น้ำ'} TextChanged={this.onTextChanged} Confirm={this.onConfirm} ImageUri={this.state.image.uri} onTakeCamera={this.onTakeCamera} canConfirm={this.state.isConfirm}/>
|
||||
<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}/>
|
||||
</View>
|
||||
<PopupMeter modalVisible={this.state.isVisible} onOk={this.onOK} onCancel={this.onPopup}/>
|
||||
<PopupMeter modalVisible={this.state.isVisible} onOk={!this.state.isLoading ? this.onOK : null} onCancel={this.onPopup}/>
|
||||
</ImageBackground>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import {
|
||||
View, ScrollView, Dimensions, TouchableOpacity, StyleSheet, FlatList, RefreshControl, Animated, ActivityIndicator, Alert
|
||||
View, ScrollView, Dimensions, TouchableOpacity, StyleSheet, FlatList, RefreshControl, Animated, ActivityIndicator, Platform, Alert, Modal
|
||||
} from 'react-native'
|
||||
import Image 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 Text from '../../components/Text'
|
||||
import { NavigationEvents } from 'react-navigation'
|
||||
import { getNews, getNewsPage, getUserProfile, getNewsByProject, login } from '../../api/UserApi'
|
||||
import {getNews, getNewsPage, getUserProfile, getNewsByProject, login, registerDevice, setPaymentLater, setFillInMeterLater, checkPaymentMeter} from '../../api/UserApi';
|
||||
import { bindActionCreators } from 'redux'
|
||||
import {
|
||||
appSetDevice,
|
||||
@ -27,13 +27,111 @@ import { connect } from 'react-redux'
|
||||
import moment from 'moment'
|
||||
import IndicatorLoading from '../../components/IndicatorLoading'
|
||||
import { loginWithFacebook } from '../../components/FacebookUtils'
|
||||
import { signinApple } from '../../components/AppleAuth'
|
||||
import parseDateLocale from '../../utils/parseDateLocale'
|
||||
import { from } from 'rxjs'
|
||||
//import Slideshow from 'react-native-image-slider-show';
|
||||
import appleAuth, {
|
||||
AppleButton,
|
||||
} from '@invertase/react-native-apple-authentication';
|
||||
|
||||
import { t, locale } from '../../utils/i18n'
|
||||
import messaging from "@react-native-firebase/messaging";
|
||||
import {store} from '../../redux/store';
|
||||
|
||||
const { height, width } = Dimensions.get('window')
|
||||
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 {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
@ -59,7 +157,7 @@ class NewsScreen extends Component {
|
||||
is_new: false
|
||||
}],
|
||||
due_at: '',
|
||||
pending_payment: '',
|
||||
pending_payment: 0,
|
||||
noti_count: 0,
|
||||
isFirstTime: true,
|
||||
user_point: 0,
|
||||
@ -70,9 +168,20 @@ class NewsScreen extends Component {
|
||||
scrollY: new Animated.Value(0),
|
||||
loadMore: false,
|
||||
loadPage: 1,
|
||||
last_page: 1,
|
||||
isLoadmore: false,
|
||||
fb_is_link: false,
|
||||
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)
|
||||
@ -80,18 +189,51 @@ class NewsScreen extends Component {
|
||||
}
|
||||
|
||||
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 () {
|
||||
if (this.props.token != null) {
|
||||
return await getUserProfile()
|
||||
.then(res => {
|
||||
.then(async res => {
|
||||
if (res.ok) {
|
||||
console.log("News:: 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({
|
||||
pending_payment: res.data.pending_payment != null ? res.data.pending_payment : 0,
|
||||
noti_count: res.data.count_noti,
|
||||
user_point: res.data.point_balance,
|
||||
user_project_id: res.data.project_id,
|
||||
@ -106,26 +248,41 @@ class NewsScreen extends Component {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
//setTimeout(() => {
|
||||
this.setState({
|
||||
isLoading: false
|
||||
}, () => {
|
||||
this.props.appCleanUser()
|
||||
this.props.appCleanToken()
|
||||
})
|
||||
}, 600)
|
||||
|
||||
//}, 600)
|
||||
}
|
||||
})
|
||||
}else {
|
||||
await this.getAllNewsList()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async getAllNewsByProject(project_id) {
|
||||
return getNewsByProject(project_id)
|
||||
.then(res => {
|
||||
console.log('res >>>>>>> ', res)
|
||||
this.setNewsData(res)
|
||||
})
|
||||
}
|
||||
|
||||
async getAllNewsList () {
|
||||
// return getNews()
|
||||
return getNewsPage(this.state.loadPage)
|
||||
.then(res => {
|
||||
if ((res.data.data).length > 5) {
|
||||
this.setNewsData(res)
|
||||
})
|
||||
}
|
||||
|
||||
setNewsData(res) {
|
||||
if (res.data.data && (res.data.data).length > 5) {
|
||||
console.log('data >>>>> ', res)
|
||||
var cut = []
|
||||
for (let index = 0; index < 5; index++) {
|
||||
cut.push(res.data.data[index])
|
||||
@ -136,24 +293,42 @@ class NewsScreen extends Component {
|
||||
news_head: cut,
|
||||
new_all: res.data.data,
|
||||
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
|
||||
isLoading: false,
|
||||
last_page: res.data.last_page
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
initData () {
|
||||
this.setState({ isLoading: true })
|
||||
console.log('initData >>> ')
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
loadPage: 1,
|
||||
last_page: 1,
|
||||
news_head: [{
|
||||
title: 'กำลังโหลดข้อมูลข่าว',
|
||||
content: 'กำลังโหลดข้อมูลข่าว',
|
||||
date: 'กำลังโหลดข้อมูลข่าว',
|
||||
is_new: false
|
||||
}],
|
||||
new_all: [{
|
||||
title: 'กำลังโหลดข้อมูลข่าว',
|
||||
content: 'กำลังโหลดข้อมูลข่าว',
|
||||
date: 'กำลังโหลดข้อมูลข่าว',
|
||||
is_new: false
|
||||
}],
|
||||
}, () => {
|
||||
Promise.all([
|
||||
this.getUser(),
|
||||
this.getAllNewsList()
|
||||
// this.getAllNewsList()
|
||||
])
|
||||
.then(() => {
|
||||
let user_id = 0
|
||||
@ -195,12 +370,38 @@ class NewsScreen extends Component {
|
||||
this.setState({
|
||||
isLoading: false
|
||||
}, () => {
|
||||
this.props.appCleanUser()
|
||||
this.props.appCleanToken()
|
||||
//this.props.appCleanUser()
|
||||
//this.props.appCleanToken()
|
||||
})
|
||||
}, 600)
|
||||
this.initData()
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_onRefresh = () => {
|
||||
@ -208,21 +409,59 @@ class NewsScreen extends Component {
|
||||
refreshing: true, loadPage: 1, loadMore: false
|
||||
}, () => {
|
||||
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 }) => (
|
||||
<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 })}}>
|
||||
<Image source={{ uri: item.url }} defaultSource={require('../../../assets/images/default_small.png')} style={styles.image_style} resizeMode={'contain'}/>
|
||||
<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'}/>
|
||||
<View style={{ flex: 1, marginLeft: 8, justifyContent: 'space-between' }}>
|
||||
<Text style={{ fontSize: 14, color: 'white', width: '100%', }} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Icon name="ic_calendar_alt" size={16} color="white"/>
|
||||
<Text style={{ flex: 1, fontSize: 12, color: 'white', marginLeft: 5 }}>{item.date}</Text>
|
||||
<Text style={{ flex: 1, fontSize: 12, color: 'white', marginLeft: 5 }}>{parseDateLocale(item.date)}</Text>
|
||||
{
|
||||
item.is_new == true &&
|
||||
<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>
|
||||
</View>
|
||||
}
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@ -232,17 +471,21 @@ class NewsScreen extends Component {
|
||||
return <TouchableOpacity onPress={() => {
|
||||
this.props.navigation.navigate('NewsDetail', { news_id: item.id })
|
||||
}}>
|
||||
<ImageBackground source={{ uri: item.url }} onError={(e) => { this.props.source = require('../../../assets/images/default_big.png') }} style={styles.imgBg}>
|
||||
<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}>
|
||||
<LinearGradient colors={['rgba(0, 0, 0, 0)', '#000000']}>
|
||||
<View style={{ padding: 15, }}>
|
||||
{item.is_new == true ?
|
||||
<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>
|
||||
<View style={{ backgroundColor: '#FF9500', borderRadius: 10, height: 23,
|
||||
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 }
|
||||
<Text style={styles.textNewsName} ellipsizeMode={'tail'} numberOfLines={2}>{item.title}</Text>
|
||||
<View style={{ flexDirection: 'row', marginTop: 5 }}>
|
||||
<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 }}>
|
||||
{item.date}
|
||||
{parseDateLocale(item.date)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
@ -251,21 +494,11 @@ class NewsScreen extends Component {
|
||||
</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) {
|
||||
const scrollX = e.nativeEvent.contentOffset.x
|
||||
this.setState({
|
||||
position: Math.ceil(scrollX / width)
|
||||
})
|
||||
|
||||
// console.log(this.state.position)
|
||||
}
|
||||
|
||||
@ -276,41 +509,32 @@ class NewsScreen extends Component {
|
||||
}
|
||||
|
||||
loadMoreData = async () => {
|
||||
const { loadMore } = this.state
|
||||
if (loadMore) {
|
||||
return
|
||||
}
|
||||
this.setState({ loadMore: true, isLoadmore: true })
|
||||
|
||||
let loadpage = this.state.loadPage + 1
|
||||
|
||||
/*loading - set loadMore = false when done*/
|
||||
getNewsPage(loadpage)
|
||||
if(parseInt(this.state.loadPage) < parseInt(this.state.last_page)){
|
||||
this.setState({
|
||||
loadMore: true,
|
||||
isLoadmore: true,
|
||||
loadPage: this.state.loadPage + 1
|
||||
}, () => {
|
||||
getNewsPage(this.state.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)
|
||||
})
|
||||
let news_all = this.state.new_all
|
||||
let news_arr = news_all.concat(resData)
|
||||
|
||||
this.setState({
|
||||
loadPage: loadpage,
|
||||
new_all: news_arr,
|
||||
refreshing: false,
|
||||
loadMore: false,
|
||||
isLoadmore: false
|
||||
isLoadmore: false,
|
||||
last_page: res.data.last_page
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (resData.length < 10) {
|
||||
this.setState({
|
||||
loadMore: true
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
/*loading - set loadMore = false when done*/
|
||||
}
|
||||
|
||||
_keyExtractorNewHead = (item, index) => 'new_head_' + index
|
||||
@ -326,14 +550,19 @@ class NewsScreen extends Component {
|
||||
}}>
|
||||
<NavigationEvents
|
||||
onDidFocus={() => {
|
||||
this.setState({ isLoading: true })
|
||||
let checkNav = this.props.navigation.getParam('isLogin')
|
||||
this.setState({
|
||||
isLoading: true
|
||||
}, () => {
|
||||
this.initData()
|
||||
// this.checkNotifiedPopup()
|
||||
})
|
||||
/*let checkNav = this.props.navigation.getParam('isLogin')
|
||||
if (checkNav) {
|
||||
this.props.navigation.setParams({ isLogin: false })
|
||||
this.initData()
|
||||
} else {
|
||||
this.setState({ isLoading: false })
|
||||
}
|
||||
}*/
|
||||
}}
|
||||
/>
|
||||
<BackgroundImage>
|
||||
@ -347,7 +576,8 @@ class NewsScreen extends Component {
|
||||
showsVerticalScrollIndicator={false}
|
||||
scrollEventThrottle={16}
|
||||
onScroll={Animated.event(
|
||||
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }]
|
||||
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
|
||||
{useNativeDriver: false}
|
||||
)}
|
||||
onMomentumScrollEnd={({ nativeEvent }) => {
|
||||
if (this.isCloseToBottom(nativeEvent)) {
|
||||
@ -366,7 +596,11 @@ class NewsScreen extends Component {
|
||||
onScroll={this._onCarouselScroll}
|
||||
/>
|
||||
<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>
|
||||
{this.state.auth !== null &&
|
||||
@ -377,9 +611,9 @@ class NewsScreen extends Component {
|
||||
<View style={{ flex: 1, alignItems: 'center', padding: 10 }}>
|
||||
<View>
|
||||
<Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('for_csa_customer')}</Text>
|
||||
<Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('create_account')} {t('to_view_outstanding_balance')}</Text>
|
||||
<Text style={{ color: 'white', fontSize: 16, textAlign: 'center' }}>{t('login')} {t('to_view_outstanding_balance')}</Text>
|
||||
</View>
|
||||
<TouchableOpacity onPress={() => {
|
||||
{/*<TouchableOpacity onPress={() => {
|
||||
// this.props.navigation.navigate('Register')
|
||||
this.props.navigation.navigate('Terms')
|
||||
}}>
|
||||
@ -388,8 +622,8 @@ class NewsScreen extends Component {
|
||||
<Text style={{ fontSize: 16, color: 'white', padding: 5, textAlign: 'center' }}>{t('create_account')}</Text>
|
||||
</Badge>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text>
|
||||
</TouchableOpacity>*/}
|
||||
{/* <Text style={{ color: 'white', marginTop: 10 }}>{t('or')}</Text> */}
|
||||
<TouchableOpacity onPress={() => { this.props.navigation.navigate('Login') }}>
|
||||
<View>
|
||||
<Badge style={{ backgroundColor: '#145EB3', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', marginTop: 10, height: null, width: 150 }}>
|
||||
@ -397,10 +631,26 @@ class NewsScreen extends Component {
|
||||
</Badge>
|
||||
</View>
|
||||
</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>
|
||||
|
||||
<TouchableOpacity onPress={() => {
|
||||
|
||||
loginWithFacebook(() => {
|
||||
this.initData()
|
||||
})
|
||||
@ -408,7 +658,7 @@ class NewsScreen extends Component {
|
||||
loginWithFacebook(() => {
|
||||
this.initData()
|
||||
})
|
||||
}else{
|
||||
}else
|
||||
Alert.alert(
|
||||
"",
|
||||
"อิเมล์ "+this.state.email+" ยังไม่ได้ลงทะเบียนในระบบ กรุณาสมัครสมาชิก",
|
||||
@ -435,7 +685,7 @@ class NewsScreen extends Component {
|
||||
<View style={{ padding: 5 }}>
|
||||
<View style={[styles.row, { alignItems: 'stretch' }]}>
|
||||
<View style={styles.custom_card}>
|
||||
<Card style={{ borderRadius: 5, backgroundColor: '#00420A', borderColor: 'rbga(0,0,0,0)' }}>
|
||||
<Card style={{ borderRadius: 5, backgroundColor: '#00420A', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
|
||||
<BackgroundImage_RegisterForm>
|
||||
<View style={{ flex: 1, flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: 10, minHeight: 177 }}>
|
||||
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
|
||||
@ -447,7 +697,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: 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>
|
||||
{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>}
|
||||
{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>}
|
||||
</View>
|
||||
<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>*/}
|
||||
@ -457,7 +707,7 @@ class NewsScreen extends Component {
|
||||
</BackgroundImage_RegisterForm>
|
||||
</Card>
|
||||
</View>
|
||||
<View style={[styles.custom_card, { paddingLeft: 5 }]}>
|
||||
<View style={[styles.custom_card]}>
|
||||
<Card title='' style={{ borderRadius: 5, backgroundColor: '#003114', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
|
||||
<BackgroundImage_RegisterForm>
|
||||
<View style={{
|
||||
@ -471,12 +721,14 @@ class NewsScreen extends Component {
|
||||
<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 }}>{t('view_points')}</Text>
|
||||
<Text style={{ color: 'white', fontSize: 28 }}>{this.state.user_point}</Text>
|
||||
<Text style={{ color: 'white', fontSize: 28 }}>{parseFloat(this.state.user_point).toLocaleString()}</Text>
|
||||
{/*<Text style={{ color: 'white', fontSize: 18 }}>พอยต์</Text>*/}
|
||||
<Text style={{ color: 'white', fontSize: 14 }}>{t('point')}</Text>
|
||||
<TouchableOpacity style={{ marginTop: 5 }} disabled={true} onPress={() => {}}>
|
||||
{/*<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: 'gray', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent: 'center' }}><Text style={{ fontSize: 12, color: 'white' }}>{t('redeem')}</Text></Badge>
|
||||
<TouchableOpacity style={{ marginTop: 5 }}
|
||||
onPress={() => {this.props.navigation.navigate('Redeem')}}>
|
||||
<Badge style={{ backgroundColor: '#145EB3', borderRadius: 5, borderColor: 'rbga(0,0,0,0)', justifyContent: 'center' }}>
|
||||
<Text style={{ fontSize: 12, color: 'white' }}>{t('redeem')}</Text>
|
||||
</Badge>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</BackgroundImage_RegisterForm>
|
||||
@ -484,7 +736,6 @@ class NewsScreen extends Component {
|
||||
</View>
|
||||
</View>
|
||||
<View style={[styles.row, { flexWrap: 'wrap', alignItems: 'stretch' }]}>
|
||||
{this.state.isMeter ?
|
||||
<View style={[styles.custom_card]}>
|
||||
<TouchableOpacity disabled={false} onPress={() => {
|
||||
this.props.navigation.navigate('Meter')
|
||||
@ -505,11 +756,11 @@ class NewsScreen extends Component {
|
||||
</Card>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
: null}
|
||||
{this.state.isShipping ?
|
||||
<View style={[styles.custom_card]}>
|
||||
<TouchableOpacity disabled={false} onPress={() => {
|
||||
this.props.navigation.navigate('Object')
|
||||
this.props.navigation.navigate('Object',{
|
||||
user:this.props.user
|
||||
})
|
||||
}} style={{ flex: 1 }}>
|
||||
<Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
|
||||
<View style={{
|
||||
@ -527,12 +778,12 @@ class NewsScreen extends Component {
|
||||
</Card>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
: null}
|
||||
<View style={[styles.custom_card]}>
|
||||
<TouchableOpacity disabled={false}
|
||||
onPress={() => { this.props.navigation.navigate('RepairService',{
|
||||
/*onPress={() => { this.props.navigation.navigate('RepairService',{
|
||||
user:this.props.user
|
||||
}) }}
|
||||
}) }}*/
|
||||
onPress={() => { this.props.navigation.navigate('Repair')}}
|
||||
style={{ flex: 1 }}>
|
||||
<Card title='' style={{ borderRadius: 5, backgroundColor: '#145EB3', borderColor: 'rbga(0,0,0,0)', flex: 1 }}>
|
||||
<View style={{
|
||||
@ -583,21 +834,59 @@ class NewsScreen extends Component {
|
||||
data={this.state.new_all}
|
||||
renderItem={this.renderNativeItem}
|
||||
keyExtractor={this._keyExtractorNewAll}
|
||||
// onEndReachedThreshold={0.01}
|
||||
// onEndReached={this.loadMoreData.bind(this)}
|
||||
ItemSeparatorComponent={() => {
|
||||
return <View style={{ width: '100%', height: 8 }}></View>
|
||||
}}
|
||||
ListFooterComponent={() => {
|
||||
if (!this.state.isLoadmore) return null
|
||||
return (<View style={{ padding: 16, flexDirection: 'row', borderRadius: 10, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<ActivityIndicator size="small" color="black"/>
|
||||
<Text style={{ fontSize: 12, marginLeft: 10, color: 'black' }}>Loading...</Text>
|
||||
</View>)
|
||||
return (<ActivityIndicator
|
||||
size="large"
|
||||
color={'white'}
|
||||
/>)
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</BackgroundImage>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
@ -649,6 +938,51 @@ const styles = StyleSheet.create({
|
||||
custom_card: {
|
||||
width: '50%', paddingHorizontal: 5,
|
||||
// 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',
|
||||
}
|
||||
})
|
||||
|
||||
@ -656,5 +990,15 @@ const mapDisPatchToProps = state => {
|
||||
return state.app
|
||||
}
|
||||
|
||||
const setUser = dispatch => bindActionCreators({ appSetToken, appSetPushToken, appSetDevice, appSetUser, appCleanToken, appCleanUser, appSetNotification, appSetProjectID }, dispatch)
|
||||
const setUser = dispatch => bindActionCreators({
|
||||
appSetToken,
|
||||
appSetPushToken,
|
||||
appSetDevice,
|
||||
appSetUser,
|
||||
appCleanToken,
|
||||
appCleanUser,
|
||||
appSetNotification,
|
||||
appSetProjectID,
|
||||
setPaymentLater
|
||||
}, dispatch)
|
||||
export default connect(mapDisPatchToProps, setUser)(NewsScreen)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import {View, ScrollView, StyleSheet, Linking, Button, TouchableOpacity, Alert} from 'react-native';
|
||||
import {View, ScrollView, StyleSheet, Linking, Button, TouchableOpacity, Alert, Platform, Modal, ImageBackground} from 'react-native';
|
||||
import Image from 'react-native-fast-image'
|
||||
import { WebView } from 'react-native-webview';
|
||||
import { Body, Badge, List, ListItem, Right, Title } from 'native-base'
|
||||
@ -10,9 +10,12 @@ import { BackgroundImage } from '../../components/BackgroundImage'
|
||||
import { getNewsDetail } from '../../api/UserApi';
|
||||
import IndicatorLoading from '../../components/IndicatorLoading';
|
||||
import { t } from '../../utils/i18n'
|
||||
|
||||
import parseDateLocale from '../../utils/parseDateLocale';
|
||||
import ImageView from 'react-native-image-view';
|
||||
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;
|
||||
const injectScript = `
|
||||
(function () {
|
||||
@ -41,11 +44,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){
|
||||
this.props.navigation.state.params.getNotification()
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
getNewsData(){
|
||||
this.setState({
|
||||
@ -54,26 +57,34 @@ export default class NewsDetailScreen extends Component {
|
||||
getNewsDetail(this.state.news_id)
|
||||
.then(res => {
|
||||
if(res.ok){
|
||||
if(res.data.data){
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
news_detail: res.data.data
|
||||
})
|
||||
}else{
|
||||
}else {
|
||||
console.log('ถูกยกเลิกเผยแพร่ข่าว')
|
||||
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว', [{
|
||||
text: t('ok'),
|
||||
onPress: () => {
|
||||
console.log('press')
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
news_detail: [
|
||||
{
|
||||
title: '',
|
||||
content: '',
|
||||
style: '',
|
||||
is_new: true,
|
||||
date:'',
|
||||
url:'',
|
||||
}
|
||||
],
|
||||
|
||||
news_detail: {}
|
||||
})
|
||||
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว')
|
||||
}
|
||||
}])
|
||||
}
|
||||
}else{
|
||||
Alert.alert('','ถูกยกเลิกเผยแพร่ข่าว', [{
|
||||
text: t('ok'),
|
||||
onPress: () => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
news_detail: {}
|
||||
})
|
||||
}
|
||||
}])
|
||||
// alert('ถูกยกเลิกเผยแพร่ข่าว')
|
||||
// this.context.router.goBack()
|
||||
|
||||
@ -82,6 +93,25 @@ export default class NewsDetailScreen extends Component {
|
||||
}
|
||||
|
||||
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 (
|
||||
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
|
||||
flex: 1,
|
||||
@ -89,29 +119,36 @@ export default class NewsDetailScreen extends Component {
|
||||
height: null
|
||||
}}>
|
||||
<BackgroundImage>
|
||||
{
|
||||
Platform.OS === 'android' &&
|
||||
<ImageView
|
||||
images={[{source: {uri: this.state.news_detail != null && this.state.news_detail.url }}]}
|
||||
images={[{source: {uri: this.state.news_detail != null && this.state.news_detail.url ? this.state.news_detail.url : '' }}]}
|
||||
imageIndex={0}
|
||||
isVisible={this.state.isImageViewVisible}
|
||||
animationType={'fade'}
|
||||
onClose={() => {this.setState({isImageViewVisible: false})}}
|
||||
/>
|
||||
}
|
||||
<View>
|
||||
<TouchableOpacity onPress={() => {this.setState({isImageViewVisible: true})}}>
|
||||
<Image source={{ uri: this.state.news_detail != null && this.state.news_detail.url }} style={styles.imgBg} />
|
||||
<Image source={{ uri: this.state.news_detail != null && this.state.news_detail.url ? this.state.news_detail.url : '' }} style={styles.imgBg} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{ backgroundColor: 'white', padding: 15 }}>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={{ color: '#00420A', fontSize: 16, }}>{this.state.news_detail.title}</Text>
|
||||
<Text style={{ color: '#00420A', fontSize: 16, }}>{this.state.news_detail != null && this.state.news_detail.title}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row', marginTop: 5 }}>
|
||||
<View style={{ width: '50%', flexDirection: "row", marginTop: 5 }}>
|
||||
<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 style={{ width: '50%', flexDirection: "row", flex: 1, justifyContent: 'flex-end' }}>
|
||||
{this.state.news_detail.is_new == true ? <Badge style={{ backgroundColor: '#FF9500', borderRadius: 50, paddingLeft: 10, paddingTop: 5 }}>
|
||||
<Text style={{ fontSize: 12, color: 'white' }}>{t('latest_news')} </Text>
|
||||
{this.state.news_detail && 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>
|
||||
</Badge> : null}
|
||||
</View>
|
||||
</View>
|
||||
@ -127,26 +164,55 @@ export default class NewsDetailScreen extends Component {
|
||||
flex: 1,
|
||||
}}
|
||||
originWhitelist={['*']}
|
||||
source={{ baseUrl: '', html: `${this.state.news_detail.style}<div id="content_detail"><meta charset="UTF-8">`+this.state.news_detail.content+'</div>' }}
|
||||
// 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={source_webview}
|
||||
ref={(ref) => { this.webview = ref; }}
|
||||
javaScriptEnabled={true}
|
||||
domStorageEnabled={true}
|
||||
// onShouldStartLoadWithRequest={(navState)=>{ //open external browser for android
|
||||
// console.log('onShouldStartLoadWithRequest >>>>>> ',navState);
|
||||
// Linking.openURL(navState.url)
|
||||
// return false;
|
||||
// }}
|
||||
onMessage={(event) => {
|
||||
if(event.nativeEvent.data){
|
||||
let data = JSON.parse(event.nativeEvent.data);
|
||||
if(data.video_id){
|
||||
Linking.openURL(`https://youtube.com/embed/${data.video_id}`);
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
onNavigationStateChange={(event) => {
|
||||
/*onNavigationStateChange={(event) => {
|
||||
console.log('onNavigationStateChange >>>>>> ',event);
|
||||
if (event.url.startsWith("http")) {
|
||||
this.webview.stopLoading();
|
||||
this.webview.goBack();
|
||||
Linking.openURL(event.url);
|
||||
}
|
||||
}}
|
||||
}}*/
|
||||
/>
|
||||
</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}/>
|
||||
</LinearGradient>
|
||||
)
|
||||
@ -167,5 +233,11 @@ const styles = StyleSheet.create({
|
||||
|
||||
textAlign: 'center',
|
||||
fontSize: 12
|
||||
},
|
||||
backgroundImage: {
|
||||
flex: 1,
|
||||
width: null,
|
||||
height: null,
|
||||
resizeMode: 'cover'
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, {Component} from 'react'
|
||||
import {FlatList, View, TouchableOpacity, RefreshControl, ScrollView, ActivityIndicator} from 'react-native'
|
||||
import {FlatList, View, TouchableOpacity, RefreshControl, ScrollView, ActivityIndicator, SafeAreaView} from 'react-native'
|
||||
import Image from 'react-native-fast-image'
|
||||
import {BackgroundImage} from '../../components/BackgroundImage'
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
@ -8,8 +8,9 @@ import { get_notification, news, read_notification} from '../../api/UserApi'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {appSetNotification} from '../../redux/app/action'
|
||||
import {connect} from 'react-redux';
|
||||
import moment from "moment";
|
||||
import { t } from '../../utils/i18n';
|
||||
import parseDateLocale from '../../utils/parseDateLocale';
|
||||
import { NavigationEvents } from "react-navigation";
|
||||
|
||||
const injectScript = `
|
||||
(function () {
|
||||
@ -33,10 +34,138 @@ class NotificationScreen extends Component {
|
||||
}
|
||||
|
||||
_set_read(item) {
|
||||
switch (item.source_type) {
|
||||
case 'payment_success':
|
||||
case 'update_app':
|
||||
return false;
|
||||
default:
|
||||
read_notification(item.id).then(res => {
|
||||
console.log('read noti => ', res.data.message)
|
||||
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() {
|
||||
if (this.props.token != null && this.props.user != null) {
|
||||
@ -67,7 +196,7 @@ class NotificationScreen extends Component {
|
||||
|
||||
// console.log('user_noti_id => ', user_noti_id)
|
||||
if(this.props.token != null){
|
||||
get_notification(user_noti_id, 1).then(res => {
|
||||
get_notification(user_noti_id, this.state.page).then(res => {
|
||||
if (res.data) {
|
||||
this.setState({
|
||||
new_noti: res.data.data,
|
||||
@ -130,76 +259,79 @@ class NotificationScreen extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
getTypeNoti(source_type) {
|
||||
getTypeNoti(item) {
|
||||
let type = 'ข่าวใหม่';
|
||||
switch (source_type) {
|
||||
switch (item.source_type) {
|
||||
case 'news':
|
||||
case 'general':
|
||||
type = t('latest_news');
|
||||
break;
|
||||
case 'rooms':
|
||||
type = t('new_room');
|
||||
break;
|
||||
case 'parcels':
|
||||
type = t('new_parcel');
|
||||
break;
|
||||
case 'promotion':
|
||||
type = t('latest_promotion');
|
||||
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:
|
||||
type = t('latest_news');
|
||||
type = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
getDateNoti(date) {
|
||||
let d = moment(date).format('D')
|
||||
let m = moment(date).format('MM')
|
||||
let y = parseInt(moment(date).format('Y')) + 543
|
||||
let new_month = 'ม.ค.';
|
||||
let new_date = d + ' ' + new_month + ' ' + y;
|
||||
switch (m) {
|
||||
case '01':
|
||||
new_month = 'ม.ค.';
|
||||
break;
|
||||
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;
|
||||
getStatusParcel (status) {
|
||||
switch (status) {
|
||||
case 'PENDING':
|
||||
return t('waiting_for_pickup');
|
||||
case 'WAIT_PICKUP':
|
||||
return t('awaiting_payment');
|
||||
case 'RECEIVE':
|
||||
return t('paid');
|
||||
case 'OTHER':
|
||||
return t('other');
|
||||
case 'ERROR':
|
||||
default:
|
||||
new_month = 'ม.ค.';
|
||||
break;
|
||||
return t('contact_front_desk');
|
||||
}
|
||||
}
|
||||
|
||||
new_date = d + ' ' + new_month + ' ' + y;
|
||||
return new_date;
|
||||
displayParcelContent (data) {
|
||||
console.log('data >>> ', JSON.parse(data.data))
|
||||
if(data.parcel_status){
|
||||
return t('status') + ' : ' + this.getStatusParcel(data.parcel_status)
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
renderSeparator() {
|
||||
@ -218,11 +350,57 @@ class NotificationScreen extends Component {
|
||||
if (!this.state.refreshing) return null;
|
||||
return (
|
||||
<ActivityIndicator
|
||||
style={{ color: '#000' }}
|
||||
size="large"
|
||||
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
|
||||
|
||||
render() {
|
||||
@ -234,17 +412,30 @@ class NotificationScreen extends Component {
|
||||
resizeMode: 'cover'
|
||||
}}>
|
||||
<BackgroundImage>
|
||||
<ScrollView contentContainerStyle={styles.contentContainer}
|
||||
{/*<ScrollView contentContainerStyle={styles.contentContainer}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={this._onRefresh}
|
||||
/>
|
||||
}
|
||||
>
|
||||
>*/}
|
||||
<View style={styles.container}>
|
||||
<NavigationEvents
|
||||
onWillFocus={payload => {
|
||||
this._onRefresh()
|
||||
}}
|
||||
/>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<FlatList
|
||||
data={this.state.new_noti}
|
||||
refreshing={true}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={this.state.refreshing}
|
||||
onRefresh={this._onRefresh}
|
||||
/>
|
||||
}
|
||||
keyExtractor={this._keyExtractorNewNoti}
|
||||
ListEmptyComponent={() =>
|
||||
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', margin: 16,padding:16,borderRadius:5,backgroundColor:'white'}}>
|
||||
@ -253,48 +444,50 @@ class NotificationScreen extends Component {
|
||||
}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ListFooterComponent={this.renderFooter.bind(this)}
|
||||
onEndReachedThreshold={0.01}
|
||||
onEndReached={this.loadMoreNoti.bind(this)}
|
||||
renderItem={({item, rowData, index}) =>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
this._set_read(item),
|
||||
this.props.navigation.navigate('NewsDetail', {
|
||||
this._set_read(item)
|
||||
/*this.props.navigation.navigate('NewsDetail', {
|
||||
news_id: item.source_id,
|
||||
getNotification: () => this.getNotification()
|
||||
})
|
||||
})*/
|
||||
}}
|
||||
key={index}
|
||||
delayPressIn={50}
|
||||
activeOpacity={0.8}
|
||||
style={[item.is_read === false ? styles.isReadFalse : styles.isReadTrue]}
|
||||
style={[ item && item.is_read === false ? styles.isReadFalse : styles.isReadTrue]}
|
||||
>
|
||||
<View style={styles.viewimages} key={index}>
|
||||
<Image style={styles.image} //source={{uri: rowData.image}}
|
||||
source={item.url ? {uri: item.url} : require('../../../assets/images/news_test.png')}
|
||||
source={this.getImageCover(item)}
|
||||
defaultSource={require('../../../assets/images/default_small.png')}
|
||||
/>
|
||||
<View style={styles.viewcontainer}>
|
||||
<Text style={{fontSize: 14, color: '#145EB3', marginBottom: 3,}}>
|
||||
{/*{this.getTypeNoti(item.source_type)}*/}
|
||||
{
|
||||
item.source &&
|
||||
item.source.content_type &&
|
||||
item.source.content_type == 'general' ? t('latest_news') : t('latest_promotion')
|
||||
item && item.source_type && this.getTypeNoti(item)
|
||||
}
|
||||
</Text>
|
||||
<Text numberOfLines={2} style={{fontSize: 14, color: 'black', marginBottom: 3,}}>
|
||||
{item.title}
|
||||
<Text
|
||||
numberOfLines={item.source_type === 'payment_success' ? 0 : 3}
|
||||
style={{fontSize: 14, color: 'black', marginBottom: 3,}}>
|
||||
{this.getContent(item)}
|
||||
</Text>
|
||||
|
||||
<Text style={{fontSize: 10, color: 'rgba(0, 0, 0, 0.5)',}}>
|
||||
{this.getDateNoti(item.notified_at)}
|
||||
{ item && item.notified_at && parseDateLocale(item.notified_at, 'D MMM Y, HH:mm')}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
</ScrollView>
|
||||
{/*</ScrollView>*/}
|
||||
</BackgroundImage>
|
||||
</LinearGradient>
|
||||
)
|
||||
|
||||
@ -4,7 +4,7 @@ import Image from 'react-native-fast-image'
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import Text from '../../components/Text';
|
||||
import Icon from '../../components/Icon'
|
||||
import {getObjectMessage} from '../../api/UserApi'
|
||||
import {getObjectMessage, getRoomParcel} from '../../api/UserApi'
|
||||
import moment from 'moment';
|
||||
import IndicatorLoading from '../../components/IndicatorLoading';
|
||||
import { NavigationEvents } from 'react-navigation'
|
||||
@ -18,7 +18,9 @@ export default class MessageObject extends Component {
|
||||
this.state = {
|
||||
isRefreshing: false,
|
||||
isLoading: true,
|
||||
message_list:[]
|
||||
message_list:[],
|
||||
users:[],
|
||||
roomIds:[],
|
||||
};
|
||||
|
||||
this.statusText = this.statusText.bind(this)
|
||||
@ -27,23 +29,55 @@ export default class MessageObject extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
// 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(){
|
||||
this.setState({
|
||||
isLoading: true
|
||||
})
|
||||
}, () => {
|
||||
getObjectMessage()
|
||||
.then(res => {
|
||||
if(res.ok){
|
||||
if(res.ok && res.data){
|
||||
// let parcel_data = new Array()
|
||||
// parcel_data=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({
|
||||
isLoading: false
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
statusColor(status){
|
||||
@ -69,6 +103,8 @@ export default class MessageObject extends Component {
|
||||
return t('awaiting_payment')
|
||||
case 'RECEIVE':
|
||||
return t('paid')
|
||||
case 'OTHER':
|
||||
return t('other')
|
||||
case 'ERROR':
|
||||
default:
|
||||
return t('contact_front_desk')
|
||||
@ -79,8 +115,8 @@ export default class MessageObject extends Component {
|
||||
|
||||
_renderItem = ({item,index}) => (
|
||||
<TouchableOpacity onPress={() => {this.props.navigation.navigate('ObjectDetail',{object_id: item.id})}}
|
||||
disabled={item.status == 'PENDING' ? false : true}
|
||||
style={{opacity:item.status == 'PENDING' ? 1 : 0.5}}>
|
||||
disabled={item.status == 'PENDING' || item.status === 'wait_customer_code' ? false : true}
|
||||
style={{opacity:item.status == 'PENDING' ? 0.5 : 1}}>
|
||||
<View style={{paddingHorizontal:16,height: 88,backgroundColor:'white',borderWidth:1,borderColor:'#EAEAF4'}}>
|
||||
<View style={{flex:1,flexDirection:'row',alignItems:'center'}}>
|
||||
<View style={{height: 64,width: 64,justifyContent:'center',marginRight:8}}>
|
||||
@ -89,11 +125,19 @@ export default class MessageObject extends Component {
|
||||
<View style={{flex:1,justifyContent:'center'}}>
|
||||
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
|
||||
<Text style={styles.textTitle} numberOfLines={1}>{item.parcel_name}</Text>
|
||||
<Text>{item.code != null && t('confirmation_code')}</Text>
|
||||
<Text>
|
||||
|
||||
{((item.code != null) && (item.status != 'PENDING' && item.status != 'OTHER' && item.status != 'ERROR') ) ? t('confirmation_code'): '' }
|
||||
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
|
||||
<Text style={styles.textTitle} numberOfLines={1}>{t('consignee')} : { item.customer ? item.customer.name : "" }</Text>
|
||||
<Text style={{fontWeight: 'bold',fontSize: 18}}>{item.code != null && item.code}</Text>
|
||||
<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={{fontWeight: 'bold',fontSize: 18}}>
|
||||
|
||||
{((item.code != null)&&(item.status != 'PENDING' && item.status != 'OTHER' && item.status != 'ERROR')) ? item.code: '' }
|
||||
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
|
||||
<View style={{justifyContent:'center',alignItems:'center',flexDirection:'row'}}>
|
||||
|
||||
@ -24,6 +24,12 @@ export default class MessageObjectDetail extends Component {
|
||||
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(){
|
||||
getObjectMessageByID(this.state.object_id)
|
||||
.then(res => {
|
||||
@ -88,7 +94,7 @@ export default class MessageObjectDetail extends Component {
|
||||
</View>
|
||||
<View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/>
|
||||
<Text style={styles.textTitle}>ผู้รับ</Text>
|
||||
<Text style={styles.textBaclk}>{this.state.object_data.customer != null && this.state.object_data.customer.name}</Text>
|
||||
<Text style={styles.textBaclk}>{this.state.object_data.customer_name != null && this.state.object_data.customer_name}</Text>
|
||||
{/*<View style={{marginVertical:16,height: 1,backgroundColor:'silver',width: '100%'}}/>
|
||||
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
|
||||
<View>
|
||||
|
||||
@ -4,33 +4,48 @@ import Text from '../../components/Text';
|
||||
import Signature from 'react-native-signature-canvas';
|
||||
import {postSignatureImage} from '../../api/UserApi';
|
||||
import { t } from '../../utils/i18n';
|
||||
import SignaturePad from 'react-native-signature-pad';
|
||||
|
||||
export default class SignaturePadScreen extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
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 => {
|
||||
if(signature === '' || !signature){
|
||||
Alert.alert(null, t('please_sign'), [{text: 'ok'}])
|
||||
}else {
|
||||
let param = {
|
||||
id: this.state.object_id,
|
||||
image: signature
|
||||
}
|
||||
console.log('-----------> handle signature')
|
||||
console.log('-----------> handle signature', signature);
|
||||
this.setState({ signature },() => {
|
||||
postSignatureImage(param)
|
||||
.then(res => {
|
||||
if(res.ok){
|
||||
Alert.alert(null,'บันทึกสำเร็จ',[{text: t('ok')}])
|
||||
Alert.alert(null,t('save_success'),[{text: t('ok')}])
|
||||
this.props.navigation.navigate('Object')
|
||||
}else{
|
||||
Alert.alert(null,'บันทึกไม่สำเร็จ กรุณาลองอีกครั้ง',[{text: t('ok')}])
|
||||
Alert.alert(null,t('save_fail_and_try'),[{text: t('ok')}])
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
clearSignPad = () => {
|
||||
this.setState({
|
||||
keySign: this.state.keySign + 1
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -39,6 +54,7 @@ export default class SignaturePadScreen extends Component {
|
||||
background-color: #269A21;
|
||||
color: #FFF;
|
||||
}`;
|
||||
|
||||
return (
|
||||
<View style={{flex:1}}>
|
||||
{/*image show signature when save*/}
|
||||
@ -51,18 +67,31 @@ export default class SignaturePadScreen extends Component {
|
||||
/>
|
||||
) : null}
|
||||
</View>*/}
|
||||
<Signature
|
||||
ref={(c) => { this._signature = c }}
|
||||
onOK={this.handleSignature}
|
||||
descriptionText="ลายเซ็น"
|
||||
clearText="ล้าง"
|
||||
confirmText="บันทึกรูป"
|
||||
webStyle={signatureStyle}
|
||||
/>
|
||||
{/*<TouchableOpacity style={{margin:16,height: 40,backgroundColor:'#269A21',justifyContent:'center',alignItems:'center',borderRadius:5}}*/}
|
||||
{/*onPress={() => {this._signature.onOK()}}>*/}
|
||||
{/*<Text style={{color:'white'}}>ยืนยัน</Text>*/}
|
||||
{/*</TouchableOpacity>*/}
|
||||
{/*<Signature*/}
|
||||
{/*ref={(c) => { this._signature = c }}*/}
|
||||
{/*onOK={this.handleSignature}*/}
|
||||
{/*descriptionText="ลายเซ็น"*/}
|
||||
{/*clearText="ล้าง"*/}
|
||||
{/*confirmText="บันทึกรูป"*/}
|
||||
{/*webStyle={signatureStyle}*/}
|
||||
{/*/>*/}
|
||||
<View style={{flex: 0.95, marginVertical: 10, marginHorizontal: 15, borderWidth: 1, borderColor: '#e8e8e8'}}>
|
||||
<SignaturePad ref={this.signPad} key={this.state.keySign}/>
|
||||
</View>
|
||||
<View style={{flex: 0.05, flexDirection: 'row', alignItems: 'center', marginBottom: 15, marginHorizontal: 15, justifyContent: 'space-between'}}>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,12 +2,12 @@ import React, { Component } from 'react'
|
||||
import {
|
||||
View,
|
||||
ScrollView,
|
||||
Image,
|
||||
TouchableOpacity,
|
||||
Platform,
|
||||
KeyboardAvoidingView,
|
||||
Alert
|
||||
} from 'react-native'
|
||||
import Image from 'react-native-fast-image'
|
||||
import Icon from '../../components/Icon'
|
||||
import { Picker } from 'native-base'
|
||||
import { BackgroundImage_RegisterForm } from '../../components/BackgroundImage_RegisterForm'
|
||||
@ -56,31 +56,42 @@ class EditProfileScreen extends Component {
|
||||
componentDidMount () {
|
||||
const { navigation } = this.props
|
||||
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)
|
||||
if(users_state.gender == null || users_state.gender == 'null'){
|
||||
console.log('NULL');
|
||||
// this.state.user.show_birth_date = users_state.birth_date;
|
||||
this.setState({
|
||||
user: {
|
||||
gender: 'male',
|
||||
...users_state
|
||||
name: users_state.name,
|
||||
...users_state,
|
||||
}
|
||||
})
|
||||
}else{
|
||||
console.log('NOT NULL');
|
||||
this.setState({
|
||||
user: users_state
|
||||
user: {
|
||||
...users_state,
|
||||
name: users_state.name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.getProjectList()
|
||||
// this.getProjectList()
|
||||
}
|
||||
|
||||
getProjectList() {
|
||||
project()
|
||||
.then(res => {
|
||||
if (res.ok) {
|
||||
return this.setState({
|
||||
if (res.ok && res.data && res.data.data) {
|
||||
this.setState({
|
||||
project_list: res.data.data,
|
||||
selected_project: res.data.data[0].id
|
||||
})
|
||||
@ -100,22 +111,49 @@ class EditProfileScreen extends Component {
|
||||
}
|
||||
|
||||
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 === this.state.user.confirm_password){
|
||||
edit_profile(this.state.user).then(res => res.data)
|
||||
edit_profile(this.state.user)
|
||||
.then(res => {
|
||||
this.props.appSetUser(res)
|
||||
if(res.ok){
|
||||
this.props.appSetUser(res.data)
|
||||
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{
|
||||
Alert.alert('รหัสผ่านไม่ถูกต้อง',`รหัสผ่านใหม่ไม่ตรงกับรหัสยืนยัน\nกรุณาลองอีกครั้ง`)
|
||||
}
|
||||
}else{
|
||||
edit_profile(this.state.user).then(res => res.data)
|
||||
edit_profile(this.state.user)
|
||||
.then(res => {
|
||||
this.props.appSetUser(res)
|
||||
if(res.ok){
|
||||
this.props.appSetUser(res.data)
|
||||
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')
|
||||
}
|
||||
}])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -127,21 +165,24 @@ class EditProfileScreen extends Component {
|
||||
cropping: true,
|
||||
includeBase64: true
|
||||
}).then(image => {
|
||||
// console.log('received base64 image', image)
|
||||
console.log('received base64 image', image)
|
||||
let image_profile = {
|
||||
uri: image.path,
|
||||
type: image.mime,
|
||||
name: 'image_profile.jpg',
|
||||
}
|
||||
|
||||
let image_data = { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height };
|
||||
this.setState({
|
||||
image_url: { uri: `data:${image.mime};base64,` + image.data, width: image.width, height: image.height },
|
||||
image_url: image_profile,
|
||||
images: null,
|
||||
user: {
|
||||
...this.state.user,
|
||||
profile_image_id: image_profile
|
||||
profile_image_id: image_profile,
|
||||
profile_image: image_data
|
||||
}
|
||||
})
|
||||
}).catch(e => alert(e))
|
||||
})
|
||||
}
|
||||
|
||||
onTakeCamera () {
|
||||
@ -149,9 +190,12 @@ class EditProfileScreen extends Component {
|
||||
cropping: true,
|
||||
width: 300,
|
||||
height: 300,
|
||||
includeExif: true
|
||||
includeExif: true,
|
||||
includeBase64: true
|
||||
}).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 = {
|
||||
uri: image.path,
|
||||
type: image.mime,
|
||||
@ -162,10 +206,11 @@ class EditProfileScreen extends Component {
|
||||
images: null,
|
||||
user: {
|
||||
...this.state.user,
|
||||
profile_image_id: image_profile
|
||||
profile_image_id: image_profile,
|
||||
profile_image: image_data
|
||||
}
|
||||
})
|
||||
}).catch(e => alert(e))
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
@ -173,18 +218,24 @@ class EditProfileScreen extends Component {
|
||||
const users = navigation.getParam('user', 'NO ITEM')
|
||||
// console.log('users :', users);
|
||||
return (
|
||||
<View style={{ flex: 1, backgroundColor: '#00420A' }}>
|
||||
<KeyboardAvoidingView style={{flex:1}} keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0} behavior={Platform.OS == 'ios' ? "padding" : ""} enabled>
|
||||
<KeyboardAvoidingView style={{flex:1}}
|
||||
keyboardVerticalOffset={Platform.OS == 'ios' ? 75 : 0}
|
||||
behavior={Platform.OS == 'ios' ? 'padding' : ''}
|
||||
ref={(view) => {this.scrollView = view;}}
|
||||
>
|
||||
<View style={{ flex: 1, backgroundColor: '#00420A'}}>
|
||||
<BackgroundImage_RegisterForm>
|
||||
<ScrollView style={{ flexDirection: 'column' }}>
|
||||
<ScrollView style={{ flex: 1, height: '100%' }}>
|
||||
<View style={{ flexDirection: 'column', flex: 1}}>
|
||||
<View>
|
||||
<LinearGradient colors={['#3AA40C', '#2C7C0B']} style={{
|
||||
flex: 1,
|
||||
// flex: 1,
|
||||
width: null,
|
||||
height: null,
|
||||
resizeMode: 'cover'
|
||||
}}>
|
||||
<View style={{ flex: 1, paddingVertical: 20, alignItems: 'center' }}>
|
||||
<View style={{ width: '30%' }}>
|
||||
<View style={{ paddingVertical: 20, alignItems: 'center' }}>
|
||||
<View>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
backgroundColor: '#FFF',
|
||||
@ -192,7 +243,7 @@ class EditProfileScreen extends Component {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
right: '-5%',
|
||||
right: '0%',
|
||||
top: '0%',
|
||||
zIndex: 1
|
||||
}}
|
||||
@ -216,21 +267,16 @@ class EditProfileScreen extends Component {
|
||||
<Icon name={'ic_outline_camera'} size={20} color={'#8BC34A'}/>
|
||||
</TouchableOpacity>
|
||||
<Image
|
||||
style={{
|
||||
width: 120,
|
||||
height: 120,
|
||||
borderRadius: 60,
|
||||
borderColor: 'white',
|
||||
borderWidth: 2
|
||||
}}
|
||||
source={this.state.image_url}
|
||||
style={{width: 120, height: 120, borderRadius: 60, borderColor: 'white', borderWidth: 2}}
|
||||
source={{ uri: this.state.image_url && this.state.image_url.uri ? this.state.image_url.uri : ''}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<View style={{ flex: 1, height: '100%' }}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<View style={[styles.form]}>
|
||||
</View>
|
||||
|
||||
<View style={{ flexDirection: 'column' , padding: 15, paddingTop: 5, paddingBottom: 0,}}>
|
||||
<View>
|
||||
<Text style={styles.headerTitle}>{t('profile')}</Text>
|
||||
<View style={styles.row}>
|
||||
<CustomInput
|
||||
@ -243,7 +289,8 @@ class EditProfileScreen extends Component {
|
||||
this.setState({
|
||||
user: {
|
||||
...this.state.user,
|
||||
name: text
|
||||
name: text,
|
||||
name_th: text
|
||||
}
|
||||
})
|
||||
}}/>
|
||||
@ -264,7 +311,7 @@ class EditProfileScreen extends Component {
|
||||
})
|
||||
}}/>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
{/*<View style={styles.row}>
|
||||
<View style={styles.row_grow_first}>
|
||||
<View
|
||||
style={{
|
||||
@ -322,19 +369,20 @@ class EditProfileScreen extends Component {
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
</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) => {
|
||||
<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')
|
||||
birth_date: moment(data).format('YYYY-MM-DD'),
|
||||
show_birth_date: moment(data).format('YYYY-MM-DD')
|
||||
}
|
||||
})}}/>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
</View>*/}
|
||||
{/*<View style={styles.row}>
|
||||
<CustomInput
|
||||
style={styles.register_input}
|
||||
labelColor={'white'}
|
||||
@ -349,7 +397,7 @@ class EditProfileScreen extends Component {
|
||||
}
|
||||
})
|
||||
}}/>
|
||||
</View>
|
||||
</View>*/}
|
||||
<View style={styles.row}>
|
||||
<CustomInput
|
||||
style={styles.register_input}
|
||||
@ -366,8 +414,8 @@ class EditProfileScreen extends Component {
|
||||
})
|
||||
}}/>
|
||||
</View>
|
||||
<Text style={styles.headerTitle}>{t('accom_info')}</Text>
|
||||
<View style={styles.row}>
|
||||
{/*<Text style={styles.headerTitle}>{t('accom_info')}</Text>*/}
|
||||
{/*<View style={styles.row}>
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
@ -426,8 +474,8 @@ class EditProfileScreen extends Component {
|
||||
</Picker>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
</View>*/}
|
||||
{/*<View style={styles.row}>
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
@ -459,10 +507,6 @@ class EditProfileScreen extends Component {
|
||||
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')}
|
||||
@ -475,7 +519,7 @@ class EditProfileScreen extends Component {
|
||||
}
|
||||
})
|
||||
}}>
|
||||
{this.state.building_list.length > 0 && this.state.building_list.map((item,index) => {
|
||||
{this.state.building_list.map((item,index) => {
|
||||
return <Picker.Item label={item.room_build} value={item.room_build} key={'building_'+index}/>
|
||||
})}
|
||||
</Picker>
|
||||
@ -499,7 +543,8 @@ class EditProfileScreen extends Component {
|
||||
})
|
||||
}}/>
|
||||
</View>
|
||||
</View>
|
||||
</View>*/}
|
||||
|
||||
<Text style={styles.headerTitle}>{t('change_password')}</Text>
|
||||
<View>
|
||||
<View style={styles.row}>
|
||||
@ -540,6 +585,9 @@ class EditProfileScreen extends Component {
|
||||
}}/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<View style={styles.buttons}>
|
||||
<View style={styles.row_grow}>
|
||||
<CustomButton style={styles.btn_next_register} title={t('complete')}
|
||||
@ -553,8 +601,8 @@ class EditProfileScreen extends Component {
|
||||
</View>
|
||||
</ScrollView>
|
||||
</BackgroundImage_RegisterForm>
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -609,10 +657,10 @@ const styles = {
|
||||
backgroundColor: 'rgba(255,255,255,0.3)',
|
||||
borderRadius: 30,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const mapDisPatchToProps = state => {
|
||||
return state.app
|
||||
}
|
||||
};
|
||||
const setUser = dispatch => bindActionCreators({ appSetDevice, appSetUser, appCleanUser }, dispatch)
|
||||
export default connect(mapDisPatchToProps, setUser)(EditProfileScreen)
|
||||
|
||||
@ -23,6 +23,7 @@ class ProfileScreen extends Component {
|
||||
isLoading: false,
|
||||
user:{},
|
||||
room:null,
|
||||
profileImage: require('../../../assets/images/profile.png')
|
||||
}
|
||||
this.getUserData = this.getUserData.bind(this)
|
||||
}
|
||||
@ -42,10 +43,18 @@ class ProfileScreen extends Component {
|
||||
.then(res => {
|
||||
// console.log('user profile -------> ',res);
|
||||
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({
|
||||
isLoading: false,
|
||||
user: res.data.user,
|
||||
room: res.data.room
|
||||
room: res.data.room && res.data.room.length > 0 ? res.data.room[0] : null,
|
||||
profileImage : image,
|
||||
})
|
||||
}else{
|
||||
this.setState({
|
||||
@ -55,6 +64,31 @@ 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() {
|
||||
window.location.reload(false);
|
||||
}
|
||||
@ -69,6 +103,7 @@ class ProfileScreen extends Component {
|
||||
}}>
|
||||
<NavigationEvents
|
||||
onDidFocus={() => {
|
||||
console.log('getUserData');
|
||||
this.getUserData()
|
||||
}}
|
||||
/>
|
||||
@ -80,7 +115,7 @@ class ProfileScreen extends Component {
|
||||
}}>
|
||||
<Image
|
||||
style={{ width: 120, height: 120, borderRadius: 60, borderColor: 'white', borderWidth: 2 }}
|
||||
source={require('../../../assets/images/profile.png')}
|
||||
source={this.state.profileImage}
|
||||
/>
|
||||
</View>
|
||||
<View style={{ flex: 1, padding: 15, }}>
|
||||
@ -89,7 +124,7 @@ class ProfileScreen extends Component {
|
||||
<Text style={{ color: '#8BC34A', marginBottom: 10 }}>{t('profile')}</Text>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('category')}</Text>
|
||||
<Text style={styles.data_field_style}>{t('individual2')}</Text>
|
||||
<Text style={styles.data_field_style}>{this.state.user.is_customer ? t('customer') : t('guest')}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('name')}</Text>
|
||||
@ -97,7 +132,7 @@ class ProfileScreen extends Component {
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('email')}</Text>
|
||||
<Text style={styles.data_field_style}>{this.state.user.email}</Text>
|
||||
<Text style={styles.data_field_style}>{this.state.user.email ? this.state.email : '-'}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('phone2')}</Text>
|
||||
@ -109,11 +144,11 @@ class ProfileScreen extends Component {
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('gender')}</Text>
|
||||
<Text style={styles.data_field_style}>{this.state.user.gender=="male"? t('male') : t('female')}</Text>
|
||||
<Text style={styles.data_field_style}>{this.state.user.gender == "male" || this.state.user.gender == "ชาย" ? t('male') : t('female')}</Text>
|
||||
</View>
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
<Text style={styles.text_field_style}>{t('birth_date')}</Text>
|
||||
<Text style={styles.data_field_style}>{moment(this.state.user.birth_date).format('DD-MM-YYYY')}</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>
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
@ -144,18 +179,9 @@ class ProfileScreen extends Component {
|
||||
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
|
||||
<Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }}
|
||||
onPress={() => {
|
||||
|
||||
setTimeout( () => {
|
||||
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);
|
||||
loginWithFacebook(this.connectFBSuccess)
|
||||
},1000);
|
||||
|
||||
|
||||
|
||||
}} >
|
||||
<Text style={{ color: '#ffffff', fontSize: 14 }}>{t('connect_facebook')}</Text>
|
||||
</Button>
|
||||
@ -164,18 +190,7 @@ class ProfileScreen extends Component {
|
||||
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
|
||||
<Button block style={{ backgroundColor: '#145EB3', marginHorizontal: 15 }}
|
||||
onPress={() => {
|
||||
|
||||
disconnectWithFacebook();
|
||||
|
||||
setTimeout( () => {
|
||||
this.state.user.fb_is_link = 'f'
|
||||
//alert("Disconnected!")
|
||||
this.props.navigation.replace('Profile',{user:this.state.user})
|
||||
},3000);
|
||||
|
||||
|
||||
|
||||
|
||||
disconnectWithFacebook(this.disConnectFBSuccess);
|
||||
}}
|
||||
>
|
||||
<Text style={{ color: '#ffffff', fontSize: 14 }}>{t('disconnect_facebook')}</Text>
|
||||
@ -186,7 +201,8 @@ class ProfileScreen extends Component {
|
||||
<View style={{ flexGrow: 0.5, justifyContent: 'flex-end', backgroundColor: 'rgba(0,0,0,0)' }}>
|
||||
<Button block style={{ backgroundColor: '#145EB3', margin:15 }}
|
||||
onPress={() => { this.props.navigation.navigate('EditProfile',{
|
||||
user:this.props.user
|
||||
user:this.state.user,
|
||||
image:this.state.profileImage,
|
||||
}) }}>
|
||||
<Text style={{ color: '#ffffff', fontSize: 14 }}><Icon name={'ic_edit'} size={15}/> {t('edit_profile')} </Text>
|
||||
</Button>
|
||||
|
||||
199
src/screens/redeem/AllRewards.js
Normal file
@ -0,0 +1,199 @@
|
||||
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)
|
||||