Checkpoint commit. 80% IQAIR Module done.

This commit is contained in:
Harley Catubag 2022-06-28 17:26:47 +08:00
parent 449a381540
commit 5defcd2bb1
18 changed files with 224 additions and 81 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -5,7 +5,6 @@ export class index extends Component {
render() {
return (
<View>
<Text>index</Text>
</View>
)
}

View File

@ -10,6 +10,8 @@ import {
returnIcon,
returnStatus
} from '../../../utils/IQAIRhelper';
import { useNavigation } from '@react-navigation/native';
import CustomHeader from '../../../components/header.js';
import CustomSafeArea from '../../../components/safeArea.component';
import Elements from '../../../components/elements.js';
import Theme from '../../../components/theme.style.js';
@ -54,6 +56,8 @@ const status = [
]
const Guide = () => {
const navigation = useNavigation();
const renderItem = ({item, index}) => {
return (
<Elements.shadowView>
@ -72,6 +76,8 @@ const Guide = () => {
return (
<CustomSafeArea>
<CustomHeader back={true} onBackPress={() => navigation.goBack()} title="IQAIR Guide" menu={false} navigation={navigation} />
<FlatList
data={status}
renderItem={renderItem}

View File

@ -4,13 +4,17 @@ import {
StyleSheet,
AppState
} from 'react-native';
import { useNavigation } from '@react-navigation/native';
import IQAIRDetails from './IQAIRDetails';
import Map from './Map';
import CustomHeader from '../../../../components/header.js';
import RNLocation from 'react-native-location';
import REQUEST from '../../../../components/api';
import DB from '../../../../components/storage';
import Map from './Map';
const MapContainer = () => {
const navigation = useNavigation();
const [permissionLocation, setPermissionLocation] = useState(false);
const [selected, setSelected] = useState(undefined);
const [stations, setStations] = useState([]);
@ -100,6 +104,7 @@ const MapContainer = () => {
return (
<View style={styles.container}>
<CustomHeader back={true} onBackPress={() => navigation.goBack()} title="IQAIR Location" menu={false} navigation={navigation} />
<Map
region={region}
getRef={getRef}

View File

@ -3,6 +3,7 @@ import { createStackNavigator } from '@react-navigation/stack';
import Lists from './list';
import Search from './search';
import Details from '../details';
const Stack = createStackNavigator();
@ -15,6 +16,7 @@ const index = () => {
<Stack.Navigator initialRouteName="List" >
<Stack.Screen name="List" key="List" component={Lists} options={navOptions} />
<Stack.Screen name="Search" key="Search" component={Search} options={navOptions} />
<Stack.Screen name="Details" key="Details" component={Details} options={navOptions} />
</Stack.Navigator>
)
}

View File

@ -0,0 +1,44 @@
import React from 'react'
import {
View,
Text,
StyleSheet,
Image
} from 'react-native'
import { useSelector } from 'react-redux';
import Theme from '../../../../components/theme.style.js';
const Empty = () => {
const app_theme = useSelector(state => state.appThemeReducer.theme);
return (
<View style={styles.container}>
<View style={styles.emptyContainer}>
<Image style={styles.emptyImage} source={require("../../../../assets/iqair-empty-stations.png")}/>
<Text style={styles.emptyText(app_theme)}>No Station Yet</Text>
</View>
</View>
)
}
export default Empty
const styles = StyleSheet.create({
container: {
flex: 1,
},
emptyContainer: {
paddingHorizontal: 30,
alignItems: 'center'
},
emptyImage: {
width: '100%',
resizeMode: 'contain'
},
emptyText: (theme) => {
return {
color: theme?.theme.dark ? theme.theme.colors.text : Theme.colors.searchGray,
marginTop: -(Theme.screen.w * .15)
}
}
})

View File

@ -6,12 +6,14 @@ import {
View
} from 'react-native'
import Theme from '../../../../components/theme.style.js';
import Empty from './Empty.js';
import ListItem from './ListItem.js';
const List = (props) => {
const renderItem = (value, data) => {
return <ListItem
init={props.init}
value={value}
data={data}
/>
@ -23,6 +25,8 @@ const List = (props) => {
<FlatList
data={props.data}
renderItem={(item) => renderItem(item, props.data)}
contentContainerStyle={props.data?.length === 0 && { flex: 1 }}
ListEmptyComponent={Empty}
/>
</View>
)

View File

@ -12,12 +12,24 @@ import {
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;
@ -26,7 +38,7 @@ const ListItem = (props) => {
const [ID, setID] = useState(0);
useEffect(() => {
init();
// init();
}, []);
const init = () => {
@ -51,16 +63,48 @@ const ListItem = (props) => {
}, 1000)
}
const onDelete = () => {
dispatch(openModal({
open: true,
title: "Warning",
body: "Are you sure you want to delete this staion?",
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",
yesCB: deleteStation,
theme: app_theme
}))
}, () => {});
}
}
const onPressDetails = () => {
navigation.navigate("Details")
}
return (
<Elements.shadowView>
<View style={styles.renderItem(index, data)}>
<TouchableOpacity 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}>{item.name}</Text>
<Text style={styles.addressText}>{item.address}</Text>
<Text style={[styles.nameText, styles.darkColor(app_theme)]}>{item.name}</Text>
<Text style={[styles.addressText, styles.darkColor(app_theme)]}>{item.address}</Text>
</View>
<TouchableOpacity>
<TouchableOpacity onPress={onDelete}>
<Icon.Ionicons name="trash" size={22} color={Theme.colors.primary} />
</TouchableOpacity>
</View>
@ -77,11 +121,11 @@ const ListItem = (props) => {
</Elements.shadowView>
</View>
<View style={styles.airlevelContainer(ID)}>
<Text style={styles.airlevelTitle}>{IQAir?.pollution.aqius} *</Text>
<Text style={styles.airlevelIndicator}>US AQI</Text>
<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} numberOfLines={2} adjustsFontSizeToFit >{returnStatus(ID).title}</Text>
<Text style={[styles.statusText, styles.darkColor(app_theme)]} numberOfLines={2} adjustsFontSizeToFit >{returnStatus(ID).title}</Text>
</View>
</>
}
@ -95,21 +139,21 @@ const ListItem = (props) => {
<>
<View style={styles.water}>
<Image style={styles.waterIcon} source={require("../../../../assets/iqairwater.png")}/>
<Text style={styles.infoText}>{IQAir?.weather.hu}%</Text>
<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}>{(IQAir?.weather.ws * 3.6).toFixed(2)} km/h</Text>
<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}>{IQAir?.weather.tp}°</Text>
<Text style={[styles.infoText, styles.darkColor(app_theme)]}>{IQAir?.weather.tp}°</Text>
</View>
</>
}
</View>
</View>
</TouchableOpacity>
</Elements.shadowView>
)
@ -118,9 +162,9 @@ const ListItem = (props) => {
export default ListItem
const styles = StyleSheet.create({
renderItem: (index, data) => {
renderItem: (index, data, appTheme) => {
return {
backgroundColor: 'white',
backgroundColor: appTheme?.theme.dark ? appTheme?.theme.colors.border : Theme.colors.white,
borderRadius: 5,
marginHorizontal: 18,
paddingHorizontal: 15,
@ -131,7 +175,7 @@ const styles = StyleSheet.create({
},
firstRow: {
flexDirection: 'row',
flex: 1
height: 50,
},
infoContainer: {
flex: 1,
@ -149,18 +193,18 @@ const styles = StyleSheet.create({
secondRow: {
flexDirection: 'row',
height: 70,
flex: 1,
marginTop: 10
},
iconContainer: {
flex: .25,
backgroundColor: Theme.colors.whitesmoke,
alignItems: 'center',
justifyContent: 'center'
justifyContent: 'center',
borderTopLeftRadius: 5,
borderBottomLeftRadius: 5
},
iconShadow: {
alignItems: 'center',
justifyContent: 'center'
justifyContent: 'center',
},
icon: {
height: '75%',
@ -201,7 +245,6 @@ const styles = StyleSheet.create({
},
thirdRow: {
flexDirection: 'row',
flex: 1,
height: 20,
alignItems: 'center',
marginTop: 14,
@ -254,5 +297,12 @@ const styles = StyleSheet.create({
infoText: {
fontSize: 10,
color: Theme.colors.searchText
},
darkColor: (appTheme) => {
if(appTheme?.theme.dark) {
return {
color: Theme.colors.white
}
}
}
})

View File

@ -1,9 +1,12 @@
import React, { useEffect, useState } from 'react'
import {
View,
StyleSheet
StyleSheet,
Text,
TouchableOpacity
} from 'react-native'
import { useNavigation } from '@react-navigation/native';
import Theme from '../../../../components/theme.style.js';
import List from './List.js';
import Search from '../search/Search.js';
import SearchResult from '../search/SearchResult';
@ -51,7 +54,11 @@ const Lists = (props) => {
<Search onPress={onPress} />
{ result.length === 0 &&
<List data={savedLocations}/> }
<List data={savedLocations} init={init} /> }
<TouchableOpacity onPress={onPress} style={styles.addLocationButton}>
<Text style={styles.addLocationText}>ADD UNIOIL STATION</Text>
</TouchableOpacity>
</View>
</CustomSafeArea>
)
@ -63,5 +70,18 @@ const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20,
},
addLocationButton: {
backgroundColor: Theme.colors.primary,
width: Theme.screen.w - 80,
alignSelf: 'center',
marginBottom: 20,
alignItems: 'center',
paddingVertical: 10,
borderRadius: 5
},
addLocationText: {
color: Theme.colors.white,
fontSize: 15
}
})

View File

@ -54,20 +54,21 @@ const Search = (props) => {
const onPressSearch = () => {
if(cityDropDown.length !== 0) {
setSearchValue("");
setCityDropDown([]);
} else {
search();
}
}
const search = async () => {
const search = async (item) => {
setLoading(true);
let SESSION = await DB.session()
REQUEST("gas_stations_city", "get", {
Authorization: SESSION.token
}, {
noID: true,
value: selectedCity.city_uuid
value: item ? item.city_uuid : selectedCity.city_uuid
}, {}, (res) => {
if(res.data.length > 0){
setSearchValue("");
@ -85,11 +86,12 @@ const Search = (props) => {
setSearchValue(item.name);
setSelectedCity(item);
setCityDropDown([]);
search(item);
}
return (
<TouchableOpacity onPress={onPress} style={[styles.searchItemButton]}>
<Text style={styles.searchItemText}>{item.name}</Text>
<TouchableOpacity onPress={onPress} style={styles.searchItemButton}>
<Text style={styles.searchItemText(app_theme)}>{item.name}</Text>
</TouchableOpacity>
)
}
@ -137,7 +139,7 @@ const Search = (props) => {
{
cityDropDown.length > 0 &&
<View style={styles.dropDown}>
<View style={styles.dropDown(app_theme)}>
<FlatList
data={cityDropDown}
renderItem={renderItem}
@ -171,31 +173,35 @@ const styles = StyleSheet.create({
return {
flex: 1,
fontSize: 15,
color: apptheme.theme.dark ? 'white' : 'black'
color: apptheme.theme.dark ? Theme.colors.white : Theme.colors.black
}
},
dropDown: {
position: 'absolute',
height: 400,
left: 0,
right: 0,
bottom: -405,
backgroundColor: 'white',
shadowColor: '#000',
shadowOffset: { width: 0, height: .8},
shadowOpacity: .4,
shadowRadius: 1,
elevation: 3,
paddingHorizontal: 5,
dropDown: (apptheme) => {
return {
position: 'absolute',
height: 400,
left: 0,
right: 0,
bottom: -405,
backgroundColor: apptheme?.theme.dark ? apptheme?.theme.colors.border : Theme.colors.white,
shadowColor: '#000',
shadowOffset: { width: 0, height: .8},
shadowOpacity: .4,
shadowRadius: 1,
elevation: 3,
paddingHorizontal: 5
}
},
searchItemButton: {
searchItemButton: {
paddingVertical: 20,
paddingHorizontal: 10,
borderBottomWidth: 1,
borderColor: Theme.colors.searchGray
},
searchItemText: {
color: Theme.colors.darkerGray
searchItemText: (appTheme) => {
return {
color: appTheme?.theme.dark ? appTheme?.theme.colors.text : Theme.colors.darkerGray
}
},
buttonText: {
flex: 1,

View File

@ -6,11 +6,13 @@ import {
Text,
TouchableOpacity
} from 'react-native';
import { useSelector } from 'react-redux';
import Icon from '../../../../components/icons.js';
import Theme from '../../../../components/theme.style.js';
import DB from '../../../../components/storage';
const SearchResult = (props) => {
const app_theme = useSelector(state => state.appThemeReducer.theme);
const [savedLocations, setSavedLocations] = useState([]);
useEffect(() => {
@ -57,11 +59,11 @@ const SearchResult = (props) => {
}
return(
<View style={styles.item}>
<View style={styles.item(app_theme)}>
<Icon.Ionicons name="location" size={20} color={Theme.colors.primary} />
<View style={styles.itemInfo}>
<Text style={styles.itemName} numberOfLines={1} adjustsFontSizeToFit>{value.name}</Text>
<Text style={styles.itemsAddress}>{value.address}</Text>
<Text style={styles.itemName(app_theme)} numberOfLines={1} adjustsFontSizeToFit>{value.name}</Text>
<Text style={styles.itemsAddress(app_theme)}>{value.address}</Text>
</View>
<View style={styles.addLocationContainer}>
{renderAddButton()}
@ -94,35 +96,41 @@ const styles = StyleSheet.create({
addLocationContainer: {
justifyContent: 'center',
},
item: {
marginHorizontal: 18,
backgroundColor: "white",
paddingVertical: 10,
paddingHorizontal: 17,
shadowColor: '#000',
marginBottom: 10,
shadowOffset: { width: 0, height: .8},
shadowOpacity: .3,
shadowRadius: 3,
elevation: 3,
flexDirection: 'row'
item: (appTheme) => {
return {
marginHorizontal: 18,
backgroundColor: appTheme?.theme.dark ? appTheme?.theme.colors.border : Theme.colors.white,
paddingVertical: 10,
paddingHorizontal: 17,
shadowColor: '#000',
marginBottom: 10,
shadowOffset: { width: 0, height: .8},
shadowOpacity: .3,
shadowRadius: 3,
elevation: 3,
flexDirection: 'row'
}
},
itemInfo: {
marginLeft: 10,
paddingRight: 10,
flex: 1
},
itemName: {
fontSize: 14,
color: Theme.colors.searchText
itemName: (appTheme) => {
return {
fontSize: 14,
color: appTheme?.theme.dark ? Theme.colors.white : Theme.colors.searchText
}
},
itemsAddress: {
fontSize: 9,
color: Theme.colors.searchText
itemsAddress: (appTheme) => {
return {
fontSize: 9,
color: appTheme?.theme.dark ? Theme.colors.white : Theme.colors.searchText
}
},
scrollView: {
marginVertical: 20,
flex: 1
flex: 1,
}
})

View File

@ -277,11 +277,6 @@ class Home extends React.PureComponent {
this.displayBanner = false
})
}
// let timeout = setTimeout(() => {
// this.getNotifications()
// clearTimeout(timeout)
// }, 3000);
}
getNotifications = async () => {

View File

@ -38,11 +38,13 @@ const Tracker = (navigation) => {
tracks.push(data)
await DB.set("tracker", JSON.stringify(tracks), function(){
const taskToShow = `Fuel Efficiency tracker added`
navigation.route.params?.reload();
navigation.openModal({
open: true,
title: "Tracker",
body: "Fuel Efficiency tracker ${task}",
body: taskToShow,
yesCB: () => navigation.navigation.goBack(),
yesButtonOnly: true,
theme: navigation.app_theme

View File

@ -71,11 +71,13 @@ const Tracker = (navigation) => {
}
const onDone = (task) => {
const taskToShow = `Fuel Efficiency tracker ${task}`
navigation.route.params?.reload();
navigation.openModal({
open: true,
title: "Tracker",
body: "Fuel Efficiency tracker ${task}",
body: taskToShow,
yesCB: () => navigation.navigation.goBack(),
yesButtonOnly: true,
theme: navigation.app_theme

View File

@ -1063,7 +1063,7 @@
CODE_SIGN_ENTITLEMENTS = "RNUnioilLoyaltyApp/Unioil Loyalty App.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 6;
CURRENT_PROJECT_VERSION = 0;
DEVELOPMENT_TEAM = J29MB7XX75;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -1211,7 +1211,7 @@
"\"${PODS_ROOT}/CocoaLibEvent/lib\"",
"\"${PODS_ROOT}/OpenSSL-Universal/ios/lib\"",
);
MARKETING_VERSION = 1.6.3;
MARKETING_VERSION = 1.6.5;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = (
"$(inherited)",
@ -1238,7 +1238,7 @@
CODE_SIGN_ENTITLEMENTS = "RNUnioilLoyaltyApp/Unioil Loyalty App.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 6;
CURRENT_PROJECT_VERSION = 0;
DEVELOPMENT_TEAM = J29MB7XX75;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@ -1309,7 +1309,7 @@
"\"${PODS_ROOT}/CocoaLibEvent/lib\"",
"\"${PODS_ROOT}/OpenSSL-Universal/ios/lib\"",
);
MARKETING_VERSION = 1.6.3;
MARKETING_VERSION = 1.6.5;
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = (
"$(inherited)",