Commit a3612c55 authored by malai victor's avatar malai victor
Browse files

WIP

parent fb837106
......@@ -21,6 +21,7 @@ import {
DrawerItemList,
} from "@react-navigation/drawer";
import * as Location from "expo-location";
import Main from "./src/screens/Main/Main";
const theme = {
Button: {
......@@ -76,6 +77,11 @@ const RootDrawer = (props) => {
</>
) : (
<>
<Drawer.Screen
options={{ drawerLabel: "Main" }}
name="Main"
component={Main}
/>
<Drawer.Screen
options={{ drawerLabel: "View Requests" }}
name="Orders"
......@@ -177,15 +183,19 @@ const App = (props) => {
getAllOrders: async () => {
const getOrders = axios.get(`${API_URL}/order/gps`);
const getActiveOrders = axios.get(`${API_URL}/order`);
console.log('111');
axios
.all([getActiveOrders, getOrders])
.then(
axios.spread((...responses) => {
console.log('result');
const myOrders = responses[0].data.orders;
const inPr = responses[0].data.volunteer_orders;
const ordersGps = responses[1].data;
dispatch({ type: "SET_ORDERS", payload: [myOrders, inPr, ordersGps] });
console.log('RESULT ORDERS');
dispatch({ type: "SET_ORDERS", payload: [...myOrders, ...inPr, ...ordersGps] });
})
)
.catch((errors) => {
......
......@@ -21,6 +21,7 @@
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
"react-native-24h-timepicker": "^1.1.0",
"react-native-elements": "^1.2.7",
"react-native-gesture-handler": "~1.6.0",
"react-native-maps": "^0.27.1",
......
import * as React from "react";
import {View, StyleSheet, Dimensions, ScrollView, AsyncStorage, Alert, Image} from "react-native";
import MapView, {Marker} from "react-native-maps";
import {useContext} from "react";
import {AuthContext} from "../../../App";
import {createRef} from "react";
import {useState} from "react";
import {useEffect} from "react";
import * as Location from "expo-location";
import RequestForm from "./RequestForm";
import OrderDetailModal from "../../components/OrderDetailModal";
import AcceptActions from "../../components/AcceptActions";
import {Icon, Overlay} from "react-native-elements";
import axios from "axios";
import {API_URL} from "../../constants/constant";
import CreatedByActions from "../../components/CreatedByActions";
import AcceptedByActions from "../../components/AcceptedByActions";
const Help = ({navigation}) => {
const {state: {orders}, authContext: {getAllOrders}} = useContext(AuthContext);
const [overlayOrder, setOverlayOrder] = useState(false);
const [userId, setUserId] = useState();
const [location, setLocation] = useState(null);
const map = createRef();
useEffect(() => {
getUserLocation();
return () => {
authContext.backToScreen(null);
};
}, []);
const showModal = (order) => {
setOverlayOrder(order);
};
const getUserLocation = async () => {
let { status } = await Location.requestPermissionsAsync();
const user = JSON.parse(await AsyncStorage.getItem("user"));
setUserId(user.userId);
if (status !== "granted") {
}
let location = await Location.getCurrentPositionAsync({});
const { latitude, longitude } = location.coords;
setLocation({ latitude, longitude });
};
const onMapReady = () => {
if (orders.length === 0) {
return;
}
const locations = orders.map((order) => ({
latitude: order.latitude,
longitude: order.longitude,
}));
map.current.fitToCoordinates(locations, {
edgePadding: { top: 30, right: 30, bottom: 30, left: 30 },
animated: false,
});
};
const getMarkerColor = (order) => {
const {status} = order;
if (status === 'open') return "green";
if (status === 'canceled' || status === 'done') return "red";
if (status === 'in progress') return "yellow";
}
const onAccept = async (order) => {
const { token } = JSON.parse(await AsyncStorage.getItem("user"));
axios
.post(
`${API_URL}/order/${order.id}/accept`,
{},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
)
.then((res) => {
setOverlayOrder(false);
Alert.alert("Alert", "You are the hero. Go for it.", [
{
text: "OK",
onPress: () => getAllOrders(),
},
]);
})
.catch((err) => {
console.log(err.response);
});
};
const isCreatedByUser = () => {
if (!userId) return false;
return overlayOrder.created_by?.id === userId;
};
const isAcceptedByUser = () => {
if (!userId) return false;
return overlayOrder.accepted_by?.id === userId;
};
if (!location) return null;
return (
<View style={style.container}>
<Overlay
isVisible={!!overlayOrder}
onBackdropPress={() => setOverlayOrder(false)}
height={600}
overlayStyle={{ padding: 0, borderRadius: 5 }}
>
<OrderDetailModal order={overlayOrder}>
{isCreatedByUser() && (
<CreatedByActions
navigation={navigation}
order={overlayOrder}
onAccept={() => {
console.log("123");
}}
onClose={() => setOverlayOrder(false)}
/>
)}
{isAcceptedByUser() && (
<AcceptedByActions
navigation={navigation}
order={overlayOrder}
onAccept={() => {
console.log("123");
}}
onClose={() => setOverlayOrder(false)}
/>
)}
{!isAcceptedByUser() && !isCreatedByUser() && (
<AcceptActions
order={overlayOrder}
onAccept={onAccept}
onClose={() => setOverlayOrder(false)}
/>
)}
</OrderDetailModal>
</Overlay>
<View>
<ScrollView>
<MapView
onLayout={onMapReady}
ref={map}
style={style.mapStyle}
showsUserLocation={true}
initialRegion={{
latitude: parseFloat(location?.latitude),
longitude: parseFloat(location?.longitude),
zoomControlEnabled: true,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{orders.length > 0 &&
orders.map((order) => (
<Marker
pinColor={getMarkerColor(order)}
key={order.id}
coordinate={{
latitude: parseFloat(order.latitude),
longitude: parseFloat(order.longitude),
}}
onPress={() => showModal(order)}
title={order.name}
description={order.description}
>
</Marker>
))}
</MapView>
</ScrollView>
{/*<View style={style.form}>*/}
{/* <RequestForm onSuccess={onSuccess}/>*/}
{/*</View>*/}
</View>
</View>
)
};
const style = StyleSheet.create({
form: {position: "absolute", bottom: 100, width: "100%", paddingHorizontal: 20},
container: {
flex: 1
},
mapStyle: {
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
})
export default Help;
import * as React from "react";
import {useState} from "react";
import Request from "./Request";
import {Text, View, StyleSheet} from "react-native";
import TopBar from "./TopBar";
import Help from "./Help";
import {useContext} from "react";
import {AuthContext} from "../../../App";
const Main = ({navigation}) => {
const [view, setView] = useState('Request');
const { authContext: {getAllOrders} } = useContext(AuthContext);
const showHelpView = () => {
getAllOrders();
setView('Help');
}
const showRequestView = () => setView('Request');
return (
<View style={{flex: 1}}>
<TopBar showHelpView={showHelpView} showRequestView={showRequestView}/>
{view === 'Request' ? <Request /> : <Help navigation={navigation} />}
</View>
)
};
export default Main;
import * as React from "react";
import {View, StyleSheet, Dimensions, ScrollView} from "react-native";
import MapView, {Marker} from "react-native-maps";
import {useContext} from "react";
import {AuthContext} from "../../../App";
import {createRef} from "react";
import {useState} from "react";
import {useEffect} from "react";
import * as Location from "expo-location";
import RequestForm from "./RequestForm";
const Request = () => {
const {state: {orders}, authContext} = useContext(AuthContext);
const [location, setLocation] = useState(null);
const { authContext: {getAllOrders} } = useContext(AuthContext);
const map = createRef();
useEffect(() => {
authContext.backToScreen("ListOrdersScreen");
getUserLocation();
return () => {
authContext.backToScreen(null);
};
}, []);
const getUserLocation = async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== "granted") {
}
let location = await Location.getCurrentPositionAsync({});
const { latitude, longitude } = location.coords;
setLocation({ latitude, longitude });
};
const onMapReady = () => {
if (orders.length === 0) {
return;
}
const locations = orders.map((order) => ({
latitude: order.latitude,
longitude: order.longitude,
}));
map.current.fitToCoordinates(locations, {
edgePadding: { top: 30, right: 30, bottom: 30, left: 30 },
animated: false,
});
};
const onSuccess = () => {
getAllOrders();
}
if (!location) return null;
return (
<View style={style.container}>
<View>
<ScrollView>
<MapView
onLayout={onMapReady}
ref={map}
style={style.mapStyle}
showsUserLocation={true}
initialRegion={{
latitude: parseFloat(location?.latitude),
longitude: parseFloat(location?.longitude),
zoomControlEnabled: true,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{orders.length > 0 &&
orders.map((order) => (
<Marker
key={order.id}
coordinate={{
latitude: parseFloat(order.latitude),
longitude: parseFloat(order.longitude),
}}
onPress={() => showModal(order)}
title={order.name}
description={order.description}
/>
))}
</MapView>
</ScrollView>
<View style={style.form}>
<RequestForm onSuccess={onSuccess}/>
</View>
</View>
</View>
)
};
const style = StyleSheet.create({
form: {position: "absolute", bottom: 100, width: "100%", paddingHorizontal: 20},
container: {
flex: 1
},
mapStyle: {
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
})
export default Request;
import * as React from "react";
import {View, StyleSheet, Text, TouchableOpacity, AsyncStorage, Alert} from "react-native";
import {Button, Input} from "react-native-elements";
import moment from "moment";
import {Formik} from "formik";
import TimePicker from "react-native-24h-timepicker";
import {createRef} from "react";
import {useState} from "react";
import * as Location from "expo-location";
import axios from "axios";
import {API_URL} from "../../constants/constant";
const RequestForm = (props) => {
const timePicker = createRef();
const [time, setTime] = useState();
const getLocation = async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== "granted") {
}
let location = await Location.getCurrentPositionAsync({});
return location.coords;
}
const onSubmit = async (values, {resetForm}) => {
const date = new Date();
date.setHours(time.hour);
date.setMinutes(time.minute);
values.expires_at = moment(date).format('YYYY-MM-DD HH:mm');
const {latitude, longitude} = await getLocation();
values.latitude = latitude;
values.longitude = longitude;
save(values, resetForm);
}
const save = async (data, resetForm) => {
const { token } = JSON.parse(await AsyncStorage.getItem("user"));
axios
.post(`${API_URL}/order`, data, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
resetForm({});
setTime(null);
Alert.alert("Alert", "Your request has been added successfully.", [
{ text: "OK", onPress: () => props.onSuccess() },
]);
})
.catch((err) => {
console.log(err.response);
});
};
const onCancel = () => {
timePicker.close();
}
const onConfirm = (hour, minute) => {
setTime({
hour: hour,
minute: minute
});
timePicker.current.close();
}
return (
<Formik
initialValues={{
description: "",
title: "",
address: "",
expires_at: moment(new Date()).format("YYYY-MM-DD HH:mm"),
mylocation: "",
}}
onSubmit={onSubmit}
>
{({
handleChange,
handleBlur,
handleSubmit,
setFieldValue,
values,
errors,
touched,
setFieldTouched,
isSubmitting,
isValid,
}) => (
<View>
<TimePicker
ref={timePicker}
value={time}
onCancel={onCancel}
onConfirm={onConfirm}
/>
<TouchableOpacity
onPress={() => {
timePicker.current.open()
}}
>
<View style={[style.input, style.when]}>
<Text style={{fontSize: 18}}>{time ? (time.hour + ":" + time.minute) : 'When'}</Text>
</View>
</TouchableOpacity>
<View style={style.input}>
<Input
inputContainerStyle={{borderBottomWidth: 0}}
style={style.input}
name="title"
placeholder="Title"
onBlur={() => setFieldTouched("title")}
onChangeText={handleChange("title")}
/>
</View>
<View style={[style.input, style.inputMulti]}>
<Input
inputContainerStyle={{borderBottomWidth: 0}}
containerStyle={[style.input, style.inputMultiInput]}
multiline
name="Description"
placeholder="Description"
onBlur={() => setFieldTouched("description")}
onChangeText={handleChange("description")}
/>
</View>
<View style={{justifyContent: "flex-end"}}>
<Button
buttonStyle={style.button}
title={"Request"}
onPress={handleSubmit}
/>
</View>
</View>
)}
</Formik>
)
};
const style = StyleSheet.create({
button: {
marginTop: 20,
borderRadius: 4,
backgroundColor: "#37AE47",
},
inputMultiInput: {
height: 100,
margin: 0,
padding: 0
},
when: {
fontSize: 20,
marginBottom: 20,
justifyContent: "center",
paddingLeft: 10,
width: "100%",
},
inputMulti: {
backgroundColor: "transparent",
borderWidth: 0,
marginTop: 20,
padding: 0,
height: 100,
},
input: {
borderRadius: 4,
borderColor: "#E2E5EE",
borderWidth: 1,
height: 50,
paddingVertical: 5,
backgroundColor: "white",
width: "100%",
},
});
export default RequestForm;
import {View, Text, StyleSheet, TouchableOpacity} from "react-native";
import { Icon } from "react-native-elements";
import React from "react";
const MyCustomLeftComponent = ({onPress}) => {
return (
<TouchableOpacity
onPress={onPress}
style={{
flexDirection: "row",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Icon color="#1665D8" type="font-awesome" name="support" />
<Text
style={{
paddingLeft: 10,
fontSize: 16,
color: "black",
}}
>
Help someone
</Text>
</TouchableOpacity>
);
};
const MyCustomRightComponent = ({onPress}) => {
return (
<TouchableOpacity
onPress={onPress}
style={{
flexDirection: "row",
flex: 1,
justifyContent: "center",
alignItems: "center",
borderLeftWidth: 1,
borderLeftColor: "#EAEDF3",
}}
>
<Icon color="#34AA44" type="material-community" name="bullseye-arrow" />
<Text
style={{
paddingLeft: 10,
fontSize: 16,
color: "black",
}}
>
Request help
</Text>
</TouchableOpacity>
);
};
const TopButtons = ({ showHelpView, showRequestView }) => {
return (
<View style={styles.textContainer}>
<MyCustomLeftComponent onPress={() => showHelpView()}/>
<MyCustomRightComponent onPress={() => showRequestView()}/>
</View>
);
};
const styles = StyleSheet.create({
textContainer: {
flexDirection: "row",
height: 45,
backgroundColor: "#fff",
},
});
export default TopButtons;
......@@ -4489,6 +4489,13 @@ react-is@^16.12.0, react-is@^16.13.0, react-is@^16.7.0, react-is@^16.8.1, react-
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-native-24h-timepicker@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/react-native-24h-timepicker/-/react-native-24h-timepicker-1.1.0.tgz#b95a86339c0bd7261216956d16c3f41b7bbfb8dd"
integrity sha512-rnOHWmKcSbbdpYBVl2MxkQY7IU83f/5K6NB8iq4nmWdq8WfHklnkfvfpjnga8uY6sqLDAK11j+dQHo0XVK+QIg==
dependencies:
react-native-raw-bottom-sheet "^1.0.0"
react-native-elements@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/react-native-elements/-/react-native-elements-1.2.7.tgz#1eca2db715c41722aeb67aea62bd2a4621adb134"
......@@ -4531,6 +4538,13 @@ react-native-ratings@^6.3.0:
lodash "^4.17.4"
prop-types "^15.5.10"
react-native-raw-bottom-sheet@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/react-native-raw-bottom-sheet/-/react-native-raw-bottom-sheet-1.1.4.tgz#1f79bd1bf5b74fec3c9a97b108a5a527d5157318"
integrity sha512-rn9KZuxWLE/EwxuoVzVBrzuTTcUZyhUfOOmAXScuGc90W6sf2NgM38vx6+SkZ0pqWgXmAKnUALmjE3kdNnxAFQ==
dependencies:
prop-types "^15.6.2"
react-native-reanimated@~1.7.0:
version "1.7.1"
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.7.1.tgz#6363c7f3ebbabc56a05d5dccaf09d95f3b6a2d69"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment