diff --git a/app/App.js b/app/App.js
new file mode 100644
index 00000000..e43ea3e7
--- /dev/null
+++ b/app/App.js
@@ -0,0 +1,245 @@
+
+import 'react-native-gesture-handler';
+import * as React from 'react';
+import { Platform, AppState } from 'react-native';
+import { Provider } from "react-redux";
+import firebase from '@react-native-firebase/app';
+import '@react-native-firebase/messaging';
+import { NativeBaseProvider } from 'native-base';
+import Router from './screens/route.js';
+import store from './redux/store';
+
+import DeviceInfo from 'react-native-device-info';
+import DB from './components/storage/';
+
+var PushNotification = require("react-native-push-notification");
+
+export default class App extends React.Component {
+
+ constructor(props) {
+ super(props)
+ }
+
+ _isMounted = false
+ state = {
+ appState: AppState.currentState,
+ backgroundCaptureTime: null
+ }
+
+ async componentDidMount() {
+ this._isMounted = true
+ this.saveDeviceUUID()
+ this.notificationAuthorization()
+ this.createNotificationListener()
+ AppState.addEventListener('change', this._handleAppStateChange)
+ }
+
+ componentWillUnmount() {
+ this._isMounted = false
+ try {
+ this.messageListener()
+ this.notificationOpenedListener()
+ this.notificationListener()
+ AppState.removeEventListener('change', this._handleAppStateChange)
+ } catch (error) {}
+ }
+
+ _handleAppStateChange = (nextAppState) => {
+ if(this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
+
+ } else {
+
+ }
+ }
+
+ saveDeviceUUID = () => {
+ DB.set("deviceUUID", DeviceInfo.getUniqueId(), () => {}, (e) => console.log("DEVICE INFO SAVING FAILED!", e))
+ }
+
+ notificationAuthorization = async () => {
+ const authStatus = await firebase.messaging().requestPermission();
+ const enabled = authStatus === firebase.messaging.AuthorizationStatus.AUTHORIZED || authStatus === firebase.messaging.AuthorizationStatus.PROVISIONAL;
+ if (enabled) {
+ try {
+ const token = await firebase.messaging().getToken()
+ if(token) {
+ let existingToken = await DB.get("fcmToken") || ""
+ if(token != existingToken){
+ DB.set("fcmRegistration", "new", (r) => {}, (e) => {})
+ DB.set("fcmToken", token, () => console.log("FCM TOKEN SAVED", token), () => console.log("FCM TOKEN SAVING FAILED"))
+ }
+ }
+ console.log('device_token:', token);
+ } catch (error) {
+ console.log(error);
+ }
+ }
+ }
+
+ createNotificationListener = () => {
+ this.messageListener = firebase.messaging().onMessage(message => {
+ const { notification } = message
+ PushNotification.localNotification({
+ title: notification.title || "Unioil Loyalty App",
+ message: notification.body,
+ playSound: false,
+ soundName: "default"
+ })
+ });
+
+ /*
+ * Triggered when a particular notification has been received in foreground
+ * */
+ this.notificationListener = firebase.messaging().onMessage(async remoteMessage => {
+ console.log(remoteMessage)
+ });
+
+ /*
+ * If your app is in background, you can listen for when a notification is clicked / tapped / opened as follows:
+ * */
+ this.notificationOpenedListener = firebase.messaging().onNotificationOpenedApp(remoteMessage => {
+ console.log(remoteMessage)
+ });
+
+
+ firebase.messaging()
+ .getInitialNotification()
+ .then(async remoteMessage => {
+ if (remoteMessage) {
+ if(Platform.OS == 'ios'){
+ console.log(
+ 'Notification caused app to open from quit state:',
+ remoteMessage.data.notification,
+ );
+ let result = await DB.AddNotification({
+ messageId: remoteMessage.data.from,
+ title: remoteMessage.data.notification.title,
+ body: remoteMessage.data.notification.body,
+ visible: true,
+ delivery: false,
+ recieved: remoteMessage.data.from
+ })
+ console.log("Notifications rendered on background", result)
+ }else{
+ console.log(
+ 'Notification caused app to open from quit state:',
+ remoteMessage.notification,
+ );
+ let result = await DB.AddNotification({
+ messageId: remoteMessage.messageId,
+ title: remoteMessage.notification.title,
+ body: remoteMessage.notification.body,
+ visible: true,
+ delivery: false,
+ recieved: remoteMessage.sentTime
+ })
+ console.log("Notifications rendered on background", result)
+ }
+
+ }
+ });
+ }
+
+ render() {
+ return (
+
+
+
+
+
+ )
+ }
+}
+
+// export default function App(){
+
+// useEffect(() => {
+// const uniqueId = DeviceInfo.getUniqueId();
+// DB.set("deviceUUID", uniqueId, function(){
+// }, function(e){
+// console.log("DEVICE INFO SAVING FAILED!", e)
+// })
+// }, [])
+
+// const GetFCMToken = () => {
+// messaging().getToken().then(async fcmToken => {
+// if(fcmToken){
+// let existingToken = await DB.get("fcmToken") || ""
+// if(fcmToken != existingToken){
+// DB.set("fcmRegistration", "new", (r) => console.log(r), (e) => console.log(e))
+// DB.set("fcmToken", fcmToken, () => console.log("FCM TOKEN SAVED"), () => console.log("FCM TOKEN SAVING FAILED"))
+// }
+// }
+// })
+// }
+
+// const NotificationAuthorization = async () => {
+// await messaging().registerDeviceForRemoteMessages();
+// const enabled = await messaging().hasPermission()
+// if (!enabled) {
+// try {
+// await messaging().requestPermission()
+// } catch (error) {
+// // permission denied
+// return
+// }
+// }
+// GetFCMToken()
+// }
+
+// useEffect(() => {
+// if(Platform.OS === 'ios'){
+// NotificationAuthorization()
+// }else{
+// GetFCMToken()
+// }
+// }, [])
+
+// useEffect(() => {
+// messaging()
+// .getInitialNotification()
+// .then(async remoteMessage => {
+// if (remoteMessage) {
+
+// if(Platform.OS == 'ios'){
+// console.log(
+// 'Notification caused app to open from quit state:',
+// remoteMessage.data.notification,
+// );
+// let result = await DB.AddNotification({
+// messageId: remoteMessage.data.from,
+// title: remoteMessage.data.notification.title,
+// body: remoteMessage.data.notification.body,
+// visible: true,
+// delivery: false,
+// recieved: remoteMessage.data.from
+// })
+// console.log("Notifications rendered on background", result)
+// }else{
+// console.log(
+// 'Notification caused app to open from quit state:',
+// remoteMessage.notification,
+// );
+// let result = await DB.AddNotification({
+// messageId: remoteMessage.messageId,
+// title: remoteMessage.notification.title,
+// body: remoteMessage.notification.body,
+// visible: true,
+// delivery: false,
+// recieved: remoteMessage.sentTime
+// })
+// console.log("Notifications rendered on background", result)
+// }
+
+// }
+// });
+// }, [])
+
+// return (
+//
+//
+//
+//
+//
+// )
+// }
\ No newline at end of file
diff --git a/app/assets/100086780_691038501729006_175336722689687552_n.jpg b/app/assets/100086780_691038501729006_175336722689687552_n.jpg
new file mode 100644
index 00000000..26337fa4
Binary files /dev/null and b/app/assets/100086780_691038501729006_175336722689687552_n.jpg differ
diff --git a/app/assets/98331769_3168630556522364_3516965718727852032_n.jpg b/app/assets/98331769_3168630556522364_3516965718727852032_n.jpg
new file mode 100644
index 00000000..984eb354
Binary files /dev/null and b/app/assets/98331769_3168630556522364_3516965718727852032_n.jpg differ
diff --git a/app/assets/baseline_call_black_24.png b/app/assets/baseline_call_black_24.png
new file mode 100755
index 00000000..04423ef7
Binary files /dev/null and b/app/assets/baseline_call_black_24.png differ
diff --git a/app/assets/baseline_delete_white_24.png b/app/assets/baseline_delete_white_24.png
new file mode 100755
index 00000000..fe91d65f
Binary files /dev/null and b/app/assets/baseline_delete_white_24.png differ
diff --git a/app/assets/baseline_edit_white_24.png b/app/assets/baseline_edit_white_24.png
new file mode 100755
index 00000000..c2124f1b
Binary files /dev/null and b/app/assets/baseline_edit_white_24.png differ
diff --git a/app/assets/baseline_email_black_24.png b/app/assets/baseline_email_black_24.png
new file mode 100755
index 00000000..e2d1d37e
Binary files /dev/null and b/app/assets/baseline_email_black_24.png differ
diff --git a/app/assets/baseline_info_black_18.png b/app/assets/baseline_info_black_18.png
new file mode 100755
index 00000000..2ac9e1d5
Binary files /dev/null and b/app/assets/baseline_info_black_18.png differ
diff --git a/app/assets/baseline_keyboard_arrow_left_black_48.png b/app/assets/baseline_keyboard_arrow_left_black_48.png
new file mode 100755
index 00000000..45c24123
Binary files /dev/null and b/app/assets/baseline_keyboard_arrow_left_black_48.png differ
diff --git a/app/assets/baseline_keyboard_arrow_right_black_48.png b/app/assets/baseline_keyboard_arrow_right_black_48.png
new file mode 100755
index 00000000..16eed615
Binary files /dev/null and b/app/assets/baseline_keyboard_arrow_right_black_48.png differ
diff --git a/app/assets/bg_classic.png b/app/assets/bg_classic.png
new file mode 100755
index 00000000..e1e62efb
Binary files /dev/null and b/app/assets/bg_classic.png differ
diff --git a/app/assets/bg_fuel_efficiency.png b/app/assets/bg_fuel_efficiency.png
new file mode 100755
index 00000000..871bae35
Binary files /dev/null and b/app/assets/bg_fuel_efficiency.png differ
diff --git a/app/assets/bg_grab.png b/app/assets/bg_grab.png
new file mode 100755
index 00000000..db7eac40
Binary files /dev/null and b/app/assets/bg_grab.png differ
diff --git a/app/assets/bg_ica.png b/app/assets/bg_ica.png
new file mode 100755
index 00000000..31cdff23
Binary files /dev/null and b/app/assets/bg_ica.png differ
diff --git a/app/assets/bg_scheduler.png b/app/assets/bg_scheduler.png
new file mode 100755
index 00000000..bc2ed8be
Binary files /dev/null and b/app/assets/bg_scheduler.png differ
diff --git a/app/assets/bg_xavier.png b/app/assets/bg_xavier.png
new file mode 100755
index 00000000..25e2998b
Binary files /dev/null and b/app/assets/bg_xavier.png differ
diff --git a/app/assets/dexie.jpg b/app/assets/dexie.jpg
new file mode 100644
index 00000000..77692140
Binary files /dev/null and b/app/assets/dexie.jpg differ
diff --git a/app/assets/empty_state_history.png b/app/assets/empty_state_history.png
new file mode 100755
index 00000000..aa47255b
Binary files /dev/null and b/app/assets/empty_state_history.png differ
diff --git a/app/assets/empty_state_home_promo.png b/app/assets/empty_state_home_promo.png
new file mode 100755
index 00000000..9ac95caa
Binary files /dev/null and b/app/assets/empty_state_home_promo.png differ
diff --git a/app/assets/empty_state_image.png b/app/assets/empty_state_image.png
new file mode 100755
index 00000000..2731a77a
Binary files /dev/null and b/app/assets/empty_state_image.png differ
diff --git a/app/assets/empty_state_no_internet.png b/app/assets/empty_state_no_internet.png
new file mode 100755
index 00000000..25de66a0
Binary files /dev/null and b/app/assets/empty_state_no_internet.png differ
diff --git a/app/assets/empty_state_promo.png b/app/assets/empty_state_promo.png
new file mode 100755
index 00000000..d496bd9e
Binary files /dev/null and b/app/assets/empty_state_promo.png differ
diff --git a/app/assets/empty_state_top_up_error.png b/app/assets/empty_state_top_up_error.png
new file mode 100755
index 00000000..a044e0f3
Binary files /dev/null and b/app/assets/empty_state_top_up_error.png differ
diff --git a/app/assets/empty_state_top_up_success.png b/app/assets/empty_state_top_up_success.png
new file mode 100755
index 00000000..5ae232b2
Binary files /dev/null and b/app/assets/empty_state_top_up_success.png differ
diff --git a/app/assets/empty_state_transaction.png b/app/assets/empty_state_transaction.png
new file mode 100755
index 00000000..1a353165
Binary files /dev/null and b/app/assets/empty_state_transaction.png differ
diff --git a/app/assets/googleMapsIcon.png b/app/assets/googleMapsIcon.png
new file mode 100644
index 00000000..924b442b
Binary files /dev/null and b/app/assets/googleMapsIcon.png differ
diff --git a/app/assets/guide_card.png b/app/assets/guide_card.png
new file mode 100755
index 00000000..3061786d
Binary files /dev/null and b/app/assets/guide_card.png differ
diff --git a/app/assets/ic_about.png b/app/assets/ic_about.png
new file mode 100755
index 00000000..cef86beb
Binary files /dev/null and b/app/assets/ic_about.png differ
diff --git a/app/assets/ic_account.png b/app/assets/ic_account.png
new file mode 100755
index 00000000..1989090e
Binary files /dev/null and b/app/assets/ic_account.png differ
diff --git a/app/assets/ic_account_active.png b/app/assets/ic_account_active.png
new file mode 100644
index 00000000..f7f7be0e
Binary files /dev/null and b/app/assets/ic_account_active.png differ
diff --git a/app/assets/ic_account_inactive.png b/app/assets/ic_account_inactive.png
new file mode 100644
index 00000000..c573f41e
Binary files /dev/null and b/app/assets/ic_account_inactive.png differ
diff --git a/app/assets/ic_account_inactive2.png b/app/assets/ic_account_inactive2.png
new file mode 100644
index 00000000..5d017b8b
Binary files /dev/null and b/app/assets/ic_account_inactive2.png differ
diff --git a/app/assets/ic_add_white_24dp.png b/app/assets/ic_add_white_24dp.png
new file mode 100755
index 00000000..d64c22e9
Binary files /dev/null and b/app/assets/ic_add_white_24dp.png differ
diff --git a/app/assets/ic_card.png b/app/assets/ic_card.png
new file mode 100755
index 00000000..10c93ee2
Binary files /dev/null and b/app/assets/ic_card.png differ
diff --git a/app/assets/ic_card_active.png b/app/assets/ic_card_active.png
new file mode 100644
index 00000000..211f7efd
Binary files /dev/null and b/app/assets/ic_card_active.png differ
diff --git a/app/assets/ic_card_inactive.png b/app/assets/ic_card_inactive.png
new file mode 100644
index 00000000..8b741a94
Binary files /dev/null and b/app/assets/ic_card_inactive.png differ
diff --git a/app/assets/ic_card_inactive2.png b/app/assets/ic_card_inactive2.png
new file mode 100644
index 00000000..f8718ca1
Binary files /dev/null and b/app/assets/ic_card_inactive2.png differ
diff --git a/app/assets/ic_chevron_down.png b/app/assets/ic_chevron_down.png
new file mode 100755
index 00000000..0756f042
Binary files /dev/null and b/app/assets/ic_chevron_down.png differ
diff --git a/app/assets/ic_close_white_24dp.png b/app/assets/ic_close_white_24dp.png
new file mode 100755
index 00000000..39641921
Binary files /dev/null and b/app/assets/ic_close_white_24dp.png differ
diff --git a/app/assets/ic_contact.png b/app/assets/ic_contact.png
new file mode 100755
index 00000000..43bcd1d3
Binary files /dev/null and b/app/assets/ic_contact.png differ
diff --git a/app/assets/ic_dashboard.png b/app/assets/ic_dashboard.png
new file mode 100755
index 00000000..285fb4e1
Binary files /dev/null and b/app/assets/ic_dashboard.png differ
diff --git a/app/assets/ic_fav_empty.png b/app/assets/ic_fav_empty.png
new file mode 100755
index 00000000..a30d4eb3
Binary files /dev/null and b/app/assets/ic_fav_empty.png differ
diff --git a/app/assets/ic_fav_full.png b/app/assets/ic_fav_full.png
new file mode 100755
index 00000000..1b00f75a
Binary files /dev/null and b/app/assets/ic_fav_full.png differ
diff --git a/app/assets/ic_fuel.png b/app/assets/ic_fuel.png
new file mode 100755
index 00000000..1baa3ea6
Binary files /dev/null and b/app/assets/ic_fuel.png differ
diff --git a/app/assets/ic_fuel_tab.png b/app/assets/ic_fuel_tab.png
new file mode 100755
index 00000000..67058c16
Binary files /dev/null and b/app/assets/ic_fuel_tab.png differ
diff --git a/app/assets/ic_history.png b/app/assets/ic_history.png
new file mode 100755
index 00000000..3a224f31
Binary files /dev/null and b/app/assets/ic_history.png differ
diff --git a/app/assets/ic_history_active.png b/app/assets/ic_history_active.png
new file mode 100644
index 00000000..dfb0981c
Binary files /dev/null and b/app/assets/ic_history_active.png differ
diff --git a/app/assets/ic_home.png b/app/assets/ic_home.png
new file mode 100755
index 00000000..ad9489cf
Binary files /dev/null and b/app/assets/ic_home.png differ
diff --git a/app/assets/ic_home_inactive.png b/app/assets/ic_home_inactive.png
new file mode 100644
index 00000000..a25877af
Binary files /dev/null and b/app/assets/ic_home_inactive.png differ
diff --git a/app/assets/ic_info.png b/app/assets/ic_info.png
new file mode 100755
index 00000000..8111603a
Binary files /dev/null and b/app/assets/ic_info.png differ
diff --git a/app/assets/ic_km_liter.png b/app/assets/ic_km_liter.png
new file mode 100755
index 00000000..637df6dd
Binary files /dev/null and b/app/assets/ic_km_liter.png differ
diff --git a/app/assets/ic_launcher.png b/app/assets/ic_launcher.png
new file mode 100755
index 00000000..def89273
Binary files /dev/null and b/app/assets/ic_launcher.png differ
diff --git a/app/assets/ic_launcher_foreground.png b/app/assets/ic_launcher_foreground.png
new file mode 100755
index 00000000..fd884a2e
Binary files /dev/null and b/app/assets/ic_launcher_foreground.png differ
diff --git a/app/assets/ic_launcher_round.png b/app/assets/ic_launcher_round.png
new file mode 100755
index 00000000..2511a290
Binary files /dev/null and b/app/assets/ic_launcher_round.png differ
diff --git a/app/assets/ic_logout.png b/app/assets/ic_logout.png
new file mode 100755
index 00000000..497f24a8
Binary files /dev/null and b/app/assets/ic_logout.png differ
diff --git a/app/assets/ic_my_location_black_24dp.png b/app/assets/ic_my_location_black_24dp.png
new file mode 100755
index 00000000..0812b0e3
Binary files /dev/null and b/app/assets/ic_my_location_black_24dp.png differ
diff --git a/app/assets/ic_my_profile_card.png b/app/assets/ic_my_profile_card.png
new file mode 100755
index 00000000..c65e0dd7
Binary files /dev/null and b/app/assets/ic_my_profile_card.png differ
diff --git a/app/assets/ic_my_profile_profile.png b/app/assets/ic_my_profile_profile.png
new file mode 100755
index 00000000..a1092f26
Binary files /dev/null and b/app/assets/ic_my_profile_profile.png differ
diff --git a/app/assets/ic_payatpump.png b/app/assets/ic_payatpump.png
new file mode 100644
index 00000000..8f57d3fc
Binary files /dev/null and b/app/assets/ic_payatpump.png differ
diff --git a/app/assets/ic_peso.png b/app/assets/ic_peso.png
new file mode 100755
index 00000000..747b921e
Binary files /dev/null and b/app/assets/ic_peso.png differ
diff --git a/app/assets/ic_products.png b/app/assets/ic_products.png
new file mode 100755
index 00000000..d61ea0e1
Binary files /dev/null and b/app/assets/ic_products.png differ
diff --git a/app/assets/ic_promos.png b/app/assets/ic_promos.png
new file mode 100755
index 00000000..8b622ce0
Binary files /dev/null and b/app/assets/ic_promos.png differ
diff --git a/app/assets/ic_promos_active.png b/app/assets/ic_promos_active.png
new file mode 100644
index 00000000..b5bc6f39
Binary files /dev/null and b/app/assets/ic_promos_active.png differ
diff --git a/app/assets/ic_reminder.png b/app/assets/ic_reminder.png
new file mode 100755
index 00000000..0596fa1d
Binary files /dev/null and b/app/assets/ic_reminder.png differ
diff --git a/app/assets/ic_rewards.png b/app/assets/ic_rewards.png
new file mode 100755
index 00000000..4ec55365
Binary files /dev/null and b/app/assets/ic_rewards.png differ
diff --git a/app/assets/ic_rewards_active.png b/app/assets/ic_rewards_active.png
new file mode 100644
index 00000000..df1cd54a
Binary files /dev/null and b/app/assets/ic_rewards_active.png differ
diff --git a/app/assets/ic_scheduler.png b/app/assets/ic_scheduler.png
new file mode 100755
index 00000000..c7518313
Binary files /dev/null and b/app/assets/ic_scheduler.png differ
diff --git a/app/assets/ic_search_white_24dp.png b/app/assets/ic_search_white_24dp.png
new file mode 100755
index 00000000..dd5adfc7
Binary files /dev/null and b/app/assets/ic_search_white_24dp.png differ
diff --git a/app/assets/ic_selected_station_pin.png b/app/assets/ic_selected_station_pin.png
new file mode 100755
index 00000000..36bcbdc4
Binary files /dev/null and b/app/assets/ic_selected_station_pin.png differ
diff --git a/app/assets/ic_station.png b/app/assets/ic_station.png
new file mode 100755
index 00000000..0fd3ca6e
Binary files /dev/null and b/app/assets/ic_station.png differ
diff --git a/app/assets/ic_station_map_pin.png b/app/assets/ic_station_map_pin.png
new file mode 100755
index 00000000..cf42a0b8
Binary files /dev/null and b/app/assets/ic_station_map_pin.png differ
diff --git a/app/assets/ic_station_map_pin_lg.png b/app/assets/ic_station_map_pin_lg.png
new file mode 100755
index 00000000..79a64270
Binary files /dev/null and b/app/assets/ic_station_map_pin_lg.png differ
diff --git a/app/assets/ic_stations.png b/app/assets/ic_stations.png
new file mode 100755
index 00000000..acdb6d70
Binary files /dev/null and b/app/assets/ic_stations.png differ
diff --git a/app/assets/ic_stations_active.png b/app/assets/ic_stations_active.png
new file mode 100644
index 00000000..368a9846
Binary files /dev/null and b/app/assets/ic_stations_active.png differ
diff --git a/app/assets/ic_topup.png b/app/assets/ic_topup.png
new file mode 100755
index 00000000..4191f251
Binary files /dev/null and b/app/assets/ic_topup.png differ
diff --git a/app/assets/ic_tutorial.png b/app/assets/ic_tutorial.png
new file mode 100755
index 00000000..76bf54aa
Binary files /dev/null and b/app/assets/ic_tutorial.png differ
diff --git a/app/assets/ic_type.png b/app/assets/ic_type.png
new file mode 100755
index 00000000..c6d0ccae
Binary files /dev/null and b/app/assets/ic_type.png differ
diff --git a/app/assets/icon_googlemaps.png b/app/assets/icon_googlemaps.png
new file mode 100755
index 00000000..f5ac4a58
Binary files /dev/null and b/app/assets/icon_googlemaps.png differ
diff --git a/app/assets/icon_internet.png b/app/assets/icon_internet.png
new file mode 100755
index 00000000..1706adbf
Binary files /dev/null and b/app/assets/icon_internet.png differ
diff --git a/app/assets/icon_unioil.png b/app/assets/icon_unioil.png
new file mode 100755
index 00000000..538849bc
Binary files /dev/null and b/app/assets/icon_unioil.png differ
diff --git a/app/assets/icon_waze.png b/app/assets/icon_waze.png
new file mode 100755
index 00000000..1e9ca6ee
Binary files /dev/null and b/app/assets/icon_waze.png differ
diff --git a/app/assets/img_bg_about.png b/app/assets/img_bg_about.png
new file mode 100755
index 00000000..786a44d6
Binary files /dev/null and b/app/assets/img_bg_about.png differ
diff --git a/app/assets/loading.gif b/app/assets/loading.gif
new file mode 100644
index 00000000..81105847
Binary files /dev/null and b/app/assets/loading.gif differ
diff --git a/app/assets/login_background.jpg b/app/assets/login_background.jpg
new file mode 100644
index 00000000..fe6a5291
Binary files /dev/null and b/app/assets/login_background.jpg differ
diff --git a/app/assets/login_bg.jpg b/app/assets/login_bg.jpg
new file mode 100644
index 00000000..c925913b
Binary files /dev/null and b/app/assets/login_bg.jpg differ
diff --git a/app/assets/logo_paypal.png b/app/assets/logo_paypal.png
new file mode 100755
index 00000000..f562f6af
Binary files /dev/null and b/app/assets/logo_paypal.png differ
diff --git a/app/assets/logo_unioil.png b/app/assets/logo_unioil.png
new file mode 100755
index 00000000..3f695b43
Binary files /dev/null and b/app/assets/logo_unioil.png differ
diff --git a/app/assets/logo_unioil_new.png b/app/assets/logo_unioil_new.png
new file mode 100644
index 00000000..965794ba
Binary files /dev/null and b/app/assets/logo_unioil_new.png differ
diff --git a/app/assets/logo_unioil_reverse.png b/app/assets/logo_unioil_reverse.png
new file mode 100755
index 00000000..39405dbd
Binary files /dev/null and b/app/assets/logo_unioil_reverse.png differ
diff --git a/app/assets/mapsIcon.png b/app/assets/mapsIcon.png
new file mode 100644
index 00000000..8760537e
Binary files /dev/null and b/app/assets/mapsIcon.png differ
diff --git a/app/assets/onboarding_01.png b/app/assets/onboarding_01.png
new file mode 100644
index 00000000..34b74e40
Binary files /dev/null and b/app/assets/onboarding_01.png differ
diff --git a/app/assets/onboarding_01x.png b/app/assets/onboarding_01x.png
new file mode 100755
index 00000000..0c6accc4
Binary files /dev/null and b/app/assets/onboarding_01x.png differ
diff --git a/app/assets/onboarding_02.png b/app/assets/onboarding_02.png
new file mode 100755
index 00000000..42f1657d
Binary files /dev/null and b/app/assets/onboarding_02.png differ
diff --git a/app/assets/onboarding_03.png b/app/assets/onboarding_03.png
new file mode 100644
index 00000000..b902601d
Binary files /dev/null and b/app/assets/onboarding_03.png differ
diff --git a/app/assets/onboarding_03x.png b/app/assets/onboarding_03x.png
new file mode 100755
index 00000000..372ce777
Binary files /dev/null and b/app/assets/onboarding_03x.png differ
diff --git a/app/assets/onboarding_04.png b/app/assets/onboarding_04.png
new file mode 100755
index 00000000..48e5b059
Binary files /dev/null and b/app/assets/onboarding_04.png differ
diff --git a/app/assets/philippine_peso.png b/app/assets/philippine_peso.png
new file mode 100644
index 00000000..dee2d82d
Binary files /dev/null and b/app/assets/philippine_peso.png differ
diff --git a/app/assets/place_holder_profile_pic.png b/app/assets/place_holder_profile_pic.png
new file mode 100755
index 00000000..3ba19110
Binary files /dev/null and b/app/assets/place_holder_profile_pic.png differ
diff --git a/app/assets/points_balance.png b/app/assets/points_balance.png
new file mode 100644
index 00000000..6614c9bb
Binary files /dev/null and b/app/assets/points_balance.png differ
diff --git a/app/assets/pump_grey.png b/app/assets/pump_grey.png
new file mode 100644
index 00000000..5f18f916
Binary files /dev/null and b/app/assets/pump_grey.png differ
diff --git a/app/assets/pump_loader.png b/app/assets/pump_loader.png
new file mode 100644
index 00000000..4bc7e512
Binary files /dev/null and b/app/assets/pump_loader.png differ
diff --git a/app/assets/pump_logo.png b/app/assets/pump_logo.png
new file mode 100644
index 00000000..0e0f2b57
Binary files /dev/null and b/app/assets/pump_logo.png differ
diff --git a/app/assets/pump_plain.png b/app/assets/pump_plain.png
new file mode 100644
index 00000000..eee23318
Binary files /dev/null and b/app/assets/pump_plain.png differ
diff --git a/app/assets/stp_card_jcb.png b/app/assets/stp_card_jcb.png
new file mode 100644
index 00000000..f9746682
Binary files /dev/null and b/app/assets/stp_card_jcb.png differ
diff --git a/app/assets/stp_card_mastercard.png b/app/assets/stp_card_mastercard.png
new file mode 100644
index 00000000..9022725e
Binary files /dev/null and b/app/assets/stp_card_mastercard.png differ
diff --git a/app/assets/stp_card_unknown.png b/app/assets/stp_card_unknown.png
new file mode 100644
index 00000000..59def1fd
Binary files /dev/null and b/app/assets/stp_card_unknown.png differ
diff --git a/app/assets/stp_card_unlabeled.png b/app/assets/stp_card_unlabeled.png
new file mode 100644
index 00000000..2a076e6a
Binary files /dev/null and b/app/assets/stp_card_unlabeled.png differ
diff --git a/app/assets/stp_card_visa.png b/app/assets/stp_card_visa.png
new file mode 100644
index 00000000..07bf33af
Binary files /dev/null and b/app/assets/stp_card_visa.png differ
diff --git a/app/assets/stp_close_form.png b/app/assets/stp_close_form.png
new file mode 100644
index 00000000..9da57921
Binary files /dev/null and b/app/assets/stp_close_form.png differ
diff --git a/app/assets/success_icon.png b/app/assets/success_icon.png
new file mode 100644
index 00000000..2af1b3a1
Binary files /dev/null and b/app/assets/success_icon.png differ
diff --git a/app/assets/wazeIcon.png b/app/assets/wazeIcon.png
new file mode 100644
index 00000000..e02c212d
Binary files /dev/null and b/app/assets/wazeIcon.png differ
diff --git a/app/components/api/endpoints.js b/app/components/api/endpoints.js
new file mode 100644
index 00000000..db1924a5
--- /dev/null
+++ b/app/components/api/endpoints.js
@@ -0,0 +1,188 @@
+// const api_url = "https://mobileapid.unioil.com/api/mobile/";
+// export const api_url = "https://mobileapi.unioilapps.com/api/mobile/";
+// export const api_url = "https://unioilapi.lbteksystems.com/api/mobile/";
+export const api_url = "https://stag-mobapi.unioilapps.com/api/mobile/"; // staging
+// export const api_url = "https://mobilerest.unioilapps.com/api/mobile/"; // prod
+// const api_url = "https://unioilapi.taxikel.com/api/mobile/"
+
+const notifications = "https://stag-notifapi.unioilapps.com/api/notification/mobile/all"; //staging
+const account_fcm = "https://stag-notifapi.unioilapps.com/api/fcmtoken/notifs"; //staging
+const fcm_register = "https://stag-notifapi.unioilapps.com/api/fcmtoken"; //staging
+// const notifications = "https://notification.unioilapps.com/api/notification/mobile/all"; //prod
+// const account_fcm = "https://notification.unioilapps.com/api/fcmtoken/notifs"; //prod
+// const fcm_register = "https://notification.unioilapps.com/api/fcmtoken"; //prod
+// const notifications = "https://unioil-notif-api.herokuapp.com/api/notification/mobile/all";
+// const account_fcm = "https://unioil-notif-api.herokuapp.com/api/fcmtoken/notifs";
+// const fcm_register = "https://unioil-notif-api.herokuapp.com/api/fcmtoken";
+// const fcm_regoster = "https://mhcuuigdea.execute-api.us-east-1.amazonaws.com/dev/api/fcmtoken";
+
+// const post_pay = "https://partnerapi-lab.petrozone.com/v5/";
+// const post_pay = "https://partnerapi-au-uat.petrozone.com/v5/";
+const post_pay = "https://partnerapi-int.petrozone.com/v5/";
+
+const card_validation = api_url + "loginCardNumber";
+const card_validation_enroll = api_url + "loginCardNumberEnroll";
+const login = api_url + "loginBirthdate";
+const login_mobile = api_url + "loginMobileNumber";
+const security_question = api_url + "securityQuestion";
+const setup_mpin = api_url + "mpinUpdate";
+const requestOTP = api_url + "requestOtp";
+const sendOTP = api_url + "sendOTP";
+const mobileOTP = api_url + "mobileOtp";
+const registerAndValidate = api_url + "registerAndValidate";
+const validateMobileOTP = api_url + "validateMobileOTP";
+const submitRegistration = api_url + "submitRegistration";
+const validateOTP = api_url + "validateOtp";
+const terms_and_privacy = api_url + "termsAndPrivacy";
+const contact_us = api_url + "contactus";
+
+const user_profile = api_url + "userProfile";
+const send_card_pin = api_url + "validatePin";
+const activateCard = api_url + "activateCard";
+const apply = api_url + "signUp";
+const signup_id_number = api_url + "signUpIDNumber";
+
+const get_card_prompt_info = api_url + "systemPreference/information_guide_details";
+
+const gas_stations = api_url + "stationNearby";
+const gas_stations_city = api_url + "stationViaCity";
+const gas_station_details = api_url + "stationDetails";
+const gas_station_fuel = api_url + "stationfuels";
+
+const loyalty_cards = api_url + "getcardtype";
+const products = api_url + "products";
+const cities = api_url + "cityList";
+const station_search = api_url + "stationSearch";
+
+const whats_hot = api_url + "whatshot";
+const new_promos = api_url + "getpromo";
+const promo_gps = api_url + "promotionsGPS";
+const promos = api_url + "promotions";
+
+const update_profile_no_otp = api_url + "editProfile";
+const update_profile_with_otp = api_url + "editProfileOTP";
+
+const shared_treats = api_url + "sharedtreats";
+const logout = api_url + "logout";
+
+const station_favorites = api_url + "stationFavorites";
+const station_add_favorite = api_url + "stationSetFavorite";
+const station_delete_favorite = api_url + "stationDeleteFavorite";
+
+const transactions = api_url + "transactions";
+const transaction_rate = api_url + "rateTransaction";
+const transaction_single = api_url + "singleTransaction";
+
+const topup_paypal = api_url + "paypalURL";
+const topup = api_url + "paymaya_execute";
+const topup_paypal_execute = api_url + "transactionStatus";
+const topup_transaction_entry = api_url + "transactionEntry";
+
+// const fuel_types = api_url + "fuelList";
+const fuel_types = api_url + "fuels";
+
+const validate_mobile = api_url + "checkMobile";
+const paymaya_tokens = api_url + "paymayatokens";
+
+const getAppVersion = api_url + "getVersion/ios";
+
+
+// P97 API
+const post_pay_api_key = "BZ3SGKGaGPNb9PtIoALywvizQZC26qgSFx3Ac9zc3yNQKw79CI5mabma3eXcBzo5IfUKy84JgIj";
+const getStores = post_pay + "stores";
+const getStoreDetails = post_pay + "stores/details";
+const payOutsideStore = post_pay + "pay/outside/store";
+const getTransactionDetails = post_pay + "transactions";
+const postClaim = post_pay + "postpay/claim";
+const postpay = post_pay + "postpay";
+const getWalletPublicKey = post_pay + "wallet/register/publickey";
+const addCreditCard = post_pay + "wallet/register";
+const deleteCreditCard = post_pay + "wallet/unregister";
+const getFunding = post_pay + "wallet/funding";
+
+export default {
+
+ server: api_url,
+
+ card_validation,
+ card_validation_enroll,
+ login,
+ login_mobile,
+ security_question,
+ setup_mpin,
+ requestOTP,
+ sendOTP,
+ terms_and_privacy,
+ contact_us,
+
+ user_profile,
+ send_card_pin,
+ activateCard,
+ apply,
+ signup_id_number,
+
+ get_card_prompt_info,
+
+ gas_stations,
+ gas_stations_city,
+ gas_station_details,
+ gas_station_fuel,
+
+ loyalty_cards,
+ products,
+ cities,
+ station_search,
+
+ whats_hot,
+ new_promos,
+ promo_gps,
+ promos,
+
+ update_profile_no_otp,
+ update_profile_with_otp,
+
+ shared_treats,
+ logout,
+
+ station_favorites,
+ station_add_favorite,
+ station_delete_favorite,
+
+ transactions,
+ transaction_rate,
+ transaction_single,
+
+ topup_paypal,
+ topup_paypal_execute,
+ topup_transaction_entry,
+ fuel_types,
+ topup,
+
+ validate_mobile,
+
+ notifications,
+ account_fcm,
+ fcm_register,
+
+ paymaya_tokens,
+
+ mobileOTP,
+ registerAndValidate,
+ validateMobileOTP,
+ submitRegistration,
+ validateOTP,
+
+ getAppVersion,
+
+ post_pay_api_key,
+ getStores,
+ getStoreDetails,
+ payOutsideStore,
+ getTransactionDetails,
+ postClaim,
+ postpay,
+ getFunding,
+ getWalletPublicKey,
+ addCreditCard,
+ deleteCreditCard
+}
\ No newline at end of file
diff --git a/app/components/api/file.manager.js b/app/components/api/file.manager.js
new file mode 100644
index 00000000..5f8cd53d
--- /dev/null
+++ b/app/components/api/file.manager.js
@@ -0,0 +1,30 @@
+import React from 'react'
+import EP from './endpoints';
+import RNFetchBlob from 'rn-fetch-blob'
+
+export default async function API(endpoint, method, headers, params, body, onSuccess, onError) {
+ RNFetchBlob.fetch(method, endpoint.includes(":") ? endpoint : EP[endpoint], {
+ Authorization : headers.Authorization,
+ 'Content-Type' : 'multipart/form-data',
+ }, [
+ // { name : 'file', filename : 'photo.png', type: body.image.type, data: RNFetchBlob.wrap(decodeURIComponent(body.image.uri.replace("file:///", "")))},
+ { name : 'photo', filename : 'photo.png', type: body.image.type, data: body.image.data},
+ { name : 'firstname', data : body.firstname},
+ { name : 'middlename', data : body.middlename},
+ { name : 'lastname', data : body.lastname},
+ { name : 'birthdate', data : body.birthdate},
+ { name : 'mobile', data : body.mobile},
+ { name : 'email', data : body.email},
+ { name : 'address', data : body.address},
+ // { name : 'city', data : body.city},
+ { name : 'vo_code', data : body.vo_code},
+ { name : 'fueltype_code', data : body.fueltype_code},
+ { name : 'civilstatus_code', data : body.civilstatus_code},
+ { name : 'gender_code', data : body.gender_code},
+ { name : 'is_deleted', data : body.is_deleted}
+ ]).then((resp) => {
+ onSuccess(resp.json())
+ }).catch((err) => {
+ onError(err)
+ })
+}
\ No newline at end of file
diff --git a/app/components/api/index.js b/app/components/api/index.js
new file mode 100644
index 00000000..f570710a
--- /dev/null
+++ b/app/components/api/index.js
@@ -0,0 +1,99 @@
+import * as React from 'react';
+import EP from './endpoints.js';
+
+const defaultHeaders = {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+}
+
+const Options = (method, headers, params, body) => {
+ let obj = {}
+ if(method == "post"){
+ obj = {method: method, body: JSON.stringify(body), headers: headers || defaultHeaders, params: params}
+ }else if(method == "get"){
+ obj = {method: method, headers: headers || defaultHeaders, params: params}
+ }
+ return obj
+}
+
+export default async function API(endpoint, method, headers, params, body, onSuccess, onError) {
+ try {
+ if(method == "post"){
+ let Head = {
+ 'Accept': headers.Accept ? headers.Accept : 'application/json',
+ 'Content-Type': headers['Content-Type'] ? headers['Content-Type'] : 'application/json',
+ 'Authorization': headers.Authorization || '',
+ 'card_number': headers.card_number || ''
+ }
+ let response = await fetch(endpoint.includes(":") ? endpoint : EP[endpoint], {
+ method: method,
+ body: body?._parts ? body : JSON.stringify(body),
+ headers: Head,
+ params: params
+ });
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }else if(method == "get"){
+ let url = !params.noID ? (EP[endpoint] + "?" + params) : EP[endpoint] + "/" + params.value
+ console.log("URL", url)
+ if(headers.Authorization){
+ let response = await fetch(endpoint.includes(":") ? endpoint : url, {
+ method: method,
+ headers: new Headers({
+ 'Accept': 'application/json',
+ 'Authorization': `${headers.Authorization || ''}`,
+ 'card_number': `${headers.card_number}` || ''
+ })
+ });
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }else{
+ let response = await fetch(endpoint.includes(":") ? endpoint : url);
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }
+ }else if(method == "delete"){
+ let url = !params.noID ? (EP[endpoint] + "?" + params) : EP[endpoint] + "/" + params.value
+ console.warn('URL delete', url);
+ if(headers.Authorization){
+ let response = await fetch(endpoint.includes(":") ? endpoint : url, {
+ method: method,
+ headers: new Headers({
+ 'Accept': 'application/json',
+ 'Authorization': `${headers.Authorization || ''}`,
+ 'card_number': `${headers.card_number}` || ''
+ })
+ });
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }else{
+ let response = await fetch(endpoint.includes(":") ? endpoint : url);
+ console.warn('Response', JSON.stringify(res))
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }
+ }else if(method == "put") {
+ let Head = {
+ 'Content-Type': 'application/json'
+ }
+ let response = await fetch(endpoint.includes(":") ? endpoint : EP[endpoint], {
+ method: method,
+ body: body?._parts ? body : JSON.stringify(body),
+ headers: Head,
+ params: params
+ });
+ let json = await response.json();
+ onSuccess(json)
+ return json
+ }
+
+ } catch (error) {
+ onError(error)
+ return error
+ }
+}
\ No newline at end of file
diff --git a/app/components/api/mobile.js b/app/components/api/mobile.js
new file mode 100644
index 00000000..e2242742
--- /dev/null
+++ b/app/components/api/mobile.js
@@ -0,0 +1,13 @@
+import * as React from 'react';
+import EP from './endpoints';
+
+export default function ValidateMobile(mobile) {
+ return fetch(EP.validate_mobile + "/" + mobile)
+ .then((response) => response.json())
+ .then((json) => {
+ return json
+ })
+ .catch((error) => {
+ return error
+ });
+}
\ No newline at end of file
diff --git a/app/components/api/postpayapi.js b/app/components/api/postpayapi.js
new file mode 100644
index 00000000..148c7779
--- /dev/null
+++ b/app/components/api/postpayapi.js
@@ -0,0 +1,73 @@
+import EP from './endpoints.js';
+
+export default async function API(endpoint, method, headers, params, body, onSuccess, onError) {
+ try {
+ if(method == "post") {
+ var Head = {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ 'x-p97-tenantid': '8ba3cd89-74be-4a7a-91a5-5eb59a2040b8',
+ 'x-p97-apikey': EP.post_pay_api_key
+ }
+ let url = endpoint.includes(":") ? endpoint : EP[endpoint]
+ if(headers.token != undefined) {
+ Head = {...Head, 'Authorization': `Bearer ${headers.token}`}
+ }
+ if(headers.language != undefined) {
+ Head = {...Head, 'Accept-Language': headers.language}
+ }
+ console.log(url, Head)
+ let response = await fetch(url, {
+ method: method,
+ body: body?._parts ? body : JSON.stringify(body),
+ headers: Head,
+ params: params
+ });
+ let json = await response.json();
+ onSuccess(json)
+ } else if(method == "get") {
+ var Head = {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json',
+ 'x-p97-tenantid': '8ba3cd89-74be-4a7a-91a5-5eb59a2040b8',
+ 'x-p97-apikey': EP.post_pay_api_key,
+ }
+ let paramsItem = Object.entries(params).map(([key, value]) => `${key}=${value}`)
+ let url = paramsItem.length > 1 ? `${EP[endpoint]}?${paramsItem.join('&').toString()}` : `${EP[endpoint]}/${Object.entries(params).map(([key, value]) => value).join('').toString()}`
+ if(headers.token != undefined) {
+ Head = {...Head, 'Authorization': `Bearer ${headers.token}`}
+ }
+ if(headers.language != undefined) {
+ Head = {...Head, 'Accept-Language': headers.language}
+ }
+ console.log(url, Head)
+ let response = await fetch(endpoint.includes(":") ? endpoint : url, {
+ method: method,
+ headers: Head
+ });
+ let json = await response.json();
+ onSuccess(json)
+ } else if(method == "delete") {
+ let url = !params.noID ? (EP[endpoint] + "?" + params) : EP[endpoint] + "/" + params.value
+ console.warn('URL delete', url);
+ if(headers.Authorization){
+ let response = await fetch(endpoint.includes(":") ? endpoint : url, {
+ method: method,
+ headers: new Headers({
+ 'Accept': 'application/json',
+ 'Authorization': `${headers.Authorization || ''}`
+ })
+ });
+ let json = await response.json();
+ onSuccess(json)
+ } else {
+ let response = await fetch(endpoint.includes(":") ? endpoint : url);
+ console.warn('Response', JSON.stringify(res))
+ let json = await response.json();
+ onSuccess(json)
+ }
+ }
+ } catch (error) {
+ onError(error)
+ }
+}
\ No newline at end of file
diff --git a/app/components/assets.manager.js b/app/components/assets.manager.js
new file mode 100644
index 00000000..c4add19f
--- /dev/null
+++ b/app/components/assets.manager.js
@@ -0,0 +1,245 @@
+import {Platform} from 'react-native';
+
+const icons = {
+ about: require("../assets/ic_about.png"),
+ account: require("../assets/ic_account.png"),
+ add: require("../assets/ic_add_white_24dp.png"),
+ card: require("../assets/ic_card.png"),
+ down: require("../assets/ic_chevron_down.png"),
+ close: require("../assets/ic_close_white_24dp.png"),
+ contact: require("../assets/ic_contact.png"),
+ dashboard: require("../assets/ic_dashboard.png"),
+ favEmpty: require("../assets/ic_fav_empty.png"),
+ favFull: require("../assets/ic_fav_full.png"),
+ fuelTab: require("../assets/ic_fuel_tab.png"),
+ fuel: require("../assets/ic_fuel.png"),
+ history: require("../assets/ic_history.png"),
+ info: require("../assets/ic_info.png"),
+ kmLiter: require("../assets/ic_km_liter.png"),
+ logout: require("../assets/ic_logout.png"),
+ mylocation: require("../assets/ic_my_location_black_24dp.png"),
+ peso: require("../assets/ic_peso.png"),
+ products: require("../assets/ic_products.png"),
+ promos: require("../assets/ic_promos.png"),
+ reminders: require("../assets/ic_reminder.png"),
+ rewards: require("../assets/ic_rewards.png"),
+ sheduler: require("../assets/ic_scheduler.png"),
+ search: require("../assets/ic_search_white_24dp.png"),
+ selectedStationPin: require("../assets/ic_selected_station_pin.png"),
+ // stationMapPin: Platform.OS == 'ios' ? require("../assets/ic_station_map_pin_lg.png") : require("../assets/ic_station_map_pin.png"),
+ stationMapPin: require("../assets/ic_station_map_pin.png"),
+ station: require("../assets/ic_station.png"),
+ stations: require("../assets/ic_stations.png"),
+ topup: require("../assets/ic_topup.png"),
+ tutorial: require("../assets/ic_tutorial.png"),
+ type: require("../assets/ic_type.png"),
+
+ googleMaps: require("../assets/icon_googlemaps.png"),
+ internet: require("../assets/icon_internet.png"),
+ unioil: require("../assets/icon_unioil.png"),
+ waze: require("../assets/icon_waze.png"),
+
+ activehome: require("../assets/ic_home.png"),
+ activepromos: require("../assets/ic_promos_active.png"),
+ activestation: require("../assets/ic_stations_active.png"),
+ activerewards: require("../assets/ic_rewards_active.png"),
+
+ inactivehome: require("../assets/ic_home_inactive.png"),
+ inactivepromos: require("../assets/ic_promos.png"),
+ inactivestation: require("../assets/ic_stations.png"),
+ inactiverewards: require("../assets/ic_rewards.png"),
+
+ activeaccount: require("../assets/ic_account_active.png"),
+ activecard: require("../assets/ic_card_active.png"),
+ activehistory: require("../assets/ic_history_active.png"),
+
+ inactiveaccount: require("../assets/ic_account_inactive2.png"),
+ inactivecard: require("../assets/ic_card_inactive2.png"),
+
+ activepayatpump: require("../assets/ic_payatpump.png"),
+
+ stpcloseform: require("../assets/stp_close_form.png"),
+ stpunknown: require("../assets/stp_card_unknown.png"),
+ stpjcb: require("../assets/stp_card_jcb.png"),
+ stpvisa: require("../assets/stp_card_visa.png"),
+ stpmastercard: require("../assets/stp_card_mastercard.png"),
+ stpunlabeled: require("../assets/stp_card_unlabeled.png"),
+
+ philippine_pesos: require("../assets/philippine_peso.png"),
+ points_balance: require("../assets/points_balance.png"),
+
+ successmpinupdate: require("../assets/success_icon.png"),
+ no_connection: require('../assets/empty_state_no_internet.png'),
+ animated_loading: require("../assets/loading.gif")
+}
+
+const cards = {
+ classic: require("../assets/bg_classic.png"),
+ grab: require("../assets/bg_grab.png"),
+ ica: require("../assets/bg_ica.png"),
+ xavier: require("../assets/bg_xavier.png")
+}
+
+const pumps = {
+ plain_pump: require("../assets/pump_plain.png"),
+ plain_pump_grey: require("../assets/pump_grey.png"),
+ pump_logo: require("../assets/pump_logo.png"),
+ pump_loader: require("../assets/pump_loader.png")
+}
+
+const bg = {
+ fuelEfficiency: require("../assets/bg_fuel_efficiency.png"),
+ scheduler: require("../assets/bg_scheduler.png"),
+ about: require("../assets/img_bg_about.png"),
+ loginBg: require('../assets/login_background.jpg'),
+ login_bg: require('../assets/login_bg.jpg')
+}
+
+const boarding = [
+ require("../assets/onboarding_01.png"),
+ require("../assets/onboarding_02.png"),
+ require("../assets/onboarding_03.png"),
+ require("../assets/onboarding_04.png")
+]
+
+const logo = {
+ unioil: require("../assets/logo_unioil_new.png"),
+ reverse: require("../assets/logo_unioil_reverse.png"),
+ profileHolder: require("../assets/place_holder_profile_pic.png"),
+ icon: require('../assets/ic_launcher.png'),
+ iconWhite: require('../assets/ic_launcher_foreground.png'),
+ round: require('../assets/ic_launcher_round.png'),
+ profileHolderString: '../assets/place_holder_profile_pic.png'
+}
+
+const baseline = {
+ callBlack: require("../assets/baseline_call_black_24.png"),
+ deleteWhite: require("../assets/baseline_delete_white_24.png"),
+ editWhite: require("../assets/baseline_edit_white_24.png"),
+ mailBlack: require("../assets/baseline_email_black_24.png"),
+ infoBlack: require("../assets/baseline_info_black_18.png"),
+ keyboardLeft: require("../assets/baseline_keyboard_arrow_left_black_48.png"),
+ keyboardRight: require("../assets/baseline_keyboard_arrow_right_black_48.png"),
+}
+
+const directionIcon = {
+ wazeIcon: require("../assets/wazeIcon.png"),
+ googleMapsIcon: require("../assets/googleMapsIcon.png"),
+ mapsIcon: require("../assets/mapsIcon.png")
+}
+
+const guidecard = require("../assets/guide_card.png")
+
+const test = {
+ dixie: [
+ {
+ uri: "https://3.bp.blogspot.com/-G1qbDEhxq1s/XMvr8wvTevI/AAAAAAAAOk0/RXfFIBKhXpQS-LtXxa9fU58MSn501IY8gCEwYBhgL/s1600/52563319_308667079841654_99526654379950080_n.jpg"
+ },{
+ uri: "https://i.pinimg.com/236x/7a/19/27/7a1927f35e9c8a97d129b68ff9177c3c.jpg"
+ },{
+ uri: "https://www.famousbirthdays.com/headshots/dexie-diaz-3.jpg"
+ },{
+ uri: "https://i.pinimg.com/originals/8b/6d/93/8b6d933fed4733cc7f461dbde449c60a.jpg"
+ },{
+ uri: "https://images.networthlist.org/imgs/7/78/dexie-diaz.jpg"
+ },{
+ uri: "https://i.pinimg.com/originals/9b/2e/1f/9b2e1f385ddc4996a1d08cbebe36ee31.jpg"
+ },{
+ uri: "https://i.pinimg.com/originals/9b/ba/ce/9bbace72ca15124c4a88df8d7509c07b.jpg"
+ }],
+ zuvapit: [{
+ uri: "https://i.pinimg.com/originals/d8/a7/b9/d8a7b9a2e78879782f7e8791c5036f41.jpg"
+ },{
+ uri: "https://i.pinimg.com/originals/84/a9/9e/84a99e02d1cbb758335240a0ff0014d3.jpg"
+ },{
+ uri: "https://pic.kissgoddess.com/girl/24177/24177.jpg"
+ }
+ ],
+ mina: [{
+ uri: 'https://i.redd.it/4abcufq84ep01.jpg'
+ },{
+ uri: 'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcTDtLc7hLmie9EP5KENw-PVPcwFPyjoNTGr7ZsrEQVt1WyfUCcN&usqp=CAU'
+ },{
+ uri: 'https://lh3.googleusercontent.com/CoCRup6zxPpqhP_wjwSe4-nbAyLwl4NQF2Cd3eEGcVkzuHDMW3vBYqHh0Cs2tPc72OCOUPwlC69xGP9rZKui4ZPCuPCvypUYOfo=w1200-h630-rj-pp'
+ },{
+ uri: 'https://c1.staticflickr.com/1/515/18524221670_2bc8c35ff7_o.jpg'
+ },
+ ]
+}
+
+const dixie = require("../assets/dexie.jpg")
+
+const fueltypes = [{
+ value: "1",
+ string: "Euro 5 GASOLINE 97"
+ },{
+ value: "2",
+ string: "Euro 5 GASOLINE 95"
+ },{
+ value: "3",
+ string: "Euro 5 GASOLINE 91"
+ },{
+ value: "4",
+ string: "Euro 5 Diesel"
+ },{
+ value: "0",
+ string: ""
+}]
+
+const vehicletypes = [{
+ value: "1",
+ string: "4 Wheeler"
+ },{
+ value: "2",
+ string: "2 Wheeler"
+ },{
+ value: "0",
+ string: ""
+}]
+
+const civilstatus = [{
+ value: "S",
+ string: "Single"
+ },{
+ value: "M",
+ string: "Married"
+ },{
+ value: "0",
+ string: "No Data Entered"
+ },{
+ value: "W",
+ string: "Widow"
+ },{
+ value: "SE",
+ string: "Separated"
+}]
+
+const gender = [{
+ value: "M",
+ string: "Male"
+ },{
+ value: "F",
+ string: "Female"
+ },{
+ value: "0",
+ string: "No Data Entered"
+}]
+
+
+export default {
+ icons,
+ cards,
+ bg,
+ boarding,
+ logo,
+ baseline,
+ dixie,
+ test,
+ fueltypes,
+ vehicletypes,
+ civilstatus,
+ gender,
+ guidecard,
+ directionIcon,
+ pumps
+}
\ No newline at end of file
diff --git a/app/components/cardencrypt/encryptcard.js b/app/components/cardencrypt/encryptcard.js
new file mode 100644
index 00000000..dae11dfc
--- /dev/null
+++ b/app/components/cardencrypt/encryptcard.js
@@ -0,0 +1,14 @@
+import forge from 'node-forge';
+import { Buffer } from 'buffer';
+
+const encryptCard = async (card, pubkey) => {
+ var formatpubkey = `-----BEGIN PUBLIC KEY-----\n${pubkey}\n-----END PUBLIC KEY-----`
+ const publicKey = forge.pki.publicKeyFromPem(formatpubkey)
+ const cardBuffer = Buffer.from(card)
+ let encryptedCard = publicKey.encrypt(card, 'RSA-OAEP')
+ return forge.util.encode64(encryptedCard)
+}
+
+export default {
+ encryptCard
+}
\ No newline at end of file
diff --git a/app/components/carousel/board.js b/app/components/carousel/board.js
new file mode 100644
index 00000000..6df2b3b2
--- /dev/null
+++ b/app/components/carousel/board.js
@@ -0,0 +1,85 @@
+import React from 'react'
+import { View, ScrollView, Text, StyleSheet, Image, ImageBackground, TouchableOpacity, Platform } from 'react-native'
+import Theme from '../theme.style.js';
+
+export default function BoardCarousel(props) {
+ return (
+
+ {props.items.map((item, index) => {
+ return (
+
+
+ {item.title}
+ {item.subtitle}
+
+
+ )
+ })}
+
+
+ {props.bullets}
+
+
+
+ GET STARTED
+
+ )
+}
+
+const styles = StyleSheet.create({
+ statsHead: {
+ paddingTop: 10,
+ paddingHorizontal: 12,
+ },
+ container: {
+ height: '100%',
+ width: '100%',
+ backgroundColor: '#fbfbfb',
+ shadowColor: '#fcfcfc',
+ shadowOpacity: 1,
+ shadowOffset: {
+ width: 0,
+ height: 5
+ },
+ },
+ scrollView: {
+ display: 'flex',
+ flexDirection: 'row',
+ overflow: 'hidden',
+ width: '100%',
+ height: '100%'
+ },
+ bullets: {
+ position: 'absolute',
+ bottom: Platform.OS == 'ios' ? 35 : 0,
+ display: 'flex',
+ justifyContent: 'flex-start',
+ flexDirection: 'row',
+ paddingHorizontal: 10,
+ paddingTop: 5,
+ },
+ button: {
+ position: 'absolute',
+ bottom: Platform.OS == 'ios' ? 50 : 20,
+ right: 35,
+ display: 'flex',
+ justifyContent: 'flex-end',
+ flexDirection: 'row',
+ paddingHorizontal: 10,
+ paddingTop: 5,
+ },
+ bullet: {
+ paddingHorizontal: 3,
+ alignSelf: 'center',
+ left: 20
+ }
+});
\ No newline at end of file
diff --git a/app/components/carousel/index.js b/app/components/carousel/index.js
new file mode 100644
index 00000000..4dfb658a
--- /dev/null
+++ b/app/components/carousel/index.js
@@ -0,0 +1,171 @@
+import React from 'react'
+import { View, ScrollView, Text, StyleSheet, Image, ImageBackground, TouchableOpacity } from 'react-native'
+import Theme from '../theme.style.js';
+import Board from './board.js';
+import Promo from './promo.js';
+
+export const Carousel = (props) => {
+
+ const { items, style } = props;
+ const itemsPerInterval = props.itemsPerInterval === undefined ? 1 : props.itemsPerInterval;
+ const [interval, setInterval] = React.useState(1);
+ const [intervals, setIntervals] = React.useState(1);
+ const [width, setWidth] = React.useState(0);
+
+ const init = (width) => {
+ // initialise width
+ setWidth(width);
+ // initialise total intervals
+ const totalItems = items.length;
+ setIntervals(Math.ceil(totalItems / itemsPerInterval));
+
+ }
+
+ const getInterval = (offset) => {
+ for (let i = 1; i <= intervals; i++) {
+ if (offset < (width / intervals) * i) {
+ return i;
+ }
+ if (i == intervals) {
+ return i;
+ }
+ }
+ }
+
+ let bullets = [];
+ for (let i = 1; i <= intervals; i++) {
+
+ if(props.type == "board"){
+ bullets.push(
+
+ •
+
+ );
+ }else if(props.type == "promo"){
+ bullets.push(
+
+ •
+
+ );
+ }
+
+ }
+
+ return (
+
+ {props.type == "board" ?
+ init(w)}
+ onScroll={data => {
+ setWidth(data.nativeEvent.contentSize.width);
+ setInterval(getInterval(data.nativeEvent.contentOffset.x));
+ }}
+ items={items}
+ onPress={props.onPress}
+ bullets={bullets}
+ /> :
+ init(w)}
+ onScroll={data => {
+ setWidth(data.nativeEvent.contentSize.width);
+ setInterval(getInterval(data.nativeEvent.contentOffset.x));
+ }}
+ items={items}
+ onPress={props.onPress}
+ bullets={bullets}
+ /> }
+
+ )
+}
+
+const styles = StyleSheet.create({
+ statsHead: {
+ paddingTop: 10,
+ paddingHorizontal: 12,
+ },
+ container: {
+ height: '100%',
+ width: '100%',
+ backgroundColor: '#fbfbfb',
+ shadowColor: '#fcfcfc',
+ shadowOpacity: 1,
+ shadowOffset: {
+ width: 0,
+ height: 5
+ },
+ },
+ scrollView: {
+ display: 'flex',
+ flexDirection: 'row',
+ overflow: 'hidden',
+ width: '100%',
+ height: '100%'
+ },
+ bullets: {
+ position: 'absolute',
+ bottom: 0,
+ display: 'flex',
+ justifyContent: 'flex-start',
+ flexDirection: 'row',
+ paddingHorizontal: 10,
+ paddingTop: 5,
+ },
+ button: {
+ position: 'absolute',
+ bottom: 20,
+ right: 35,
+ display: 'flex',
+ justifyContent: 'flex-end',
+ flexDirection: 'row',
+ paddingHorizontal: 10,
+ paddingTop: 5,
+ },
+ bullet: {
+ paddingHorizontal: 3,
+ alignSelf: 'center',
+ left: 20
+ },
+ bullet2: {
+ paddingHorizontal: 5,
+ alignSelf: 'center',
+ }
+});
+
+export default Carousel;
+
+ // switch (style) {
+ // case 'stats':
+ // return (
+ //
+ // );
+ // default:
+ // return (
+ //
+ // );
+ // }
\ No newline at end of file
diff --git a/app/components/carousel/promo.js b/app/components/carousel/promo.js
new file mode 100644
index 00000000..e2b88166
--- /dev/null
+++ b/app/components/carousel/promo.js
@@ -0,0 +1,79 @@
+import React from 'react'
+import { View, ScrollView, Text, StyleSheet, Image, ImageBackground, TouchableOpacity } from 'react-native'
+import Theme from '../theme.style.js';
+
+export default function BoardCarousel(props) {
+
+ const [scrollView, setscrollView] = React.useState(null);
+ let interval;
+
+ React.useEffect(() => {
+ // setInterval(function(){
+ // // if(scrollView) scrollView.scrollTo({x: 0, y: `${100 * props.intervals}%`, animated: true})
+ // if(scrollView) scrollView.scrollTo({x: 0, y: 100, animated: true})
+ // // console.log(scrollView.isTouching)
+ // }, 3000)
+ // return () => {
+ // clearInterval(interval)
+ // }
+ }, [])
+
+ return (
+
+ setscrollView(el)}
+ horizontal={true}
+ contentContainerStyle={{ ...styles.scrollView, width: `${100 * props.intervals}%` }}
+ showsHorizontalScrollIndicator={false}
+ onContentSizeChange={props.onContentSizeChange}
+ onScroll={props.onScroll}
+ scrollEventThrottle={200}
+ pagingEnabled
+ decelerationRate="fast"
+ >
+ {props.items.map((item, index) => {
+ return (
+
+
+
+ )
+ })}
+
+
+ {props.bullets}
+
+ )
+}
+
+const styles = StyleSheet.create({
+ statsHead: {
+ paddingTop: 10,
+ paddingHorizontal: 12,
+ },
+ container: {
+ height: '100%',
+ width: '100%',
+ backgroundColor: '#fbfbfb',
+ shadowColor: '#fcfcfc',
+ shadowOpacity: 1,
+ shadowOffset: {
+ width: 0,
+ height: 5
+ },
+ },
+ scrollView: {
+ display: 'flex',
+ flexDirection: 'row',
+ overflow: 'hidden',
+ width: '100%',
+ height: '100%'
+ },
+ bullets: {
+ flex: 1,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: 10,
+ paddingTop: 20,
+ }
+});
\ No newline at end of file
diff --git a/app/components/contact.action.js b/app/components/contact.action.js
new file mode 100644
index 00000000..ab16f284
--- /dev/null
+++ b/app/components/contact.action.js
@@ -0,0 +1,133 @@
+import * as React from 'react';
+import {Linking, Platform} from 'react-native';
+import {ActionSheet} from 'native-base';
+import REQUEST from './api/';
+import { openComposer } from 'react-native-email-link';
+
+export const ContactOptions = () => {
+ let options = [
+ {text: 'Call Customer Service', icon: 'call-outline', execute: async () => {
+
+ await REQUEST("contact_us", "get", {}, {}, {}, async (res) => {
+ if(res.status == 1 && res.data){
+ let url = Platform.OS == 'ios' ? 'telprompt:' : 'tel:'
+ Linking.canOpenURL(url).then(supported => {
+ if (!supported) {
+ console.log('Cant handle url')
+ alert("Call Not Supported")
+ } else {
+ return Linking.openURL(`${url}${res.data.contact_number_mobile}`)
+ }
+ }).catch(err => {
+ console.error('An error occurred', err)
+ })
+ }else{
+ console.log(res.message, res.data)
+ }
+ }, function(error){
+ console.log(error)
+ })
+
+
+ }},
+ {text: 'Email Customer Service', icon: 'mail-outline', execute: async () => {
+
+ await REQUEST("contact_us", "get", {}, {}, {}, async (res) => {
+ if(res.status == 1 && res.data){
+
+ openComposer({
+ to: res.data.contact_email_address_mobile,
+ subject: `CN`,
+ body: ''
+ })
+
+ }else{
+ console.log(res.message, res.data)
+ }
+ }, function(error){
+ console.log(error)
+ })
+ }},
+ {text: 'Cancel', execute: () => ActionSheet.hide()}
+ ]
+
+ ActionSheet.show(
+ {
+ options: options,
+ title: "Select an option",
+ destructiveButtonIndex: 2,
+ cancelButtonIndex: 2
+ },
+ buttonIndex => {
+ options[buttonIndex].execute()
+ }
+ )
+
+}
+
+export const ContactOptionsWithParams = (params) => {
+ let options = [
+ {text: 'Call Customer Service', icon: 'call-outline', execute: async () => {
+
+ await REQUEST("contact_us", "get", {}, {}, {}, async (res) => {
+ if(res.status == 1 && res.data){
+ let url = Platform.OS == 'ios' ? 'telprompt:' : 'tel:'
+ Linking.canOpenURL(url).then(supported => {
+ if (!supported) {
+ console.log('Cant handle url')
+ alert("Call Not Supported")
+ } else {
+ return Linking.openURL(`${url}${res.data.contact_number_mobile}`)
+ }
+ }).catch(err => {
+ console.error('An error occurred', err)
+ })
+ }else{
+ console.log(res.message, res.data)
+ }
+ }, function(error){
+ console.log(error)
+ })
+
+
+ }},
+ {text: 'Email Customer Service', icon: 'mail-outline', execute: async () => {
+
+ await REQUEST("contact_us", "get", {}, {}, {}, async (res) => {
+ if(res.status == 1 && res.data){
+
+ openComposer({
+ to: res.data.contact_email_address_mobile,
+ subject: `Mobile App Feedback: ${(params == undefined && params.cardnumber == undefined) ? "" : "CN"+params.cardnumber}`,
+ body: ''
+ })
+
+ }else{
+ console.log(res.message, res.data)
+ }
+ }, function(error){
+ console.log(error)
+ })
+
+ }},
+
+ {text: 'Cancel', execute: () => ActionSheet.hide()}
+ ]
+
+ ActionSheet.show(
+ {
+ options: options,
+ title: "Select an option",
+ destructiveButtonIndex: 2,
+ cancelButtonIndex: 2
+ },
+ buttonIndex => {
+ options[buttonIndex].execute()
+ }
+ )
+
+}
+
+export default {
+
+}
\ No newline at end of file
diff --git a/app/components/crypto.js b/app/components/crypto.js
new file mode 100644
index 00000000..22158e22
--- /dev/null
+++ b/app/components/crypto.js
@@ -0,0 +1,28 @@
+import CryptoJS from "react-native-crypto-js";
+
+const encrypt = (data, hash) => {
+ var key = CryptoJS.enc.Latin1.parse(`${hash}-loyalty`)
+ var iv = CryptoJS.enc.Latin1.parse('unioilloyaltyapp')
+ var encrypted = CryptoJS.AES.encrypt(
+ data,
+ key,
+ {iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7
+ }).toString()
+ return encrypted
+}
+
+const decrypt = (data, hash) => {
+ var key = CryptoJS.enc.Latin1.parse(`${hash}-loyalty`)
+ var iv = CryptoJS.enc.Latin1.parse('unioilloyaltyapp')
+ var decrypted = CryptoJS.AES.decrypt(
+ data,
+ key,
+ {iv:iv,padding:CryptoJS.pad.Pkcs7}
+ ).toString(CryptoJS.enc.Utf8)
+ return decrypted
+}
+
+export default {
+ encrypt,
+ decrypt
+}
\ No newline at end of file
diff --git a/app/components/custominput.js b/app/components/custominput.js
new file mode 100644
index 00000000..5ff4be6d
--- /dev/null
+++ b/app/components/custominput.js
@@ -0,0 +1,167 @@
+import * as React from 'react'
+import {useState, useEffect, useRef} from 'react'
+import {View, Text, TouchableOpacity, TextInput, StyleSheet, Keyboard} from 'react-native'
+import Theme from './theme.style.js'
+
+export default function CustomInput(props){
+
+ const [focus, setfocus] = useState(false)
+ const [activefield, setactivefield] = useState(null)
+ const [activeInput, setactiveinput] = useState(null)
+ const [value, setvalue] = useState(null)
+ const inputs = {}
+
+ let [cn1, setcn1] = useState("")
+ let [cn2, setcn2] = useState("")
+ let [cn3, setcn3] = useState("")
+ let [cn4, setcn4] = useState("")
+
+ let [mobilenumber, setmobilenumber] = useState("+63")
+
+ const send = () => {
+ props.onChangeText(value)
+ }
+
+ const onFocus = (key) => {
+ setactiveinput(key)
+ setfocus(true)
+ }
+
+ const onSubmitEditing = (key) => {
+ inputs[key].focus()
+ }
+
+ if(props.isMobileNumber) {
+ return (
+
+ {
+ nativeEvent.key === 'Backspace' && mobilenumber.length === 3
+ }}
+ onChangeText={(value) => {
+ if(value.substring(0, 3) == "+63") {
+ setmobilenumber(value)
+ props.onChangeText(value)
+ }
+ }}
+ onSubmitEditing={Keyboard.dismiss}
+ style={[{...styles.input, borderBottomColor: focus && activeInput == 1 ? Theme.colors.accent : "gray", borderBottomWidth: focus && activeInput == 1 ? 1.5 : 1, textAlign: 'left' }, { color: props.textColor || Theme.colors.black}]}
+ />
+
+ )
+ }
+
+ return (
+
+ inputs['field1'] = input}
+ returnKeyType={ 'next' }
+ onSubmitEditing={() => { onSubmitEditing('field2'); }}
+ blurOnSubmit={ false }
+ keyboardType="numeric"
+ maxLength={4}
+ onFocus={() => onFocus(1)}
+ onKeyPress={({ nativeEvent }) => {
+ if(cn1.length == 4 && nativeEvent.key != "Backspace") onSubmitEditing("field2")
+ }}
+ value={cn1}
+ onChangeText={(value) => {
+ setcn1(value)
+ // setvalue(value + cn2 + cn3 + cn4)
+ // send()
+ props.onChangeText(value + cn2 + cn3 + cn4)
+ if(value.length == 4) onSubmitEditing("field2")
+ }}
+ style={[{...styles.input, borderBottomColor: focus && activeInput == 1 ? Theme.colors.accent : "gray", borderBottomWidth: focus && activeInput == 1 ? 1.5 : 1 }, { color: props.textColor || Theme.colors.black}]}
+ />
+ inputs['field2'] = input}
+ returnKeyType={ 'next' }
+ onSubmitEditing={() => { onSubmitEditing('field3'); }}
+ keyboardType="numeric"
+ maxLength={4}
+ blurOnSubmit={ false }
+ onFocus={() => onFocus(2)}
+ value={cn2}
+ onKeyPress={({ nativeEvent }) => {
+ nativeEvent.key === 'Backspace' && cn2 === "" ? onSubmitEditing("field1") : null
+ if(cn2.length == 4 && nativeEvent.key != "Backspace") onSubmitEditing("field3")
+ }}
+ onChangeText={(value) => {
+ setcn2(value)
+ // setvalue(cn1 + value + cn3 + cn4)
+ // send()
+ props.onChangeText(cn1 + value + cn3 + cn4)
+ if(value.length == 4) onSubmitEditing("field3")
+ else if(value == "" || value == "" && cn2 == "") onSubmitEditing("field1")
+ }}
+ style={[{...styles.input, borderBottomColor: focus && activeInput == 2 ? Theme.colors.accent : "gray", borderBottomWidth: focus && activeInput == 2 ? 1.5 : 1 }, { color: props.textColor || Theme.colors.black}]}
+ />
+ inputs['field3'] = input}
+ returnKeyType={ 'next' }
+ onSubmitEditing={() => { onSubmitEditing('field4'); }}
+ keyboardType="numeric"
+ maxLength={4}
+ blurOnSubmit={ false }
+ onFocus={() => onFocus(3)}
+ value={cn3}
+ onKeyPress={({ nativeEvent }) => {
+ nativeEvent.key === 'Backspace' && cn3 === "" ? onSubmitEditing("field2") : null
+ if(cn3.length == 4 && nativeEvent.key != "Backspace") onSubmitEditing("field4")
+ }}
+ onChangeText={(value) => {
+ setcn3(value)
+ // setvalue(cn1 + cn2 + value + cn4)
+ // send()
+ props.onChangeText(cn1 + cn2 + value + cn4)
+ if(value.length == 4) onSubmitEditing("field4")
+ else if(value == "") onSubmitEditing("field2")
+ }}
+ style={[{...styles.input, borderBottomColor: focus && activeInput == 3 ? Theme.colors.accent : "gray", borderBottomWidth: focus && activeInput == 3 ? 1.5 : 1 }, { color: props.textColor || Theme.colors.black}]}
+ />
+ inputs['field4'] = input}
+ keyboardType="numeric"
+ maxLength={4}
+ blurOnSubmit={ false }
+ onFocus={() => onFocus(4)}
+ value={cn4}
+ onKeyPress={({ nativeEvent }) => {
+ nativeEvent.key === 'Backspace' && cn4 === "" ? onSubmitEditing("field3") : null
+ }}
+ onChangeText={(val) => {
+ setcn4(val)
+ // setvalue(cn1 + cn2 + cn3 + cn4)
+ // send()
+ props.onChangeText(cn1 + cn2 + cn3 + val)
+ if(val == "") onSubmitEditing("field3")
+ if(val.length == 4){
+ // setvalue(value + val)
+ // alert(value + " / " + val)
+ // alert(value)
+ // console.log(value)
+ // props.onDone(value + val)
+ }
+ // else{
+ // setvalue(cn1 + cn2 + cn3 + cn4)
+ // }
+ // if(value.length == 4) props.onDone()
+ }}
+ style={[{...styles.input, borderBottomColor: focus && activeInput == 4 ? Theme.colors.accent : "gray", borderBottomWidth: focus && activeInput == 4 ? 1.5 : 1 }, { color: props.textColor || Theme.colors.black}]}
+ />
+
+ )
+}
+
+const styles = StyleSheet.create({
+ input: {
+ flex: 1, padding: 0, margin: 5, fontSize: 18, textAlign: 'center', borderBottomColor: Theme.colors.accent, borderBottomWidth: 1.5, color: Theme.colors.white
+ }
+ });
\ No newline at end of file
diff --git a/app/components/drawer.js b/app/components/drawer.js
new file mode 100644
index 00000000..e1268b5a
--- /dev/null
+++ b/app/components/drawer.js
@@ -0,0 +1,305 @@
+import * as React from 'react';
+import {
+ SafeAreaView,
+ Text,
+ View,
+ FlatList,
+ Alert,
+ Platform,
+} from 'react-native';
+import { connect } from "react-redux";
+import { createDrawerNavigator } from '@react-navigation/drawer';
+import { ListItem } from 'react-native-elements';
+import Assets from './assets.manager.js';
+import Elements from './elements.js';
+import DB from './storage/';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import Theme from '../components/theme.style.js';
+import NetInfo from "../components/netstatus";
+
+const User = [
+ {
+ name: 'Guest',
+ avatar_url: Assets.logo.profileHolder,
+ subtitle: '',
+ icon: 'chevron-right',
+ },
+];
+
+const Options = [
+ {
+ title: 'My Profile',
+ icon: 'account',
+ screen: 'MyProfile',
+ props: {tab: 0, onBackPress: () => console.log('backed')}
+ },
+ {
+ title: 'Top-up Points',
+ icon: 'topup',
+ screen: 'TopUp',
+ },
+ {
+ title: 'Fuel Efficiency Tracker',
+ icon: 'fuelTab',
+ screen: 'Tracker',
+ },
+];
+
+const Options2 = [
+ {
+ title: 'About Us',
+ icon: 'about',
+ screen: 'About',
+ },
+ {
+ title: 'Loyalty Program',
+ icon: 'card',
+ screen: 'Loyalty',
+ },
+ {
+ title: 'Contact Us',
+ icon: 'contact',
+ screen: 'Contact',
+ },
+ {
+ title: 'Getting Started',
+ icon: 'tutorial',
+ screen: 'OnBoarding',
+ },
+];
+
+const Drawer = createDrawerNavigator();
+
+const styles = {
+ container: {padding: 13, paddingTop: 14},
+ title: {fontSize: 13, marginLeft: 12},
+ titleDisabled: {fontSize: 13, marginLeft: 12, color: '#7e7e7e'},
+ icon: {size: 28},
+ enrollBtn: {
+ backgroundColor: '#e74610',
+ height: Theme.screen.h / 17,
+ marginHorizontal: 15,
+ borderRadius: 10,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ enrollBtnTxt: {
+ textAlign: 'center',
+ alignItems: 'center',
+ color: '#fff',
+ fontWeight: '600',
+ fontSize: 16,
+ },
+ marginEnroll: {
+ ...Platform.select({
+ ios: {
+ marginTop: Theme.screen.h / 2 - 270,
+ },
+ android: {
+ marginTop: Theme.screen.h / 4 + 10,
+ },
+ }),
+ },
+};
+
+class CustomDrawer extends React.PureComponent {
+
+ constructor(props) {
+ super(props)
+ this.logoutdialog = false
+ }
+
+ state = {
+ loading: false,
+ guest: false
+ }
+
+ componentDidMount() {
+ this.init()
+ }
+
+ componentWillUnmount() {
+
+ }
+
+ init = async () => {
+ let isGuest = await DB.get('is_guest');
+ this.setState({ guest: isGuest })
+ };
+
+ onLogout = async () => {
+ this.setState({ loading: true })
+ NetInfo.netstatus(isConnected => {
+ if (isConnected) {
+ this.setState({ loading: false })
+ this.logoutAccount(success => {
+ let props = this.props.props
+ props.navigation.reset({
+ index: 0,
+ routes: [{name: 'Mpin'}],
+ });
+ }, error =>{})
+ } else {
+ this.setState({ loading: false })
+ Elements.nointernet2();
+ }
+ })
+ };
+
+ logoutAccount = (successCallback, errorCallback) => {
+ DB.logoutAccount(success => {
+ successCallback()
+ }, error => {
+ errorCallback()
+ })
+ }
+
+ navigateTo = (screen = null, param = null, drawerParam = null) => {
+ let props = this.props.props
+ let params = screen == "OnBoarding" ? { onBackToMain: () => this.backToMainView() } : param
+ props.navigation.closeDrawer(drawerParam)
+ props.navigation.navigate(screen, params)
+ }
+
+ renderItem(item) {
+ let range = 4;
+ let indexes = [0, 4, 8, 12];
+ let cn = '';
+ for (let i = 0; i < indexes.length; i++) {
+ cn += item.subtitle.substr(indexes[i], range) + (i < indexes.length - 1 ? ' ' : '')
+ }
+ if (this.state.guest) {
+ return (
+
+ );
+ } else {
+ return (
+
+ this.navigateTo('Account', { test: {} }),
+ }}
+ bottomDivider
+ containerStyle={{ backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.background : Theme.colors.white }}
+ subtitleStyle={{ color: this.props.app_theme?.theme.colors.text }}
+ titleStyle={{fontWeight: 'bold', fontSize: 15, color: this.props.app_theme?.theme.colors.text}}
+ />
+
+ );
+ }
+ }
+
+ backToMainView = () => {
+ this.props.props.navigation.navigate('Main')
+ }
+
+ render() {
+ return (
+
+
+
+ index.toString()}
+ data={this.props.User}
+ navigation={this.props.navigation}
+ renderItem={({item, index}) => {
+ return this.renderItem(item, index)
+ }}
+ style={{fontSize: 16}}
+ />
+
+ {Options.map((item, i) => (
+ }
+ titleStyle={[this.state.guest ? styles.titleDisabled : styles.title, { color: !this.state.guest ? this.props.app_theme?.theme.colors.text : '#7e7e7e' }]}
+ bottomDivider={i == Options.length - 1 ? true : false}
+ containerStyle={[styles.container, { backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.background : Theme.colors.white }]}
+ disabled={this.state.guest ? true : false}
+ onPress={() => {
+ this.navigateTo(item.screen, item.props || {})
+ }}
+ />
+ ))}
+
+
+ {Options2.map((item, i) => (
+ }
+ titleStyle={[styles.title, { color: this.props.app_theme?.theme.colors.text }]}
+ containerStyle={[styles.container, { backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.background : Theme.colors.white }]}
+ bottomDivider={i == Options2.length - 1 ? true : false}
+ onPress={() => {
+ this.navigateTo(item.screen, item.props || {}, item.screen)
+ }}
+ />
+ ))}
+
+ {this.state.guest ? (
+
+ {
+ let props = this.props.props
+ props.navigation.reset({
+ index: 0,
+ routes: [{name: 'Login'}],
+ });
+ }}>
+ Enroll Your Card Now
+
+
+ ) : (
+ }
+ titleStyle={[styles.title, { color: this.props.app_theme?.theme.colors.text }]}
+ containerStyle={[styles.container, { backgroundColor: this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.background : Theme.colors.white }]}
+ onPress={() => {
+ this.props.props.navigation.closeDrawer();
+ Alert.alert(
+ 'Logout',
+ '\nAre you sure you want to logout?\n',
+ [
+ {
+ text: 'CANCEL',
+ style: 'cancel',
+ },
+ {
+ text: 'OK',
+ onPress: () => this.onLogout(),
+ },
+ ],
+ {cancelable: true},
+ );
+ }}
+ />
+ )}
+
+ )
+ }
+}
+
+const mapStateToProps = (state) => {
+ return {
+ app_theme: state.appThemeReducer.theme
+ }
+}
+
+export default connect(mapStateToProps, null)(CustomDrawer)
diff --git a/app/components/elements.js b/app/components/elements.js
new file mode 100644
index 00000000..868bf4a6
--- /dev/null
+++ b/app/components/elements.js
@@ -0,0 +1,956 @@
+import * as React from 'react';
+import {useEffect, useState, useRef} from 'react';
+import { Platform, View, Text, Image, TouchableOpacity, ScrollView, StyleSheet, TextInput, Modal, TouchableWithoutFeedback, ActivityIndicator, Alert } from 'react-native'
+import { Card, ListItem, Button, Icon, Divider, Input, Overlay, CheckBox } from 'react-native-elements'
+import {ActionSheet} from 'native-base';
+import DateTimePicker from '@react-native-community/datetimepicker';
+import DateTimePickerModal from "react-native-modal-datetime-picker";
+import DatePicker from "react-native-date-picker";
+import MonthPicker from 'react-native-month-year-picker';
+import moment from 'moment';
+import Theme from './theme.style.js';
+import Assets from './assets.manager.js';
+import CustomIcon from './icons.js';
+
+var styles = StyleSheet.create({
+ column: {
+ flexDirection: 'column',
+ alignItems: 'flex-start',
+ width: '100%',
+ padding: 15
+ },
+ row: {
+ flexDirection: 'row',
+ alignItems: 'flex-start',
+ flexWrap: 'wrap',
+ flex: 1,
+ padding: 5,
+ fontSize: 16,
+ },
+ bullet: {
+ width: 10
+ },
+ bulletText: {
+ flex: 1,
+ color: 'rgba(0, 0, 0, 0.7)'
+ },
+ boldText: {
+ fontWeight: 'bold'
+ },
+ normalText: {
+ color: 'rgba(0, 0, 0, 0.7)'
+ },
+ container: {
+ flex: 1,
+ backgroundColor: 'blue',
+ flexDirection: 'row',
+ flexWrap: 'wrap'
+ },
+
+ item: {
+ backgroundColor: 'orange',
+ width: Theme.screen.w / 2,
+ height: Theme.screen.h / 2,
+ margin: 5
+ },
+ image: {
+ width: Theme.screen.w / 2,
+ height: Theme.screen.h / 2
+ },
+ centeredView: {
+ flex: 1,
+ justifyContent: "center",
+ alignItems: "center",
+ backgroundColor: '#00000090',
+ padding: 30
+ },
+ bottomView: {
+ flex: 1,
+ justifyContent: "flex-end",
+ alignItems: "center",
+ backgroundColor: '#00000090',
+ padding: 0
+ },
+ modalView: {
+ backgroundColor: '#fff',
+ padding: 20
+ },
+ modalTitle: {
+ padding: 5,
+ fontSize: 18,
+ fontWeight: 'bold'
+ },
+ modalText: {
+ padding: 5,
+ fontSize: 16,
+ color: 'gray',
+ marginTop: 10
+ },
+});
+
+const ModalDialogContainer = (props) => {
+ const Content = props.content;
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const ul = function(props){
+
+ const [drop, setdrop] = useState(false);
+
+ const renderlist = (dataset) => {
+ return dataset.map((data, index) => {
+ return (
+
+
+ {'\u2022' + " "}
+
+
+
+ {data.label}
+
+
+ )
+ })
+ }
+
+ return (
+
+
+ {setdrop(!drop)}}>
+ {props.title}
+
+
+
+
+
+ {drop ? {renderlist(props.list || [])} : null}
+ )
+}
+
+const product = function(props){
+ return (
+
+
+
+
+ {props.title}
+
+ )
+}
+
+const loyaltycard = function(props){
+ return (
+
+
+
+
+ {props.title}
+
+ )
+}
+
+const card = function(props){
+ let h = props.height ? props.height : 200
+ return (
+
+
+
+
+ {props.title}
+ )
+}
+
+const button = function(props){
+ return (