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

View File

@@ -0,0 +1,189 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
Alert,
NetInfo,
Geolocation,
TouchableOpacity,
SafeAreaView,
StatusBar,
Image
} 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 { 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 theme from "../../config/colors";
import Size from "../../config/size";
import { Fonts } from "../../config/fonts";
import MyStatusBar from "../../components/Public/statusBar";
const asyncStorageHelper = new AsyncStorageHelper();
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 size = new Size();
@observer
@inject(["menuStore"], ["userStore"])
export default class GoogleAutoComplete extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
blur() {
// this.secondTextInput.onBlur();
}
getIndex(id) {
var index = this.userStore.pickupPointLabel.findIndex(function(item, i) {
return item.id == parseInt(id);
});
return index;
}
onTextChange(id) {
this.locationRef._onBlur();
this.locationRef.setAddressText(
this.userStore.pickupPointLabel[this.getIndex(id)].value
);
}
componentWillUnmount() {
if (this.props.onRef) {
this.props.onRef(undefined);
}
}
getIndex(id){
var index = this.userStore.pickupPointLabel.findIndex(function(item, i){
return item.id == parseInt(id)
});
return index
}
componentDidMount() {
if (this.props.onRef) {
this.props.onRef(this);
}
// this.secondTextInput.blur();
}
render() {
console.log("pickupPointId " + this.userStore.pickupPointId);
return (
<View
style={{
alignItems: "center",
backgroundColor: theme.mainColor
}}
>
<GooglePlacesAutocomplete
ref={instance => {
this.locationRef = instance;
}}
placeholder={this.userStore.text.googleSearch}
placeholderTextColor="white"
placeholderStyle={{ fontFamily: Fonts.century, fontWeight: "bold" }}
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.props.onPress && this.props.onPress(data, details);
console.log(details)
}}
textInputProps={{
onFocus: () => {
this.props.onFocus && this.props.onFocus();
}
// onBlur:() => {
// this.props.onBlur && this.props.onBlur();
// },
// onEndEditing:() => {
// this.props.onEndEditing && this.props.onEndEditing();
// },
}}
getDefaultValue={() =>
this.userStore.pickupPointLabel[this.getIndex(this.userStore.pickupPointId)]
.value
}
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.props.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>
);
}
}

307
app/components/Menu/listItem.js Executable file
View File

@@ -0,0 +1,307 @@
//plugin
import React, { Component } from "react";
import Text from "react-native-text";
import {
StyleSheet,
View,
FlatList,
TouchableOpacity,
Image
} from "react-native";
import { observable, transaction } from "mobx";
import { width, height } from "../../config/screen";
import Icon from "react-native-vector-icons/dist/MaterialCommunityIcons";
import { observer, inject } from "mobx-react/native";
import FastImage from "react-native-fast-image";
import firebase from "react-native-firebase";
import Log from '../../config/log'
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
// function
import Size from "../../config/size";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
var size = new Size();
var log = new Log();
@inject(["menuStore"], ["userStore"])
@observer
export default class ListItem extends Component {
@observable
soldout = false
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
recommended() {
return (
<Image
style={{
position: "absolute",
top: -5,
left: -5,
height: verticalScale(100),
width: scale(110)
}}
resizeMode={"contain"}
source={require("../../images/recommendation.png")}
/>
);
}
componentDidMount(){
if(this.props.items.quota - this.props.items.sold == 0){
this.soldout = true
}else{
this.soldout = false
}
}
foodAttributes() {
return (
<View
style={{
position: "absolute",
top: -5,
right: 5
}}
>
<Image
style={{ height: verticalScale(40), width: scale(40) }}
source={require("../../images/spicy.png")}
/>
<Image
style={{ height: verticalScale(40), width: scale(40) }}
source={require("../../images/vegetarian.png")}
/>
</View>
);
}
add() {
if(!this.soldout){
this.store.addCount(this.props.items.id);
}
}
sum() {
if(!this.soldout){
this.store.sumCount(this.props.items.id);
}
}
onClickAction() {
transaction(() => {
this.store.menuDetails.id = this.props.items.id;
if (!this.userStore.logined) {
this.store.menuDetails.tel = "";
} else {
this.store.menuDetails.tel = this.userStore.userData.data.mobile;
}
this.store.menuDetails.count = this.props.items.count;
this.store.menuDetails.price = this.props.items.price;
this.store.menuDetails.imageURL = this.props.items.cuisine.photo;
this.store.menuDetails.name = this.props.items.cuisine.name;
this.store.menuDetails.nameEn = this.props.items.cuisine.nameEn;
this.store.menuDetails.tags = this.props.items.cuisine.tags;
this.store.menuDetails.intro_ch = this.props.items.cuisine.description;
this.store.menuDetails.intro_en = this.props.items.cuisine.descriptionEn;
this.store.menuDetails.restaurant.name = this.props.items.cuisine.restaurant.name;
this.store.menuDetails.restaurant.nameEn = this.props.items.cuisine.restaurant.nameEn;
this.store.menuDetails.restaurant.addr = this.props.items.cuisine.restaurant.addr;
this.store.menuDetails.restaurant.addrEn = this.props.items.cuisine.restaurant.addrEn;
});
this.props.menu.foodInformationPagePopUp();
// firebase.analytics().logEvent('click_food_details', { foodName: this.store.menuDetails.nameEn });
log.firebaseLog('click_food_details',{foodName: this.store.menuDetails.nameEn,logined: this.userStore.logined})
}
getViewStye() {
if(this.props.index == this.store.menu.data.content.length-1) {
return {
marginBottom: 80, alignItems: "center"
}
} else {
return {
marginBottom: 20, alignItems: "center"
}
}
}
render() {
var lang = this.userStore.languageSelection;
return (
<View style={this.getViewStye()}>
<TouchableOpacity
style={{
width: width,
height: verticalScale(210),
alignItems: "center",
justifyContent: "center"
}}
onPress={() => this.onClickAction()}
>
<FastImage
style={{
width: this.props.screenWidth - scale(25),
height: verticalScale(200),
backgroundColor: theme.mainColor
}}
source={{ uri: this.props.items.cuisine.photo }}
>
<View
style={{
backgroundColor: theme.menuPriceBoxBackgroundColor,
alignItems: "center",
justifyContent: "center",
height: verticalScale(40),
width: scale(100),
flexDirection: "row",
position: "absolute",
right: 0,
top: 0
}}
>
<Text
style={{
color: theme.foodNameColor,
fontWeight: "bold",
fontSize: 20,
fontFamily: "CenturyGothic"
}}
numberOfLines={1}
>
HKD ${this.props.items.price}
</Text>
</View>
{
this.soldout?( <View
style={{
position: "absolute",
backgroundColor: "rgba(255,183,23,0.7)",
alignItems: "center",
justifyContent: "center",
width: this.props.screenWidth - scale(25),
height: verticalScale(200),
}}
>
<Text
style={{
color: 'white',
fontWeight: "bold",
fontSize: 30,
fontFamily: "CenturyGothic",
marginBottom:verticalScale(35)
}}
numberOfLines={1}
>
Sold out
</Text>
</View>):(
<View/>
)
}
</FastImage>
</TouchableOpacity>
{/* <View
style={{
width: this.props.screenWidth - 10,
height: verticalScale(70),
borderColor: "gray",
borderWidth: 1,
alignItems: "center"
}}
>
<Text style={{ marginTop: 20 }} numberOfLines={2}>
{this.props.items.cuisine.description}
|| {this.props.items.cuisine.descriptionEn}
</Text>
</View> */}
<View
style={{
width: this.props.screenWidth - 25,
justifyContent: "center",
alignItems: "center",
height: verticalScale(50),
backgroundColor: theme.menuPriceBoxBackgroundColor,
flexDirection: "row",
position: "absolute",
bottom: verticalScale(0)
}}
>
<View
style={{
width: "65%",
height: "100%",
paddingLeft: scale(10),
borderTopLeftRadius: verticalScale(25),
borderBottomLeftRadius: verticalScale(25),
justifyContent: "center"
}}
>
<Text
style={{
color: theme.foodNameColor,
fontFamily: Fonts.century,
fontWeight: "bold"
}}
numberOfLines={1}
>
{this.userStore.dataLanguage(this.props.items.cuisine, "name")}
</Text>
<Text
style={{
color: theme.foodNameColor,
fontFamily: Fonts.century,
fontSize: 11
}}
numberOfLines={1}
>
{this.userStore.dataLanguage(
this.props.items.cuisine.restaurant,
"name"
)}
</Text>
</View>
<View
style={{
width: "35%",
height: "100%",
borderTopRightRadius: verticalScale(25),
borderBottomRightRadius: verticalScale(25),
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row"
}}
>
<Icon
name="minus-circle-outline"
size={size.getSize(24)}
color={theme.foodNameColor}
style={{ marginLeft: moderateScale(20) }}
onPress={() => this.sum()}
/>
<Text
style={{ color: theme.foodNameColor, fontFamily: Fonts.century }}
>
{this.props.items.count}
</Text>
<Icon
name="plus-circle-outline"
size={size.getSize(24)}
color={theme.foodNameColor}
style={{ marginRight: moderateScale(20) }}
onPress={() => this.add()}
/>
</View>
</View>
</View>
);
}
}

