Commit 5f57fe0c by HaOuiha

fixbug

parent b241735b
import React, { Component } from 'react';
import { Icon, Text, Switch, Button } from 'native-base';
import { View, StyleSheet, FlatList, ScrollView, Modal, TouchableOpacity, Platform } from 'react-native';
import { HeaderButtons, Item as HeaderItem } from 'react-navigation-header-buttons';
import IoniconsHeaderButton from '../../../components/IoniconsHeaderButton';
import { color, theme } from '../../../constants/Styles';
import RNPickerSelect from 'react-native-picker-select';
import { CheckBox, SearchBar } from 'react-native-elements';
import SwipeableRow from '../../../components/SwipeableRow';
import DatePicker from 'react-native-date-picker';
import { height } from '../../../constants/Layout';
import { isIphoneX } from '../../../utils/isPhoneX';
import { connect } from 'react-redux';
import {
getTimers,
getSelectedTimerData,
setEditModalVisible,
createNewTimer,
editTimer,
deleteTimer,
} from '../../../reduxStore/actions/timersAction';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import Modal2 from 'react-native-modalbox';
const initTime = new Date();
initTime.setFullYear(2019);
initTime.setMonth(0);
initTime.setDate(0);
initTime.setSeconds(0);
const initTimeSetting = {
// mcbLinkId: null,
// id: null,
// key: null,
isActive: false,
isPowerOn: false,
timer: initTime,
repeatOn: [
{ id: 0, isRepeat: false, day: 'Sunday' },
{ id: 1, isRepeat: false, day: 'Monday' },
{ id: 2, isRepeat: false, day: 'Tuesday' },
{ id: 3, isRepeat: false, day: 'Wednesday' },
{ id: 4, isRepeat: false, day: 'Thursday' },
{ id: 5, isRepeat: false, day: 'Friday' },
{ id: 6, isRepeat: false, day: 'Saturday' },
],
};
const initState = {
...initTimeSetting,
isAddVisible: false,
isfilterVisible: false,
search: '',
selectedBreaker: null, //Main or mcbLink
selectedSubBreaker: null,
};
class TimerScreen extends Component {
static navigationOptions = ({ navigation }) => ({
title: 'Timer',
headerLeft: (
<HeaderButtons HeaderButtonComponent={IoniconsHeaderButton}>
<HeaderItem title="menu" iconName="md-home" onPress={() => navigation.popToTop()} />
</HeaderButtons>
),
headerRight: navigation.state.params ? navigation.state.params.headerRight : null,
});
state = {
...initState,
pickerSelectData: [],
subBreakerList: [],
data: [],
};
constructor(props) {
super(props);
this.props.getTimers();
}
setPickerSelectData = () => {
let pickerSelectData = [
{ label: `Main Device ${currentSelectedData.name ? `[${currentSelectedData.name}]` : ''}`, value: 'main' },
];
this.props.existedData.map((mcbLink, index) => {
pickerSelectData.push({ label: `MCB Link ${index + 1} ${mcbLink.name ? `[${mcbLink.name}]` : ''} ` });
});
this.setState({ pickerSelectData });
};
setExistedSubBreaker = () => {
let existedSubBreakerListLength = 0;
this.props.existedData.map((mainBreaker, index) => {
if (this.state.selectedBreaker === index + 1) {
existedSubBreakerListLength = mainBreaker.length;
}
});
let subBreakerList = new Array(existedSubBreakerListLength).fill().map((el, index) => {
return { id: index + 1, selected: false };
});
this.setState({ subBreakerList });
};
autoCloseSwipeRow = swipeInstance => {
if (this.currentlyOpenSwipe && this.currentlyOpenSwipe !== swipeInstance) {
this.currentlyOpenSwipe.close();
}
this.currentlyOpenSwipe = swipeInstance;
};
toggleActive = () => {
this.setState(prevState => ({ isActive: !prevState.isActive }));
};
togglePower = () => {
this.setState(prevState => ({ isPowerOn: !prevState.isPowerOn }));
};
toggleRepeatDays = index => {
this.setState(prevState => ({
repeatOn: prevState.repeatOn.map((element, elementIndex) =>
elementIndex === index ? { ...element, isRepeat: !prevState.repeatOn[index].isRepeat } : element
),
}));
};
updateSearch = search => {
this.setState({ search });
const newData = this.props.allTimers.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = search.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
data: newData,
});
};
createNewOrEditTimer = async () => {
const { selectedSubBreaker, selectedBreaker, isAddVisible } = this.state;
const { isEditVisible } = this.props;
// fixed year mouth date secound So we can focus on hour and minute and can sort with timestamp
let saveTimer = new Date(this.state.timer);
saveTimer.setFullYear(2019);
saveTimer.setMonth(0);
saveTimer.setDate(0);
saveTimer.setSeconds(0);
let binary = this.state.repeatOn.map(x => (x.isRepeat ? 1 : 0)).join('');
let decimal = parseInt(binary, 2);
console.log('timer', Number(saveTimer));
const timerData = {
isActive: this.state.isActive,
isPowerOn: this.state.isPowerOn,
timer: Number(saveTimer),
repeatOn: this.state.repeatOn,
};
if (isAddVisible) {
if (selectedBreaker === 'main') {
const isCreated = await this.props.createNewTimer(null, null, timerData);
if (isCreated) {
this.resetStateAndProps();
this.props.getTimers();
}
} else if (selectedBreaker && selectedSubBreaker) {
await this.props.createNewTimer(selectedBreaker, selectedSubBreaker.id, timerData);
this.resetStateAndProps();
this.props.getTimers();
} else {
alert('please select (Sub) Breaker');
}
} else if (isEditVisible) {
this.props.editTimer(timerData);
this.resetStateAndProps();
this.props.setEditModalVisible(false);
this.props.getTimers();
}
};
resetStateAndProps = async () => {
await this.props.getSelectedTimerData(initTimeSetting);
this.setState(initState);
};
componentDidUpdate = async (prevProps, prevState) => {
if (prevState.selectedBreaker !== this.state.selectedBreaker) {
this.setExistedSubBreaker();
}
if (prevProps.existedData !== this.props.existedData) {
this.setPickerSelectData();
}
if (prevState.subBreakerList !== this.state.subBreakerList && this.state.subBreakerList) {
let selectedSubBreaker = this.state.subBreakerList.find(subBreaker => {
return subBreaker.selected === true;
});
this.setState({ selectedSubBreaker: selectedSubBreaker });
}
if (prevProps.selectedTimerData !== this.props.selectedTimerData) {
this.setState({
isActive: this.props.selectedTimerData.isActive,
isPowerOn: this.props.selectedTimerData.isPowerOn,
timer: this.props.selectedTimerData.timer,
repeatOn: this.props.selectedTimerData.repeatOn,
});
}
};
componentDidMount = () => {
this.props.navigation.setParams({
headerRight: (
<TouchableOpacity onPress={() => this.setState({ isAddVisible: true })}>
<View style={{ marginRight: 17 }}>
<Icon name="ios-add" style={{ color: color.white }} />
</View>
</TouchableOpacity>
),
});
console.log('STATE', this.state);
};
renderAddAndEditTimerModal = () => {
const { isAddVisible } = this.state;
const { isEditVisible, selectedTimerData } = this.props;
return (
<>
<View style={styles.dragIndicator} />
<View
style={{
display: 'flex',
marginTop: 30,
paddingHorizontal: 30,
marginBottom: 10,
flexDirection: 'row',
alignContent: 'stretch',
justifyContent: 'space-between',
}}
>
<Text style={[theme.title]}>{isAddVisible ? 'Create Timer' : 'Edit Timer'}</Text>
{isEditVisible && (
<Icon
name="trash-o"
type="FontAwesome"
style={{ color: color.grey, fontSize: 22 }}
onPress={() => {
this.props.deleteTimer(selectedTimerData);
this.resetStateAndProps();
this.props.setEditModalVisible(false);
}}
/>
)}
</View>
<ScrollView contentContainerStyle={{ paddingHorizontal: 30, paddingBottom: 20 }}>
<Text style={[theme.modalText, theme.textDark, theme.mt2]}>Set Time</Text>
<DatePicker
date={new Date(this.state.timer)}
onDateChange={date => this.setState({ timer: date })}
mode="time"
style={{
marginTop: 10,
height: 115,
display: 'flex',
alignSelf: 'center',
fontSize: 24,
}}
/>
{isAddVisible && (
<>
<Text style={[theme.modalText, theme.textDark, theme.mt2]}>Select Breaker</Text>
<View style={styles.pickerContainer}>
<RNPickerSelect
items={this.state.pickerSelectData}
useNativeAndroidPickerStyle={false}
onValueChange={(value, index) => {
this.setState({ selectedBreaker: value });
}}
placeholder={{ label: 'Select...', value: null }}
style={pickerStyle}
Icon={() => (
<Icon
name="ios-arrow-down"
style={{ fontSize: 16, color: '#c8c8c8', marginBottom: 5 }}
/>
)}
/>
</View>
<FlatList
style={{ marginTop: 15 }}
data={this.state.subBreakerList}
extradata={this.state}
ItemSeparatorComponent={() => <View style={theme.mt1} />}
renderItem={({ item, index }) => (
<CheckBox
containerStyle={styles.checkboxContainer}
fontFamily={'Avenir-Roman'}
textStyle={{ fontWeight: 'normal', color: color.darkGrey }}
title={`Sub Breaker ${item.id} ${item.name ? `[${item.name}]` : ''}`}
checked={this.state.subBreakerList[index].selected}
checkedIcon={
<Icon
name="md-radio-button-on"
style={{ color: color.primary, fontSize: 22 }}
/>
}
uncheckedIcon={
<Icon
name="md-radio-button-off"
style={{ color: color.grey, fontSize: 22 }}
/>
}
onPress={() => {
this.setState(prevState => ({
subBreakerList: prevState.subBreakerList.map((el, elementIndex) =>
elementIndex === index
? {
...el,
selected: !this.state.subBreakerList[index].selected,
}
: { ...el, selected: false }
),
}));
}}
/>
)}
keyExtractor={(item, index) => `sub${index}`}
/>
</>
)}
<View
style={[
styles.rowContainer,
{ marginTop: 12 },
{ marginRight: Platform.OS === 'android' ? -4 : 0 },
]}
>
<Text style={[theme.modalText, theme.textDark]}>Power</Text>
<Switch value={this.state.isPowerOn} onValueChange={this.togglePower} />
</View>
<View style={[styles.rowContainer, theme.mt2, { marginRight: Platform.OS === 'android' ? -4 : 0 }]}>
<Text style={[theme.modalText, theme.textDark]}>Active</Text>
<Switch value={this.state.isActive} onValueChange={this.toggleActive} />
</View>
<View style={theme.mt2}>
<Text style={[theme.modalText, theme.textDark, { marginBottom: 10 }]}>Repeat</Text>
<FlatList
data={this.state.repeatOn}
extraData={this.props}
contentContainerStyle={[styles.dayContainer, { marginTop: 10 }]}
keyExtractor={(item, index) => `days${item.day}`}
renderItem={({ item, index }) => {
let dynamicColor = this.state.repeatOn[index].isRepeat ? color.primary : color.grey;
return (
<View style={{ borderRadius: 20, width: 40, height: 40 }}>
<TouchableWithoutFeedback
onPress={() => this.toggleRepeatDays(index)}
// background={TouchableNativeFeedback.Ripple(color.lightRed, true)}
>
<View style={[styles.dayBtn, { borderColor: dynamicColor }]}>
<Text style={[theme.modalText, { color: dynamicColor }]}>
{item.day.substr(0, 1)}
</Text>
</View>
</TouchableWithoutFeedback>
</View>
);
}}
/>
</View>
<View
style={{
marginTop: 30,
marginBottom: 10,
flexDirection: 'row',
justifyContent: 'space-evenly',
alignSelf: 'flex-end',
}}
>
<Button
transparent
style={{ flex: 1, justifyContent: 'center' }}
onPress={() => {
this.resetStateAndProps();
this.props.setEditModalVisible(false);
}}
>
<Text uppercase={false} style={[theme.modalBtnText, { color: color.grey }]}>
Cancel
</Text>
</Button>
<Button
rounded
style={{
flex: 1,
justifyContent: 'center',
backgroundColor: color.primary,
}}
onPress={this.createNewOrEditTimer}
>
<Text uppercase={false} style={[theme.modalBtnText, { color: color.white }]}>
Confirm
</Text>
</Button>
</View>
</ScrollView>
</>
);
};
renderFilterModal = () => {
return (
<>
<View style={styles.dragIndicator} />
<View
style={{ paddingTop: 20, paddingBottom: 18, paddingHorizontal: 25, backgroundColor: color.white }}
>
<View style={styles.filterHeaderContainer}>
<Text style={[theme.smallTitle, theme.textDark]}>Reset</Text>
<Text style={[theme.smallTitle, theme.textDark]}>Filters</Text>
<Text
style={[theme.smallTitle, theme.textDanger]}
onPress={() => this.setState({ isfilterVisible: false })}
>
Done
</Text>
</View>
<Text style={[theme.smallTitle, theme.textDanger, theme.mt2]}>Select Breaker</Text>
<View style={styles.pickerContainer}>
<RNPickerSelect
items={this.state.pickerSelectData}
onValueChange={(value, index) => {
this.setState({ selectedBreaker: value });
}}
useNativeAndroidPickerStyle={false}
placeholder={{ label: 'Select...', value: null }}
style={pickerStyle}
Icon={() => <Icon name="ios-arrow-down" style={{ fontSize: 14, color: '#c8c8c8' }} />}
/>
</View>
<FlatList
style={theme.mt2}
data={this.state.subBreakerList}
ListEmptyComponent={() => (
<View>
<Text style={[theme.modalText, theme.mt2]}>No Sub breaker</Text>
</View>
)}
ItemSeparatorComponent={() => <View style={theme.mt1} />}
renderItem={({ item, index }) => (
<CheckBox
containerStyle={styles.checkboxContainer}
fontFamily={'Avenir-Roman'}
textStyle={{ fontWeight: 'normal', color: color.darkGrey }}
title={`Sub Breaker ${item.id} ${item.name ? `[${item.name}]` : ''}`}
checked={this.state.subBreakerList[index].selected}
checkedIcon={<Icon name="md-checkbox" style={{ color: color.primary, fontSize: 26 }} />}
uncheckedIcon={
<Icon name="md-square-outline" style={{ color: color.grey, fontSize: 26 }} />
}
onPress={() => {
this.setState(prevState => ({
subBreakerList: prevState.subBreakerList.map((el, elementIndex) =>
elementIndex === index
? {
...el,
selected: !this.state.subBreakerList[index].selected,
}
: { ...el }
),
}));
}}
/>
)}
keyExtractor={(item, index) => `sub${index}`}
/>
</View>
</>
);
};
render() {
return (
<>
{/* Search Bar */}
<View style={{ marginTop: 10, padding: 15, flexDirection: 'row', alignItems: 'center' }}>
<SearchBar
containerStyle={styles.searchBarContainer}
inputContainerStyle={styles.searchBarInputContainer}
inputStyle={styles.searchBarInput}
round
lightTheme
placeholder="Search..."
onChangeText={this.updateSearch}
value={this.state.search}
/>
<Icon
name="md-funnel"
style={{ color: '#c7cad1', fontSize: 20, marginLeft: 10, marginRight: 5 }}
onPress={() => this.setState({ isfilterVisible: true })}
/>
</View>
{/* List Timer */}
<FlatList
contentContainerStyle={{ paddingBottom: isIphoneX() ? 90 : 55 }}
data={this.state.search ? this.state.data : this.props.allTimers}
refreshing={this.props.isLoading}
onRefresh={this.props.getTimers}
ListEmptyComponent={() => (
<View>
<Text style={[theme.modalText, theme.mt2]}>No timers</Text>
</View>
)}
ItemSeparatorComponent={() => <View style={styles.separator} />}
renderItem={({ item, index }) => (
<SwipeableRow item={item} index={index} onSwipeOpen={this.autoCloseSwipeRow} />
)}
keyExtractor={(item, index) => `timer${item.key}`}
/>
{/* Create & Update Timer Modal */}
<Modal
transparent
presentationStyle={'overFullScreen'}
animationType="fade"
visible={this.state.isAddVisible || this.props.isEditVisible}
>
<Modal2
swipeArea={45}
swipeThreshold={65}
backdropPressToClose={false}
style={[styles.modal]}
position={'bottom'}
isOpen={this.state.isAddVisible || this.props.isEditVisible}
onClosed={() => {
this.resetStateAndProps();
this.props.setEditModalVisible(false);
}}
>
{this.renderAddAndEditTimerModal()}
</Modal2>
</Modal>
{/* Filter Modal */}
<Modal
transparent
presentationStyle={'overFullScreen'}
animationType="fade"
visible={this.state.isfilterVisible}
>
<Modal2
swipeArea={45}
swipeThreshold={65}
backdropPressToClose={false}
style={[styles.filterModal]}
position={'bottom'}
isOpen={this.state.isfilterVisible}
onClosed={() => {
this.setState({ isfilterVisible: false });
}}
>
{this.renderFilterModal()}
</Modal2>
</Modal>
</>
);
}
}
const mapStateToProps = state => ({
existedData: state.timersReducer.existedData,
allTimers: state.timersReducer.allTimers,
selectedTimerData: state.timersReducer.selectedTimerData,
isLoading: state.timersReducer.isLoading,
isEditVisible: state.timersReducer.isEditVisible,
});
const mapDispatchToProps = {
getTimers,
getSelectedTimerData,
setEditModalVisible,
createNewTimer,
editTimer,
deleteTimer,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(TimerScreen);
const pickerStyle = {
inputIOS: {
color: color.darkGrey,
fontFamily: 'Avenir-Roman',
},
iconContainer: {
top: Platform.OS === 'android' ? 7 : undefined,
right: 0,
},
inputAndroid: {
height: 22,
fontFamily: 'Avenir-Roman',
fontSize: 16,
paddingVertical: 0,
marginTop: 4,
},
};
const styles = StyleSheet.create({
searchBarContainer: {
flex: 1,
display: 'flex',
backgroundColor: 'transparent',
height: 33,
paddingVertical: 0,
borderTopWidth: 0,
borderBottomWidth: 0,
},
searchBarInputContainer: {
borderWidth: 1,
borderBottomWidth: 1,
backgroundColor: 'transparent',
minHeight: 10,
height: 33,
borderColor: '#c7cad1',
},
searchBarInput: { fontFamily: 'Avenir-Roman', fontSize: 14, color: color.grey, marginTop: 3 },
separator: {
marginHorizontal: 10,
height: StyleSheet.hairlineWidth,
backgroundColor: 'rgb(200, 199, 204)',
},
rowContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
},
dayContainer: {
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
},
dayBtn: {
width: 40,
height: 40,
borderWidth: 1,
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
},
filterModal: {
height: height * 0.7,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
},
filterHeaderContainer: {
...theme.rowContainer,
justifyContent: 'space-between',
paddingBottom: 10,
borderBottomColor: 'rgba(189, 192, 200, 0.3)',
borderBottomWidth: 1,
},
checkboxContainer: {
borderColor: 'transparent',
backgroundColor: color.white,
padding: 0,
margin: 0,
},
modal: {
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
height: height * 0.9,
},
dragIndicator: {
marginTop: 10,
width: 50,
height: 5,
borderRadius: 3,
backgroundColor: color.grey,
display: 'flex',
alignSelf: 'center',
},
pickerContainer: {
...theme.mt2,
borderWidth: 1,
borderColor: '#dcdcdc',
borderRadius: 5,
padding: 10,
},
});
...@@ -6186,11 +6186,6 @@ react-native-safe-area-view@^0.14.1: ...@@ -6186,11 +6186,6 @@ react-native-safe-area-view@^0.14.1:
dependencies: dependencies:
debounce "^1.2.0" debounce "^1.2.0"
react-native-skeleton-loader@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/react-native-skeleton-loader/-/react-native-skeleton-loader-1.0.3.tgz#93fa1da5bc1cd73b862616695f44d383aeb0958a"
integrity sha512-rBLkfLkWDfKfJ5TPfX1wed5iaOsMYtv9zopjtxM8y11nq2J/KZfNKzcXNaSc42ncsjZD9HCqlEXTxYPiAD3IGQ==
react-native-status-bar-height@^2.2.0: react-native-status-bar-height@^2.2.0:
version "2.3.1" version "2.3.1"
resolved "https://registry.yarnpkg.com/react-native-status-bar-height/-/react-native-status-bar-height-2.3.1.tgz#b92ce9112c2367290847ac11284d9d84a6330169" resolved "https://registry.yarnpkg.com/react-native-status-bar-height/-/react-native-status-bar-height-2.3.1.tgz#b92ce9112c2367290847ac11284d9d84a6330169"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment