Reference Source

src/components/views/reportlost-view.js

  1. import React, {Component} from 'react';
  2. import { StyleSheet, Text, View, TouchableOpacity, TouchableHighlight, ScrollView, Alert, Button } from 'react-native';
  3. import ModalDropdown from 'react-native-modal-dropdown';
  4. import { TextInput } from 'react-native-paper';
  5. import { HeaderBackButton } from 'react-navigation';
  6.  
  7. import { styles, colours, reportlost_styles } from './stylesheets/reportlost-styles';
  8.  
  9. import ReportLostPresenter from '../presenters/reportlost-presenter';
  10. import BaseView from './view';
  11.  
  12. /**
  13. * Class for the reportlost view
  14. * @extends BaseView
  15. */
  16. class ReportLostView extends BaseView {
  17. /**
  18. * Creates an instance of the report lost view
  19. *
  20. * @constructor
  21. * @param {Object} props - Component properties
  22. */
  23. constructor(props) {
  24. super(props);
  25. this.reportlostP = new ReportLostPresenter(this);
  26. this.state = {
  27. text: '',
  28. bikeid: '',
  29. bikeMenu: [],
  30. };
  31. }
  32.  
  33. /**
  34. * Set the navigation options, change the header to handle a back button.
  35. *
  36. * @return {Object} Navigation option
  37. */
  38. static navigationOptions = ({navigation, transitioning}) => {
  39. const { params = {} } = navigation.state;
  40. const back = params._onBack ? params._onBack : () => 'default';
  41. return {
  42. headerLeft: (<HeaderBackButton disabled={transitioning} onPress={()=>{back()}}/>),
  43. };
  44. }
  45.  
  46. /**
  47. * Component is about to mount, initialize the data before rendering.
  48. */
  49. componentWillMount = () => {
  50. this.props.navigation.setParams({
  51. _onBack: this._onBack,
  52. });
  53.  
  54. this.setState({
  55. bikeMenu: this.reportlostP.getNotStolen(this.reportlostP.getData())
  56. });
  57. const { navigation } = this.props;
  58. const data = navigation.getParam('data', 'NO-DATA');
  59. if (data && data !== "NO-DATA") {
  60. const latitude = data.data.latitude ? data.data.latitude : 'NO-DATA';
  61. const longitude = data.data.longitude ? data.data.longitude : 'NO-DATA';
  62.  
  63. this.setState({
  64. latitude: latitude,
  65. longitude: longitude
  66. });
  67. }
  68. };
  69.  
  70. /**
  71. * Component is aobut to unmount
  72. */
  73. componentWillUnmount = () => {
  74. this.viewUnmounting(this.reportlostP);
  75. }
  76.  
  77. /**
  78. * Back function to go back to the previous page.
  79. */
  80. _onBack = () => {
  81. this.props.navigation.navigate('Tabs');
  82. }
  83.  
  84. /**
  85. * Refreshes the state of the component so new data is fetched.
  86. */
  87. refreshState = () => {
  88. this.setState({
  89. refresh: !this.state.refresh
  90. });
  91. }
  92.  
  93. /**
  94. * handle the event after clicking submit.
  95. */
  96. _handleClick() {
  97. // console.log('bikeid is'+ this.state.bikeid);
  98. if (this.state.bikeid=='') {
  99. Alert.alert("Please select the bike!")
  100. } else {
  101. this.sendUpdate();
  102. }
  103. }
  104.  
  105.  
  106. /**
  107. * Get needed data from the view and send it to presenter.
  108. */
  109. sendUpdate = () => {
  110. // Extract data from components
  111. let new_data = {
  112. data: {
  113. text:this.state.text,
  114. bikeid: this.state.bikeid,
  115. latitude: this.state.latitude,
  116. longitude: this.state.longitude,
  117. }
  118. }
  119. const data = new_data;
  120.  
  121. this.reportlostP.update(data,this.alertCallback);
  122. }
  123.  
  124. /**
  125. * Sets a callback on what to do if there is a success or error when a bike is uploaded.
  126. *
  127. * @param {Boolean} success - true: Uploading successful; false: Uploading failed
  128. */
  129. alertCallback = (success) => {
  130. this.refreshState();
  131. if (success) {
  132. Alert.alert(
  133. "Report successfully uploaded!",
  134. "",
  135. [
  136. { text: "Ok", onPress: () => this.props.navigation.navigate('Tabs'), style: "ok" },
  137. ],
  138. { cancelable: false },
  139. );
  140. } else {
  141. Alert.alert(
  142. "Fail to report.",
  143. "Please try again.",
  144. [
  145. { text: "Ok", onPress: () => {}, style: "ok" },
  146. ],
  147. { cancelable: false },
  148. );
  149. }
  150. }
  151.  
  152. /**
  153. * Render the text of button.
  154. * @param {Object} rowData - the row data of the bike menu
  155. * @return {string} Returns the name of the component
  156. */
  157. _dropdown_2_renderButtonText(rowData) {
  158. const {name} = rowData;
  159. return `${name}`;
  160. }
  161.  
  162. /**
  163. * Events after selecting the item from the dropdown menu
  164. * @param {Number} idx - the id of the selected item in menu.
  165. * @param {Object} value - the value of the selected item.
  166. */
  167. _dropdown_2_onSelect = (idx,value) => {
  168. this.setState({bikeid: `${value.id}`});
  169. }
  170.  
  171. /**
  172. * Render each row in the menu
  173. * @param {Object} rowData - each data in bikemenu
  174. * @param {Number} rowID - the id of item in the menu
  175. * @param {Boolean} highlighted - Highlight the selected item.
  176. */
  177. _dropdown_2_renderRow(rowData, rowID, highlighted) {
  178. let evenRow = rowID % 2;
  179. return (
  180. <TouchableHighlight underlayColor='cornflowerblue'>
  181. <View style={[reportlost_styles.dropdown_2_row, {backgroundColor: evenRow ? 'lemonchiffon' : 'white'}]}>
  182. <Text style={[reportlost_styles.dropdown_2_row_text, highlighted && {color: colours.ppGreen}]}>
  183. {`${rowData.name} `}
  184. </Text>
  185. </View>
  186. </TouchableHighlight>
  187. );
  188. }
  189.  
  190. /**
  191. * Renders a react native component.
  192. */
  193. render() {
  194. return (
  195. <View style={styles.container}>
  196. <View style={reportlost_styles.row1}>
  197. <View style={reportlost_styles.cell}>
  198. {/* ListView is deprecated in the ModalDropdown component. If it gets removed from ReactNative, switch libraries. */}
  199. <ModalDropdown ref="dropdown_2"
  200. style={reportlost_styles.dropdown_2}
  201. textStyle={reportlost_styles.dropdown_2_text}
  202. dropdownStyle={reportlost_styles.dropdown_2_dropdown}
  203. options={this.state.bikeMenu}
  204. defaultValue = "Please select your bike"
  205. renderButtonText={(rowData) => this._dropdown_2_renderButtonText(rowData)}
  206. renderRow={this._dropdown_2_renderRow.bind(this)}
  207. onSelect={(idx,value) => this._dropdown_2_onSelect(idx,value)}/>
  208. </View>
  209. </View>
  210. <TextInput style = {reportlost_styles.row2}
  211. label="Describe the Condition"
  212. multiline={true}
  213. blurOnSubmit
  214. onChangeText={(text) => this.setState({text})}>
  215. </TextInput>
  216. <View>
  217. <TouchableHighlight style={reportlost_styles.submitButton} onPress={this._handleClick.bind(this)}>
  218. <Button color={'#000'} title="SUBMIT"/>
  219. </TouchableHighlight>
  220. </View>
  221. </View>
  222. );
  223. }
  224.  
  225. }
  226.  
  227. export default ReportLostView;