257 lines
6.9 KiB
JavaScript
257 lines
6.9 KiB
JavaScript
import React from "react"
|
|
import {
|
|
StyleSheet,
|
|
Text,
|
|
TextInput,
|
|
SectionList,
|
|
Image,
|
|
View,
|
|
TouchableOpacity,
|
|
} from "react-native"
|
|
import MapView, { Marker } from "react-native-maps"
|
|
import { Icon, Header } from "../ui"
|
|
import { api } from "../API"
|
|
import autobind from "autobind-decorator"
|
|
import { ifIphoneX } from "react-native-iphone-x-helper"
|
|
import { workItemTypeText, pad } from "../util"
|
|
import pinImage from "./images/pin.png"
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: "#FFFFFF",
|
|
alignItems: "flex-start",
|
|
justifyContent: "flex-start",
|
|
},
|
|
})
|
|
|
|
export class Home extends React.Component {
|
|
constructor(props) {
|
|
super(props)
|
|
this.state = {
|
|
sections: [],
|
|
}
|
|
api
|
|
.listWorkItemActivities()
|
|
.then((list) => {
|
|
this.setState({ sections: list.items })
|
|
})
|
|
.catch((err) => {
|
|
console.error(err)
|
|
})
|
|
}
|
|
|
|
@autobind
|
|
_handleNavigatorEvent(event) {
|
|
switch (event.id) {
|
|
case "logout":
|
|
api.logout().then(() => {
|
|
this.props.history.replace("/login")
|
|
})
|
|
break
|
|
case "viewer":
|
|
this.props.push("/viewer")
|
|
break
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleMarkerPress(e, sectionIndex) {
|
|
if (this.sectionList) {
|
|
this.sectionList.scrollToLocation({
|
|
sectionIndex,
|
|
itemIndex: 0,
|
|
viewOffset: 45,
|
|
})
|
|
}
|
|
}
|
|
|
|
@autobind
|
|
handleWorkItemsListPress() {
|
|
this.props.history.push("/workitemlist")
|
|
}
|
|
|
|
@autobind
|
|
handleItemSelect(item, index) {
|
|
this.props.history.push("/activity")
|
|
}
|
|
|
|
@autobind
|
|
handleLogoutPress() {
|
|
this.props.history.replace("/logout")
|
|
}
|
|
|
|
@autobind
|
|
handleGlassesPress() {
|
|
this.props.history.push("/arviewer")
|
|
}
|
|
|
|
@autobind
|
|
handleMyLocationPress() {
|
|
navigator.geolocation.getCurrentPosition((info) => {
|
|
if (this.map) {
|
|
this.map.animateToCoordinate({
|
|
latitude: info.coords.latitude,
|
|
longitude: info.coords.longitude,
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
render() {
|
|
const { sections } = this.state
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<Header
|
|
title="Work Item Map"
|
|
leftButton={{ icon: "logout", onPress: this.handleLogoutPress }}
|
|
rightButton={{ icon: "glasses", onPress: this.handleGlassesPress }}
|
|
/>
|
|
<MapView
|
|
ref={(ref) => {
|
|
this.map = ref
|
|
}}
|
|
style={{
|
|
width: "100%",
|
|
height: "50%",
|
|
}}
|
|
showsUserLocation
|
|
showsBuildings={false}
|
|
showsTraffic={false}
|
|
showsIndoors={false}
|
|
zoomControlEnabled
|
|
initialRegion={{
|
|
latitude: 43.653908,
|
|
longitude: -79.384293,
|
|
latitudeDelta: 0.0922,
|
|
longitudeDelta: 0.0922,
|
|
}}>
|
|
{sections.map((workItem, index) => (
|
|
<Marker
|
|
key={index}
|
|
coordinate={workItem.coordinate}
|
|
title={
|
|
pad(workItem.ticketNumber, 4) +
|
|
": " +
|
|
workItemTypeText[workItem.workItemType]
|
|
}
|
|
description={workItem.address}
|
|
anchor={{ x: 0.5, y: 1.0 }}
|
|
image={pinImage}
|
|
onPress={(e) => this.handleMarkerPress(e, index)}
|
|
/>
|
|
))}
|
|
</MapView>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
width: "100%",
|
|
height: 40,
|
|
backgroundColor: "white",
|
|
}}>
|
|
<Icon
|
|
name="search"
|
|
size={16}
|
|
style={{ marginLeft: 10, marginRight: 5, tintColor: "gray" }}
|
|
/>
|
|
<TextInput
|
|
style={{ flexGrow: 1, flexBasis: 0, height: "100%" }}
|
|
underlineColorAndroid="white"
|
|
placeholder="Search"
|
|
/>
|
|
<Icon
|
|
name="cancel"
|
|
size={16}
|
|
style={{ marginLeft: 5, marginRight: 10, tintColor: "gray" }}
|
|
/>
|
|
</View>
|
|
<SectionList
|
|
ref={(ref) => (this.sectionList = ref)}
|
|
style={{ width: "100%", flexGrow: 1 }}
|
|
sections={sections}
|
|
stickySectionHeadersEnabled={true}
|
|
renderSectionHeader={({ section: workItem }) => (
|
|
<View
|
|
key={workItem._id}
|
|
style={{
|
|
flexDirection: "column",
|
|
justifyContent: "center",
|
|
backgroundColor: "#F4F4F4",
|
|
paddingLeft: 8,
|
|
height: 45,
|
|
}}>
|
|
<Text style={{ fontSize: 16 }}>
|
|
{workItemTypeText[workItem.workItemType].toUpperCase()}{" "}
|
|
{pad(workItem.ticketNumber, 4)}
|
|
</Text>
|
|
</View>
|
|
)}
|
|
keyExtractor={(item) => item._id}
|
|
renderItem={({ item: activity, section }) => {
|
|
return (
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
height: 50,
|
|
marginTop: 3,
|
|
marginBottom: 3,
|
|
}}>
|
|
<Text
|
|
style={{
|
|
fontSize: 8,
|
|
width: 45,
|
|
marginLeft: 5,
|
|
alignSelf: "center",
|
|
}}>
|
|
{activity.status.toUpperCase()}
|
|
</Text>
|
|
<View style={{ width: "75%", flexDirection: "column" }}>
|
|
<Text style={{ fontSize: 20, fontWeight: "bold" }}>
|
|
{activity.resolution}
|
|
</Text>
|
|
<Text style={{ fontSize: 14, color: "gray" }}>
|
|
{activity.address || "..."}
|
|
</Text>
|
|
</View>
|
|
<TouchableOpacity
|
|
style={{ alignSelf: "center" }}
|
|
onPress={() => this.handleItemSelect(activity, index)}>
|
|
<Icon name="rightArrow" size={16} />
|
|
</TouchableOpacity>
|
|
</View>
|
|
)
|
|
}}
|
|
/>
|
|
<View
|
|
style={{
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
width: "100%",
|
|
height: 45,
|
|
backgroundColor: "#F4F4F4",
|
|
...ifIphoneX({ marginBottom: 22 }, {}),
|
|
}}>
|
|
<TouchableOpacity onPress={this.handleMyLocationPress}>
|
|
<Icon
|
|
name="center"
|
|
size={24}
|
|
style={{ marginLeft: 15, tintColor: "gray" }}
|
|
/>
|
|
</TouchableOpacity>
|
|
<Text style={{ color: "gray", fontSize: 20 }}>Hide List</Text>
|
|
<TouchableOpacity onPress={this.handleWorkItemsListPress}>
|
|
<Icon
|
|
name="settings"
|
|
size={24}
|
|
style={{ marginRight: 15, tintColor: "gray" }}
|
|
/>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
)
|
|
}
|
|
}
|