src/components/views/reportlost-view.js
import React, {Component} from 'react';
import { StyleSheet, Text, View, TouchableOpacity, TouchableHighlight, ScrollView, Alert, Button } from 'react-native';
import ModalDropdown from 'react-native-modal-dropdown';
import { TextInput } from 'react-native-paper';
import { HeaderBackButton } from 'react-navigation';
import { styles, colours, reportlost_styles } from './stylesheets/reportlost-styles';
import ReportLostPresenter from '../presenters/reportlost-presenter';
import BaseView from './view';
/**
* Class for the reportlost view
* @extends BaseView
*/
class ReportLostView extends BaseView {
/**
* Creates an instance of the report lost view
*
* @constructor
* @param {Object} props - Component properties
*/
constructor(props) {
super(props);
this.reportlostP = new ReportLostPresenter(this);
this.state = {
text: '',
bikeid: '',
bikeMenu: [],
};
}
/**
* Set the navigation options, change the header to handle a back button.
*
* @return {Object} Navigation option
*/
static navigationOptions = ({navigation, transitioning}) => {
const { params = {} } = navigation.state;
const back = params._onBack ? params._onBack : () => 'default';
return {
headerLeft: (<HeaderBackButton disabled={transitioning} onPress={()=>{back()}}/>),
};
}
/**
* Component is about to mount, initialize the data before rendering.
*/
componentWillMount = () => {
this.props.navigation.setParams({
_onBack: this._onBack,
});
this.setState({
bikeMenu: this.reportlostP.getNotStolen(this.reportlostP.getData())
});
const { navigation } = this.props;
const data = navigation.getParam('data', 'NO-DATA');
if (data && data !== "NO-DATA") {
const latitude = data.data.latitude ? data.data.latitude : 'NO-DATA';
const longitude = data.data.longitude ? data.data.longitude : 'NO-DATA';
this.setState({
latitude: latitude,
longitude: longitude
});
}
};
/**
* Component is aobut to unmount
*/
componentWillUnmount = () => {
this.viewUnmounting(this.reportlostP);
}
/**
* Back function to go back to the previous page.
*/
_onBack = () => {
this.props.navigation.navigate('Tabs');
}
/**
* Refreshes the state of the component so new data is fetched.
*/
refreshState = () => {
this.setState({
refresh: !this.state.refresh
});
}
/**
* handle the event after clicking submit.
*/
_handleClick() {
// console.log('bikeid is'+ this.state.bikeid);
if (this.state.bikeid=='') {
Alert.alert("Please select the bike!")
} else {
this.sendUpdate();
}
}
/**
* Get needed data from the view and send it to presenter.
*/
sendUpdate = () => {
// Extract data from components
let new_data = {
data: {
text:this.state.text,
bikeid: this.state.bikeid,
latitude: this.state.latitude,
longitude: this.state.longitude,
}
}
const data = new_data;
this.reportlostP.update(data,this.alertCallback);
}
/**
* Sets a callback on what to do if there is a success or error when a bike is uploaded.
*
* @param {Boolean} success - true: Uploading successful; false: Uploading failed
*/
alertCallback = (success) => {
this.refreshState();
if (success) {
Alert.alert(
"Report successfully uploaded!",
"",
[
{ text: "Ok", onPress: () => this.props.navigation.navigate('Tabs'), style: "ok" },
],
{ cancelable: false },
);
} else {
Alert.alert(
"Fail to report.",
"Please try again.",
[
{ text: "Ok", onPress: () => {}, style: "ok" },
],
{ cancelable: false },
);
}
}
/**
* Render the text of button.
* @param {Object} rowData - the row data of the bike menu
* @return {string} Returns the name of the component
*/
_dropdown_2_renderButtonText(rowData) {
const {name} = rowData;
return `${name}`;
}
/**
* Events after selecting the item from the dropdown menu
* @param {Number} idx - the id of the selected item in menu.
* @param {Object} value - the value of the selected item.
*/
_dropdown_2_onSelect = (idx,value) => {
this.setState({bikeid: `${value.id}`});
}
/**
* Render each row in the menu
* @param {Object} rowData - each data in bikemenu
* @param {Number} rowID - the id of item in the menu
* @param {Boolean} highlighted - Highlight the selected item.
*/
_dropdown_2_renderRow(rowData, rowID, highlighted) {
let evenRow = rowID % 2;
return (
<TouchableHighlight underlayColor='cornflowerblue'>
<View style={[reportlost_styles.dropdown_2_row, {backgroundColor: evenRow ? 'lemonchiffon' : 'white'}]}>
<Text style={[reportlost_styles.dropdown_2_row_text, highlighted && {color: colours.ppGreen}]}>
{`${rowData.name} `}
</Text>
</View>
</TouchableHighlight>
);
}
/**
* Renders a react native component.
*/
render() {
return (
<View style={styles.container}>
<View style={reportlost_styles.row1}>
<View style={reportlost_styles.cell}>
{/* ListView is deprecated in the ModalDropdown component. If it gets removed from ReactNative, switch libraries. */}
<ModalDropdown ref="dropdown_2"
style={reportlost_styles.dropdown_2}
textStyle={reportlost_styles.dropdown_2_text}
dropdownStyle={reportlost_styles.dropdown_2_dropdown}
options={this.state.bikeMenu}
defaultValue = "Please select your bike"
renderButtonText={(rowData) => this._dropdown_2_renderButtonText(rowData)}
renderRow={this._dropdown_2_renderRow.bind(this)}
onSelect={(idx,value) => this._dropdown_2_onSelect(idx,value)}/>
</View>
</View>
<TextInput style = {reportlost_styles.row2}
label="Describe the Condition"
multiline={true}
blurOnSubmit
onChangeText={(text) => this.setState({text})}>
</TextInput>
<View>
<TouchableHighlight style={reportlost_styles.submitButton} onPress={this._handleClick.bind(this)}>
<Button color={'#000'} title="SUBMIT"/>
</TouchableHighlight>
</View>
</View>
);
}
}
export default ReportLostView;