unioil-loyalty-rn-app/app/screens/main/station/fragments/stationpanel.js

241 lines
6.9 KiB
JavaScript

import React from 'react';
import {useState, useEffect} from 'react';
import {
Text,
View,
Dimensions,
TouchableOpacity,
ActivityIndicator,
SafeAreaView,
Platform,
Alert,
} from 'react-native';
import { connect } from 'react-redux';
import { Divider } from 'react-native-elements';
import BottomSheet from 'reanimated-bottom-sheet';
import Theme from '../../../../components/theme.style.js';
import Icon from '../../../../components/icons';
import DB from '../../../../components/storage';
import REQUEST from '../../../../components/api';
import { navigate } from '../../../../utils/navigation.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',
},
};
const {height} = Dimensions.get('window');
const renderStations = (isGuest, data, onPress, onUpdateFavorite, props) => {
return data.map((station, index) => {
let stars = [1, 2, 3, 4, 5].map((star, i) => {
let name = station.stars >= star ? 'star' : 'staro';
let mgn = index > 0 ? 5 : 0;
return (
<Icon.AntDesign
name={name}
style={{marginLeft: mgn}}
color={Theme.colors.yellow}
size={20}
/>
);
});
return (
<TouchableOpacity
key={index}
activeOpacity={1}
onPress={() => onPress(station) || null}
style={{backgroundColor: props.app_theme?.theme.dark ? Theme.colors.black : Theme.colors.white}}
>
<View style={{flex: 0, padding: 15, flexDirection: 'row'}}>
<View style={{flex: 5}}>
<Text
style={{
fontSize: 16,
padding: 5,
color: props.app_theme?.theme.colors.text,
}}>
{station.name}
</Text>
<Text
style={{
color: props.app_theme?.theme.colors.text,
padding: 5,
width: '90%',
fontSize: 13,
}}>
{station.address}
</Text>
<View style={{flexDirection: 'row', paddingTop: 7}}>{stars}</View>
</View>
<TouchableOpacity
onPress={() => {
if(isGuest){
guestError()
} else {
updateFavorite(station, index, onUpdateFavorite)
}
}}
style={{flex: 0, justifyContent: 'center'}}>
<Icon.FontAwesome
name={station.favorite ? 'heart' : 'heart-o'}
size={28}
color={station.favorite ? 'red' : Theme.colors.darkGray}
/>
</TouchableOpacity>
</View>
<Divider
style={{marginTop: 5, padding: 0, margin: 0, width: Theme.screen.w}}
/>
</TouchableOpacity>
);
});
};
const guestError = () => {
Alert.alert(
"Information",
`\nApply for a card to enjoy this feature`,
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: { color: 'red' },
},
{
text: 'Enroll Card',
onPress: () => navigate('Login')
},
]
);
}
const updateFavorite = async (city, index, callback) => {
let session = await DB.session();
let urlTask = city.favorite
? 'station_delete_favorite'
: 'station_add_favorite'
let method = city.favorite ? 'delete' : 'get';
REQUEST(
urlTask,
method, { Authorization: session.token },
{
noID: true,
value: city.station_uuid,
}, {},
(res) => {
callback(index, city.favorite ? false : true);
},
(err) => {
Alert.alert("Information", `\n${err.message}`);
},
);
};
const renderStationPanel = (props) => {
const [snap, setSnap] = useState(['10', '10', '3']);
useEffect(() => {
init();
}, [props.visible, props.data]);
const init = () => {
if (props.data.length === 0) {
if(Platform.OS === "android") return setSnap(['14', '14', '3']);
return setSnap(['14', '14', '14'])
} else if (props.data.length === 1) {
return setSnap(['22', '22', '22']);
}
else if (props.data.length > 1) {
return setSnap(['35','8','8']);
} else {
return setSnap(props.snapPoints ? props.snapPoints : ['14', '14', '14']);
}
};
const getPanelTitle = () => {
if(props.error) return 'There was an error'
else if(props.loading && !props.isSearched && props.data.length == 0) return 'Getting Nearby Stations'
else if(!props.loading && props.isFavorite && props.data.length == 0) return 'No Favorite'
else if(props.isSearched) return 'Unioil Stations found: ' + (props.data.length > 0 ? props.data.length : 0)
else return 'Unioil Stations found: ' + (props.data.length > 0 ? props.data.length : 0)
}
const renderHeaders = () => {
return (
<View style={styles.panel}>
<View style={[styles.panelHeader, { backgroundColor: props.app_theme?.theme.dark ? Theme.colors.darkerGray : Theme.colors.lightGray }]}>
<View
style={{
flexDirection: 'row',
justifyContent: 'center',
padding: 15,
}}>
<Text
style={{
flex: 4,
padding: 5,
color: props.app_theme?.theme.colors.text,
fontSize: 15,
}}>
{getPanelTitle()}
</Text>
<View style={{flex: 0, justifyContent: 'center'}}>
{props.error ? (
<TouchableOpacity onPress={props.onError} activeOpacity={1}>
<Text style={{color: '#fff'}}>Try Again</Text>
</TouchableOpacity>
) : props.loading ? (
<ActivityIndicator color={Theme.colors.primary} size={25} />
) : null}
</View>
</View>
</View>
</View>
);
};
const renderContents = () => {
return (
<SafeAreaView>
{props.data.length > 0 ? renderStations(props.isGuest, props.data, props.onClick, props.onUpdateFavorite, props) : <View style={{height: 250, width: '100%', backgroundColor: props.app_theme?.theme.dark ? props.app_theme?.theme.colors.border : Theme.colors.white }}></View>}
</SafeAreaView>
);
};
return (
<View style={{ flex: 1 }}>
<BottomSheet
snapPoints={snap}
renderContent={renderContents}
enabledBottomInitialAnimation={true}
enabledInnerScrolling={true}
renderHeader={renderHeaders} />
</View>
);
}
const mapStateToProps = (state) => {
return {
app_theme: state.appThemeReducer.theme
}
}
export default connect(mapStateToProps, null)(renderStationPanel)