This commit is contained in:
2024-02-27 16:19:55 +08:00
commit feebeffcd9
141 changed files with 25124 additions and 0 deletions

125
app/containers/Account/account.js Executable file
View File

@@ -0,0 +1,125 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
SafeAreaView
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import ScrollableTabView from "react-native-scrollable-tab-view";
//component
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import AccountSettings from "./accountSettings";
import Login from "../Login/login";
import Payment from "./payment";
import Header from '../../components/Public/signInUpHeader'
// function
import { width, height } from "../../config/screen";
import Log from '../../config/log'
import theme from "../../config/colors";
import {Fonts} from '../../config/fonts'
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import language from "../../config/language";
const asyncStorageHelper = new AsyncStorageHelper();
const log = new Log()
@inject(["menuStore"], ["userStore"])
@observer
export default class Account extends Component {
constructor(props) {
super(props);
this.store = this.props.userStore;
this.menuStore = this.props.menuStore;
}
@observable
static navigationOptions = {
drawerLabel: "Account",
swipeEnabled: false,
tabBarLabel: language.en.profile,
};
componentWillMount() {
this.init();
}
init() {
console.log(this.store.logined)
if (!this.store.logined) {
// this.props.navigation.navigate("Login");
} else {
}
}
changeIndex(index) {
this.tabMap.index = index;
}
logoutAlert() {
Alert.alert(
"Logout",
"Are you sure to Logout?",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "Sure", onPress: () => this.logoutAction() }
],
{ cancelable: false }
);
}
logoutAction() {
this.store.logoutPost(this);
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
render() {
log.firebaseClass('profile')
return (
<SafeAreaView style={{ backgroundColor: theme.mainColor, flex: 1 }}>
<View style={styles.container}>
<Header navigation = {this.props.navigation}/>
<ScrollableTabView
style={{marginTop: 20, }}
tabBarTextStyle = {{fontFamily:Fonts.century,fontWeight:'bold'}}
tabBarActiveTextColor={theme.mainColor}
tabBarUnderlineStyle={{ backgroundColor: "white", height: 1 }}
tabBarBackgroundColor={"white"}>
<AccountSettings
tabLabel="My Information"
navigation={this.props.navigation}
/>
<Payment tabLabel="Credit card details" navigation={this.props.navigation} />
</ScrollableTabView>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
height: height,
width: width
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});

View File

@@ -0,0 +1,336 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TextInput,
TouchableOpacity
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import Text from "react-native-text";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { Dropdown } from "react-native-material-dropdown";
import { Button } from "react-native-elements";
import firebase from "react-native-firebase";
import Toast, { DURATION } from "react-native-easy-toast";
//component
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import Size from "../../config/size";
import Countdown, { CountdownStatus } from "rn-countdown";
// function
import { width, height } from "../../config/screen";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import Loader from "../../components/Public/loader";
const asyncStorageHelper = new AsyncStorageHelper();
const size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
export default class AccountSettings extends Component {
@observable pickupPointIndexExist = false;
password = "";
pickupPoint = [];
@observable index = 1;
@observable
code = 0;
@observable
password = "";
@observable
verificationCode = "";
static navigationOptions = {
drawerLabel: "Account"
};
constructor(props) {
super(props);
this.store = this.props.userStore;
this.menuStore = this.props.menuStore;
}
navigatieAction(page, Param) {
this.props.navigation.navigate(page, Param);
}
checking() {
asyncStorageHelper.getData("pickupPointId", pickupPointId => {
if (pickupPointId != null) {
console.log("index: " + pickupPointId);
this.pickupPointIndexExist = true;
this.index = this.getIndex(pickupPointId);
}
});
}
changeIndex(index) {
this.tabMap.index = index;
}
positionValue() {
if (this.pickupPointIndexExist) {
return this.store.pickupPointLabel[this.pickupPointIndex].value;
} else {
return null;
}
}
positionChange(id) {
asyncStorageHelper.saveData("pickupPointId", id);
this.menuStore.getMenuItem();
}
handleNetworkFailed = () => alert("network failed");
handleStopCountdown = () => this.countdown && this.countdown.stopCountdown();
handleClickCountdown = () => {
var bodyFormData = new FormData();
bodyFormData.append("country_code", "852");
bodyFormData.append(
"phone_number",
this.store.userData.data.member.mobile.toString()
);
this.store.sendsmsVerify(bodyFormData, this);
};
getIndex(id) {
var index = this.store.pickupPointLabel.findIndex(function(item, i) {
return item.id == parseInt(id);
});
return index;
}
startToCountDown = () => {
this.countdown && this.countdown.startCountdown();
};
resetPassword() {
// this.store.signupPost(api.signup, this.signInData, this);
if (this.verificationCode != null || this.verificationCode != "") {
if (this.password != null || this.password != "") {
if (this.password.length >= 8) {
var data = {
verificationCode: this.verificationCode,
mobile: this.store.userData.data.member.mobile.toString(),
countryCode: "852",
password: this.password
};
this.store.forgotPassword(data, this);
} else {
this.refs.toast.show("your password must be at least 8 characters");
}
} else {
this.refs.toast.show("Please enter reset password");
}
} else {
this.refs.toast.show("Please enter verification number");
}
}
countDownButton() {
return (
<View style={{ flex: 1 }}>
<Countdown
ref={r => (this.countdown = r)}
time={60}
onPress={this.handleClickCountdown}
onNetworkFailed={this.handleNetworkFailed}
onDidFinishCountdown={this.handleCountdownOver}
>
{({ status, time }) => {
let title, containerStyle, titleStyle;
switch (status) {
case CountdownStatus.Idle:
title = "send";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Counting:
title = `sent(${time})`;
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Over:
title = "send";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
}
return (
<View style={containerStyle}>
<Text style={titleStyle}>{title}</Text>
</View>
);
}}
</Countdown>
</View>
);
}
render() {
if (this.store.logined) {
this.checking();
return (
<View style={styles.container}>
<Loader loading={this.store.loading} />
<View style={{ flex: 1 }}>
<View style={styles.TextContainer}>
<Text
style={styles.TextView}
underlineColorAndroid="rgba(0,0,0,0)"
>
{this.store.userData.data.member.name}
</Text>
</View>
<View style={styles.TextContainer}>
<Text style={styles.TextView}>
{this.store.userData.data.member.email}
</Text>
</View>
<View style={styles.TextContainer}>
<Text style={styles.TextView}>
+{this.store.userData.data.member.countryCode}{" "}
{this.store.userData.data.member.mobile}
</Text>
</View>
<View style={styles.TextContainer}>
<TextInput
style={styles.TextView}
placeholder={"Reset Password(at least 8 characters)"}
secureTextEntry={true}
underlineColorAndroid="rgba(0,0,0,0)"
value={this.password}
onChangeText={value => (this.password = value)}
/>
</View>
<View
style={{
marginLeft: 20,
marginRight: 20,
marginTop: 20,
flexDirection: "row",
justifyContent: "space-between"
}}
>
{this.countDownButton()}
<View
style={{
backgroundColor: theme.inputBgc,
marginLeft: 10,
alignSelf: 'stretch',
justifyContent: "center",
height: verticalScale(40),
borderRadius: 5,
flex: 1
}}
>
<TextInput
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
fontSize: size.getSize(12),
paddingRight: 30,
paddingLeft: 40,
fontFamily: Fonts.century,
paddingVertical: 0,
alignSelf: 'stretch'
}}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="verification no."
keyboardType={"numeric"}
placeholderStyle={{
fontWeight: "bold",
fontFamily: Fonts.century,
fontSize: size.getSize(10),
paddingVertical: 0
}}
value={this.verificationCode}
onChangeText={text => (this.verificationCode = text)}
placeholderTextColor={theme.foodNameColor}
/>
</View>
</View>
</View>
<Button
title="Reset"
fontWeight="bold"
fontSize={size.getSize(18)}
fontFamily={Fonts.century}
titleStyle={{
color: "white",
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 50
}}
onPress={() => this.resetPassword()}
// loading={false}
loadingProps={{ size: "large", color: "rgba(111, 202, 186, 1)" }}
buttonStyle={styles.signupButton}
/>
<Toast ref="toast" position={"center"} />
</View>
);
} else {
return null;
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white",
width: width
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
TextView: {
color: theme.coolGrey,
fontSize: size.getSize(15),
paddingRight: 20,
paddingLeft: 20,
fontWeight: "bold",
fontFamily: Fonts.century
},
TextContainer: {
backgroundColor: theme.inputBgc,
marginTop: 20,
marginLeft: 20,
marginRight: 20,
width: width - 40,
height: verticalScale(40),
borderRadius: 5,
justifyContent: "center"
},
signupButton: {
width: width,
height: verticalScale(60),
backgroundColor: theme.mainColor
},
countdown: {
borderRadius: 5,
borderWidth: 2,
borderColor: theme.coolGrey,
height: verticalScale(40),
justifyContent: "center",
alignItems: "center"
},
countdownTitle: {
color: theme.coolGrey,
fontSize: 12
}
});

177
app/containers/Account/addCard.js Executable file
View File

@@ -0,0 +1,177 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TouchableOpacity,
ScrollView,
Switch,
SafeAreaView,
} from "react-native";
import { observable, action } from "mobx";
import Text from "react-native-text";
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Icon from "react-native-vector-icons/dist/Ionicons";
import Toast, { DURATION } from "react-native-easy-toast";
import {
CreditCardInput,
LiteCreditCardInput
} from "react-native-credit-card-input";
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import Loader from "../../components/Public/loader"
import { width, height } from "../../config/screen";
import theme from '../../config/colors'
import {Fonts} from '../../config/fonts'
import Size from "../../config/size";
const size = new Size();
@inject(["userStore"])
@observer
export default class AddCard extends Component {
constructor(props) {
super(props);
this.store = this.props.userStore;
}
cardData = null;
//_onFocus = field => console.log("focusing", field);
addCardAction() {
var BreakException = {};
if (this.cardData != null) {
if (this.cardData.valid) {
let data = {
num: this.cardData.values.number.replace(/\s/g, ""),
expiry: this.cardData.values.expiry.replace("/", ""),
cvc: this.cardData.values.cvc
};
console.log(this.cardData);
this.store.postCreditCard(this.props.navigation,data);
} else {
try {
Object.keys(this.cardData.status).forEach(e => {
console.log(e + " - " + this.cardData.status[e]);
if (
this.cardData.status[e] == "incomplete" ||
this.cardData.status[e] == "invalid"
) {
this.refs.toast.show(e + " " + this.cardData.status[e]);
throw BreakException;
}
});
} catch (e) {
if (e !== BreakException) throw e;
}
}
} else {
this.refs.toast.show("please insert card number");
}
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<View style={styles.container}>
<Loader
loading = {this.store.loading}/>
<View
style={{
width: width,
height: "10%",
alignItems: "center",
justifyContent: "center",
marginTop: 20,
flexDirection: "row"
}}
>
<View
style={{
width: "30%",
height: "100%",
justifyContent: "center",
paddingLeft: 5
}}
>
<Icon
name="ios-arrow-back"
size={size.getSize(50)}
color="black"
onPress={() => {
this.props.navigation.goBack();
}}
/>
</View>
<View
style={{
width: "40%",
height: "100%",
justifyContent: "center",
alignItems: "center"
}}
>
<Text style={{ fontSize: 22, fontFamily: Fonts.century, }}>Add a Card</Text>
</View>
<View
style={{
width: "30%",
paddingRight: 5,
height: "100%",
flexDirection: "row",
justifyContent: "flex-end",
alignItems: "center"
}}
>
<Icon
name="md-add"
size={size.getSize(50)}
color="black"
onPress={() => this.addCardAction()}
/>
</View>
</View>
<LiteCreditCardInput
autoFocus
requiresName
requiresCVC
labelStyle={styles.label}
inputStyle={styles.input}
validColor={"black"}
invalidColor={"red"}
placeholderColor={"darkgray"}
onChange={form => (this.cardData = form)}
/>
</View>
<Toast ref="toast" />
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5FCFF"
},
switch: {
alignSelf: "center",
marginTop: 20,
marginBottom: 20
},
label: {
color: "black",
fontSize: 12
},
input: {
fontSize: 16,
color: "black"
}
});

374
app/containers/Account/payment.js Executable file
View File

@@ -0,0 +1,374 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TouchableOpacity,
Alert,
SafeAreaView
} from "react-native";
import { observable, action, transaction } from "mobx";
import Text from "react-native-text";
import { Button } from "react-native-elements";
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Icon from "react-native-vector-icons/dist/Ionicons";
import Icon2 from "react-native-vector-icons/dist/MaterialCommunityIcons";
import Toast, { DURATION } from "react-native-easy-toast";
import Log from '../../config/log'
import {
CreditCardInput,
LiteCreditCardInput
} from "react-native-credit-card-input";
//component
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
// function
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import { width, height } from "../../config/screen";
import Loader from "../../components/Public/loader";
import Size from "../../config/size";
const size = new Size();
const log = new Log()
@inject(["userStore"])
@observer
export default class Payment extends Component {
@observable
menu = false;
@observable
addCard = false;
cardData = null;
static navigationOptions = {
drawerLabel: "Account"
};
constructor(props) {
super(props);
this.store = this.props.userStore;
}
changeIndex(index) {
this.tabMap.index = index;
}
addCardAction() {
var BreakException = {};
if (this.cardData != null) {
if (this.cardData.valid) {
let data = {
num: this.cardData.values.number.replace(/\s/g, ""),
expiry: this.cardData.values.expiry.replace("/", ""),
cvc: this.cardData.values.cvc
};
console.log(this.cardData);
log.firebaseLog('press_add_button_on_creditCard_progress',{})
this.store.postCreditCard(this, data);
} else {
try {
Object.keys(this.cardData.status).forEach(e => {
console.log(e + " - " + this.cardData.status[e]);
if (
this.cardData.status[e] == "incomplete" ||
this.cardData.status[e] == "invalid"
) {
this.refs.toast.show(e + " " + this.cardData.status[e]);
throw BreakException;
}
});
} catch (e) {
if (e !== BreakException) throw e;
}
}
} else {
console.log("error");
this.refs.toast.show("please insert card number");
}
}
testing(token, data) {
Alert.alert(token, data, { text: "ok", onPress: () => console.log("ok") });
}
@action
removeCard() {
Alert.alert("", "Are you sure? ", [
{ text: "Cancel", onPress: () => console.log("Cancel") },
{
text: "Sure",
onPress: () => this.store.deleCreditCard(this)
}
]);
}
updateCard() {
//this.removeCard();
this.props.navigation.navigate("AddCard");
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<View style={styles.container}>
<Loader loading={this.store.loading} />
{!this.store.addedCard ? (
<View>
<View
style={{
alignItems: "center",
marginTop: 20,
marginRight: 30,
marginLeft: 30,
flexDirection: "row"
}}
>
<View style={{ width: "25%", alignItems: "flex-start" }}>
<Icon
name="ios-card"
size={size.getSize(45)}
color={theme.coolGrey}
/>
</View>
<TouchableOpacity
style={{
width: "75%",
height: verticalScale(40),
alignItems: "center",
borderWidth: 2,
borderColor: theme.coolGrey,
borderRadius: 5,
justifyContent: "center"
}}
onPress={() => {
this.addCard = true;
log.firebaseLog('press_add_creditCard_button',{})
}}
>
<Text
style={{
fontSize: 15,
fontFamily: Fonts.century,
color: theme.coolGrey,
fontWeight: "bold"
}}
>
Add credit card
</Text>
</TouchableOpacity>
</View>
{this.addCard ? (
<View>
<LiteCreditCardInput
autoFocus
labelStyle={styles.label}
inputStyle={styles.input}
validColor={"black"}
invalidColor={"red"}
placeholderColor={"darkgray"}
onChange={form => (this.cardData = form)}
/>
<View
style={{
justifyContent: "space-between",
marginTop: 20,
marginRight: 30,
marginLeft: 30,
flexDirection: "row"
}}
>
<TouchableOpacity
style={{
width: "45%",
alignItems: "center",
justifyContent: "center",
borderWidth: 2,
borderColor: theme.coolGrey,
borderRadius: 5,
height: verticalScale(40)
}}
onPress={() => {
this.addCardAction();
}}
>
<Text>Add</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
width: "45%",
alignItems: "center",
justifyContent: "center",
borderWidth: 2,
borderColor: theme.coolGrey,
borderRadius: 5,
height: verticalScale(40)
}}
onPress={() => {
this.addCard = false;
this.cardData = null;
log.firebaseLog('press_cancel_button_on_creditCard_progress',{})
}}
>
<Text>CANCEL</Text>
</TouchableOpacity>
</View>
</View>
) : (
<View />
)}
</View>
) : (
<View
style={{
alignItems: "center",
marginTop: 20,
marginRight: 30,
marginLeft: 30,
flexDirection: "row"
}}
>
<View style={{ width: "25%", alignItems: "flex-start" }}>
<Icon
name="ios-card"
size={size.getSize(45)}
color={theme.coolGrey}
/>
</View>
<View
style={{
width: "75%",
height: verticalScale(40),
alignItems: "center",
flexDirection: "row",
borderWidth: 2,
borderColor: theme.coolGrey,
borderRadius: 5,
justifyContent: "space-between"
}}
onPress={() => {
this.addCard = true;
}}
>
<Text
style={{
fontSize: 15,
paddingLeft: scale(20),
fontFamily: Fonts.century,
color: theme.coolGrey,
fontWeight: "bold"
}}
>
{this.store.creditCardinfo.num}
</Text>
<TouchableOpacity
style={{ justifyContent: "center",alignItems:'center' }}
onPress={() => (this.menu = !this.menu)}
>
<Icon2
name="dots-vertical"
size={size.getSize(30)}
color={theme.coolGrey}
style={{ marginLeft: 10 }}
/>
</TouchableOpacity>
</View>
</View>
)}
{this.menu ? (
<View
style={{
justifyContent: "space-between",
width:width,
marginTop: 20,
marginRight: 30,
marginLeft: 30,
flexDirection: "row"
}}
>
<TouchableOpacity
style={{
width: "40%",
alignItems: "center",
justifyContent: "center",
borderWidth: 2,
marginLeft: 30,
borderColor: theme.coolGrey,
borderRadius: 5,
height: verticalScale(40)
}}
onPress={() => {
this.removeCard();
this.menu = !this.menu;
log.firebaseLog('press_remove_card_button',{})
}}
>
<Text>Remove Card</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
width: "40%",
alignItems: "center",
justifyContent: "center",
borderWidth: 2,
marginRight: 30,
borderColor: theme.coolGrey,
borderRadius: 5,
height: verticalScale(40)
}}
onPress={() => {
this.menu = !this.menu;
}}
>
<Text>CANCEL</Text>
</TouchableOpacity>
</View>
) : (
<View />
)}
</View>
<Toast ref="toast" position={"center"} />
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
buttonView: {
width: "80%",
height: 60,
marginTop: 10,
alignItems: "center",
justifyContent: "center",
borderColor: "black",
borderWidth: 1
},
label: {
color: "black",
fontSize: 12
},
input: {
fontSize: 16,
color: "black"
}
});

View File

@@ -0,0 +1,185 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
NetInfo,
Geolocation
} from "react-native";
import Header from "../../components/Public/header";
import { observer, inject } from "mobx-react/native";
import { observable, transaction } from "mobx";
import { width, height } from "../../config/screen";
import MapView, { Polyline } from "react-native-maps";
import MapViewDirections from "react-native-maps-directions";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
const asyncStorageHelper = new AsyncStorageHelper();
const origin = { latitude: 22.320508, longitude: 114.170222 };
const destination = { latitude: 22.320568, longitude: 114.171273 };
const GOOGLE_MAPS_APIKEY = "AIzaSyB_9Wi7BcAgqMPxZvW_5DWb8UxF5W9tWz0";
export const getCurrentLocation = () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => resolve(position),
e => reject(e)
);
});
};
@inject(["menuStore"], ["userStore"])
@observer
export default class Location extends Component {
title = "";
pickUpPointLoaction = { latitude: 0, longitude: 0 };
static navigationOptions = {
drawerLabel: "My Orders"
};
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
this.state = {
region: {
latitude: null,
longitude: null,
latitudeDelta: 1,
longitudeDelta: 1
}
};
}
getIndex(id) {
var index = this.userStore.pickupPointLabel.findIndex(function(item, i) {
return item.id == parseInt(id);
});
return index;
}
getUserLocation() {
navigator.geolocation.getCurrentPosition(
position => {
this.userStore.userLocation = position;
},
error => {
console.log(error);
},
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
componentWillMount() {
const { navigation } = this.props;
this.getUserLocation();
this.title = navigation.getParam("title", "Location");
this.pickUpPointLoaction = navigation.getParam("location", {
latitude: 0,
longitude: 0
});
this.setState({
region: {
latitude: this.userStore.userLocation.coords.latitude,
longitude: this.userStore.userLocation.coords.longitude,
latitudeDelta: 0.02,
longitudeDelta: 0.02
}
});
}
clickMarkerAction(id) {
Alert.alert(
"",
"Select " +
this.userStore.pickupPointLabel[this.getIndex(id)].value +
"?",
[
{ text: "Cancel", onPress: () => console.log("Cancel") },
{ text: "Yes", onPress: () => this.picked(id) }
]
);
}
picked(id) {
asyncStorageHelper.saveData("pickupPointId", id);
this.store.getMenuItem();
this.props.navigation.goBack();
}
render() {
console.log(this.userStore.userLocation);
if (this.title == "Pick the loaction") {
return (
<View style={styles.container}>
<Header title={this.title} navigation={this.props.navigation} />
<MapView
style={{ width: width, height: 400 }}
showsUserLocation={true}
initialRegion={this.state.region}
>
{this.userStore.pickupLoactionPoint.data.content.map(marker => (
<MapView.Marker
coordinate={{ latitude: marker.lat, longitude: marker.lng }}
title={marker.name}
onPress={() => this.clickMarkerAction(marker.id)}
/>
))}
</MapView>
</View>
);
} else {
return (
<View style={styles.container}>
<Header title={this.title} navigation={this.props.navigation} />
<MapView
style={{ width: width, height: 400 }}
showsUserLocation={true}
initialRegion={this.state.region}
>
<MapView.Marker
coordinate={{
latitude: this.userStore.userLocation.coords.latitude,
longitude: this.userStore.userLocation.coords.longitude
}}
/>
<MapView.Marker coordinate={this.pickUpPointLoaction} />
<MapViewDirections
origin={{latitude: this.userStore.userLocation.coords.latitude,
longitude: this.userStore.userLocation.coords.longitude,}}
destination={this.pickUpPointLoaction}
apikey={GOOGLE_MAPS_APIKEY}
mode = 'walking'
strokeWidth={3}
strokeColor="red"
/>
)
</MapView>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});

View File

@@ -0,0 +1,390 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
Alert,
NetInfo,
Geolocation,
TouchableOpacity,
SafeAreaView,
StatusBar,
Image,
ImageBackground
} from "react-native";
import Header from "../../components/Public/header";
import Text from "react-native-text";
import { SearchBar } from "react-native-elements";
import { observer, inject } from "mobx-react/native"
import { Fonts } from "../../config/fonts";;
import { observable, transaction } from "mobx";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { width, height } from "../../config/screen";
import MapView, { Polyline } from "react-native-maps";
import MapViewDirections from "react-native-maps-directions";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
import { ifIphoneX } from 'react-native-iphone-x-helper'
import theme from "../../config/colors";
import FastImage from "react-native-fast-image";
import MyStatusBar from "../../components/Public/statusBar";
const asyncStorageHelper = new AsyncStorageHelper();
import Log from '../../config/log'
import { GooglePlacesAutocomplete } from "react-native-google-places-autocomplete";
const origin = { latitude: 22.320508, longitude: 114.170222 };
const destination = { latitude: 22.320568, longitude: 114.171273 };
const GOOGLE_MAPS_APIKEY = "AIzaSyBM8eEWcSWBuZcM0lGH_JSoDjgImlqHwPs";
const log = new Log()
export const getCurrentLocation = () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
position => resolve(position),
e => reject(e)
);
});
};
@inject(["menuStore"], ["userStore"])
@observer
export default class LocationRequest extends Component {
@observable
markerId = null;
title = "";
pickUpPointLoaction = { latitude: 0, longitude: 0 };
perdefinedPlaces = [];
static navigationOptions = {
drawerLabel: "My Orders"
};
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
this.state = {
region: {
latitude: null,
longitude: null,
latitudeDelta: 1,
longitudeDelta: 1
}
};
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
_requestPermission() {
Permissions.request("location").then(response => {
if (
response == "allow" ||
response == "restricted" ||
response == "authorized"
) {
navigator.geolocation.getCurrentPosition(
position => {
this.userStore.userLocation = position;
console.log(position);
// self.navigatieAction("LocationRequest");
},
error => {
console.log(error);
// self.navigatieAction("LocationRequest");
},
{ enableHighAccuracy: false, timeout: 4000, maximumAge: 10000 }
);
} else {
// self.navigatieAction("LocationRequest");
}
});
}
onClickAction(data, details) {
this.map.animateToRegion({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
latitudeDelta: 0.02,
longitudeDelta: 0.02
});
for (var i = 0; i < this.userStore.perdefinedPlaces.length; i++) {
if (
this.userStore.perdefinedPlaces[i].geometry.location.lat ==
details.geometry.location.lat &&
this.userStore.perdefinedPlaces[i].geometry.location.lng ==
details.geometry.location.lng
) {
this.markerId = this.userStore.perdefinedPlaces[i].id
break;
}
}
console.log(details);
}
googlePlacesAutoComplete() {
return (
<View
style={{
position: "absolute",
top: 0,
backgroundColor: theme.mainColor,
...ifIphoneX(
{
//height:'10%'
},{
}
)
}}
>
<GooglePlacesAutocomplete
placeholder={this.userStore.text.googleSearch}
placeholderTextColor="white"
minLength={1} // minimum length of text to search
autoFocus={false}
returnKeyType={"search"} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed="false" // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => {
this.onClickAction(data, details);
}}
getDefaultValue={() => ""}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: GOOGLE_MAPS_APIKEY,
language: "zh-TW||en", // language of the results
types: ["(cities)", "(country)"],
components: "country:hk" // default: 'geocode'
}}
styles={{
textInputContainer: {
backgroundColor: theme.mainColor,
borderTopWidth: 0,
borderBottomWidth: 0,
width: width,
paddingRight: 20,
paddingLeft: 20,
marginBottom: 10
},
textInput: {
textAlign: "center",
height: verticalScale(40),
color: "white",
fontSize: 16,
borderWidth: 0,
backgroundColor: theme.searchMapInputColor,
fontFamily: Fonts.century,
fontWeight: "bold"
},
description: {
fontWeight: "bold"
},
listView: {
backgroundColor: "white"
},
predefinedPlacesDescription: {
color: "#1faadb",
}
}}
currentLocation={false} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI="GooglePlacesSearch" // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={
{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}
}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: "distance",
types: "food"
}}
filterReverseGeocodingByTypes={[
"locality",
"administrative_area_level_3"
]} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={this.userStore.perdefinedPlaces}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
// renderLeftButton={() => <Image source={require('path/custom/left-icon')} />}
//renderRightButton={() => <Text>Custom text </Text>}
/>
</View>
);
}
getIndex(id) {
var index = this.userStore.pickupPointLabel.findIndex(function(item, i) {
return item.id == parseInt(id);
});
return index;
}
getUserLocation() {
navigator.geolocation.getCurrentPosition(
position => {
this.userStore.userLocation = position;
},
error => {
console.log(error);
},
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
}
componentWillMount() {
const { navigation } = this.props;
this.title = navigation.getParam("title", "Location");
this.pickUpPointLoaction = navigation.getParam("location", {
latitude: 0,
longitude: 0
});
this.setUserLocation();
this.userStore.pickupLoactionPoint.data.content.forEach(element => {
var place = {
description: element.name,
geometry: { location: { lat: element.lat, lng: element.lng } }
};
this.perdefinedPlaces.push(place);
});
}
setUserLocation() {
console.log(this.userStore.userLocation);
if (this.userStore.userLocation === null) {
this.setState({
region: {
latitude: 22.396427,
longitude: 114.109497,
latitudeDelta: 1,
longitudeDelta: 1
}
});
} else {
this.setState({
region: {
latitude: this.userStore.userLocation.coords.latitude,
longitude: this.userStore.userLocation.coords.longitude,
latitudeDelta: 0.02,
longitudeDelta: 0.02
}
});
}
}
clickMarkerAction(id) {
this.markerId = id;
}
confirmAction() {
Alert.alert(
"",
"Select " +
this.userStore.pickupPointLabel[this.getIndex(this.markerId)].value +
"?",
[
{ text: "Cancel", onPress: () => console.log("Cancel") },
{ text: "Yes", onPress: () => this.picked(this.markerId) }
]
);
}
picked(id) {
if(this.markerId != null){
asyncStorageHelper.saveData("pickupPointId", id);
this.userStore.pickupPointId = id;
this.store.pickupPointId = id;
log.firebaseLog("select_pickuppoint_first_time_start_app",{pickuppointid:id})
this.store.getMenuItem(this);
}
}
searchClear() {}
searchChangeText() {}
confirmButton() {
if (!this.markerId) {
return null;
} else {
return (
<TouchableOpacity
style={{
height: verticalScale(60),
width: width,
backgroundColor: theme.mainColor,
alignItems: "center",
justifyContent: "center"
}}
onPress={() => this.confirmAction()}
>
<Text style={{ color: "white", fontWeight: "bold" }}>confirm</Text>
</TouchableOpacity>
);
}
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<MyStatusBar
backgroundColor={theme.mainColor}
barStyle="light-content"
/>
<View style={styles.container}>
<MapView
ref={ref => {
this.map = ref;
}}
style={{ width: width, flex: 1 }}
showsUserLocation={true}
initialRegion={this.state.region}
>
{this.userStore.pickupPointLabel.map(marker => (
<MapView.Marker
coordinate={{ latitude: marker.lat, longitude: marker.lng }}
title={marker.name}
onPress={() => this.clickMarkerAction(marker.id)}
>
<Image
resizeMode={"contain"}
source={require("../../images/maplocator.png")}
style={{ width: scale(50), height: scale(50) }}
/>
</MapView.Marker>
))}
</MapView>
{this.confirmButton()}
{this.googlePlacesAutoComplete()}
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});

284
app/containers/Login/login.js Executable file
View File

@@ -0,0 +1,284 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TextInput,
TouchableOpacity,
SafeAreaView,
Keyboard,
ScrollView,
TouchableWithoutFeedback
} from "react-native";
import { observable } from "mobx";
import { KeyboardAccessoryNavigation } from "react-native-keyboard-accessory";
import { observer, inject } from "mobx-react/native";
import Text from "react-native-text";
import Header from "../../components/Public/signInUpHeader";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import Log from '../../config/log'
import { width, height } from "../../config/screen";
import { Button } from "react-native-elements";
import CommonTextInput from "../../components/Public/commonTextInput";
import api from "../../stores/api";
const size = new Size();
import Toast, { DURATION } from "react-native-easy-toast";
import SignUpInformation from "../signUp/signUpInformation";
import Loader from "../../components/Public/loader";
let log = new Log()
let inputs = [
{
//value: this.account,
// onChangeText: this.loginData.pwd,
placeholder: "Email/Mobile",
secureTextEntry: false
// componentRef: this.first
},
{
//value: this.password,
//onChangeText: this.loginData.pwd,
placeholder: "Password",
secureTextEntry: true
// componentRef: this.secound
}
];
@inject(["userStore"])
@observer
export default class Login extends Component {
loginData = {
id: "",
pwd: ""
};
data = [
{
value: this.account,
onChangeText: this.loginData.pwd,
componentRef: this.first
},
{
value: this.password,
onChangeText: this.loginData.pwd,
componentRef: this.secound
}
];
constructor(props) {
super(props);
this.store = this.props.userStore;
inputs = inputs.map((input, index) => ({
componentRef: React.createRef(),
value: this.data[index].value,
onChangeText: this.data[index].onChangeText,
...input
}));
this.state = {
activeInputIndex: 0,
nextFocusDisabled: false,
previousFocusDisabled: false,
buttonsDisabled: false,
buttonsHidden: false
};
}
handleFocus = index => () => {
this.setState({
nextFocusDisabled: index === inputs.length - 1,
previousFocusDisabled: index === 0,
activeInputIndex: index
});
};
handleFocusNext = () => {
const { nextFocusDisabled, activeInputIndex } = this.state;
if (nextFocusDisabled) {
return;
}
// this.inputs[activeInputIndex + 1].componentRef.focus();
inputs[1].componentRef.current.focus();
};
handleFocusPrevious = () => {
const { previousFocusDisabled, activeInputIndex } = this.state;
if (previousFocusDisabled) {
return;
}
inputs[activeInputIndex - 1].componentRef.current.focus();
};
navigatieAction(page) {
this.props.navigation.navigate(page);
}
componentWillMount() {
console.log("login componentWillMount");
}
loginAction() {
this.store.loginPost(this.loginData, this, true);
log.firebaseLog('press_login_button',{})
}
testing() {
var bodyFormData = new FormData();
bodyFormData.append("country_code", "852");
bodyFormData.append("phone_number", "97726727");
this.store.sendsmsVerify(bodyFormData, this);
}
render() {
console.log("state: ", this.props.navigation.state);
log.firebaseClass('Login')
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<Loader loading={this.store.loading} />
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View>
<Header navigation={this.props.navigation} back={true} />
<View style={styles.mainContainer}>
<View style={{ width: width }}>
<ScrollView>
<CommonTextInput
value={this.account}
onChangeText={account => (this.loginData.id = account)}
placeholder="Email"
secureTextEntry={false}
returnKeyType={"next"}
onSubmitEditing={event => {
this.passTextInput.focus();
}}
/>
<CommonTextInput
value={this.password}
onChangeText={password => (this.loginData.pwd = password)}
placeholder="Password"
inputRef={input => {
this.passTextInput = input;
}}
returnKeyType={"done"}
secureTextEntry={true}
onSubmitEditing={event => {
Keyboard.dismiss()
}}
/>
</ScrollView>
<TouchableOpacity
style={{ alignItems: "flex-end" }}
onPress={() => {
this.navigatieAction("ForgetPassword");
}}
>
<Text
style={{
color: theme.forgetTextColor,
fontFamily: Fonts.century,
fontWeight: "bold",
marginRight: 30,
marginTop: 5,
textDecorationLine: "underline"
}}
>
Forget Password ? Go Reset
</Text>
</TouchableOpacity>
</View>
</View>
<TouchableOpacity
style={{ alignItems: "center", marginBottom: 15 }}
onPress={() => this.navigatieAction("SignUpInformation")}
// onPress = {()=>this.testing()}
>
<Text
style={{
color: theme.forgetTextColor,
fontFamily: Fonts.century,
fontWeight: "bold",
marginTop: 5,
textDecorationLine: "underline"
}}
>
No Account ? Go Register
</Text>
</TouchableOpacity>
<Button
title="Login"
fontWeight="bold"
fontSize={size.getSize(18)}
fontFamily={Fonts.century}
titleStyle={{
color: "white",
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 50
}}
loadingProps={{
size: "large",
color: "rgba(111, 202, 186, 1)"
}}
buttonStyle={styles.signupButton}
onPress={() => this.loginAction()}
/>
<Toast ref="toast" />
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
TextViewContainer: {
backgroundColor: theme.inputBgc,
marginLeft: 20,
marginRight: 20,
marginTop: 30,
height: verticalScale(40),
borderRadius: 5
},
TextView: {
color: theme.foodNameColor,
height: verticalScale(35),
marginBottom: moderateScale(30),
paddingBottom: 0,
fontSize: size.getSize(15),
paddingRight: 20,
paddingLeft: 20,
fontFamily: Fonts.century
},
mainContainer: {
flex: 1,
alignItems: "center",
marginTop: 10
},
loginButton: {
width: scale(200),
height: verticalScale(50),
marginTop: moderateScale(60)
},
signupButton: {
width: width,
height: verticalScale(60),
backgroundColor: theme.mainColor
}
});

253
app/containers/Menu/init.js Executable file
View File

@@ -0,0 +1,253 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
SafeAreaView,
TouchableOpacity,
ImageBackground,
NetInfo,
Geolocation,
Image,
Text
} from "react-native";
import { observable, transaction } from "mobx";
import Icon2 from "react-native-vector-icons/dist/MaterialCommunityIcons";
import Permissions from "react-native-permissions";
import firebase from "react-native-firebase";
import { observer, inject } from "mobx-react/native";
import Size from "../../config/size";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import { width, height } from "../../config/screen";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import debounce from "lodash.debounce";
import theme from '../../config/colors'
const size = new Size();
const asyncStorageHelper = new AsyncStorageHelper();
@inject(["menuStore"], ["userStore"])
@observer
class Init extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
firebase.analytics().setAnalyticsCollectionEnabled(true);
}
static navigationOptions = {
gesturesEnabled: false
}
navigatieAction(page,Param) {
console.log(page)
this.props.navigation.navigate(page,Param);
}
debounceInput = debounce(() => {
this.init();
}, 100);
login() {
asyncStorageHelper.getData("userInfo", userInfo => {
if (userInfo != null) {
console.log(userInfo);
this.userStore.loginPost(userInfo, this, false);
}
});
}
notificationInit() {
firebase
.messaging()
.hasPermission()
.then(enabled => {
if (enabled) {
firebase
.messaging()
.getToken()
.then(notificationToken => {
console.log("LOG: ", notificationToken);
this.userStore.regUserNotificationTokenWithNoMid(notificationToken)
});
// user has permissions
} else {
firebase
.messaging()
.requestPermission()
.then(() => {
// alert("User Now Has Permission");
})
.catch(error => {
console.log(error);
// alert("Error", error);
// User has rejected permissions
});
}
});
this.notificationListener = firebase
.notifications()
.onNotification(notification => {
// Process your notification as required
const {
body,
data,
notificationId,
sound,
subtitle,
title
} = notification;
console.log("LOG: ", title, body, JSON.stringify(data));
});
}
getMenuItemFromInit(){
this.store.getMenuItem(this);
}
init() {
var testdate = new Date(2019, 2, 20, 11, 1, 0, 0)
console.log('testdate: '+ testdate)
console.log('utc: '+testdate.getUTCDate())
console.log('utc: '+testdate.getDate())
this.userStore.languageInit()
asyncStorageHelper.getData("userInfo", userInfo => {
console.log('test')
if (userInfo != null) {
//this.store.getMenuItem(this);
this.login();
// console.log('testing '+ this.store.pickupPointId)
asyncStorageHelper.getData("pickupPointId", pickupPointId => {
this.userStore.pickupPointId = pickupPointId
this.store.pickupPointId = pickupPointId
console.log('testing '+ this.store.pickupPointId)
this.userStore.pickupLoaction(this, true,pickupPointId);
})
} else {
this.notificationInit();
asyncStorageHelper.getData("pickupPointId", pickupPointId => {
console.log(pickupPointId)
if (pickupPointId != null) {
this.userStore.pickupPointId = pickupPointId
this.store.pickupPointId = pickupPointId
console.log('init pickupPointId: ' + pickupPointId)
this.userStore.pickupLoaction(this, true,pickupPointId);
//this.store.getMenuItem(this);
} else {
this.userStore.pickupLoaction(this, false,0);
}
});
}
});
}
getUserLocation() {
navigator.geolocation.getCurrentPosition(
position => {
this.userStore.userLocation = position;
console.log(position);
},
error => {
console.log(error);
},
{ enableHighAccuracy: false, timeout: 10000, maximumAge: 10000 }
);
}
async createNotificationListeners() {
/*
* Triggered when a particular notification has been received in foreground
* */
this.notificationListener = firebase
.notifications()
.onNotification(notification => {
const { title, body } = notification;
// this.showAlert(title, body);
});
/*
* If your app is in background, you can listen for when a notification is clicked / tapped / opened as follows:
* */
this.notificationOpenedListener = firebase
.notifications()
.onNotificationOpened(notificationOpen => {
const { title, body } = notificationOpen.notification;
// this.showAlert(title, body);
});
/*
* If your app is closed, you can check if it was opened by a notification being clicked / tapped / opened as follows:
* */
const notificationOpen = await firebase
.notifications()
.getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
// this.showAlert(title, body);
}
/*
* Triggered for data only payload in foreground
* */
this.messageListener = firebase.messaging().onMessage(message => {
//process data message
console.log(JSON.stringify(message));
});
}
showAlert(title, body) {
Alert.alert(
title,
body,
[{ text: "OK", onPress: () => console.log("OK Pressed") }],
{ cancelable: false }
);
}
componentDidMount() {
NetInfo.isConnected.addEventListener("connectionChange", isConnected => {
console.log("Network status:" + (isConnected ? "online" : "offline"));
});
this.debounceInput();
this.createNotificationListeners();
Permissions.check("location", { type: "whenInUse" }).then(response => {
console.log(response);
});
// this._requestPermission();
console.log(this.userStore.logined);
}
_requestPermission = () => {
Permissions.request("location").then(response => {
// Returns once the user has chosen to 'allow' or to 'not allow' access
// Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
// this.setState({ photoPermission: response })
console.log(response);
});
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center",backgroundColor:theme.mainColor }}>
<Image
style={{ tintColor: "white",height:scale(70),width:scale(70) }}
source={require("../../images/appicon.png")}
resizeMode = {'contain'}
/>
<Text>
{this.store.errorMessage}
</Text>
</View>
);
}
}
export default Init;

388
app/containers/Menu/menu.js Executable file
View File

@@ -0,0 +1,388 @@
// plug in
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
SafeAreaView,
TouchableOpacity,
ImageBackground,
NetInfo,
Alert,
StatusBar,
Keyboard,
TouchableWithoutFeedback,
AppState,
BackHandler
} from "react-native";
import { observable, transaction } from "mobx";
import Text from "react-native-text";
import { observer, inject } from "mobx-react/native";
import Icon from "react-native-vector-icons/dist/Ionicons";
import Icon2 from "react-native-vector-icons/dist/MaterialCommunityIcons";
import { SearchBar } from "react-native-elements";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import debounce from "lodash.debounce";
import Toast, { DURATION } from "react-native-easy-toast";
import PopupDialog, { SlideAnimation } from "react-native-popup-dialog";
import firebase from "react-native-firebase";
import Autocomplete from "react-native-autocomplete-input";
import { ifIphoneX } from 'react-native-iphone-x-helper'
// component
import TopMessageText from "../../components/Menu/topMessageText";
import MenuFlatList from "../../components/Menu/menuFlatList";
import TotalPriceView from "../../components/Menu/totalPriceView";
import MenuDetailsView from "../../components/Menu/menuDetailsView";
import GoogleAutoComplete from "../../components/Menu/googleAutoComplete";
import Map from "../../components/Menu/map";
// function
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import Log from '../../config/log'
import Size from "../../config/size";
import { width, height } from "../../config/screen";
import api from "../../stores/api";
import theme from "../../config/colors";
import MyStatusBar from "../../components/Public/statusBar";
import Language from "../../config/language"
import language from "../../config/language";
const log = new Log()
const size = new Size();
const asyncStorageHelper = new AsyncStorageHelper();
const slideAnimation = new SlideAnimation({
slideFrom: "bottom"
});
const endDate = new Date();
endDate.setHours(endDate.getHours() + 1);
@inject(["menuStore"], ["userStore"])
@observer
export default class Menu extends Component {
data = {};
@observable
menuDetails = {
id: 0,
count: 0,
price: 0,
name: "",
nameEn: "",
imageURL: "",
intro_ch: "",
intro_en: "",
restaurant: {
name: "",
nameEn: "",
addrEn: "",
addr: ""
}
};
@observable
query = "";
@observable
autoPlaceFocus = false;
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
static navigationOptions = {
drawerLabel: "Menu of the Day",
swipeEnabled: false,
tabBarLabel: language.en.menu,
};
async componentDidMount() {
this.checkPermission();
// this.createNotificationListeners();
}
async checkPermission() {
const enabled = await firebase.messaging().hasPermission();
if (enabled) {
this.getToken();
} else {
this.requestPermission();
}
}
onClickAction(data, details) {
this.map.goPosition(data, details)
}
add(id) {
this.store.addCount(id);
}
sum(id) {
this.store.sumCount(id);
}
//3
async getToken() {
let fcmToken = await AsyncStorage.getItem("fcmToken", value);
if (!fcmToken) {
fcmToken = await firebase.messaging().getToken();
if (fcmToken) {
// user has a device token
await AsyncStorage.setItem("fcmToken", fcmToken);
}
}
}
//2
async requestPermission() {
try {
await firebase.messaging().requestPermission();
// User has authorised
this.getToken();
} catch (error) {
// User has rejected permissions
console.log("permission rejected");
}
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', function () {
return true
})
}
getIndex(id) {
var index = this.userStore.pickupPointLabel.findIndex(function(item, i) {
return item.id == parseInt(id);
});
return index;
}
confirmAction(id) {
Alert.alert(
"",
"Select " +
this.userStore.pickupPointLabel[this.getIndex(id)].value +
"?",
[
{ text: "Cancel", onPress: () => console.log("Cancel") },
{ text: "Yes", onPress: () => this.update(id) }
]
);
}
componentDidMount(){
// console.log('token: '+ this.userStore.userData.data.token)
//this.store.userCoupon(this,this.userStore.userData.data.token,true)
AppState.addEventListener('change', (state) => {
if (state === 'active') {
console.log('state active');
this.store.updateMenu()
}
if(state === 'background'){
console.log('background');
}
})
this.props.navigation.addListener('willFocus', (route) => {this.store.updateMenu()});
}
async createNotificationListeners() {
/*
* Triggered when a particular notification has been received in foreground
* */
this.notificationListener = firebase
.notifications()
.onNotification(notification => {
const { title, body } = notification;
this.showAlert(title, body);
});
/*
* If your app is in background, you can listen for when a notification is clicked / tapped / opened as follows:
* */
this.notificationOpenedListener = firebase
.notifications()
.onNotificationOpened(notificationOpen => {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
});
/*
* If your app is closed, you can check if it was opened by a notification being clicked / tapped / opened as follows:
* */
const notificationOpen = await firebase
.notifications()
.getInitialNotification();
if (notificationOpen) {
const { title, body } = notificationOpen.notification;
this.showAlert(title, body);
}
/*
* Triggered for data only payload in foreground
* */
this.messageListener = firebase.messaging().onMessage(message => {
//process data message
console.log(JSON.stringify(message));
});
}
showAlert(title, body) {
Alert.alert(
title,
body,
[{ text: "OK", onPress: () => console.log("OK Pressed") }],
{ cancelable: false }
);
}
navigatieAction(page, Param) {
this.props.navigation.navigate(page, Param);
}
searchClear() {}
searchChangeText() {}
foodInformationPagePopUp() {
this.popupDialog.show();
}
foodInformationPageDismiss() {
this.popupDialog.dismiss();
}
foodInformationPageDismissedCallBack() {
console.log("dismiss dialog");
}
update(id){
// this.autoPlaceFocus = false;
console.log('update')
this.googleInput.blur()
asyncStorageHelper.saveData("pickupPointId", id);
this.store.pickupPointId = id;
this.userStore.pickupPointId = id;
log.firebaseLog('change_pickuppoint_from_menu',{logined:this.userStore.logined,pickupPointId:id})
this.store.updateMenuByMap(this,id);
this.googleInput.onTextChange(id);
asyncStorageHelper.getData("userInfo", userInfo => {
if (userInfo != null) {
this.userStore.savePickUpPointToServer(id);
}
});
}
render() {
log.firebaseClass('menu')
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<MyStatusBar
backgroundColor={theme.mainColor}
barStyle="light-content"
/>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={[this.autoPlaceFocus? styles.topContainerForIphoneX:styles.topContainer]} />
{this.autoPlaceFocus == false ? (
<View style={styles.titleAndDateContainer}>
<TopMessageText date={this.store.cutoffDateTime} />
</View>
) : (
<View/>
)}
{this.autoPlaceFocus == false ? (
<View style={styles.flatViewContainer}>
<MenuFlatList data={this.store.menu} menu={this} />
</View>
) : (
<Map perfdefinedPlaces = {this.userStore.perdefinedPlaces} onRef={ref => (this.map = ref)} onPress ={(id)=>{
this.confirmAction(id)
}}/>
)}
<View style={{ position: "absolute", top: verticalScale(1) }}>
<GoogleAutoComplete
onRef={ref => (this.googleInput = ref)}
perdefinedPlaces={this.userStore.perdefinedPlaces}
onFocus={() => {
this.autoPlaceFocus = true;
}}
onPress = {(data,details)=>{this.onClickAction(data,details)}}
/>
</View>
</View>
</TouchableWithoutFeedback>
<PopupDialog
ref={popupDialog => {
this.popupDialog = popupDialog;
}}
dialogAnimation={slideAnimation}
height={height - moderateScale(90)}
onDismissed={() => this.foodInformationPageDismissedCallBack()}
>
<MenuDetailsView self={this} />
</PopupDialog>
<TotalPriceView self={this} />
<Toast ref="toast" />
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
topContainer: {
height: "8%",
width: "100%",
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.mainColor
},
topContainerForIphoneX:{
...ifIphoneX({
height: "12%",
},
{
height: "8%",
}),
width: "100%",
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.mainColor
},
titleAndDateContainer: {
height: "9%",
width: "100%",
backgroundColor: theme.mainColor,
justifyContent: "center"
},
flatViewContainer: {
height: "85%",
width: "100%",
marginTop: 10,
alignItems: "center",
}
});

View File

@@ -0,0 +1,587 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
ScrollView,
TouchableOpacity,
Image,
SafeAreaView,
TextInput,
Alert
} from "react-native";
import { observable } from "mobx";
import Text from "react-native-text";
import { Button } from "react-native-elements";
import { observer, inject } from "mobx-react/native";
import Header from "../../components/Public/header";
import Toast, { DURATION } from "react-native-easy-toast";
import { width, height } from "../../config/screen";
import FoodsRow from "../../components/MyOrders/foodsRow";
import FastImage from "react-native-fast-image";
import Icon from "react-native-vector-icons/dist/MaterialCommunityIcons";
import Log from "../../config/log";
import Size from "../../config/size";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { Dropdown } from "react-native-material-dropdown";
import CommonTextView from "../../components/Public/commonTextView";
import theme from "../../config/colors";
import Loader from "../../components/Public/loader";
import { Popup } from "react-native-map-link";
import { Fonts } from "../../config/fonts";
import { colors } from "react-native-elements";
const size = new Size();
const log = new Log();
const time = [
{
value: "12:10 - 12:40",
format: "12101240"
},
{
value: "13:10 - 13:40",
format: "13101340"
},
{
value: "14:10 - 14:40",
format: "14101440"
}
];
@inject(["menuStore"], ["userStore"])
@observer
export default class ConfirmOrder extends Component {
@observable
message = "";
@observable
tel = "1234556";
@observable
pomoCode = "";
@observable
total = 0;
@observable
discount = 0;
@observable
subVaule = 0;
@observable
options = {
latitude: 38.8976763,
longitude: -77.0387185,
title: "",
dialogTitle: "Select the map",
dialogMessage: "",
cancelText: "Cancel"
};
timeIndex = null;
couponLabel = [];
static navigationOptions = {
drawerLabel: "My Orders"
};
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
this.state = {
isVisible: false
};
}
componentDidMount() {
log.firebaseClass("ConfirmOrder");
this.total = this.store.totalMoney.toFixed(2);
this.tel = this.userStore.userData.data.member.mobile;
console.log(this.store.couponLabel);
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
renderFoodsList() {
return this.store.orderList.map(items => {
console.log(items.cuisine.nameEn);
return (
<FoodsRow
items={items}
key={items.id}
lang={this.userStore.languageSelection}
/>
);
});
}
dateFormat() {
var cutoffDate = this.store.cutoffDateTime;
console.log(this.store.cutoffDateTime);
var today = new Date();
var tomorrowOrToday = "";
if (today.getUTCDate() == cutoffDate.getUTCDate()) {
var tomorrowOrToday = "(Today)";
}
var options = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
};
return cutoffDate.toLocaleDateString("En", options) + tomorrowOrToday;
}
discountText() {
if (this.discount > 0) {
return (
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 13
}}
>
Discount {this.discount + "%" + " off"}
</Text>
);
} else if (this.subVaule > 0) {
return (
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 13
}}
>
Total {"- " + this.subVaule}
</Text>
);
}
}
orderAction() {
var today = new Date();
yymmdd =
today.getFullYear() +
"-" +
("0" + (today.getMonth() + 1)).slice(-2) +
"-" +
("0" + (today.getDay() + 1)).slice(-2);
console.log(yymmdd);
var token = this.userStore.userData.data.token;
console.log(token);
var orderData = {
pickUpLocation: {
id: this.userStore.pickupPointId
},
// "pickUpDate": yymmdd,
// "pickUpTime": time[this.timeIndex].format,
items: this.store.items,
coupon: this.pomoCode,
mobile: this.tel,
remark: this.message
};
console.log(orderData);
this.store.order(token, orderData, this);
}
onChangeText(text) {
this.pomoCode = text;
this.pressYeahButton();
}
pay() {
this.store.loading = false;
Alert.alert("", "Pay now? ", [
{
text: "Cancel",
onPress: () => {
log.firebaseLog("press_cancel_button_on_confirmOrder", {}),
this.store.cancelOrder(this.userStore.userData.data.token);
}
},
{
text: "Pay",
onPress: () => {
log.firebaseLog("press_pay_button_on_confirmOrder", {}),
this.store.pay(
this.userStore.userData.data.token,
this,
this.userStore.creditCardinfo.id
);
}
}
]);
}
// type 0 all user can use, type 1 all user can use once
discountAction(data) {
if (data.value == 0) {
this.discount = data.percent;
if (this.discount == null || this.discount == 0) {
this.total = this.store.totalMoney.toFixed(2);
} else {
var total = (this.store.totalMoney * (100 - this.discount)) / 100;
this.total = total.toFixed(2);
}
} else {
this.subVaule = data.value;
if (this.subVaule == null || this.subVaule == 0) {
this.total = this.store.totalMoney.toFixed(2);
} else {
var total = this.store.totalMoney - this.subVaule;
this.total = total.toFixed(2);
}
}
}
pressYeahButton() {
log.firebaseLog("press_yeah_button_on_confirmOrder", {}),
this.store.coupon(
this.userStore.userData.data.token,
this,
this.pomoCode
);
this.subVaule = 0;
this.discount = 0;
}
back() {
this.props.navigation.goBack();
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<Loader loading={this.store.loading} />
<View style={styles.container}>
<View style={{ width: width, marginTop: 15 }}>
<Icon
name="chevron-left"
size={size.getSize(40)}
color={theme.foodNameColor}
style={{ marginLeft: 10 }}
onPress={() => this.back()}
/>
</View>
<ScrollView style={{ width: width, flex: 1 }}>
<View style={{ marginRight: 20, marginLeft: 20 }}>
{this.renderFoodsList()}
<View
style={{
flexDirection: "row",
marginTop: 10,
marginBottom: 10,
marginLeft: 5,
marginRight: 5,
alignItems: "flex-start",
justifyContent: "space-between"
}}
>
<View style={{ flexDirection: "row" }}>
<Image
resizeMode={"contain"}
source={require("../../images/promo.png")}
/>
<View>
<View
style={{
backgroundColor: theme.inputBgc,
justifyContent: "center",
alignItems: "center",
width: 110,
height: 20,
marginLeft: 5
}}
>
<TextInput
style={{
width: 100,
color: theme.coolGrey,
...Platform.select({
ios: {
height: 20
},
android: {
paddingBottom: 5,
height: 30
}
})
}}
value={this.pomoCode}
underlineColorAndroid="rgba(0,0,0,0)"
onChangeText={text => (this.pomoCode = text)}
placeholder={"Promo Code"}
placeholderStyle={{
fontWeight: "bold",
fontFamily: Fonts.century
}}
placeholderTextColor={theme.coolGrey}
/>
</View>
<View style={{ marginLeft: 5, marginTop: -5 }}>
<Dropdown
label={this.userStore.text.coupon}
onChangeText={text => {
this.onChangeText(text);
}}
data={this.store.couponLabel}
fontSize={12}
/>
</View>
</View>
</View>
<TouchableOpacity
style={{
backgroundColor: theme.mainColor,
height: 20,
width: 60,
alignItems: "center",
justifyContent: "center"
}}
onPress={() => {
this.pressYeahButton();
}}
>
<Text
style={{
fontFamily: Fonts.century,
color: "white",
fontSize: 13,
fontWeight: "bold"
}}
>
Yeah
</Text>
</TouchableOpacity>
</View>
{this.discountText()}
<View
style={{
flexDirection: "row",
marginTop: 10,
marginBottom: 10,
marginLeft: 5,
marginRight: 5,
alignItems: "center",
justifyContent: "space-between"
}}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 15
}}
>
TOTAL
</Text>
<View
style={{ flexDirection: "row", justifyContent: "flex-end" }}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 15
}}
>
HKD ${this.total}
</Text>
</View>
</View>
<Text
style={{
fontSize: 13,
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold"
}}
>
Delivery Details
</Text>
<View>
<CommonTextView
title="Pickup Date"
content={this.dateFormat()}
/>
<TouchableOpacity
onPress={() => {
this.options.latitude = this.userStore.pickupPointLabel[
this.userStore.pickupIndex
].lat;
this.options.longitude = this.userStore.pickupPointLabel[
this.userStore.pickupIndex
].lng;
this.setState({ isVisible: true });
}}
>
<CommonTextView
title="Pickup Location"
content={this.userStore.dataLanguage(
this.userStore.pickupPointLabel[
this.userStore.pickupIndex
],
"name"
)}
/>
</TouchableOpacity>
<CommonTextView
title="Pickup Time"
content={
this.userStore.pickupPointLabel[this.userStore.pickupIndex]
.pickupStartTime +
" - " +
this.userStore.pickupPointLabel[this.userStore.pickupIndex]
.pickupEndTime
}
/>
</View>
<View
style={{
borderBottomColor: "black",
borderBottomWidth: 1,
marginTop: 15,
marginBottom: 10,
width: "70%"
}}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontSize: 13
}}
>
Mobile phone
</Text>
<TextInput
style={{
width: "60%",
color: theme.coolGrey,
fontSize: size.getSize(13),
paddingVertical: 0
}}
value={this.tel}
keyboardType={"numeric"}
underlineColorAndroid="rgba(0,0,0,0)"
onChangeText={tel => (this.tel = tel)}
/>
</View>
<FastImage
style={{
width: width - 40,
marginTop: 15,
marginBottom: 15,
height: verticalScale(200),
backgroundColor: theme.mainColor
}}
source={{
uri: this.userStore.pickupPointLabel[
this.userStore.pickupIndex
].photo
}}
/>
<Text
style={{
marginTop: 15,
marginBottom: 5,
fontSize: 13,
color: theme.coolGrey,
fontFamily: Fonts.century
}}
>
Message box
</Text>
<TextInput
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
width: width - 40,
height: verticalScale(100),
marginBottom: 20,
paddingBottom: 0,
paddingRight: 5,
paddingLeft: 5,
fontSize: size.getSize(13),
fontFamily: Fonts.century,
borderColor: theme.foodNameColor,
borderWidth: 1,
borderRadius: 5,
paddingVertical: 0
}}
multiline={true}
value={this.message}
underlineColorAndroid="rgba(0,0,0,0)"
onChangeText={text => (this.message = text)}
placeholder={"Tell me any requires"}
placeholderStyle={{
fontWeight: "bold",
fontFamily: Fonts.century
}}
placeholderTextColor={theme.foodNameColor}
/>
</View>
</ScrollView>
<Button
title="confirm order"
fontWeight="bold"
fontSize={size.getSize(15)}
fontFamily={Fonts.century}
titleStyle={{
color: "white",
fontFamily: Fonts.century,
fontWeight: "bold"
}}
loadingProps={{
size: "large",
color: "rgba(111, 202, 186, 1)"
}}
buttonStyle={styles.signupButton}
onPress={() => this.orderAction()}
/>
<Toast ref="toast" />
</View>
<Popup
isVisible={this.state.isVisible}
onCancelPressed={() => this.setState({ isVisible: false })}
onAppPressed={() => this.setState({ isVisible: false })}
onBackButtonPressed={() => this.setState({ isVisible: false })}
options={this.options}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "white"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
signupButton: {
width: width,
height: verticalScale(50),
backgroundColor: theme.mainColor
}
});

View File

@@ -0,0 +1,165 @@
import React, { Component } from "react";
import { Platform, StyleSheet, Text, View, SafeAreaView } from "react-native";
import { observer, inject } from "mobx-react/native";
import { observable } from "mobx";
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import OrderFlatList from "../../components/MyOrders/orderFlatList";
import ScrollableTabView from "react-native-scrollable-tab-view";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Loader from "../../components/Public/loader";
import Login from "../Login/login";
import Log from "../../config/log"
import { width, height } from "../../config/screen";
import Header from '../../components/Public/signInUpHeader'
import theme from "../../config/colors";
import language from "../../config/language";
const log = new Log()
const asyncStorageHelper = new AsyncStorageHelper();
@inject(["menuStore"], ["userStore"])
@observer
export default class MyOrders extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
static navigationOptions = {
drawerLabel: "My Orders",
swipeEnabled: false,
tabBarLabel: "My Order"
};
componentWillMount() {
// this.init();
}
init() {
if (this.userStore.logined == false) {
// this.props.navigation.navigate('Login')
} else {
var token = this.userStore.userData.data.token;
this.store.getOrder(this, token);
}
}
componentDidMount(){
log.firebaseClass('orders')
console.log('componentDidMount')
this.props.navigation.addListener('willFocus', (route) => {this.init()});
}
render() {
console.log(this.store.passOrder);
return (
<SafeAreaView style={{ backgroundColor: theme.mainColor, flex: 1 }}>
<Loader loading={this.store.loading} />
<View style={styles.container}>
<ScrollableTabView
tabBarActiveTextColor={theme.mainColor}
tabBarUnderlineStyle={{ backgroundColor: "white", height: 1 }}
tabBarBackgroundColor={"white"}
>
<CurrentOrder
tabLabel="Current Order"
orderHistory={this.store.currentOrder}
navigation={this.props.navigation}
whichOrder = {true}
/>
<PassOrder
tabLabel="Past Order"
orderHistory={this.store.passOrder}
navigation={this.props.navigation}
whichOrder = {false}
/>
</ScrollableTabView>
</View>
</SafeAreaView>
);
}
}
const PassOrder = props => {
return (
<View>
<View
style={{
marginTop: 20,
alignItems: "center",
flexDirection: "row",
backgroundColor: "white",
width: width - 1
}}
>
</View>
<View style={styles.flatViewContainer}>
<OrderFlatList
whichOrder = {props.whichOrder}
data={props.orderHistory}
navigation={props.navigation}
/>
</View>
</View>
);
};
const CurrentOrder = props => {
return (
<View>
{/* <View
style={{
marginTop: 20,
alignItems: "center",
flexDirection: "row",
backgroundColor: "white",
width: width - 1
}}
>
<View style={{ width: "65%" }}>
<Text
style={[styles.textView, { fontWeight: "bold" }]}
numberOfLines={1}
>
Order details
</Text>
</View>
<View style={{ width: "45%" }}>
<Text style={[styles.textView, { fontWeight: "bold" }]}>Status</Text>
</View>
</View> */}
<View style={styles.flatViewContainer}>
<OrderFlatList
data={props.orderHistory}
navigation={props.navigation}
whichOrder = {props.whichOrder}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
...Platform.select({
android: {
marginTop: verticalScale(30)
}
})
},
flatViewContainer: {
height: "98%",
width: "100%",
alignItems: "center",
marginBottom: 40
},
textView: {
marginLeft: scale(15),
marginBottom: scale(5)
}
});

View File

@@ -0,0 +1,394 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
ScrollView,
TouchableOpacity,
ActivityIndicator,
Alert,
SafeAreaView
} from "react-native";
import { observable } from "mobx";
import { Button } from "react-native-elements";
import Text from "react-native-text";
import { observer, inject } from "mobx-react/native";
import Header from "../../components/Public/header";
import Toast, { DURATION } from "react-native-easy-toast";
import { width, height } from "../../config/screen";
import FoodsRow from "../../components/MyOrders/foodsRow";
import moment from "moment";
import FoodsRowForOrderDetails from "../../components/MyOrders/foodsRowForOrderDetails";
import Icon from "react-native-vector-icons/dist/MaterialCommunityIcons";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { Dropdown } from "react-native-material-dropdown";
import FastImage from "react-native-fast-image";
import { Popup } from "react-native-map-link";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import CommonTextView from "../../components/Public/commonTextView";
import Size from "../../config/size";
const size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
export default class OrderDetails extends Component {
@observable
buttonColor = theme.mainColor;
@observable
buttonDisabled = false;
@observable
options = {
latitude: 38.8976763,
longitude: -77.0387185,
title: "",
dialogTitle: "Select the map",
dialogMessage: "",
cancelText: "Cancel"
};
timeIndex = null;
data = {};
static navigationOptions = {
drawerLabel: "My Orders"
};
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
this.state = {
isVisible: false
};
}
componentWillMount() {
const { navigation } = this.props;
this.data = navigation.getParam("data", {});
this.time = navigation.getParam("time", {});
//console.log(this.data+" "+this.time);
this.options.latitude = this.data.pickUpLocation.lat;
this.options.longitude = this.data.pickUpLocation.lng;
this.options.title = this.data.pickUpLocation.name;
this.canCancelOrNot();
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
dateFormat() {
var momentDate = moment(this.data.items[0].pickupEnd);
var timestamp = momentDate.toDate();
var options = {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
};
return timestamp.toLocaleDateString("En", options);
}
pickupTime(){
var pickupTimeStartString = this.data.items[0].pickupStart.substring(11,16)
var pickupTimeEndString = this.data.items[0].pickupEnd.substring(11,16)
return pickupTimeStartString + " - " + pickupTimeEndString
}
canCancelOrNot() {
if (this.data.status != "D") {
if (this.time) {
this.buttonColor = theme.inputBgc;
this.buttonDisabled = true;
} else {
console.log('this')
this.buttonColor = theme.mainColor;
this.buttonDisabled = false;
}
} else {
this.buttonColor = theme.inputBgc;
this.buttonDisabled = true;
}
}
renderFoodsList() {
return this.data.items.map(items => {
return (
<FoodsRowForOrderDetails
items={items}
key={items.id}
lang={this.userStore.languageSelection}
/>
);
});
}
back() {
this.props.navigation.goBack();
}
goLocationAction() {
this.props.navigation.navigate("Location", {
location: {
latitude: this.data.pickUpLocation.lat,
longitude: this.data.pickUpLocation.lng
}
});
}
discountText() {
if (this.data.discount > 0) {
return (
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize: 10
}}
>
{"- "+this.data.discount}
</Text>
);
}
}
cancelAction() {}
cancelOrderAlert() {
Alert.alert("", "Are you sure to cancel this order?", [
{ text: "Cancel", onPress: () => console.log("Cancel") },
{ text: "Cancel order", onPress: () => this.cancelOrder() }
]);
}
cancelOrder() {
var token = this.userStore.userData.data.token;
this.store.voidOrder(token, this.data.id, this);
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<View style={styles.container}>
<View style={{ width: width, marginTop: 15 }}>
<Icon
name="chevron-left"
size={size.getSize(40)}
color={theme.foodNameColor}
style={{ marginLeft: 10 }}
onPress={() => this.back()}
/>
</View>
<ScrollView style={{ width: width, flex: 1 }}>
<View style={{ marginRight: 20, marginLeft: 20 }}>
{this.renderFoodsList()}
{this.discountText()}
<View
style={{
flexDirection: "row",
marginTop: 10,
marginBottom: 10,
marginLeft: 5,
marginRight: 5,
alignItems: "center",
justifyContent: "space-between"
}}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize:15,
}}
>
TOTAL
</Text>
<View
style={{ flexDirection: "row", justifyContent: "flex-end" }}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize:15
}}
>
HKD ${this.data.payAmount.toFixed(2)}
</Text>
</View>
</View>
<Text
style={{
fontSize: 10,
color: theme.coolGrey,
fontFamily: Fonts.century,
fontWeight: "bold",
fontSize:15
}}
>
Delivery Details
</Text>
<View>
<CommonTextView
title="Pickup Date"
content={this.dateFormat()}
/>
<TouchableOpacity
onPress={() => {
this.setState({ isVisible: true });
}}
>
<CommonTextView
title="Pickup Location"
content={this.userStore.dataLanguage(
this.data.pickUpLocation,
"name"
)}
/>
</TouchableOpacity>
<CommonTextView
title="Pickup Time"
content={
this.pickupTime()
}
/>
</View>
<View
style={{
borderBottomColor: "black",
borderBottomWidth: 1,
marginTop: 15,
marginBottom: 10,
width: "70%"
}}
>
<Text
style={{
color: theme.coolGrey,
fontFamily: Fonts.century,
fontSize: 13
}}
>
Mobile phone
</Text>
<Text
style={{
width: "60%",
color: theme.coolGrey,
fontSize: 13
}}
>
{this.data.mobile}
</Text>
</View>
<FastImage
style={{
width: width - 40,
marginTop: 15,
marginBottom: 15,
height: verticalScale(200),
backgroundColor: theme.mainColor
}}
source={{
uri: this.data.pickUpLocation.photo
}}
/>
<Text
style={{
marginTop: 15,
marginBottom: 5,
fontSize: 13,
color: theme.coolGrey,
fontFamily: Fonts.century
}}
>
Message box
</Text>
<Text
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
width: width - 40,
height: verticalScale(100),
marginBottom: 20,
paddingBottom: 0,
paddingRight: 5,
paddingLeft: 5,
fontSize: 13,
fontFamily: Fonts.century,
borderColor: theme.foodNameColor,
borderWidth: 1,
borderRadius: 5
}}
>
{this.data.remark}
</Text>
</View>
</ScrollView>
<Button
title="Cancel order"
fontWeight="bold"
disabled={ this.buttonDisabled}
fontSize={size.getSize(15)}
fontFamily={Fonts.century}
titleStyle={{
color: "white",
fontFamily: Fonts.century,
fontWeight: "bold"
}}
loadingProps={{
size: "large",
color: "rgba(111, 202, 186, 1)"
}}
buttonStyle={{
width: width,
height: verticalScale(50),
backgroundColor: this.buttonColor
}}
onPress={() => this.cancelOrderAlert()}
/>
<Toast ref="toast" />
</View>
<Popup
isVisible={this.state.isVisible}
onCancelPressed={() => this.setState({ isVisible: false })}
onAppPressed={() => this.setState({ isVisible: false })}
onBackButtonPressed={() => this.setState({ isVisible: false })}
options={this.options}
/>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "white"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
signupButton: {
width: width,
height: verticalScale(50),
backgroundColor: theme.mainColor
}
});

75
app/containers/Pay/pay.js Executable file
View File

@@ -0,0 +1,75 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
ScrollView,
TouchableOpacity
} from "react-native";
import Text from "react-native-text";
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Log from '../../config/log'
import Loader from '../../components/Public/loader'
import Toast, { DURATION } from "react-native-easy-toast";
import Header from "../../components/Public/header";
import { width, height } from "../../config/screen";
const log = new Log()
@inject(["menuStore"], ["userStore"])
@observer
class Pay extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
back() {
console.log(this.userStore.userData.data.token);
this.store.cancelOrder(this.userStore.userData.data.token);
this.props.navigation.goBack();
}
pay() {
log.firebaseLog('press_pay_button_on_pay_page')
this.store.pay(
this.userStore.userData.data.token,
this,
this.userStore.creditCardinfo.id
);
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
render() {
log.firebaseClass('pay')
return (
<View style={{ flex: 1, alignItems: "center" }}>
<Loader loading = {this.userStore.loading}/>
<Header
title="Pay"
navigation={this.props.navigation}
onPress={() => this.back()}
order={true}
/>
<TouchableOpacity
style={{
borderColor: "black",
borderWidth: 1,
height: 50,
width: 100,
alignItems: "center",
justifyContent: "center"
}}
onPress={() => this.pay()}
>
<Text>Pay</Text>
</TouchableOpacity>
<Toast ref="toast" />
</View>
);
}
}
export default Pay;

4
app/containers/README.md Executable file
View File

@@ -0,0 +1,4 @@
# Container Component here
1. Named with `xx_screen.js`
2. Classname with`XxScreen`

View File

@@ -0,0 +1,114 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
SafeAreaView,
Picker,
TouchableOpacity,
TouchableHighlight,
} from "react-native";
import RadioForm, {RadioButton, RadioButtonInput, RadioButtonLabel} from 'react-native-simple-radio-button';
import Size from "../../config/size";
import Icon from "react-native-vector-icons/dist/Ionicons";
import { observer, inject } from "mobx-react/native";
import { observable } from "mobx";
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { width, height } from "../../config/screen";
import language from "../../config/language";
import theme from "../../config/colors";
const asyncStorageHelper = new AsyncStorageHelper();
const size = new Size();
var radio_language = [
{label: 'English', value: 'english'},
{label: 'Chinese', value: 'chinese' }
];
@inject(["menuStore"], ["userStore"])
@observer
export default class Language extends Component {
//language = 'english'
static navigationOptions = {
drawerLabel: "Settings",
swipeEnabled: false,
tabBarLabel: language.en.setting,
};
state = { language: "chinese",
initial:0
};
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
componentWillMount() {
this.setState({ language: this.userStore.languageSelection });
if(this.userStore.languageSelection == 'chinese'){
this.setState({initial:1})
}else if (this.userStore.languageSelection == 'english'){
this.setState({initial:0})
}
console.log(this.state.language);
}
updateUser(language) {
this.userStore.saveLanguage(language);
this.setState({ language: language });
}
backAction() {
console.log('back')
this.props.navigation.goBack();
}
render() {
return (
<SafeAreaView style={{ backgroundColor: theme.mainColor, flex: 1 }}>
<View style={styles.container}>
<Icon
onPress={() => {this.backAction()}}
name="ios-arrow-back-outline"
size={size.getSize(40)}
color={"black"}
/>
{/* <Picker
selectedValue={this.state.language}
style={{ height: 50, width: 100 }}
onValueChange={(itemValue, itemIndex) => {
this.updateUser(itemValue);
}}
>
<Picker.Item label="中文" value="chinese" />
<Picker.Item label="English" value="english" />
</Picker> */}
<RadioForm
style = {{paddingTop: verticalScale(50),}}
radio_props={radio_language}
initial={this.state.initial}
onPress={(value) => {this.updateUser(value)}}/>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white"
},
flatViewContainer: {
height: "100%",
width: "100%",
alignItems: "center",
marginTop: 20
},
textView: {
marginLeft: scale(15),
marginBottom: scale(5)
}
});

View File

@@ -0,0 +1,193 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
ScrollView,
TouchableOpacity,
SafeAreaView,
Image
} from "react-native";
import Text from "react-native-text";
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Log from "../../config/log";
import theme from "../../config/colors";
import Size from "../../config/size";
import { Fonts } from "../../config/fonts";
import Icon2 from "react-native-vector-icons/dist/MaterialCommunityIcons";
import Loader from "../../components/Public/loader";
import moment from "moment";
import Toast, { DURATION } from "react-native-easy-toast";
import Header from "../../components/Public/header";
import CardView from "react-native-cardview";
import { width, height } from "../../config/screen";
const log = new Log();
const size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
class MyCoupons extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
back() {
this.props.navigation.goBack();
}
exiryDate(item) {
if (item.hasOwnProperty("expiry")) {
var nowDatemoment = moment(this.store.coupons.data.timestamp);
var nowDate = nowDatemoment.toDate();
var expiryDatemoment = moment(item.expiry);
var expiryDate = expiryDatemoment.toDate();
if (nowDate < expiryDate) {
return item.expiry;
} else {
return item.expiry + "(" + this.userStore.text.expired + ")";
}
} else {
return "N/A";
}
}
checking(item) {
if (item.used) {
return this.userStore.text.used;
} else {
if (item.hasOwnProperty("expiry")) {
var nowDatemoment = moment(this.store.coupons.data.timestamp);
var nowDate = nowDatemoment.toDate();
var expiryDatemoment = moment(item.expiry);
var expiryDate = expiryDatemoment.toDate();
if (nowDate < expiryDate) {
return this.userStore.text.canuse;
} else {
return this.userStore.text.cannotuse;
}
} else {
return this.userStore.text.canuse;
}
}
}
renderCoupons() {
return this.store.coupons.data.content.map((item, index, array) => {
return (
<CardView
cardElevation={5}
cardMaxElevation={5}
cornerRadius={5}
style={{
marginBottom: 20,
marginTop: 20,
marginLeft: 25,
marginRight: 25,
backgroundColor: theme.mainColor
}}
>
<Text
style={{
fontSize: 30,
fontFamily: Fonts.century,
color: "white",
paddingLeft: 10
}}
>
Coupon
</Text>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
marginTop: 10
}}
>
<Image
style={{
height: scale(70),
width: scale(70),
tintColor: "white",
marginLeft: 10
}}
source={require("../../images/appicon.png")}
/>
<View style={{ alignItems: "flex-end" }}>
<Text
style={{
fontSize: 15,
fontFamily: Fonts.century,
color: "white",
paddingRight: 10
}}
>
{item.id}
</Text>
<Text
style={{
fontSize: 15,
fontFamily: Fonts.century,
color: "white",
paddingRight: 10,
paddingTop: 10
}}
>
{this.checking(item)}
</Text>
</View>
</View>
<View style={{ alignItems: "flex-end",paddingRight:10,marginTop:10,marginBottom:5 }}>
<Text style={{ color: "white", fontSize: 15 }}>
{this.userStore.text.expireDate + ": " + this.exiryDate(item)}
</Text>
</View>
</CardView>
);
});
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
render() {
log.firebaseClass("MyCoupons");
return (
<SafeAreaView
style={{ flex: 1, backgroundColor: theme.mainColor, width: width }}
>
<Loader loading={this.userStore.loading} />
<View style={{ height: verticalScale(40) }}>
<Icon2
name="chevron-left"
size={size.getSize(40)}
color={"white"}
style={{ marginLeft: 10 }}
onPress={() => this.props.navigation.goBack()}
/>
</View>
<ScrollView
style={{
width: width,
backgroundColor: "white"
}}
>
<View
style={{
backgroundColor: "white",
width: width,
marginTop: 25
}}
>
{this.renderCoupons()}
</View>
</ScrollView>
<Toast ref="toast" />
</SafeAreaView>
);
}
}
export default MyCoupons;

View File

@@ -0,0 +1,15 @@
import React, { Component } from 'react';
import Header from '../../components/Public/header'
class NotificationSetting extends Component {
render() {
return (
<View>
<Header title={'Notification Preferences'} navigation={this.props.navigation} />
</View>
);
}
}
export default NotificationSetting;

View File

@@ -0,0 +1,446 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TouchableOpacity,
SafeAreaView,
ScrollView,
Image,
Linking,
Alert,
Share
} from "react-native";
import Text from "react-native-text";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import Icon from "react-native-vector-icons/dist/Ionicons";
import Icon2 from "react-native-vector-icons/dist/MaterialCommunityIcons";
import { width, height } from "../../config/screen";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import PopupDialog, { SlideAnimation } from "react-native-popup-dialog";
import language from "../../config/language";
const size = new Size();
const slideAnimation = new SlideAnimation({
slideFrom: "bottom"
});
@inject(["menuStore"], ["userStore"])
@observer
export default class SettingInside extends Component {
@observable
items = [
{
icon: require("../../images/settinglang.png"),
popup: true,
screen: "language",
id: 0
},
{
icon: require("../../images/settingnotification.png"),
screen: "NotificationSetting",
popup: true,
id: 1
},
{
icon: require("../../images/settinghowtouse.png"),
popup: true,
id: 2
},
{
icon: require("../../images/settinglogout.png"),
popup: true,
id: 3
}
];
@observable
lang = false;
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
static navigationOptions = {
drawerLabel: "Settings",
swipeEnabled: false,
tabBarLabel: language.en.setting
};
getTitle(id) {
switch (id) {
case 0:
return this.props.userStore.text.language;
break;
case 1:
return this.props.userStore.text.notification;
break;
case 2:
return this.props.userStore.text.howtouse;
break;
case 3:
return this.props.userStore.text.logout;
break;
}
}
componentWillMount() {
if (this.userStore.languageSelection == "english") {
this.lang = false;
} else {
this.lang = true;
}
}
languageText() {
if (this.userStore.languageSelection == "english") {
return "English";
} else {
return "繁體中文";
}
}
languageView(id) {
if (id == 0) {
return (
<View style={{ justifyContent: "center" }}>
<Text
style={{
fontSize: 15,
marginRight: scale(30),
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
{this.languageText()}
</Text>
</View>
);
} else {
return <View />;
}
}
onPressAction(index) {
if (this.items[index].popup) {
switch (index) {
case 0:
this.languagePagePopUp();
break;
case 1:
Linking.openURL("app-settings:");
break;
case 2:
this.props.navigation.navigate("Tutorial", { data: "setting" });
break;
case 3:
this.logoutAlert();
break;
}
} else {
console.log(this.items[index].screen);
this.props.navigation.navigate(this.items[index].screen);
}
}
logoutAlert() {
Alert.alert(
"Logout",
"Are you sure to Logout?",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "Sure", onPress: () => this.logoutAction() }
],
{ cancelable: false }
);
}
referYourFriender() {
Share.share({
message: "Hello,Come to join Hangry, this is my refer code: ",
title: "Hangry no more"
});
}
logoutAction() {
this.userStore.logoutPost(this, false);
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
renderItems() {
return this.items.map((item, index, array) => {
if (item.id == 3 && !this.userStore.logined) {
return null;
} else {
if (item.id == 1 && Platform.OS !== 'ios') {
return null;
}else{
return (
<TouchableOpacity
style={{ marginBottom: 20, marginLeft: 25, paddingRight: 25 }}
onPress={() => this.onPressAction(index)}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center"
}}
>
<Image source={item.icon} />
<Text
style={{
fontSize: 15,
marginLeft: 10,
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
{this.getTitle(item.id)}
</Text>
</View>
<View style={{ flexDirection: "row" }}>
{this.languageView(item.id)}
<Icon
name={"ios-arrow-forward"}
size={size.getSize(35)}
color={theme.coolGrey}
/>
</View>
</View>
<View
style={{
backgroundColor: theme.inputBgc,
flex: 1,
marginTop: 5,
marginLeft: 40,
height: 1
}}
/>
</TouchableOpacity>
);
}
}
});
}
languagePagePopUp() {
this.popupDialog.show();
}
languagePageDismiss() {
this.popupDialog.dismiss();
}
updateUser() {
if (this.lang) {
this.userStore.saveLanguage("chinese");
this.popupDialog.dismiss();
} else {
this.userStore.saveLanguage("english");
this.popupDialog.dismiss();
}
}
languagePageDismissedCallBack() {
console.log("dismiss dialog");
if (this.userStore.languageSelection == "english") {
this.lang = false;
} else {
this.lang = true;
}
}
selectIcon(lang) {
if (!lang) {
if (!this.lang) {
return (
<Icon2
name={"checkbox-blank-circle"}
size={size.getSize(35)}
color={theme.mainColor}
/>
);
} else {
return (
<Icon2
name={"checkbox-blank-circle-outline"}
size={size.getSize(35)}
color={theme.mainColor}
/>
);
}
} else {
if (!this.lang) {
return (
<Icon2
name={"checkbox-blank-circle-outline"}
size={size.getSize(35)}
color={theme.mainColor}
/>
);
} else {
return (
<Icon2
name={"checkbox-blank-circle"}
size={size.getSize(35)}
color={theme.mainColor}
/>
);
}
}
}
render() {
return (
<SafeAreaView style={styles.container}>
<View style={{ height: verticalScale(40) }}>
<Icon2
name="chevron-left"
size={size.getSize(40)}
color={"white"}
style={{ marginLeft: 10 }}
onPress={() => this.props.navigation.goBack()}
/>
</View>
<ScrollView style={{ backgroundColor: "white" }}>
<View
style={{
backgroundColor: "white",
width: width,
marginTop: 25
}}
>
{this.renderItems()}
<View style={{ flex: 1, alignItems: "flex-end", paddingRight: 25 }}>
<Text
style={{
fontFamily: Fonts.century,
color: theme.coolGrey,
fontSize: 10
}}
>
{"Ver 4.4 28 - 3 - 2019"}
</Text>
</View>
</View>
</ScrollView>
<PopupDialog
ref={popupDialog => {
this.popupDialog = popupDialog;
}}
dialogAnimation={slideAnimation}
height={height / 4}
width={width - scale(60)}
onDismissed={() => this.languagePageDismissedCallBack()}
>
<View style={{ flex: 1, justifyContent: "space-between" }}>
<View style={{ flex: 4, paddingTop: 5 }}>
<Text
style={{
paddingLeft: 5,
fontSize: 15,
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
{this.userStore.text.slectLang}
</Text>
<TouchableOpacity
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
}}
onPress={() => (this.lang = false)}
>
<Text
style={{
paddingLeft: 5,
fontSize: 15,
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
English
</Text>
{this.selectIcon(false)}
</TouchableOpacity>
<TouchableOpacity
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
}}
onPress={() => (this.lang = true)}
>
<Text
style={{
paddingLeft: 5,
fontSize: 15,
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
繁體中文
</Text>
{this.selectIcon(true)}
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => this.updateUser()}
style={{
backgroundColor: theme.mainColor,
flex: 1,
justifyContent: "center",
alignItems: "center"
}}
>
<Text
style={{
fontSize: 15,
color: "white",
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
OK
</Text>
</TouchableOpacity>
</View>
</PopupDialog>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.mainColor
}
});

View File

@@ -0,0 +1,269 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TouchableOpacity,
SafeAreaView,
ScrollView,
Image,
Linking,
Alert,
Share
} from "react-native";
import Text from "react-native-text";
import { observable } from "mobx";
import Loader from '../../components/Public/loader'
import { observer, inject } from "mobx-react/native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import Icon from "react-native-vector-icons/dist/Ionicons";
import { width, height } from "../../config/screen";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import DrawerNavigationHeader from "../../components/Public/drawerNavigationHeader";
import language from "../../config/language";
const size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
export default class Settings extends Component {
@observable
items = [
{
icon: require("../../images/settingrefer.png"),
popup: true,
id: 0
},
{
icon: require("../../images/promo.png"),
screen:'myCoupons',
popup: true,
id: 1
},
{
icon: require("../../images/settingsetting.png"),
screen: "SettingInside",
popup: false,
id: 2
},
{
icon: require("../../images/settingt_c.png"),
popup: true,
id: 3
},
{
icon: require("../../images/settingprivacy.png"),
popup: true,
id: 4
},
{
icon: require("../../images/settingcontact.png"),
popup: true,
id: 5
}
];
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
static navigationOptions = {
drawerLabel: "Settings",
swipeEnabled: false,
tabBarLabel: language.en.setting
};
getTitle(id) {
switch (id) {
case 0:
return this.props.userStore.text.referYourFriends;
break;
case 1:
return this.props.userStore.text.myCoupons;
case 2:
return this.props.userStore.text.setting;
break;
case 3:
return this.props.userStore.text.termandconditions;
break;
case 4:
return this.props.userStore.text.privacy;
break;
case 5:
return this.props.userStore.text.contactUs;
break;
}
}
onPressAction(index) {
if (this.items[index].popup) {
switch (index) {
case 0:
this.referYourFriender();
break;
case 1:
this.store.userCoupon(this,this.userStore.userData.data.token,true)
break;
case 3:
Linking.openURL("https://www.hangryfood.co/terms-and-conditions");
break;
case 4:
Linking.openURL("https://www.hangryfood.co/privacy-statement");
break;
case 5:
Linking.openURL("mailto:support@hangryfood.co?subject=&body=");
break;
}
} else {
// console.log(this.items[index].screen);
this.props.navigation.navigate(this.items[index].screen);
}
}
logoutAlert() {
Alert.alert(
"Logout",
"Are you sure to Logout?",
[
{
text: "Cancel",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "Sure", onPress: () => this.logoutAction() }
],
{ cancelable: false }
);
}
referYourFriender() {
//const link = Platform.OS === 'ios' ? 'itms://itunes.apple.com/us/app/apple-store/1439173696?mt=8' : '';
var sharemessage = ""
if (this.userStore.language == 'english'){
sharemessage = this.store.sharemessage[0].contentEn
}else{
sharemessage = this.store.sharemessage[0].content
}
const link = "http://onelink.to/mh4dh2"
Share.share({
message: sharemessage+link,
title: "Hangry no more"
});
}
logoutAction() {
this.userStore.logoutPost(this);
}
navigatieAction(page) {
this.props.navigation.navigate(page);
}
renderItems() {
return this.items.map((item, index, array) => {
if (item.id == 1 && !this.userStore.logined) {
return null;
} else {
return (
<TouchableOpacity
style={{ marginBottom: 20, marginLeft: 25, paddingRight: 25 }}
onPress={() => this.onPressAction(index)}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between"
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "center",
alignItems: "center"
}}
>
<Image source={item.icon} />
<Text
style={{
fontSize: 15,
marginLeft: 10,
color: theme.coolGrey,
fontWeight: "bold",
fontFamily: Fonts.century
}}
>
{this.getTitle(item.id)}
</Text>
</View>
<View>
<Icon
name={"ios-arrow-forward"}
size={size.getSize(35)}
color={theme.coolGrey}
/>
</View>
</View>
<View
style={{
backgroundColor: theme.inputBgc,
flex: 1,
marginTop: 5,
marginLeft: 40,
height: 1
}}
/>
</TouchableOpacity>
);
}
});
}
render() {
return (
<SafeAreaView style={styles.container}>
<Loader loading = {this.store.loading}/>
<View style={{ height: verticalScale(40) }} />
<ScrollView style={{ backgroundColor: "white" }}>
<View
style={{
backgroundColor: "white",
width: width,
marginTop: 25
}}
>
{this.renderItems()}
<View style={{ flex: 1, alignItems: "flex-end", paddingRight: 25 }}>
<Text
style={{
fontFamily: Fonts.century,
color: theme.coolGrey,
fontSize: 11
}}
>
follow us on
</Text>
<View style={{ flexDirection: "row", paddingTop: 10 }}>
<Image source={require("../../images/settingfb.png")} />
<Image
source={require("../../images/settingig.png")}
style={{ marginLeft: 5 }}
/>
</View>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.mainColor
}
});

View File

@@ -0,0 +1,230 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
Alert,
SafeAreaView,
Image
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import ScrollableTabView from "react-native-scrollable-tab-view";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Icon from "react-native-vector-icons/dist/MaterialCommunityIcons";
// function
import { width, height } from "../../config/screen";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import Size from "../../config/size";
import AsyncStorageHelper from "../../config/asyncStorageHelper";
import language from "../../config/language";
const asyncStorageHelper = new AsyncStorageHelper();
import Swiper from "react-native-swiper";
var size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
export default class Tutorial extends Component {
constructor(props) {
super(props);
this.store = this.props.userStore;
this.menuStore = this.props.menuStore;
}
componentWillMount() {
const { navigation } = this.props;
this.data = navigation.getParam("data", {});
console.log(this.data);
}
init() {
console.log(this.store.logined);
if (!this.store.logined) {
// this.props.navigation.navigate("Login");
} else {
}
}
navigatieAction(page, Param) {
this.props.navigation.navigate(page, Param);
}
closeButton() {
return (
<Icon
name="close-circle"
size={size.getSize(30)}
color={'white'}
style={{ position: "absolute", top: 15,left:10 }}
onPress={() => this.finish()}
/>
);
}
swiper(){
if(this.store.languageSelection === 'english'){
return(
<Swiper
style={styles.wrapper}
activeDot={
<View
style={{
backgroundColor: "white",
width: 8,
height: 8,
borderRadius: 4,
marginLeft: 3,
marginRight: 3,
marginTop: 3,
marginBottom: 3
}}
/>
}
>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_en1.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_en2.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_en3.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_en4.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
</Swiper>
)
}else{
return(
<Swiper
style={styles.wrapper}
activeDot={
<View
style={{
backgroundColor: "white",
width: 8,
height: 8,
borderRadius: 4,
marginLeft: 3,
marginRight: 3,
marginTop: 3,
marginBottom: 3
}}
/>
}
>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_ch1.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_ch2.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_ch3.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
<View style={styles.slide1}>
<Image
source={require("../../images/apppreview_ch4.jpg")}
style={styles.image}
/>
{this.closeButton()}
</View>
</Swiper>
)
}
}
finish() {
const { navigation } = this.props;
var data = navigation.getParam("data", {});
if (data == "store") {
this.navigatieAction("LocationRequest");
} else {
this.props.navigation.goBack();
}
}
render() {
return (
<SafeAreaView style={{ backgroundColor: theme.mainColor, flex: 1 }}>
<View style={styles.container}>
{this.swiper()}
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
height: height,
width: width
},
image: {
width: width,
height: height
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
},
slide1: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: theme.mainColor
},
slide2: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#97CAE5"
},
slide3: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#92BBD9"
},
text: {
color: "#fff",
fontSize: 30,
fontWeight: "bold"
}
});

View File

@@ -0,0 +1,368 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TextInput,
TouchableOpacity,
SafeAreaView,
Keyboard,
TouchableWithoutFeedback
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import Text from "react-native-text";
import Log from '../../config/log'
import theme from "../../config/colors";
import Header from "../../components/Public/signInUpHeader";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import { width, height } from "../../config/screen";
import { Button } from "react-native-elements";
import CheckBox from "react-native-check-box";
import CommonTextInput from "../../components/Public/commonTextInput";
import api from "../../stores/api";
import CodeInput from "react-native-confirmation-code-input";
const size = new Size();
import Toast, { DURATION } from "react-native-easy-toast";
import Countdown, { CountdownStatus } from "rn-countdown";
import { Fonts } from "../../config/fonts";
let log = new Log();
@inject(["userStore"])
@observer
export default class ForgetPassword extends Component {
@observable
resend = false;
@observable
mobile = "";
@observable
password = "";
@observable
confirmPassword = "";
@observable
verificationCode = "";
constructor(props) {
super(props);
this.store = this.props.userStore;
}
componentDidMount() {
// this.startToCount();
log.firebaseClass('forget_password')
}
componentWillUnmount = () => {
// clearInterval(this.interval);
};
state = { checked: false };
navigatieAction(page) {
this.props.navigation.navigate(page);
}
startToCount() {
this.interval = setInterval(() => {
this.count();
}, 1000);
}
count() {
this.store.countdown -= 1;
if (this.store.countdown == 0) {
this.resend = true;
clearInterval(this.interval);
}
}
resetPassword() {
// this.store.signupPost(api.signup, this.signInData, this);
if (this.verificationCode != null || this.verificationCode != "") {
if (this.password != null || this.password != "") {
if (this.confirmPassword != null || this.confirmPassword != "") {
if (this.confirmPassword == this.password) {
var data = {
verificationCode: this.verificationCode,
mobile: this.mobile,
countryCode: "852",
password: this.password
};
log.firebaseLog('press_forgetpassword_button',{mobile:this.mobile})
this.store.forgotPassword(data,this)
} else {
this.refs.toast.show("Password and confirm password is not match");
}
} else {
this.refs.toast.show("Please enter confirm new password");
}
} else {
this.refs.toast.show("Please enter new password");
}
} else {
this.refs.toast.show("Please enter new verification number");
}
}
resendAction() {
this.store.countdown = 10;
this.resend = false;
this.startToCount();
}
handleClickCountdown = () => {
if (this.mobile != "" || this.mobile != null) {
var bodyFormData = new FormData();
bodyFormData.append("country_code", "852");
bodyFormData.append("phone_number", this.mobile.toString());
this.store.sendsmsVerify(bodyFormData, this);
} else {
this.refs.toast.show("Please enter your mobile number");
}
};
startToCountDown = () => {
this.countdown && this.countdown.startCountdown();
};
backAction() {
this.props.navigation.goBack();
}
handleNetworkFailed = () => alert("network failed");
handleStopCountdown = () => this.countdown && this.countdown.stopCountdown();
countDownButton() {
return (
<View style={{ flex: 1 }}>
<Countdown
ref={r => (this.countdown = r)}
time={60}
onPress={this.handleClickCountdown}
onNetworkFailed={this.handleNetworkFailed}
onDidFinishCountdown={this.handleCountdownOver}
>
{({ status, time }) => {
let title, containerStyle, titleStyle;
switch (status) {
case CountdownStatus.Idle:
title = "send";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Counting:
title = `sent(${time})`;
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Over:
title = "resend";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
}
return (
<View style={containerStyle}>
<Text style={titleStyle}>{title}</Text>
</View>
);
}}
</Countdown>
</View>
);
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Header navigation={this.props.navigation} back = {true} />
<CommonTextInput
value={this.mobile}
onChangeText={mobile => (this.mobile = mobile)}
placeholder="Mobile number"
secureTextEntry={false}
returnKeyType={"next"}
onSubmitEditing={event => {
this.verifyInput.focus();
}}
/>
<View
style={{
marginLeft: 20,
marginRight: 20,
marginTop: 30,
flexDirection: "row",
justifyContent: "space-between"
}}
>
{this.countDownButton()}
<View
style={{
backgroundColor: theme.inputBgc,
marginLeft: 10,
alignSelf: 'stretch',
justifyContent: "center",
height: verticalScale(40),
borderRadius: 5,
flex: 1
}}
>
<TextInput
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
fontSize: size.getSize(12),
paddingRight: 30,
paddingLeft: 40,
fontFamily: Fonts.century,
alignSelf: 'stretch'
}}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="verificcation no."
keyboardType={"numeric"}
placeholderStyle={{
fontWeight: "bold",
fontFamily: Fonts.century,
fontSize: size.getSize(10)
}}
ref={input => {
this.verifyInput = input;
}}
onChangeText={text => (this.verificationCode = text)}
placeholderTextColor={theme.foodNameColor}
returnKeyType={"next"}
onSubmitEditing={event => {
this.passwordInput.focus();
}}
/>
</View>
</View>
<CommonTextInput
value={this.password}
onChangeText={mobile => (this.password = mobile)}
placeholder="new password"
secureTextEntry={true}
returnKeyType={"next"}
inputRef={input => {
this.passwordInput = input;
}}
onSubmitEditing={event => {
this.confirmPasswordInput.focus();
}}
/>
<CommonTextInput
value={this.confirmPassword}
onChangeText={confirmPassword =>
(this.confirmPassword = confirmPassword)
}
placeholder="confirm new Password"
secureTextEntry={true}
returnKeyType={"done"}
inputRef={input => {
this.confirmPasswordInput = input;
}}
onSubmitEditing={event => {
Keyboard.dismiss()
}}
/>
</View>
<Toast ref="toast" />
<TouchableOpacity
style={styles.signupButton}
onPress={() => {
this.resetPassword();
}}
>
<Text
style={{
fontSize: 18,
fontFamily: Fonts.century,
color: "white",
fontWeight: "bold"
}}
>
Reset
</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
mainContainer: {
width: width,
flex: 1
},
loginButton: {
width: scale(200),
height: verticalScale(50),
marginTop: moderateScale(30)
},
signupButton: {
width: width,
height: verticalScale(50)
},
phoneCell: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: 15,
height: 40,
borderBottomWidth: 1,
borderColor: "#ebebeb",
width: width,
backgroundColor: "#fff"
},
phoneInfo: {
flexDirection: "row",
alignItems: "center"
},
input: {
height: 30,
width: width * 0.4,
marginLeft: 10,
padding: 0,
fontSize: 14
},
countdown: {
borderRadius: 5,
borderWidth: 2,
borderColor: theme.coolGrey,
height: verticalScale(40),
justifyContent: "center",
alignItems: "center"
},
countdownTitle: {
color: theme.coolGrey,
fontSize: 12
},
signupButton: {
backgroundColor: theme.mainColor,
width: width,
height: verticalScale(60),
justifyContent: "center",
alignItems: "center"
}
});