248
app/components/Menu/map.js Executable file
View File

@@ -0,0 +1,248 @@
import React, { Component } from "react";
import {
Platform,
StyleSheet,
View,
Alert,
NetInfo,
Geolocation,
TouchableOpacity,
SafeAreaView,
StatusBar,
Image,
TouchableHighlight
} 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 { observable, transaction } from "mobx";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { width, height } from "../../config/screen";
import Permissions from "react-native-permissions";
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 theme from "../../config/colors";
import MyStatusBar from "../../components/Public/statusBar";
const asyncStorageHelper = new AsyncStorageHelper();
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 = "AIzaSyB_9Wi7BcAgqMPxZvW_5DWb8UxF5W9tWz0";
@inject(["menuStore"], ["userStore"])
@observer
export default class Map extends Component {
@observable
markerId = null;
@observable
region = {
latitude: 22.396427,
longitude: 114.109497,
latitudeDelta: 1,
longitudeDelta: 1
};
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
}
};
}
_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 })
if (
response == "allow" ||
response == "restricted" ||
response == "authorized"
) {
navigator.geolocation.getCurrentPosition(
position => {
console.log(position.coords.latitude);
this.map.animateToRegion({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.02,
longitudeDelta: 0.02
});
},
error => {
console.log(error);
this.region = {
latitude: 22.396427,
longitude: 114.109497,
latitudeDelta: 1,
longitudeDelta: 1
};
},
{ enableHighAccuracy: false, timeout: 4000, maximumAge: 10000 }
);
} else {
this.region = {
latitude: 22.396427,
longitude: 114.109497,
latitudeDelta: 1,
longitudeDelta: 1
};
}
});
}
goPosition(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.props.perfdefinedPlaces.length; i++) {
if (
this.props.perfdefinedPlaces[i].geometry.location.lat ==
details.geometry.location.lat &&
this.props.perfdefinedPlaces[i].geometry.location.lng ==
details.geometry.location.lng
) {
this.markerId = this.props.perfdefinedPlaces[i].id
break;
}
}
console.log(details);
}
clickMarkerAction(id) {
this.markerId = id;
this.store.pickupPointId = id;
this.userStore.pickupPointId = id;
}
picked(id) {
asyncStorageHelper.saveData("pickupPointId", id);
this.store.getMenuItem(this);
//this.props.navigation.navigate('menu')
}
confirmButton() {
if (!this.markerId) {
return null;
} else {
return (
<TouchableHighlight
style={{
height: verticalScale(60),
width: width,
backgroundColor: theme.mainColor,
alignItems: "center",
justifyContent: "center"
}}
onPress={() => {
this.props.onPress && this.props.onPress(this.markerId);
}}
>
<Text style={{ color: "white", fontWeight: "bold" }}>
{this.userStore.text.confirm}
</Text>
</TouchableHighlight>
);
}
}
componentWillMount() {
this.setUserLocation();
this._requestPermission();
if (this.props.onRef) {
this.props.onRef(undefined);
}
}
componentDidMount() {
if (this.props.onRef) {
this.props.onRef(this);
}
}
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
}
});
}
}
render() {
return (
<View style={styles.container}>
<MapView
ref={ref => {
this.map = ref;
}}
style={{ width: width, flex: 1 }}
showsUserLocation={true}
initialRegion={this.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()}
</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,160 @@
import React, { Component } from "react";
import {
TextInput,
View,
ScrollView,
StyleSheet,
TouchableOpacity,
Image
} from "react-native";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import Size from "../../config/size";
import Text from "react-native-text";
import FastImage from "react-native-fast-image";
import { width, height } from "../../config/screen";
import Icon from "react-native-vector-icons/dist/Ionicons";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
import { observable, transaction } from "mobx";
import { observer, inject } from "mobx-react/native";
const size = new Size();
@inject(["menuStore"], ["userStore"])
@observer
export default class MenuDetailsView extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
separate(index) {
// console.log(index + " "+ this.store.menuDetails.tags.size)
if (index < 2) {
return (
<View
style={{
backgroundColor: theme.mainColor,
width: 2,
height: size.getSize(10),
marginRight: 3
}}
/>
);
}
}
tags() {}
render() {
console.log(this.userStore.languageSelection);
console.log(this.store.menuDetails.tags);
const tagsLoop = this.store.menuDetails.tags.map((tags, index) => (
<View style={{ flexDirection: "row" }}>
<Text style={[styles.TextStyle, { fontSize: 13, marginRight: 3 }]}>
{this.userStore.dataLanguage(tags, "name")}
</Text>
{this.separate(index)}
</View>
));
return (
<View style={{ flex: 1 }}>
<TouchableOpacity
style={{ backgroundColor: "#E6E6E6", width: width }}
onPress={() => this.props.self.foodInformationPageDismiss()}
>
<View
style={{
width: "100%",
height: 50,
alignItems: "center",
justifyContent: "center",
backgroundColor: "white"
}}
>
<Icon name="ios-arrow-down" size={size.getSize(25)} color="black" />
</View>
</TouchableOpacity>
<FastImage
style={{
width: width - 40,
height: verticalScale(200),
borderRadius: 4,
alignItems: "center",
marginLeft: 20
}}
source={{ uri: this.store.menuDetails.imageURL }}
>
<View
style={{
backgroundColor: theme.menuPriceBoxBackgroundColor,
alignItems: "center",
justifyContent: "center",
height: verticalScale(40),
width: scale(100),
flexDirection: "row",
position: "absolute",
right: 0,
bottom: 0
}}
>
<Text
style={{
color: theme.foodNameColor,
fontWeight: "bold",
fontSize: 20,
fontFamily: "CenturyGothic"
}}
numberOfLines={1}
>
HKD ${this.store.menuDetails.price}
</Text>
</View>
</FastImage>
<ScrollView style={{ paddingTop: 10, paddingRight: 20, paddingLeft: 20 }}>
<Text style={[styles.TextStyle, { fontSize: 15 }]}>
{this.userStore.dataLanguage(this.store.menuDetails, "name")}
</Text>
<Text style={[styles.TextStyle, { fontSize: 13, paddingTop: 5 }]}>
{this.userStore.dataLanguage(
this.store.menuDetails.restaurant,
"name"
)}
</Text>
<Text style={[styles.TextStyle, { fontSize: 13,paddingTop: 5 }]}>
{this.userStore.dataLanguage(
this.store.menuDetails.restaurant,
"addr"
)}
</Text>
<View style={{ flexDirection: "row" ,paddingTop: 5}}>
{tagsLoop}
</View>
<Text style={[styles.TextStyle, { fontSize: 13, paddingTop: 5, marginBottom: 40, }]}>
{this.userStore.dataLanguage(this.store.menuDetails, "intro")}
</Text>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
marginSide: {
marginRight: 10,
marginLeft: 10
},
introView: {
marginRight: 10,
marginLeft: 10,
marginTop: 15,
fontSize: 20
},
TextStyle: {
fontFamily: Fonts.century,
color: theme.coolGrey
}
});

View File

@@ -0,0 +1,109 @@
import React, { Component } from 'react';
import Text from 'react-native-text';
import {StyleSheet, View, FlatList,ActivityIndicator} from 'react-native';
import Size from '../../config/size'
import { observer,inject } from 'mobx-react/native'
import ListItem from './listItem'
import { width, height } from '../../config/screen';
@inject(["menuStore"], ["userStore"])
@observer
export default class MenuFlatList extends Component{
constructor(props) {
super(props);
this.store = this.props.menuStore
this.userStore = this.props.userStore
}
_renderFooter(){
if (this.store.pageNo == this.store.totalPage) {
console.log('no more')
return (
<View style={{height:30,alignItems:'center',justifyContent:'flex-start',}}>
<Text style={{color:'#999999',fontSize:14,marginTop:5,marginBottom:5,}}>
No more
</Text>
</View>
);
} else if(this.store.pageNo < this.store.totalPage) {
console.log('loading')
return (
<View style={styles.footer}>
<ActivityIndicator />
<Text>Loading...</Text>
</View>
);
}else{
return null
}
}
_onEndReached(){
if(this.store.loading){
console.log('pull loading')
return ;
}
if((this.store.pageNo!=1) && (this.store.pageNo>=this.store.totalPage)){
console.log('last page')
return;
} else {
console.log( 'pull load more ')
this.store.pageNo++;
console.log(this.store.pageNo)
this.store.menuloadmore()
}
}
render(){
return(
<FlatList
data = {this.props.data.data.content}
renderItem = {({item,index}) => <ListItem items = {item} index = {index}
screenWidth = {width}
menu = {this.props.menu}
/>}
//refreshing={this.store.loading}
//onRefresh = {()=>{console.log('reload'); this.store.getMenuItem(this);}}
// ListFooterComponent={this._renderFooter.bind(this)}
// onEndReached= {this._onEndReached.bind(this)}
// onEndReachedThreshold={10}//执行上啦的时候10%执行
/>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 15,
color: 'blue',
},
footer:{
flexDirection:'row',
height:24,
justifyContent:'center',
alignItems:'center',
marginBottom:10,
},
content: {
fontSize: 15,
color: 'black',
}
});

View File

@@ -0,0 +1,189 @@
import React, { Component } from "react";
import Text from "react-native-text";
import { StyleSheet, View } from "react-native";
import { observable, transaction } from "mobx";
import { scale, verticalScale, moderateScale } from "react-native-size-matters";
import { observer, inject } from "mobx-react/native";
import Size from "../../config/size";
import theme from "../../config/colors";
import { Fonts } from "../../config/fonts";
const size = new Size();
@inject(["menuStore"])
@observer
export default class TopMessageText extends Component {
orderClose = false;
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.state = {
time: this.timeInit(),
amPm: "am",
countDownTime: ""
};
this.getTime = this.getTime.bind(this);
}
getInitialState() {
return {
time: "00:00:00",
amPm: "am"
};
}
secToCountDownTimer() {
var time1 = this.props.date.getTime();
var time2 = new Date().getTime();
var diff = Math.abs(time1 - time2);
addZero = n => (n < 10 ? "0" + n : n);
var min = addZero(Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)));
var second = addZero(Math.floor((diff % (1000 * 60)) / 1000));
this.setState({ countDownTime: `${min}:${second}` });
}
countDownTimer() {
if (
this.props.date.getDate() == new Date().getDate() &&
this.props.date.getMonth() == new Date().getMonth() &&
this.props.date.getHours() - new Date().getHours() == 1
) {
return (
<View
style={{
width: "50%",
justifyContent: "center",
alignItems: "flex-end",
}}
>
<Text
style={{ color: "white", fontSize: 12, ontFamily: Fonts.century }}
>
{this.state.countDownTime + " remain"}
</Text>
</View>
);
} else {
return <View />;
}
}
timeInit() {
const takeTwelve = n => (n > 12 ? n - 12 : n),
addZero = n => (n < 10 ? "0" + n : n);
let d, h, m, s, t, amPm;
d = this.props.date;
h = addZero(takeTwelve(d.getHours()));
m = addZero(d.getMinutes());
s = addZero(d.getSeconds());
amPm = d.getHours() >= 12 ? "p.m" : "a.m";
t = `${h}:${m}${amPm}`;
return t;
}
componentDidMount() {
this.loadInterval = setInterval(this.getTime, 1000);
}
getTime() {
this.secToCountDownTimer();
}
componentWillMount() {
this.secToCountDownTimer();
this.setState({ time: this.timeInit() });
}
message() {
var month = new Array(12);
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
var date = this.props.date;
return (
"Menu For " +
date.getUTCDate() +
"-" +
month[date.getMonth()] +
"-" +
date.getFullYear()
);
}
cutoffDateHandle() {
this.props.date;
}
render() {
const countDown = this.store.date;
if (this.orderClose == false) {
return (
<View
style={{
flex: 1,
alignItems: "center",
paddingLeft: 30,
paddingRight: 30
}}
>
<View style={{ width: "100%", marginTop: verticalScale(8) }}>
<Text
style={{
color: "white",
fontSize: 17,
fontFamily: Fonts.century,
fontWeight: "bold",
textDecorationLine: "underline"
}}
>
{this.message()}
</Text>
</View>
<View style={{ flexDirection: "row", width: "100%", marginTop:2 }}>
<View
style={{
width: "50%",
justifyContent: "center",
alignItems: "flex-start",
}}
>
<Text
style={{
color: "white",
fontSize: 12,
ontFamily: Fonts.century
}}
>
{"Orders Close at " + this.timeInit()}
</Text>
</View>
{this.countDownTimer()}
</View>
{/* <View
style={{
width: "33%",
justifyContent: "center",
alignItems: "center"
}}
>
<Text style={{ color: "white" }}>{this.store.timestamp.getHours()}</Text>
</View> */}
</View>
);
}
}
}

