456 lines
20 KiB
JavaScript
456 lines
20 KiB
JavaScript
import React from 'react';
|
|
import { useState, useEffect, useRef } from 'react';
|
|
import { connect } from 'react-redux';
|
|
import {
|
|
Text,
|
|
View,
|
|
TouchableOpacity,
|
|
Linking,
|
|
Platform,
|
|
Alert,
|
|
Modal,
|
|
FlatList,
|
|
Image,
|
|
ActivityIndicator
|
|
} from 'react-native';
|
|
import {
|
|
List,
|
|
ListItem,
|
|
Left,
|
|
Right
|
|
} from 'native-base';
|
|
import REQUEST_POST_PAY from '../../../components/api/postpayapi';
|
|
import Assets from '../../../components/assets.manager.js';
|
|
import BottomSheet from 'reanimated-bottom-sheet';
|
|
import Theme from '../../../components/theme.style.js';
|
|
import Icon from '../../../components/icons';
|
|
import DB from '../../../components/storage/';
|
|
import { NavigationApps,actions,googleMapsTravelModes, mapsTravelModes } from "../../../components/navigationapps";
|
|
import Elements from '../../../components/elements.js';
|
|
|
|
const styles = {
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: '#f8f9fa',
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
},
|
|
panel: {
|
|
flex: 1,
|
|
backgroundColor: 'white',
|
|
position: 'relative'
|
|
},
|
|
panelHeader: {
|
|
height: 60,
|
|
backgroundColor: Theme.colors.lightGray,
|
|
alignItems: 'center',
|
|
justifyContent: 'center'
|
|
},
|
|
centeredView: {
|
|
flex: 1,
|
|
justifyContent: "center",
|
|
backgroundColor: '#00000090',
|
|
},
|
|
modalView: {
|
|
margin: 25,
|
|
borderRadius: 15,
|
|
padding: 20,
|
|
alignItems: "center",
|
|
shadowColor: "#000",
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 2
|
|
},
|
|
shadowOpacity: 0.25,
|
|
shadowRadius: 4,
|
|
elevation: 5
|
|
},
|
|
selectedPumpBorder: {
|
|
backgroundColor: '#ffbaa3',
|
|
borderRadius: 10,
|
|
borderWidth: 2,
|
|
borderColor: Theme.colors.primary,
|
|
padding: 5
|
|
},
|
|
unselectedPumpBorder: {
|
|
borderRadius: 10,
|
|
borderWidth: 2,
|
|
padding: 5
|
|
}
|
|
}
|
|
|
|
const PayatpumpStationDetails = (props) => {
|
|
|
|
const [panel, setpanel] = useState(null)
|
|
const [updateFavorite, setUpdateFavorite] = useState(0)
|
|
const [updateFavoriteVal, setUpdateFavoriteVal] = useState(false)
|
|
const [showModal, setShowModal] = useState(false)
|
|
const [error, setError] = useState(null)
|
|
const [selectedPump, setSelectedPump] = useState(null)
|
|
const [initiateCancel, setInitiateCancel] = useState(false)
|
|
const [initiateProceed, setInitiateProceed] = useState(false)
|
|
const [confirmProceed, setConfirmProceed] = useState(false)
|
|
var timerRef = null
|
|
|
|
useEffect(() => {
|
|
if(props.visible){
|
|
panel.show()
|
|
}
|
|
return setpanel(null)
|
|
}, [props.visible])
|
|
|
|
const renderStationDetails = (station, onPress) => {
|
|
let stars = [1,2,3,4,5].map((star, i) => {
|
|
let name = station.stars >= star ? "star" : "staro"
|
|
let mgn = i > 0 ? 5 : 0
|
|
return (
|
|
<TouchableOpacity key={i}>
|
|
<Icon.AntDesign name={name} style={{marginLeft: mgn}} color={Theme.colors.yellow} size={20} />
|
|
</TouchableOpacity>
|
|
)
|
|
})
|
|
|
|
// filter the value of key pair if it is empty
|
|
var filteredAddress = Object.entries(station.address).filter(([key, value]) => {
|
|
if(key === "stateCode") return `${value.replace(/\s/g, '')}`
|
|
return `${value}`
|
|
})
|
|
.map(([key, value]) => `${value}`)
|
|
|
|
return (
|
|
<TouchableOpacity activeOpacity={1} style={{backgroundColor: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.background : Theme.colors.white }}>
|
|
<View style={{flex: 0, padding: 15, flexDirection: 'row'}}>
|
|
<View style={{flex: 5}}>
|
|
<Text style={{fontFamily: 'arial',color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, padding: 5, width: '90%', fontSize: 15}}>{filteredAddress.join(', ').toString()}</Text>
|
|
<View style={{padding: 5, width: '90%', flexDirection: 'row'}}>
|
|
<Text style={{flex: 1, fontFamily: 'arial', color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, fontSize: 14}}>Contact: </Text>
|
|
<View style={{flex: 3, fontFamily: 'arial', color: Theme.colors.textPrimary, fontSize: 14}}>
|
|
<TouchableOpacity onPress={() => {
|
|
let url = Platform.OS == 'ios' ? 'telprompt:' : 'tel:'
|
|
Linking.canOpenURL(url).then(supported => {
|
|
if (!supported) {
|
|
console.log('Cant handle url')
|
|
alert("Call Not Supported")
|
|
} else {
|
|
Alert.alert("Call Customer Service", "You will be redirected to the dialer to call Unioil Customer Service", [
|
|
{
|
|
text: 'Cancel',
|
|
style: 'cancel',
|
|
},{
|
|
text: 'OK', onPress: () => Linking.openURL(`${url}${num}`)
|
|
}
|
|
],
|
|
{cancelable: true})
|
|
return true
|
|
}
|
|
}).catch(err => {
|
|
console.error('An error occurred', err)
|
|
})
|
|
}}>
|
|
<Text style={{color: "darkblue"}}>{station.phone}</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
<Text style={{fontFamily: 'arial',color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, padding: 0, width: '90%', fontSize: 13}}></Text>
|
|
<View style={{flexDirection: 'row', paddingTop: 7}}>
|
|
{stars}
|
|
</View>
|
|
</View>
|
|
<TouchableOpacity
|
|
onPress={() => {
|
|
if(props.data.fuelService?.fuelingPoints == undefined) {
|
|
Alert.alert("Error", "No pump available.")
|
|
} else {
|
|
setShowModal(true)
|
|
}
|
|
}}
|
|
style={{ backgroundColor: Theme.colors.primary, padding: 12, alignSelf: 'center', alignItems: 'center', justifyContent: 'center', borderRadius: 5 }}>
|
|
<Text style={{ color: Theme.colors.white }}>Pay at Pump</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
<List>
|
|
<ListItem itemDivider style={{backgroundColor: props.app_theme?.theme.dark ? Theme.colors.darkGray : Theme.colors.lightGray}}>
|
|
<View style={{flexDirection: 'row'}}>
|
|
<Text style={{flex: 1, color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, fontSize: 20, fontWeight: 'bold' }}>Fuel Prices</Text>
|
|
{/* <Text style={{flex: 3, alignItems: 'flex-start', color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, fontStyle: 'italic', fontSize: 12}}>Last Update: {station.latest_update}</Text> */}
|
|
</View>
|
|
</ListItem>
|
|
{station.fuelService.fuelProducts != undefined && station.fuelService.fuelProducts.length > 0 ? (
|
|
<FlatList
|
|
style={{ marginBottom: 16 }}
|
|
keyExtractor={(item, index) => index.toString()}
|
|
data={station.fuelService.fuelProducts}
|
|
scrollEnabled={true}
|
|
showsVerticalScrollIndicator={false}
|
|
renderItem={({item, index}) => {
|
|
return (
|
|
<ListItem key={index}>
|
|
<Left>
|
|
<Text style={{color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary}}>{item.name}</Text>
|
|
</Left>
|
|
<Right>
|
|
<Text style={{color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.textPrimary, color: Theme.colors.primary}}>₱ {item.creditPrice}</Text>
|
|
</Right>
|
|
</ListItem>
|
|
)
|
|
}} />
|
|
) : (
|
|
<View style={{ alignItems: 'center', justifyContent: 'center', height: 85 }}>
|
|
<Text style={{ fontSize: 18, color: props.app_theme?.theme.colors.text, textAlign: 'center' }}>No Current Data</Text>
|
|
</View>
|
|
)}
|
|
</List>
|
|
{PumpSelectorModalView()}
|
|
</TouchableOpacity>
|
|
)
|
|
}
|
|
|
|
const resetFlags = () => {
|
|
setShowModal(false)
|
|
setSelectedPump(null)
|
|
setInitiateCancel(false)
|
|
setInitiateProceed(false)
|
|
setConfirmProceed(false)
|
|
}
|
|
|
|
const initiateTransaction = async () => {
|
|
const USER_PROFILE = await DB.profile();
|
|
let store = props.data
|
|
let pump = selectedPump
|
|
|
|
let params = {
|
|
storeId: store.storeId,
|
|
pump: pump.pumpNumber
|
|
}
|
|
|
|
REQUEST_POST_PAY('postClaim', 'post', {
|
|
token: USER_PROFILE.data.auth_p97
|
|
}, {}, params, async (res) => {
|
|
console.log(res)
|
|
if(res.success == undefined) {
|
|
resetFlags()
|
|
setTimeout(() => {
|
|
Alert.alert('Error', res.Message)
|
|
}, 300)
|
|
} else {
|
|
if(res.success) {
|
|
resetFlags()
|
|
props.onTransaction(res.response, store.storeId, selectedPump)
|
|
} else {
|
|
resetFlags()
|
|
setTimeout(() => {
|
|
Alert.alert('Error', res?.error.key == 'buy_gas_pump_unavailable' ? `Pump ${pump.pumpNumber} is not yet available. Try again.` : res?.error.key == 'pay_outside_petrozone_error' ? res.error.partnerApiMessage : 'Failed transaction. Try again.')
|
|
}, 300)
|
|
}
|
|
}
|
|
}, (error) => {
|
|
resetFlags()
|
|
setTimeout(() => {
|
|
Alert.alert('Error', res?.error.key == 'buy_gas_pump_unavailable' ? `Pump ${pump.pumpNumber} is not yet available. Try again.` : res?.error.key == 'pay_outside_petrozone_error' ? res.error.partnerApiMessage : 'Failed transaction. Try again.')
|
|
}, 300)
|
|
})
|
|
}
|
|
|
|
const PumpSelectorModalView = () => {
|
|
return (
|
|
<Modal
|
|
animationType="none"
|
|
transparent={true}
|
|
visible={showModal}>
|
|
<View activeOpacity={1} style={styles.centeredView}>
|
|
<View style={[styles.modalView, { backgroundColor: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.border : Theme.colors.white, height: initiateCancel ? 250 : confirmProceed ? 250 : 350, }]}>
|
|
{!initiateCancel && !confirmProceed && (<TouchableOpacity style={{ width: 20, height: 20, alignSelf: 'flex-end', borderWidth: 1, borderColor: Theme.colors.primary, borderRadius: 30, alignItems: 'center', justifyContent: 'center' }}
|
|
onPress={() => {
|
|
setInitiateCancel(true)
|
|
if(initiateProceed) {
|
|
setInitiateProceed(false)
|
|
}
|
|
}}>
|
|
<Icon.Entypo name='cross' size={20} style={{color: Theme.colors.primary, bottom: 1, right: 0.5 }} />
|
|
</TouchableOpacity>)}
|
|
{(!initiateCancel && !initiateProceed && !confirmProceed) && PumpListView(selectedPump)}
|
|
{(initiateCancel && !initiateProceed && !confirmProceed) && CancelPumpSelectorView()}
|
|
{(initiateProceed && !initiateCancel && !confirmProceed) && ProceedPumpSelectorView()}
|
|
{confirmProceed && ConfirmPumpSelectorView()}
|
|
</View>
|
|
</View>
|
|
</Modal>
|
|
)
|
|
}
|
|
|
|
const CancelPumpSelectorView = () => {
|
|
return (
|
|
<>
|
|
<View style={{ flex: 0.7, paddingTop: 20 }}>
|
|
<Text style={{ color: props.app_theme?.theme.colors.text, fontSize: 23, textAlign: 'center' }}>Are you sure you want to cancel the transaction?</Text>
|
|
</View>
|
|
<View style={{ flex: 0.5, flexDirection: 'row', justifyContent: 'center' }}>
|
|
<TouchableOpacity onPress={() => {
|
|
setShowModal(false)
|
|
setInitiateCancel(false)
|
|
setInitiateProceed(false)
|
|
setSelectedPump(null)
|
|
}} style={{ width: 100, height: 44, margin: 12, backgroundColor: Theme.colors.white, borderColor: Theme.colors.primary, borderWidth: 0.5, alignItems: 'center', justifyContent: 'center', borderRadius: 5 }}>
|
|
<Text style={{ color: Theme.colors.primary, fontSize: 17, textAlign: 'center' }}>Cancel Transaction</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity onPress={() => {
|
|
setInitiateCancel(false)
|
|
selectedPump != null ? setInitiateProceed(true) : setInitiateProceed(false)
|
|
}} style={{ width: 100, height: 44, margin: 12, backgroundColor: Theme.colors.primary, justifyContent: 'center', alignItems: 'center', borderRadius: 5 }}>
|
|
<Text style={{ color: Theme.colors.white, fontSize: 17, textAlign: 'center' }}>Continue Transaction</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const ProceedPumpSelectorView = () => {
|
|
let message = selectedPump != null ? `This will process your transaction at Pump ${selectedPump.pumpNumber}.` : "No selected pump."
|
|
return (
|
|
<>
|
|
<View style={{ flex: 1, alignItems: 'center' }}>
|
|
<Image source={Assets.pumps.pump_logo} style={{padding: 40, width: 50, height: 50, resizeMode: 'contain'}} />
|
|
</View>
|
|
<View style={{ flex: 0.5, alignItems: 'center', padding: 5, marginBottom: 15 }}>
|
|
<Text style={{ fontSize: 19, textAlign: 'center', color: props.app_theme?.theme.colors.text }}>{message}</Text>
|
|
</View>
|
|
<View style={{ flex: 0.5, alignItems: 'center', padding: 5, marginBottom: 15 }}>
|
|
<Text style={{ fontSize: 19, textAlign: 'center', color: props.app_theme?.theme.colors.text }}>Please ensure that this is the correct pump and click Ok below to proceed.</Text>
|
|
</View>
|
|
<View style={{ flex: 0.5, alignItems: 'center' }}>
|
|
<TouchableOpacity onPress={() => {
|
|
setInitiateCancel(false)
|
|
setInitiateProceed(false)
|
|
}}
|
|
style={{ padding: 10, width: 100, backgroundColor: Theme.colors.primary, justifyContent: 'center', alignItems: 'center', borderRadius: 5 }}>
|
|
<Text style={{ fontSize: 18, color: Theme.colors.white, textAlign: 'center' }}>Ok</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const ConfirmPumpSelectorView = () => {
|
|
let message = selectedPump != null ? "Processing..." : "No selected pump."
|
|
return (
|
|
<>
|
|
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
|
<Image source={Assets.icons.animated_loading} style={{width: 120, height: 120, backgroundColor: "orange"}} />
|
|
{/* <Icon.AntDesign name={'loading1'} size={80} color={Theme.colors.primary} />
|
|
*/}
|
|
<View style={{ marginHorizontal: 40, marginTop: 10 }}>
|
|
<Text style={{ color: props.app_theme?.theme.colors.text, fontSize: 24, textAlign: 'center' }}>{message}</Text>
|
|
</View>
|
|
</View>
|
|
</>
|
|
)
|
|
}
|
|
|
|
|
|
const PumpListView = (currentSelectedPump) => {
|
|
return (
|
|
<>
|
|
<Text style={{ color: Theme.colors.primary, fontSize: 23, marginTop: -10 }}>Please select the pump</Text>
|
|
<FlatList
|
|
style={{ marginBottom: 16 }}
|
|
keyExtractor={(item, index) => index.toString()}
|
|
data={props.data.fuelService?.fuelingPoints}
|
|
scrollEnabled={true}
|
|
showsVerticalScrollIndicator={false}
|
|
renderItem={({item, index}) => {
|
|
let available = item.pumpStatus == "Available"
|
|
return (
|
|
<TouchableOpacity disabled={!available} onPress={() => {
|
|
setInitiateProceed(true)
|
|
setSelectedPump(item)
|
|
}} key={index} style={{ alignItems: 'center', justifyContent: 'center', margin: 20 }}>
|
|
{(currentSelectedPump != null && currentSelectedPump.pumpNumber == item.pumpNumber) ? (
|
|
<View style={styles.selectedPumpBorder}>
|
|
<Image source={available ? Assets.pumps.plain_pump : Assets.pumps.plain_pump_grey} style={{padding: 40, width: 50, height: 50, resizeMode: 'contain' }} />
|
|
</View>
|
|
) : (
|
|
<View style={[styles.unselectedPumpBorder, { borderColor: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.border : Theme.colors.white }]}>
|
|
<Image source={available ? Assets.pumps.plain_pump : Assets.pumps.plain_pump_grey} style={{padding: 40, width: 50, height: 50, resizeMode: 'contain' }} />
|
|
</View>
|
|
)}
|
|
<Text style={{ alignSelf: 'center', position:'absolute', color: available ? Theme.colors.primary : Theme.colors.darkGray, padding: 10, left: 21, bottom: 15 }}>{item.pumpNumber}</Text>
|
|
</TouchableOpacity>
|
|
)
|
|
}}
|
|
numColumns={2}
|
|
/>
|
|
<TouchableOpacity
|
|
disabled={!selectedPump}
|
|
style={{ width: 100, padding: 10, backgroundColor: selectedPump != null ? Theme.colors.primary : Theme.colors.darkGray, alignItems: 'center', justifyContent: 'center', borderRadius: 5 }}
|
|
onPress={() => {
|
|
if(selectedPump != null) {
|
|
setConfirmProceed(true)
|
|
initiateTransaction()
|
|
}
|
|
}}>
|
|
<Text style={{ color: Theme.colors.white }}>Ok</Text>
|
|
</TouchableOpacity>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const snapPoint = () => {
|
|
return props.data != null && props.data.fuelService?.fuelProducts != undefined && props.data.fuelService?.fuelProducts.length > 4 ? ['53', '53', '53'] : props.data != null && props.data.fuelService?.fuelProducts == undefined ? ['40', '40', '40'] : ['43', '43', '43']
|
|
}
|
|
|
|
return (
|
|
<View style={{flex: 1}}>
|
|
<BottomSheet
|
|
snapPoints={snapPoint()}
|
|
renderContent={() => {
|
|
return props.data == null ? null : renderStationDetails(props.data, props.onClick)
|
|
}}
|
|
enabledBottomInitialAnimation={true}
|
|
enabledInnerScrolling={true}
|
|
initialSnap={0}
|
|
renderHeader={() => {
|
|
if(props.data == null) return null
|
|
return (
|
|
<View style={[styles.panelHeader, {backgroundColor: props.app_theme?.theme.dark ? Theme.colors.darkGray : Theme.colors.lightGray}]}>
|
|
<View style={{flexDirection: 'row', justifyContent: 'center', padding: 15}}>
|
|
<Text style={{flex: 4, paddingTop: 17, justifyContent: 'center', color: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.text : Theme.colors.darkGray, fontSize: 16, fontWeight: 'bold'}}>
|
|
{props.data.storeName}
|
|
</Text>
|
|
<View style={{flex: 0, justifyContent: 'center'}}>
|
|
<TouchableOpacity onPress={() => {}} activeOpacity={1} style={{top: -25}}>
|
|
<View style={{width: 60, justifyContent: 'center', alignItems: 'center', height: 60, borderRadius: 30, backgroundColor: Theme.colors.primary, elevation: 10}}>
|
|
{(props.data && props.data.address != undefined && props.data.address != "") ?
|
|
<NavigationApps
|
|
iconSize={35}
|
|
row
|
|
modalVisible={true}
|
|
viewMode="sheet"
|
|
actionSheetBtnCloseTitle="Cancel"
|
|
actionSheetBtnOpenTitle={<Icon.Ionicons name="ios-send" color="#fff" size={35} />}
|
|
actionSheetTitle="Choose an application to view the route"
|
|
address={props.data.address} // address to navigate by for all apps
|
|
waze={{ address: props.data.address, lat:props.data.latitude, lon:props.data.longitude, action: actions.navigateByLatAndLon}} // specific settings for waze
|
|
googleMaps={{ address: props.data.address, lat:'',lon:'',action: actions.navigateByAddress, travelMode:googleMapsTravelModes.driving}} // specific settings for google maps
|
|
maps={{ address: props.data.address, lat:'', lon:'',action: actions.navigateByAddress, travelMode:mapsTravelModes.driving}} /> // specific settings for maps
|
|
: null}
|
|
</View>
|
|
<Text style={{color: Theme.colors.primary}}>Directions</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
)
|
|
}}/>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const mapStateToProps = (state) => {
|
|
return {
|
|
app_theme: state.appThemeReducer.theme
|
|
}
|
|
}
|
|
|
|
export default connect(mapStateToProps, null)(PayatpumpStationDetails)
|