View File

@@ -0,0 +1,308 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TextInput,
TouchableOpacity,
SafeAreaView,
Keyboard,
TouchableWithoutFeedback,
Linking
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import Text from "react-native-text";
import Header from "../../components/Public/signInUpHeader";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import { width, height } from "../../config/screen";
import { Button } from "react-native-elements";
import CheckBox from "react-native-check-box";
import CommonTextInput from "../../components/Public/commonTextInput";
import api from "../../stores/api";
import theme from "../../config/colors";
import Icon from "react-native-vector-icons/dist/MaterialCommunityIcons";
import { Fonts } from "../../config/fonts";
const size = new Size();
import Toast, { DURATION } from "react-native-easy-toast";
import SignUpVerify from "./signUpVerify";
import Loader from "../../components/Public/loader";
@inject(["userStore"])
@observer
export default class SignUpInformation extends Component {
@observable
signInData = {
email: "",
countryCode: "852",
mobile: "",
pwd: "",
name: "",
verificationCode: ""
};
constructor(props) {
super(props);
this.store = this.props.userStore;
}
state = { checked: false, confrimPassword: "" };
navigatieAction(page) {
this.props.navigation.navigate(page);
}
signupAction() {
console.log(this.signInData);
if(this.signInData.mobile.length>=8){
if (this.state.checked) {
if (this.signInData.pwd != null || this.signInData.pwd != "") {
if (this.signInData.pwd.length >= 8) {
if (this.state.confrimPassword != null || this.state.confrimPassword != "") {
if (this.state.confrimPassword == this.signInData.pwd) {
this.store.checkMember(this.signInData, this);
} else {
this.refs.toast.show(
"Password and confirm password is not match"
);
}
} else {
this.refs.toast.show("Please enter confirm password");
}
} else {
this.refs.toast.show("your password must be at least 8 characters");
}
} else {
this.refs.toast.show("Please enter password");
}
} else {
this.refs.toast.show("Please accept the privacy policy");
}}else{
this.refs.toast.show('Please input your right mobile phone number')
}
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<Loader loading={this.store.loading} />
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={{ flex: 1, width: width }}>
<Header navigation={this.props.navigation} back={true} />
<View style={styles.mainContainer}>
<CommonTextInput
value={this.signInData.name}
onChangeText={name => (this.signInData.name = name)}
placeholder="Full Name"
secureTextEntry={false}
returnKeyType={"next"}
onSubmitEditing={event => {
this.emailInput.focus();
}}
/>
<CommonTextInput
value={this.signInData.email}
onChangeText={email => (this.signInData.email = email)}
placeholder="Email address"
secureTextEntry={false}
returnKeyType={"next"}
onSubmitEditing={event => {
this.mobileInput.focus();
}}
inputRef={input => {
this.emailInput = input;
}}
/>
<CommonTextInput
value={this.signInData.mobile}
onChangeText={mobile => (this.signInData.mobile = mobile)}
placeholder="Mobile number"
secureTextEntry={false}
returnKeyType={"next"}
inputRef={input => {
this.mobileInput = input;
}}
onSubmitEditing={event => {
this.passwordInput.focus();
}}
/>
<CommonTextInput
value={this.signInData.pwd}
onChangeText={pwd => (this.signInData.pwd = pwd)}
placeholder="Password"
secureTextEntry={true}
returnKeyType={"next"}
inputRef={input => {
this.passwordInput = input;
}}
onSubmitEditing={event => {
this.confrimPasswordInput.focus();
}}
/>
<CommonTextInput
value={this.state.confrimPassword}
onChangeText={pwd => this.setState({ confrimPassword: pwd })}
placeholder="Confirm Password"
secureTextEntry={true}
inputRef={input => {
this.confrimPasswordInput = input;
}}
returnKeyType={"done"}
onSubmitEditing={event => {
Keyboard.dismiss()
}}
/>
<View
style={{
flexDirection: "row",
marginTop: 15,
marginLeft: 20,
marginRight: 20,
justifyContent: "space-between",
alignItems: "center"
}}
>
<CheckBox
checkedImage={
<Icon
color={theme.foodNameColor}
size={size.getSize(35)}
name="checkbox-marked-outline"
/>
}
unCheckedImage={
<Icon
color={theme.foodNameColor}
size={size.getSize(35)}
name="square-outline"
/>
}
onClick={() =>
this.setState({ checked: !this.state.checked })
}
checkBoxColor={theme.foodNameColor}
isChecked={this.state.checked}
/>
<View style={{ paddingRight: 10 }}>
<Text
style={{
fontFamily: Fonts.century,
color: theme.foodNameColor
}}
// onPress={() => {
// // this.navigatieAction("SignUpVerify");
// Linking.openURL(
// "https://www.hangryfood.co/privacy-statement"
// );
// }}
>
By registering you agree to our
<Text
style={{
fontFamily: Fonts.century,
color: theme.mainColor
}}
onPress={() => {
Linking.openURL(
"https://www.hangryfood.co/terms-and-conditions"
);
}}
>
{" T&Cs "}
</Text>
<Text
style={{
fontFamily: Fonts.century,
color: theme.foodNameColor
}}
>
and
</Text>
<Text
style={{
fontFamily: Fonts.century,
color: theme.mainColor
}}
onPress={() => {
Linking.openURL(
"https://www.hangryfood.co/privacy-statement"
);
}}
>
{" Privacy Policy."}
</Text>
</Text>
</View>
</View>
</View>
<TouchableOpacity
style={styles.signupButton}
onPress={() => {
this.signupAction();
}}
>
<Text
style={{
fontSize: 18,
fontFamily: Fonts.century,
color: "white",
fontWeight: "bold"
}}
>
Register
</Text>
<Text
style={{
fontSize: 10,
fontFamily: Fonts.century,
color: "white",
fontWeight: "bold"
}}
>
No More Hangry
</Text>
</TouchableOpacity>
<Toast ref="toast" />
</View>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
mainContainer: {
flex: 1
},
loginButton: {
width: scale(200),
height: verticalScale(50),
marginTop: moderateScale(30)
},
signupButton: {
backgroundColor: theme.mainColor,
height: verticalScale(60),
justifyContent: "center",
alignItems: "center"
}
});

View File

@@ -0,0 +1,338 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
TextInput,
TouchableOpacity,
SafeAreaView,
Keyboard,
TouchableWithoutFeedback
} from "react-native";
import { observable } from "mobx";
import { observer, inject } from "mobx-react/native";
import Text from "react-native-text";
import theme from "../../config/colors";
import firebase from "react-native-firebase";
import Header from "../../components/Public/signInUpHeader";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import { width, height } from "../../config/screen";
import { Button } from "react-native-elements";
import CodeInput from "react-native-confirmation-code-input";
const size = new Size();
import Toast, { DURATION } from "react-native-easy-toast";
import Countdown, { CountdownStatus } from "rn-countdown";
import { Fonts } from "../../config/fonts";
@inject(["userStore"])
@observer
export default class SignUpVerify extends Component {
@observable
resend = false;
@observable
signInData = {
email: "",
countryCode: "852",
mobile: "",
pwd: "",
name: "",
verificationCode:""
};
constructor(props) {
super(props);
this.store = this.props.userStore;
}
componentDidMount() {
// this.startToCount();
}
componentWillUnmount = () => {
// clearInterval(this.interval);
};
state = { checked: false };
navigatieAction(page) {
this.props.navigation.navigate(page);
}
startToCount() {
this.interval = setInterval(() => {
this.count();
}, 1000);
}
count() {
this.store.countdown -= 1;
if (this.store.countdown == 0) {
this.resend = true;
clearInterval(this.interval);
}
}
signupAction() {
if(this.store.signUpData.verificationCode == "" || this.store.signUpData.verificationCode == null){
this.refs.toast.show('Please enter the verification no.')
}else{
this.store.signupPost( this);
}
}
resendAction() {
this.store.countdown = 10;
this.resend = false;
this.startToCount();
}
handleClickCountdown = () => {
var bodyFormData = new FormData();
bodyFormData.append("country_code", "852");
bodyFormData.append("phone_number",this.store.signUpData.mobile.toString() );
this.store.sendsmsVerify(bodyFormData, this);
};
startToCountDown = () => {
this.countdown && this.countdown.startCountdown();
};
handleNetworkFailed = () => alert("network failed");
handleStopCountdown = () => this.countdown && this.countdown.stopCountdown();
countDownButton() {
return (
<View style={{ flex: 1 }}>
<Countdown
ref={r => (this.countdown = r)}
time={60}
onPress={this.handleClickCountdown}
onNetworkFailed={this.handleNetworkFailed}
onDidFinishCountdown={this.handleCountdownOver}
>
{({ status, time }) => {
let title, containerStyle, titleStyle;
switch (status) {
case CountdownStatus.Idle:
title = "send";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Counting:
title = `sent(${time})`;
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
case CountdownStatus.Over:
title = "resend";
containerStyle = styles.countdown;
titleStyle = styles.countdownTitle;
break;
}
return (
<View style={containerStyle}>
<Text style={titleStyle}>{title}</Text>
</View>
);
}}
</Countdown>
</View>
);
}
render() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: theme.mainColor }}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.container}>
<View style={styles.mainContainer}>
<Header navigation={this.props.navigation} back = {true} />
<View
style={{
backgroundColor: theme.inputBgc,
marginLeft: 20,
marginRight: 20,
marginTop: 30,
height: verticalScale(40),
borderRadius: 5,
justifyContent: "center"
}}
>
<Text
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
fontSize: 15,
paddingRight: 30,
paddingLeft: 30,
fontFamily: Fonts.century
}}
underlineColorAndroid="rgba(0,0,0,0)"
>
{this.store.signUpData.mobile}
</Text>
</View>
<View
style={{
marginLeft: 20,
marginRight: 20,
marginTop: 30,
flexDirection: "row",
justifyContent: "space-between"
}}
>
{this.countDownButton()}
<View
style={{
backgroundColor: theme.inputBgc,
marginLeft: 10,
alignItems: "center",
justifyContent: "center",
height: verticalScale(40),
borderRadius: 5,
flex: 1
}}
>
<TextInput
style={{
// backgroundColor:theme.inputBgc,
color: theme.foodNameColor,
fontSize: size.getSize(12),
paddingRight: 30,
paddingLeft: 40,
fontFamily: Fonts.century,
alignSelf: 'stretch'
}}
onChangeText = {(text)=>this.store.signUpData.verificationCode = text}
keyboardType = {'numeric'}
underlineColorAndroid="rgba(0,0,0,0)"
placeholder="verification no."
placeholderStyle={{
fontWeight: "bold",
fontFamily: Fonts.century,
fontSize: size.getSize(10)
}}
placeholderTextColor={theme.foodNameColor}
/>
</View>
</View>
<View
style={{
justifyContent: "center",
alignItems: "center",
height: 60,
width: "100%"
}}
>
</View>
</View>
<Toast ref="toast" />
<TouchableOpacity
style={styles.signupButton}
onPress={() => {
this.signupAction();
}}
>
<Text
style={{
fontSize: 18,
fontFamily: Fonts.century,
color: "white",
fontWeight: "bold"
}}
>
Register
</Text>
<Text
style={{
fontSize: 10,
fontFamily: Fonts.century,
color: "white",
fontWeight: "bold"
}}
>
No More Hangry
</Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
backgroundColor: "white"
},
mainContainer: {
width: width,
flex: 1
},
loginButton: {
width: scale(200),
height: verticalScale(50),
marginTop: moderateScale(30)
},
signupButton: {
width: width,
height: verticalScale(50)
},
phoneCell: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: 15,
height: 40,
borderBottomWidth: 1,
borderColor: "#ebebeb",
width: width,
backgroundColor: "#fff"
},
phoneInfo: {
flexDirection: "row",
alignItems: "center"
},
input: {
height: 30,
width: width * 0.4,
marginLeft: 10,
padding: 0,
fontSize: 14
},
countdown: {
borderRadius: 5,
borderWidth: 2,
borderColor: theme.coolGrey,
height: verticalScale(40),
justifyContent: "center",
alignItems: "center"
},
countdownTitle: {
color: theme.coolGrey,
fontSize: 12
},
signupButton: {
backgroundColor: theme.mainColor,
width: width,
height: verticalScale(60),
justifyContent: "center",
alignItems: "center"
}
});