View File

@@ -0,0 +1,176 @@
// plugin
import React, { Component } from 'react';
import Text from 'react-native-text';
import { StyleSheet, View, FlatList, TouchableOpacity, Alert } from 'react-native';
import { observer, inject } from 'mobx-react/native'
import { observable, transaction } from 'mobx';
import Icon from 'react-native-vector-icons/dist/Ionicons';
import { scale, verticalScale, moderateScale } from 'react-native-size-matters';
// function
import Size from '../../config/size';
import Log from '../../config/log'
import { width, height } from '../../config/screen';
const size = new Size;
import AsyncStorageHelper from '../../config/asyncStorageHelper'
import theme from '../../config/colors'
const log = new Log()
const asyncStorageHelper = new AsyncStorageHelper
@inject(["menuStore"], ["userStore"])
@observer
export default class TotalPriceView extends Component {
constructor(props) {
super(props);
this.store = this.props.menuStore;
this.userStore = this.props.userStore;
}
getIndex(id){
var index = this.userStore.pickupPointLabel.findIndex(function(item, i){
return item.id == parseInt(id)
});
return index
}
deg2rad(deg) {
return deg * (Math.PI / 180)
}
getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = this.deg2rad(lat2 - lat1); // deg2rad below
var dLon = this.deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
clickAction() {
if (this.userStore.logined) {
asyncStorageHelper.getData('pickupPointId', pickupPointId => {
if (pickupPointId != null) {
if(this.userStore.addedCard ){
log.firebaseLog("press_order_now_button",{logined:this.userStore.logined})
this.userStore.pickupIndex = this.getIndex(pickupPointId)
this.store.getOrderedItems(this.props.self,this.userStore.userData.data.token)
}else{
Alert.alert(
'',
'Please input your credit Card info',
[
{ text: 'Cancel', onPress: () => {console.log('Cancel'),log.firebaseLog('press_creditCard_info_cancel_onMenu_alert',{logined:this.userStore.logined}) }},
{ text: 'Ok', onPress: () => {this.props.self.navigatieAction('account'),log.firebaseLog('press_creditCard_info_ok_onMenu_alert',{logined:this.userStore.logined}) }},
],
)
}
}
else {
if (this.userStore.userLocation != null) {
var Param = {}
try {
this.userStore.pickupLoactionPoint.data.content.forEach(element => {
var km = this.getDistanceFromLatLonInKm(element.lat,element.lng,this.userStore.userLocation.coords.latitude,this.userStore.userLocation.coords.longitude)
console.log(km)
if(km<1){
Param = {'title': 'Pick the loaction'}
}
});
} catch (e) {
console.log(e)
}
Alert.alert(
'',
'Please select the pickup location',
[
{ text: 'Cancel', onPress: () => console.log('Cancel') },
{ text: 'Go', onPress: () => this.props.self.navigatieAction('Location',Param) },
],
)
}else{
Alert.alert(
'',
'Please select the pickup location',
[
{ text: 'Cancel', onPress: () => console.log('Cancel') },
{ text: 'Go', onPress: () => this.props.self.navigatieAction('account') },
],
)
}
}
})
} else {
Alert.alert(
'',
'Please login',
[
{ text: 'Cancel', onPress: () => console.log('Cancel') },
{ text: 'Login', onPress: () => this.props.self.navigatieAction('Login') },
],
)
}
}
render() {
if (!this.store.selected) {
return null
} else {
return (
<View style={{
position: 'absolute',
bottom: 0,
width: width,
height: verticalScale(50),
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: theme.mainColor
}}>
<View style={{
flexDirection: 'row',
alignItems: 'center',
marginLeft: moderateScale(10),
}}>
<Icon name="md-close-circle" size={size.getSize(24)} color='white'
onPress={() => this.store.cleanAll()} />
<Text style={{ color: 'white', marginLeft: 10 }}>
HKD {this.store.totalMoney.toFixed(2)}
</Text>
</View>
<TouchableOpacity style={{
flexDirection: 'row',
alignItems: 'center',
marginRight: moderateScale(10)
}}
onPress={() => this.clickAction()}>
<Text style={{ color: 'white', marginRight: 10 }}>
ORDER NOW
</Text>
<Icon name="ios-arrow-forward" size={size.getSize(24)} color='white' />
</TouchableOpacity>
</View>
)
}
}
}