unioil-loyalty-rn-app/app/screens/iqair/stations/list/ListItem.js

333 lines
10 KiB
JavaScript

import React, { useEffect, useState } from 'react'
import {
View,
Text,
StyleSheet,
TouchableOpacity,
ActivityIndicator,
Image,
Alert
} from 'react-native';
import {
returnStatus,
returnIcon,
returnStatusId
} from '../../../../utils/IQAIRhelper';
import {
useDispatch,
useSelector
} from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import { openModal } from '../../../../redux/actions/AlertActions';
import DB from '../../../../components/storage';
import API from '../../../../components/api/iqair';
import Theme from '../../../../components/theme.style.js';
import Elements from '../../../../components/elements.js';
import Icon from '../../../../components/icons.js';
const ListItem = (props) => {
const dispatch = useDispatch();
const navigation = useNavigation();
const app_theme = useSelector(state => state.appThemeReducer.theme);
const {value, data} = props;
const {item, index} = value;
const [IQAir, setIQAir] = useState(undefined);
const [loading, setLoading] = useState(false);
const [retry, setRetry] = useState(true);
const [ID, setID] = useState(0);
useEffect(() => {
init();
}, []);
const init = () => {
setRetry(false);
setLoading(true);
setTimeout(() => {
const data = {
lat: value.latitude,
lon: value.longitude
}
API(data, (res) => {
if(res.data.message) {
setRetry(true);
setLoading(false);
return
}
const aqius = res.data.current.pollution?.aqius;
setID(returnStatusId(aqius || 0));
setIQAir(res.data.current);
setLoading(false);
}, (err) =>{
setRetry(true)
setLoading(false);
})
}, 1000)
}
const onDelete = () => {
dispatch(openModal({
open: true,
title: "Warning",
body: "Are you sure you want to delete this station?",
yesCB: deleteStation,
theme: app_theme
}))
}
const deleteStation = async () => {
const stations = await DB.get('iqair');
if(stations) {
const newArray = [...JSON.parse(stations)];
const parsedArray = newArray.filter(station => station.station_uuid !== item.station_uuid);
await DB.set('iqair', JSON.stringify(parsedArray), () => {
props.init();
dispatch(openModal({
open: true,
title: "Success",
body: "Saved station is deleted",
yesButtonOnly: true,
yesText: "Okay",
theme: app_theme
}))
}, () => {});
}
}
const onPressDetails = () => {
navigation.navigate("Details", {
value: props.value,
data: props.value,
iqairData: IQAir,
id: ID
})
}
return (
<Elements.shadowView>
<TouchableOpacity disabled={loading && !false} onPress={onPressDetails} style={styles.renderItem(index, data, app_theme)}>
<View style={styles.firstRow}>
<Icon.Ionicons name="location" size={25} color={Theme.colors.primary} />
<View style={styles.infoContainer}>
<Text style={[styles.nameText, styles.darkColor(app_theme)]}>{item.name}</Text>
<Text style={[styles.addressText, styles.darkColor(app_theme)]}>{item.address}</Text>
</View>
<TouchableOpacity onPress={onDelete}>
<Icon.MaterialIcons name="delete" size={22} color={Theme.colors.primary} />
</TouchableOpacity>
</View>
{retry &&
<View style={[styles.secondRow, {alignItems: 'center', justifyContent: 'center'}]}>
<TouchableOpacity onPress={init}>
<Text>Retry</Text>
</TouchableOpacity>
</View>
}
{!retry &&
<View style={styles.secondRow}>
{ loading ?
<View style={styles.activityIndicator}>
<ActivityIndicator />
</View>
:
<>
<View style={styles.iconContainer}>
<Elements.shadowView style={styles.iconShadow}>
<Image source={returnIcon(ID)} style={styles.icon}/>
</Elements.shadowView>
</View>
<View style={styles.airlevelContainer(ID)}>
<Text style={[styles.airlevelTitle, styles.darkColor(app_theme)]}>{IQAir?.pollution.aqius} *</Text>
<Text style={[styles.airlevelIndicator, styles.darkColor(app_theme)]}>US AQI</Text>
</View>
<View style={styles.statusContainer(ID)}>
<Text style={[styles.statusText, styles.darkColor(app_theme)]} numberOfLines={2} adjustsFontSizeToFit >{returnStatus(ID).title}</Text>
</View>
</>
}
</View>
}
{!retry &&
<View style={styles.thirdRow}>
{ loading ?
<View style={styles.activityIndicator}>
<ActivityIndicator />
</View>
:
<>
<View style={styles.water}>
<Image style={styles.waterIcon} source={require("../../../../assets/iqairwater.png")}/>
<Text style={[styles.infoText, styles.darkColor(app_theme)]}>{IQAir?.weather.hu}%</Text>
</View>
<View style={styles.wind}>
<Image style={styles.airIcon} source={require("../../../../assets/iqairwind.png")}/>
<Text style={[styles.infoText, styles.darkColor(app_theme)]}>{(IQAir?.weather.ws * 3.6).toFixed(2)} km/h</Text>
</View>
<View style={styles.cloud}>
<Image style={styles.cloudIcon} source={require("../../../../assets/iqaircloud.png")}/>
<Text style={[styles.infoText, styles.darkColor(app_theme)]}>{IQAir?.weather.tp}°</Text>
</View>
</>
}
</View>
}
</TouchableOpacity>
</Elements.shadowView>
)
}
export default ListItem
const styles = StyleSheet.create({
renderItem: (index, data, appTheme) => {
return {
backgroundColor: appTheme?.theme.dark ? appTheme?.theme.colors.border : Theme.colors.white,
borderRadius: 5,
marginHorizontal: 18,
paddingHorizontal: 15,
paddingVertical: 8,
marginTop: index === 0 ? 10 : 0,
marginBottom: index === (data.length - 1) ? 20 : 15,
elevation: 5
}
},
firstRow: {
flexDirection: 'row',
height: 50,
},
infoContainer: {
flex: 1,
marginLeft: 8
},
nameText: {
color: Theme.colors.searchText,
fontSize: 14
},
addressText: {
color: Theme.colors.searchText,
fontSize: 10,
marginTop: 2
},
secondRow: {
flexDirection: 'row',
height: 70,
},
iconContainer: {
flex: .25,
backgroundColor: Theme.colors.whitesmoke,
alignItems: 'center',
justifyContent: 'center',
borderTopLeftRadius: 5,
borderBottomLeftRadius: 5
},
iconShadow: {
alignItems: 'center',
justifyContent: 'center',
},
icon: {
height: '75%',
resizeMode: 'contain'
},
airlevelContainer: (id) => {
return {
flex: .33,
backgroundColor:
Theme.colors.iqair[id].opacity,
alignItems: 'center',
justifyContent: 'center'
}
},
airlevelTitle: {
color: Theme.colors.white,
fontSize: 25
},
airlevelIndicator: {
color: Theme.colors.white,
fontSize: 11
},
statusContainer: (id) => {
return {
flex: .37,
borderRadius: 5,
backgroundColor: Theme.colors.iqair[id].main,
left: -10,
justifyContent: 'center',
alignItems: 'center'
}
},
statusText: {
color: Theme.colors.white,
fontSize: 12,
fontWeight: 'bold',
textAlign: 'center'
},
thirdRow: {
flexDirection: 'row',
height: 20,
alignItems: 'center',
marginTop: 14,
marginBottom: 5
},
water: {
flex: .25,
borderRightWidth: 1,
borderColor: Theme.colors.gray,
flexDirection: 'row',
alignItems: 'center'
},
waterIcon: {
marginRight: 3,
height: 15,
width: 15,
resizeMode: 'contain'
},
wind: {
flex: .33,
flexDirection: 'row',
alignItems: 'center'
},
airIcon: {
height: 20,
width: 20,
marginLeft: 10,
resizeMode: 'contain'
},
cloud: {
left: -10,
flex: .37,
borderColor: Theme.colors.gray,
borderLeftWidth: 1,
flexDirection: 'row',
alignItems: 'center'
},
cloudIcon: {
height: 20,
width: 20,
resizeMode: 'contain',
marginHorizontal: 4,
marginLeft: 15
},
activityIndicator: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
infoText: {
fontSize: 10,
color: Theme.colors.searchText
},
darkColor: (appTheme) => {
if(appTheme?.theme.dark) {
return {
color: Theme.colors.white
}
}
}
})