Files
deighton-ar/mobile/src/Activity/Activity.js
John Lyon-Smith 9730c83c9c Bug fixing
2018-04-23 14:01:52 -07:00

279 lines
7.1 KiB
JavaScript

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 {
Icon,
Header,
BoundInput,
BoundButton,
BoundOptionStrip,
BoundHeader,
PhotoPanel,
} from "../ui"
import { MessageModal } from "../Modal"
import autobind from "autobind-decorator"
import KeyboardSpacer from "react-native-keyboard-spacer"
import { isIphoneX } from "react-native-iphone-x-helper"
import { api } from "../API"
import { formatLatLng, parseLatLng } from "../util"
import "url-search-params-polyfill"
const styles = StyleSheet.create({
container: {
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,
},
label: {
fontSize: 14,
marginBottom: 4,
},
})
export class Activity extends React.Component {
static bindings = {
header: {
noValue: true,
isDisabled: (r) => !(r.anyModified && r.allValid),
},
dateTime: {
isValid: (r, v) => v !== "",
isReadOnly: true,
},
details: {
isValid: (r, v) => v !== "",
},
resolution: {
isValid: (r, v) => v !== "",
},
notes: {
isValid: (r, v) => v !== "",
},
status: {
isValid: (r, v) => v !== "",
alwaysGet: true,
},
location: {
isValid: (r, v) => v !== "",
isReadOnly: true,
},
}
constructor(props) {
super(props)
this.state = {
binder: new FormBinder({}, Activity.bindings),
messageModal: null,
}
const { search } = this.props.location
if (search) {
const id = new URLSearchParams(search).get("id")
if (id) {
api
.getActivity(id)
.then((activity) => {
if (activity) {
const [lng, lat] = activity.location.coordinates
activity.location = formatLatLng(lat, lng)
this.setState({
binder: new FormBinder(activity, Activity.bindings),
region: {
latitude: lat,
longitude: lng,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
},
})
}
})
.catch((err) => {
this.setState({
messageModal: {
icon: "hand",
message: "Unable to get activity details",
detail: err.message,
back: true,
},
})
})
}
}
}
@autobind
handleMessageDismiss() {
const back = this.state.messageModal.back
this.setState({ messageModal: null })
if (back) {
this.handleBackPress()
}
}
@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()
if (!obj._id) {
api
.createActivity(obj)
.then((activity) => {
this.handleBackPress()
})
.catch((error) => {
this.setState({
messageModal: {
icon: "hand",
message: "Unable to create activity",
detail: error.message,
},
})
})
} else {
api
.updateActivity(obj)
.then((activity) => {
this.handleBackPress()
})
.catch((error) => {
this.setState({
messageModal: {
icon: "hand",
message: "Unable to update activity",
detail: error.message,
},
})
})
}
}
render() {
const { binder, messageModal, region } = this.state
return (
<View style={{ width: "100%", height: "100%" }}>
<BoundHeader
binder={binder}
name="header"
title="Activity"
leftButton={{ icon: "back", onPress: this.handleBackPress }}
rightButton={{ icon: "done", onPress: this.handleDonePress }}
/>
<ScrollView style={styles.container}>
<View style={styles.panel}>
<BoundInput binder={binder} name="resolution" label="Resolution:" />
</View>
<View style={styles.panel}>
<BoundOptionStrip
binder={binder}
options={[
{ value: "planned", text: "Planned" },
{ value: "open", text: "Open" },
{ value: "onHold", text: "On Hold" },
{ value: "closed", text: "Closed" },
]}
label="Status:"
name="status"
/>
</View>
<View style={styles.panel}>
<BoundInput binder={binder} name="notes" label="Notes:" />
</View>
<View style={styles.panel}>
<BoundInput
binder={binder}
name="dateTime"
label="Date &amp; Time:"
/>
<BoundInput binder={binder} name="location" label="Location:" />
<View style={{ flexDirection: "column", justifyContent: "center" }}>
<MapView
style={{
flexDirection: "column",
justifyContent: "center",
width: "100%",
height: 400,
marginTop: 10,
}}
zoomControlEnabled={false}
zoomEnabled={false}
scrollEnabled={false}
rotateEnabled={false}
pitchEnabled={false}
showsIndoors={false}
showsTraffic={false}
showsCompass={false}
showsScale={false}
showsUserLocation
cacheEnabled
initialRegion={{
latitude: 43.653908,
longitude: -79.384293,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
<Icon
name="target"
size={24}
pointerEvents={false}
style={{
position: "absolute",
alignSelf: "center",
}}
/>
</View>
</View>
<View style={styles.panel}>
<PhotoPanel />
</View>
{isIphoneX ? <View style={{ height: 30, width: "100%" }} /> : null}
</ScrollView>
<MessageModal
open={!!messageModal}
icon={messageModal ? messageModal.icon : ""}
message={messageModal ? messageModal.message : ""}
detail={messageModal ? messageModal.detail : ""}
onDismiss={messageModal && this.handleMessageDismiss}
/>
{Platform.OS === "ios" && <KeyboardSpacer />}
</View>
)
}
}