Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2. import {
  3.   View, StyleSheet, Text, TouchableOpacity,
  4.   TouchableNativeFeedback, TimePickerAndroid, Platform, SafeAreaView,
  5.   DatePickerIOS, Dimensions, Modal, ActivityIndicator, KeyboardAvoidingView
  6. } from 'react-native';
  7. import { connect } from 'react-redux';
  8. import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
  9. import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
  10. import { ScrollView } from 'react-native-gesture-handler';
  11. import MapView from 'react-native-maps';
  12.  
  13. import PlaceAutoComplete from '../components/PlaceAutoComplete';
  14. import CustomInput from '../components/CustomInput';
  15. import TimeInput from '../components/TimeInput';
  16. import Label from '../components/Label';
  17. import Color from '../constants/Colors';
  18. import firebase from '../data/firebase';
  19. import { BoldText, RegularText } from '../components/StyledText';
  20. import { Collections } from '../constants/Collection';
  21. import Actions from '../state/Actions';
  22. import { UserHelper } from '../state/Records';
  23.  
  24. const { width, height } = Dimensions.get('screen');
  25.  
  26. export const styles = StyleSheet.create({
  27.   container: {
  28.     flex: 1,
  29.     padding: 16,
  30.     backgroundColor: '#fafafa'
  31.   },
  32.   map:{
  33.     position: 'absolute',
  34.     top: 0,
  35.     left: 0,
  36.     right: 0,
  37.     bottom: 0,
  38.     height: 200
  39.   },
  40.   btnText: { textAlign: 'center', fontWeight: 'bold', color: '#fff' },
  41.   button: { paddingVertical: 12, marginHorizontal: 16, marginVertical: 8, paddingHorizontal: 16, borderRadius: 16, backgroundColor: Color.primary }
  42. });
  43.  
  44. const Prayers = ["Jummah", "Fazr", "Zuhr", "Asar", "Magrib", "Esha"];
  45.  
  46. @connect(state => ManageMosqueScreen.setProps(state))
  47. class ManageMosqueScreen extends React.Component {
  48.  
  49.   constructor(props) {
  50.     super(props);
  51.     this.state = this.getInitialState();
  52.     const { navigation: { state: { params } } } = this.props;
  53.     if (params && params.Mosque) {
  54.       this.state.input = params.Mosque;
  55.       this.state.isEdit = true;
  56.     }
  57.   }
  58.  
  59.   static setProps(state) {
  60.     return {
  61.       user: state.currentUser
  62.     };
  63.   }
  64.  
  65.  
  66.   getInitialState() {
  67.     return {
  68.       isSaving: false,
  69.       isSuccess: false,
  70.       error: null,
  71.       input: {
  72.         name: '',
  73.         description: '',
  74.         address: {
  75.  
  76.         },
  77.         prayers: {
  78.  
  79.         }
  80.       },
  81.       prayerKey: null
  82.     };
  83.   }
  84.  
  85.   resetScreen() {
  86.     this.setState(this.getInitialState());
  87.   }
  88.  
  89.   handleInput(key, value) {
  90.     const { input } = this.state;
  91.     input[key] = value;
  92.     this.setState({ input, error: null });
  93.   }
  94.  
  95.   async updateToFirebase() {
  96.     const { input, isSaving } = this.state;
  97.     const { user } = this.props;
  98.     if(isSaving){
  99.       return;
  100.     }
  101.     const { name, description, address, prayers } = input;
  102.     if (name.trim().length === 0) {
  103.       this.setState({ error: 'Name must be provided.' });
  104.       return;
  105.     }
  106.     if (description.trim().length === 0) {
  107.       this.setState({ error: 'Description must be provided.' });
  108.       return;
  109.     }
  110.     if (!address) {
  111.       this.setState({ error: 'Please select location from dropdown.' });
  112.       return;
  113.     }
  114.     this.setState({ isSaving: true, error: null });
  115.     try {
  116.       const mosque = {
  117.         ...input,
  118.         accepted: UserHelper.isEditor(user),
  119.         addedBy: user.email
  120.       }
  121.       const newAddr = {
  122.         geo:{
  123.           location:{
  124.             lat:mosque.address.latitude,
  125.             lng:mosque.address.longitude
  126.           },
  127.           name:mosque.address.name
  128.         }
  129.       }
  130.       mosque.address = newAddr;
  131.       const response = await firebase.firestore
  132.           .collection(Collections.Mosques)
  133.           .doc(this.state.input.id).update(mosque);
  134.           this.setState({ isSuccess: true });
  135.           this.props.dispatch(Actions.updateMosque(mosque));
  136.     }catch(err) {
  137.       console.log(err);
  138.     }
  139.     this.setState({isSaving:false});
  140.     }
  141.  
  142.  
  143.   async saveToFirebase() {
  144.     const { input, isSaving } = this.state;
  145.     const { user } = this.props;
  146.     if (isSaving) {
  147.       return;
  148.     }
  149.     const { name, description, address, prayers } = input;
  150.     if (name.trim().length === 0) {
  151.       this.setState({ error: 'Name must be provided.' });
  152.       return;
  153.     }
  154.     if (description.trim().length === 0) {
  155.       this.setState({ error: 'Description must be provided.' });
  156.       return;
  157.     }
  158.     if (!address || !address.latitude) {
  159.       this.setState({ error: 'Please select location from dropdown.' });
  160.       return;
  161.     }
  162.     this.setState({ isSaving: true, error: null });
  163.     try {
  164.       const mosque = {
  165.         ...input,
  166.         accepted: UserHelper.isEditor(user),
  167.         addedBy: user.email
  168.       };
  169.       const newAddr = {
  170.         geo:{
  171.           location:{
  172.             lat:mosque.address.latitude,
  173.             lng:mosque.address.longitude
  174.           },
  175.           name:mosque.address.name
  176.         }
  177.       }
  178.       mosque.address = newAddr;
  179.       const response = await firebase.firestore
  180.         .collection(Collections.Mosques)
  181.         .add(mosque);
  182.       mosque.id = response.id;
  183.       this.setState({ isSuccess: true });
  184.       this.props.dispatch(Actions.addMosque(mosque));
  185.     } catch (exp) {
  186.       this.setState({ error: exp.message });
  187.     }
  188.     this.setState({ isSaving: false });
  189.   }
  190.  
  191.   async showPrayerTimeSetter(name) {
  192.     if (Platform.OS === 'android') {
  193.       try {
  194.         const time = await TimePickerAndroid.open();
  195.         if (time.action != TimePickerAndroid.dismissedAction) {
  196.           const date = new Date();
  197.           date.setHours(time.hour < 10 ? '0' + time.hour : time.hour);
  198.           date.setMinutes(time.minute < 10 ? '0' + time.minute : time.minute);
  199.           this.setPrayerTime(name, date);
  200.         }
  201.       } catch (exp) {
  202.         this.setState({ error: exp.message });
  203.       }
  204.     } else {
  205.       this.setState({ prayerKey: name });
  206.     }
  207.   }
  208.  
  209.   setPrayerTime(name, date) {
  210.     const { input } = this.state;
  211.     const hour = date.getHours();
  212.     const min = date.getMinutes();
  213.     input.prayers[name] = {
  214.       date,
  215.       time: [hour < 10 ? '0' + hour : hour, min < 10 ? '0' + min : min].join(':')
  216.     };
  217.     this.setState({ input });
  218.   }
  219.  
  220.   setLocation(details: object, which: string) {
  221.     this.handleInput('address', details);
  222.   }
  223.  
  224.   render() {
  225.     const { input: { name, prayers, description, address }, prayerKey, error, isSaving, isSuccess } = this.state;
  226.     if (isSuccess) {
  227.       return (
  228.         <View style={styles.container}>
  229.           <View style={{ backgroundColor: '#f7f7f7', justifyContent: 'center', flex: 1, padding: 16, alignItems: 'center' }}>
  230.             <MaterialIcons style={{ fontSize: 48, color: 'green', marginBottom: 16 }} name="check-circle" />
  231.             <BoldText style={{ marginBottom: 8 }}>Success!</BoldText>
  232.             <RegularText>'{name}' has been saved.</RegularText>
  233.             <TouchableOpacity activeOpacity={.85} style={[styles.button, { minWidth: 200 }]} onPress={() => this.resetScreen()}>
  234.               <Text style={{ textAlign: 'center', fontWeight: 'bold', color: '#fff' }}>Add another</Text>
  235.             </TouchableOpacity>
  236.           </View>
  237.         </View>
  238.       );
  239.     }
  240.     return (
  241.       <SafeAreaView style={{ flex: 1 }}>
  242.         {/* <KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}> */}
  243.           <ScrollView style={styles.container} keyboardShouldPersistTaps="always">
  244.             <View style={{ flex: 1 }}>
  245.               <CustomInput
  246.                 label="Name"
  247.                 value={name}
  248.                 onChangeText={(name) => this.handleInput('name', name)} />
  249.               <CustomInput
  250.                 label="Description"
  251.                 value={description}
  252.                 multiline={true}
  253.                 onChangeText={(description) => this.handleInput('description', description)} />
  254.               <Label>Prayer time</Label>
  255.               <View style={{ marginBottom: 8, backgroundColor: '#fff', padding: 8 }}>
  256.                 {
  257.                   Prayers.map(
  258.                     (name) => (
  259.                       <TimeInput
  260.                         value={prayers[name] && prayers[name].time}
  261.                         key={name}
  262.                         name={name}
  263.                         onClick={() => this.showPrayerTimeSetter(name)} />
  264.                     )
  265.                   )
  266.                 }
  267.               </View>
  268.               <Label>Address</Label>
  269.               <PlaceAutoComplete
  270.                 place={address}
  271.                 label='Address'
  272.                 placeholder='Chooose Address'
  273.                 which='address'
  274.                 setLocation={this.setLocation.bind(this)} />
  275.               {
  276.                 error && <BoldText style={{ color: 'red', marginTop: 8 }}>{error}</BoldText>
  277.               }
  278.               {
  279.                 this.state.input.address && this.state.input.address.latitude != null  ? (
  280.               <View style={{ padding: 120}}>
  281.                 <MapView
  282.                       style={styles.map}
  283.                       loadingBackgroundColor="#f9f5ed"
  284.                       showsUserLocation
  285.                       provider="google"
  286.                       initialRegion={{
  287.                         latitude: 26.667105900000003 ,
  288.                         longitude: 88.4188101,
  289.                         longitudeDelta: 0.0034,
  290.                         latitudeDelta: 0.0043,
  291.                       }}
  292.                       region={{
  293.                         latitude: this.state.input.address.latitude,
  294.                         longitude: this.state.input.address.longitude,
  295.                         longitudeDelta: 0.0034,
  296.                         latitudeDelta: 0.0043,
  297.                       }}
  298.                       >
  299.                       <View style={{}}>
  300.  
  301.                       </View>
  302.                         <MapView.Marker
  303.                               draggable
  304.                               onDragEnd={(e) => {
  305.                                 const {latitude, longitude} = e.nativeEvent.coordinate;
  306.                                 console.log(latitude+" "+longitude);
  307.                                 newObj =  this.state;
  308.                                 newObj.input.address.latitude = latitude;
  309.                                 newObj.input.address.longitude = longitude;
  310.                                 this.setState(newObj);
  311.                                 console.log(this.state);
  312.                               }}
  313.                               pinColor={'green'}
  314.                               coordinate={{ latitude: this.state.input.address.latitude, longitude: this.state.input.address.longitude }}
  315.                               title={name}
  316.                             />
  317.                   </MapView>
  318.               </View>
  319.              
  320.                 ):(
  321.                   <View style={{padding:16}}>
  322.                     <Text>Please Select Location From Above Map</Text>
  323.                   </View>
  324.                 )
  325.  
  326.               }
  327.              
  328.               <Modal
  329.                 visible={Platform.OS === 'ios' && prayerKey != null}
  330.                 onRequestClose={() => this.setState({ prayerKey: null })}
  331.                 transparent
  332.                 style={{ zIndex: 111, justifyContent: 'flex-end' }}
  333.                 animationType="slide"
  334.               >
  335.                 <View style={{ flex: 1, backgroundColor: 'transparent' }} />
  336.                 <View style={{ padding: 16, backgroundColor: '#fff' }}>
  337.                   <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
  338.                     <Text style={{ fontWeight: 'bold', paddingVertical: 8 }}>{prayerKey}</Text>
  339.                     <View style={{ width: 16 }} />
  340.                     <TouchableOpacity activeOpacity={.85} onPress={() => this.setState({ prayerKey: null })}>
  341.                       <Text style={{ paddingVertical: 8, color: 'blue', textAlign: 'right' }}>DONE</Text>
  342.                     </TouchableOpacity>
  343.                   </View>
  344.                   <DatePickerIOS
  345.                     mode='time'
  346.                     date={prayers[prayerKey] && prayers[prayerKey].date || new Date()}
  347.                     style={{ zIndex: 9999 }}
  348.                     onDateChange={(date) => {
  349.                       this.setPrayerTime(prayerKey, date);
  350.                     }}
  351.                   />
  352.                 </View>
  353.               </Modal>
  354.             </View>
  355.           </ScrollView>
  356.           <TouchableOpacity
  357.             onPress={() =>  {
  358.              if(!isSaving && this.state.isEdit){
  359.               return this.updateToFirebase();
  360.              } else if(!isSaving ){
  361.               return this.saveToFirebase();
  362.              }
  363.             }}
  364.             activeOpacity={.85}
  365.             style={styles.button}
  366.           >
  367.             {
  368.               !isSaving && <Text style={styles.btnText}>Save</Text>
  369.             }
  370.             {
  371.               isSaving && <ActivityIndicator />
  372.             }
  373.           </TouchableOpacity>
  374.         {/* </KeyboardAvoidingView> */}
  375.       </SafeAreaView>
  376.     );
  377.   }
  378. }
  379.  
  380. export default ManageMosqueScreen;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement