import React from "react" import { StyleSheet, View, Image, ScrollView, Text, TextInput, KeyboardAvoidingView, Platform, TouchableOpacity, } from "react-native" import MapView, { Marker } from "react-native-maps" import { FormBinder } from "react-form-binder" import { BoundInput, BoundButton, BoundHeader, Icon, Header, BoundOptionStrip, BoundPhotoPanel, } from "../ui" import { MessageModal, WaitModal } from "../Modal" import autobind from "autobind-decorator" import { ifIphoneX, isIphoneX } from "react-native-iphone-x-helper" import KeyboardSpacer from "react-native-keyboard-spacer" import { api } from "../API" import "url-search-params-polyfill" import { config } from "../config" import { workItemTypeEnum, formatLatLng, parseLatLng } from "../util" const styles = StyleSheet.create({ container: { flexDirection: "column", flexGrow: 1, backgroundColor: "#DDDDDD", }, panel: { width: "94%", backgroundColor: "white", alignSelf: "center", marginTop: "3%", shadowColor: "gray", shadowOffset: { width: 2, height: 2 }, shadowRadius: 2, shadowOpacity: 0.5, padding: 10, }, }) export class WorkItem extends React.Component { static bindings = { header: { noValue: true, isDisabled: (r) => !(r.anyModified && r.allValid), }, location: { isValid: (r, v) => v !== "", isReadOnly: true, alwaysGet: true, }, address: { isValid: true, isReadOnly: true, }, photos: { isValid: (r, v) => v && v.length > 0, }, details: { isValid: (r, v) => v !== "", }, workItemType: { isValid: (r, v) => v !== "", alwaysGet: true, }, } constructor(props) { super(props) region = { latitude: 43.653908, longitude: -79.384293, latitudeDelta: 0.0922, longitudeDelta: 0.0421, } this.state = { binder: new FormBinder({}, WorkItem.bindings), messageModal: null, waitModal: null, region, } const { search } = this.props.location if (search) { const id = new URLSearchParams(search).get("id") if (id) { api .getWorkItem(id) .then((workItem) => { if (workItem) { const [lng, lat] = workItem.location.coordinates const region = { latitude: lat, longitude: lng, latitudeDelta: 0.01, longitudeDelta: 0.01, } workItem.location = formatLatLng(lat, lng) this.setState({ binder: new FormBinder(workItem, WorkItem.bindings), region, }) } }) .catch((err) => { this.setState({ messageModal: { icon: "hand", message: "Unable to get work item details", detail: err.message, back: true, }, }) }) } } } componentWillUnmount() { if (this.geoCodeTimer) { clearTimeout(this.geoCodeTimer) } } @autobind handleBackPress() { const { history } = this.props if (history.length > 1) { history.goBack() } else { history.replace("/home") } } @autobind handleDonePress() { const { binder } = this.state let obj = binder.getModifiedFieldValues() obj.location = parseLatLng(obj.location) if (!obj._id) { api .createWorkItem(obj) .then((workItem) => { this.handleBackPress() }) .catch((error) => { this.setState({ messageModal: { icon: "hand", message: "Unable to create work item", detail: error.message, }, }) }) } else { api .updateWorkItem(obj) .then((workItem) => { this.handleBackPress() }) .catch((error) => { this.setState({ messageModal: { icon: "hand", message: "Unable to update work item", detail: error.message, }, }) }) } } @autobind handleMessageDismiss() { const back = this.state.messageModal.back this.setState({ messageModal: null }) if (back) { this.handleBackPress() } } @autobind handleRegionChange(region) { const { latitude, longitude } = region if (this.latLngInput) { this.latLngInput.handleChangeText(formatLatLng(latitude, longitude)) } if (this.geoCodeTimer) { clearTimeout(this.geoCodeTimer) this.geoCodeTimer = null } this.geoCodeTimer = setTimeout( () => this.handleStartAddressLookup({ latitude, longitude }), config.geocodeDelayMilliseconds ) } @autobind handleStartAddressLookup(latLng) { api .getAddress(latLng) .then((address) => { if (this.addressInput) { this.addressInput.handleChangeText(address) } }) .catch(() => { if (this.addressInput) { this.addressInput.handleChangeText("") } }) } @autobind handleUploadStarted() { this.setState({ waitModal: { message: "Uploading Photo..." } }) } @autobind handleUploadEnded() { this.setState({ waitModal: null }) } render() { const { binder, messageModal, waitModal, region } = this.state return ( (this.mapView = ref)} style={{ flexDirection: "column", justifyContent: "center", width: "100%", height: 400, marginBottom: 10, }} showsBuildings={false} showsTraffic={false} showsIndoors={false} zoomControlEnabled={false} rotateEnabled={false} region={region} onRegionChange={this.handleRegionChange} /> (this.latLngInput = ref)} binder={binder} name="location" label="Location:" /> (this.addressInput = ref)} binder={binder} name="address" label="Address:" /> {isIphoneX ? : null} {Platform.OS === "ios" && } ) } }