Error and Warning remove

This commit is contained in:
Ninjas Code - 4 2023-03-13 16:03:39 +05:00
parent ee0bd79b8f
commit 885c967cdb
14 changed files with 1380 additions and 1022 deletions

View File

@ -2,6 +2,7 @@
"expo": {
"name": "Enatega",
"version": "1.0.16",
"scheme": "enategasinglevendor",
"description": "Enatega is a starter kit food ordering app built in React Native using Expo for IOS and Android. It's made keeping good aesthetics in mind as well keeping the best coding practices in mind. Its fully customisable to easily help you in your next food delivery project. https://market.nativebase.io/view/react-native-food-delivery-backend-app",
"slug": "enategasinglevendor",
"privacy": "public",

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@
]
},
"dependencies": {
"@amplitude/analytics-react-native": "^1.1.1",
"@apollo/react-hooks": "^3.1.3",
"@expo/vector-icons": "^13.0.0",
"@ptomasroos/react-native-multi-slider": "^2.2.2",
@ -51,6 +52,7 @@
"expo-apple-authentication": "~5.0.1",
"expo-application": "~5.0.1",
"expo-asset": "~8.7.0",
"expo-auth-session": "~3.8.0",
"expo-camera": "~13.1.0",
"expo-constants": "~14.0.2",
"expo-contacts": "~11.0.1",
@ -63,6 +65,7 @@
"expo-localization": "~14.0.0",
"expo-location": "~15.0.1",
"expo-notifications": "~0.17.0",
"expo-random": "~13.0.0",
"expo-sensors": "~12.0.1",
"expo-splash-screen": "~0.17.5",
"expo-tracking-transparency": "~3.0.1",
@ -78,7 +81,7 @@
"react-native-button": "^3.0.1",
"react-native-flash-message": "^0.4.0",
"react-native-flatlist-slider": "^1.0.5",
"react-native-gesture-handler": "~2.8.0",
"react-native-gesture-handler": "~~2.1.0",
"react-native-gifted-chat": "^1.1.1",
"react-native-i18n": "1.0.0",
"react-native-maps": "1.3.2",

View File

@ -1,67 +1,67 @@
import { useNavigation, useTheme } from '@react-navigation/native'
import React, { useContext } from 'react'
import { FlatList, TouchableOpacity, View } from 'react-native'
import ConfigurationContext from '../../../context/Configuration'
import UserContext from '../../../context/User'
import { alignment } from '../../../utils/alignment'
import { NAVIGATION_SCREEN } from '../../../utils/constant'
import Spinner from '../../Spinner/Spinner'
import TextDefault from '../../Text/TextDefault/TextDefault'
import TextError from '../../Text/TextError/TextError'
import useStyle from './styles'
import { useNavigation, useTheme } from "@react-navigation/native";
import React, { useContext } from "react";
import { FlatList, TouchableOpacity, View } from "react-native";
import ConfigurationContext from "../../../context/Configuration";
import UserContext from "../../../context/User";
import { alignment } from "../../../utils/alignment";
import { NAVIGATION_SCREEN } from "../../../utils/constant";
import Spinner from "../../Spinner/Spinner";
import TextDefault from "../../Text/TextDefault/TextDefault";
import TextError from "../../Text/TextError/TextError";
import useStyle from "./styles";
export const orderStatuses = [
{
key: 'PENDING',
key: "PENDING",
status: 1,
statusText: 'Your order is still pending.'
statusText: "Your order is still pending.",
},
{
key: 'ACCEPTED',
key: "ACCEPTED",
status: 2,
statusText: 'Restaurant is preparing Food.'
statusText: "Restaurant is preparing Food.",
},
{
key: 'PICKED',
key: "PICKED",
status: 3,
statusText: 'Rider is on the way.'
statusText: "Rider is on the way.",
},
{
key: 'DELIVERED',
key: "DELIVERED",
status: 4,
statusText: 'Order is delivered.'
statusText: "Order is delivered.",
},
{
key: 'COMPLETED',
key: "COMPLETED",
status: 5,
statusText: 'Order is completed.'
}
]
statusText: "Order is completed.",
},
];
const orderStatusActive = ['PENDING', 'PICKED', 'ACCEPTED']
const orderStatusActive = ["PENDING", "PICKED", "ACCEPTED"];
const StatusCard = () => {
const { colors } = useTheme()
const styles = useStyle()
const navigation = useNavigation()
const { colors } = useTheme();
const styles = useStyle();
const navigation = useNavigation();
const {
loadingOrders,
errorOrders,
orders,
networkStatusOrders,
fetchOrders
} = useContext(UserContext)
const configuration = useContext(ConfigurationContext)
fetchOrders,
} = useContext(UserContext);
const configuration = useContext(ConfigurationContext);
const checkStatus = status => {
const obj = orderStatuses.filter(x => {
return x.key === status
})
return obj[0]
}
const checkStatus = (status) => {
const obj = orderStatuses.filter((x) => {
return x.key === status;
});
return obj[0];
};
if (loadingOrders) return <Spinner />
if (errorOrders) return <TextError>{errorOrders.message}</TextError>
if (loadingOrders) return <Spinner />;
if (errorOrders) return <TextError>{errorOrders.message}</TextError>;
return (
<FlatList
@ -71,8 +71,9 @@ const StatusCard = () => {
horizontal={true}
refreshing={networkStatusOrders === 4}
onRefresh={() => networkStatusOrders === 7 && fetchOrders()}
data={orders.filter(o => orderStatusActive.includes(o.order_status))}
keyExtractor={item => item._id}
data={orders.filter((o) => orderStatusActive.includes(o.order_status))}
//keyExtractor={(item) => item._id}
keyExtractor={(item, index) => String(index)}
renderItem={({ item, index }) => (
<TouchableOpacity
activeOpacity={0.8}
@ -80,9 +81,10 @@ const StatusCard = () => {
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.OrderDetail, {
_id: item._id,
currency_symbol: configuration.currency_symbol
currency_symbol: configuration.currency_symbol,
})
}>
}
>
<View key={index} style={styles.statusContainer}>
<View style={styles.textContainer}>
<TextDefault H5 medium textColor={styles.lightText.color}>
@ -95,8 +97,8 @@ const StatusCard = () => {
Status
</TextDefault>
<TextDefault textColor={'#00b9c6'} H5 medium>
{item.order_status}{' '}
<TextDefault textColor={"#00b9c6"} H5 medium>
{item.order_status}{" "}
<TextDefault numberOfLines={2} medium>
{/* {checkStatus(item.order_status).status}.{' '} */}(
{checkStatus(item.order_status).statusText})
@ -107,7 +109,7 @@ const StatusCard = () => {
</TouchableOpacity>
)}
/>
)
}
);
};
export default StatusCard
export default StatusCard;

View File

@ -1,59 +1,59 @@
import { useMutation } from '@apollo/react-hooks'
import { useNavigation, useTheme } from '@react-navigation/native'
import gql from 'graphql-tag'
import React, { useContext, useLayoutEffect } from 'react'
import { FlatList, TouchableOpacity, View } from 'react-native'
import i18n from '../../../i18n'
import { deleteAddress } from '../../apollo/server'
import EmptyAddress from '../../assets/images/SVG/imageComponents/EmptyAddress'
import { useMutation } from "@apollo/react-hooks";
import { useNavigation, useTheme } from "@react-navigation/native";
import gql from "graphql-tag";
import React, { useContext, useLayoutEffect } from "react";
import { FlatList, TouchableOpacity, View } from "react-native";
import i18n from "../../../i18n";
import { deleteAddress } from "../../apollo/server";
import EmptyAddress from "../../assets/images/SVG/imageComponents/EmptyAddress";
import {
CustomIcon,
RightButton,
TextDefault,
WrapperView
} from '../../components'
import UserContext from '../../context/User'
import { COLORS } from '../../Theme'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME, NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import useStyle from './styles'
WrapperView,
} from "../../components";
import UserContext from "../../context/User";
import { COLORS } from "../../Theme";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME, NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import useStyle from "./styles";
const DELETE_ADDRESS = gql`
${deleteAddress}
`
`;
function Addresses() {
const styles = useStyle()
const { colors } = useTheme()
const navigation = useNavigation()
const { profile } = useContext(UserContext)
const [mutate, { loading: loadingMutation }] = useMutation(DELETE_ADDRESS)
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const { profile } = useContext(UserContext);
const [mutate, { loading: loadingMutation }] = useMutation(DELETE_ADDRESS);
useLayoutEffect(() => {
navigation.setOptions({
title: i18n.t('myAddresses'),
title: i18n.t("myAddresses"),
headerRight: () => (
<RightButton
icon={ICONS_NAME.Plus}
iconSize={scale(18)}
onPress={() => navigation.navigate(NAVIGATION_SCREEN.NewAddress)}
/>
)
})
}, [navigation])
),
});
}, [navigation]);
const addressIcons = {
Home: ICONS_NAME.Home,
Work: ICONS_NAME.Cart,
Other: ICONS_NAME.Location
}
Other: ICONS_NAME.Location,
};
const colorIcons = {
Other: COLORS.primary,
Home: COLORS.redishPink,
Work: COLORS.primaryLightBlue
}
Work: COLORS.primaryLightBlue,
};
const emptyView = React.memo(() => {
return (
@ -66,28 +66,30 @@ function Addresses() {
textColor={colors.fontMainColor}
bold
H5
style={alignment.Msmall}>
style={alignment.Msmall}
>
No Addresses found.
</TextDefault>
<View>
<TextDefault textColor={colors.fontSecondColor}>
You haven&#39;t saved any address yet.
{'\n'}
{"\n"}
Click Add New Address to get started
</TextDefault>
</View>
<TouchableOpacity
activeOpacity={0.8}
style={styles.adressBtn}
onPress={() => navigation.navigate(NAVIGATION_SCREEN.NewAddress)}>
onPress={() => navigation.navigate(NAVIGATION_SCREEN.NewAddress)}
>
<TextDefault textColor={colors.white} H5 bold>
Add New Address
</TextDefault>
</TouchableOpacity>
</View>
</View>
)
})
);
});
return (
<WrapperView>
<View style={styles.containerInfo}>
@ -101,7 +103,8 @@ function Addresses() {
: { flexGrow: 1 }
}
ListEmptyComponent={emptyView}
keyExtractor={item => item._id}
// keyExtractor={(item) => item._id}
keyExtractor={(item, index) => String(index)}
ItemSeparatorComponent={() => <View style={styles.line} />}
ListHeaderComponent={() => <View style={alignment.MTmedium} />}
renderItem={({ item: address }) => (
@ -110,16 +113,18 @@ function Addresses() {
style={styles.width100}
onPress={() => {
navigation.navigate(NAVIGATION_SCREEN.EditAddress, {
...address
})
}}>
...address,
});
}}
>
<View style={[styles.titleAddress, styles.width100]}>
<View
style={{
alignItems: 'center',
flexDirection: 'row',
flex: 1
}}>
alignItems: "center",
flexDirection: "row",
flex: 1,
}}
>
<CustomIcon
name={addressIcons[address.label]}
size={scale(20)}
@ -128,7 +133,8 @@ function Addresses() {
<TextDefault
bold
H5
style={[alignment.MTxSmall, alignment.MLsmall]}>
style={[alignment.MTxSmall, alignment.MLsmall]}
>
{address.label}
</TextDefault>
</View>
@ -139,9 +145,10 @@ function Addresses() {
style={[styles.iconButton, alignment.MRsmall]}
onPress={() => {
navigation.navigate(NAVIGATION_SCREEN.EditAddress, {
...address
})
}}>
...address,
});
}}
>
<CustomIcon
name={ICONS_NAME.Pencil}
size={scale(20)}
@ -154,8 +161,9 @@ function Addresses() {
disabled={loadingMutation}
style={styles.iconButton}
onPress={() => {
mutate({ variables: { id: address._id } })
}}>
mutate({ variables: { id: address._id } });
}}
>
<CustomIcon
name={ICONS_NAME.Trash}
size={scale(20)}
@ -175,11 +183,12 @@ function Addresses() {
/>
<TextDefault
textColor={colors.fontSecondColor}
style={alignment.MBsmall}>
style={alignment.MBsmall}
>
All rights are reserved by Enatega
</TextDefault>
</View>
</WrapperView>
)
);
}
export default React.memo(Addresses)
export default React.memo(Addresses);

View File

@ -1,56 +1,56 @@
import { useMutation } from '@apollo/react-hooks'
import { useNavigation, useTheme } from '@react-navigation/native'
import gql from 'graphql-tag'
import React, { useContext, useLayoutEffect } from 'react'
import { FlatList, TouchableOpacity, View } from 'react-native'
import i18n from '../../../i18n'
import { selectAddress } from '../../apollo/server'
import { useMutation } from "@apollo/react-hooks";
import { useNavigation, useTheme } from "@react-navigation/native";
import gql from "graphql-tag";
import React, { useContext, useLayoutEffect } from "react";
import { FlatList, TouchableOpacity, View } from "react-native";
import i18n from "../../../i18n";
import { selectAddress } from "../../apollo/server";
import {
CustomIcon,
RightButton,
TextDefault,
WrapperView
} from '../../components'
import RadioButton from '../../components/FdRadioBtn/RadioBtn'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME, NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import useStyle from './styles'
WrapperView,
} from "../../components";
import RadioButton from "../../components/FdRadioBtn/RadioBtn";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME, NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import useStyle from "./styles";
const SELECT_ADDRESS = gql`
${selectAddress}
`
`;
function CartAddresses() {
const { colors } = useTheme()
const styles = useStyle()
const navigation = useNavigation()
const { profile } = useContext(UserContext)
const { colors } = useTheme();
const styles = useStyle();
const navigation = useNavigation();
const { profile } = useContext(UserContext);
const [mutate] = useMutation(SELECT_ADDRESS, { onError })
const [mutate] = useMutation(SELECT_ADDRESS, { onError });
useLayoutEffect(() => {
navigation.setOptions({
title: i18n.t('myAddresses'),
title: i18n.t("myAddresses"),
headerRight: () => (
<RightButton
icon={ICONS_NAME.Plus}
iconSize={scale(18)}
onPress={() => navigation.navigate(NAVIGATION_SCREEN.NewAddress)}
/>
)
})
}, [navigation])
),
});
}, [navigation]);
function onError(error) {
console.log(error)
console.log(error);
}
const onSelectAddress = address => {
mutate({ variables: { id: address._id } })
navigation.goBack()
}
const onSelectAddress = (address) => {
mutate({ variables: { id: address._id } });
navigation.goBack();
};
return (
<WrapperView>
@ -59,7 +59,7 @@ function CartAddresses() {
showsVerticalScrollIndicator={false}
style={styles.flex}
data={profile.addresses}
keyExtractor={item => item._id}
keyExtractor={(item, index) => String(index)}
contentContainerStyle={styles.contentContainer}
ItemSeparatorComponent={() => <View style={styles.line} />}
ListHeaderComponent={() => <View style={{ ...alignment.MTmedium }} />}
@ -69,8 +69,9 @@ function CartAddresses() {
activeOpacity={0.7}
style={styles.width100}
onPress={() => {
onSelectAddress(address)
}}>
onSelectAddress(address);
}}
>
<View style={styles.width100}>
<View style={[styles.titleAddress, styles.width100]}>
<View style={[styles.homeIcon]}>
@ -78,14 +79,14 @@ function CartAddresses() {
size={10}
outerColor={colors.radioOuterColor}
innerColor={colors.radioColor}
animation={'bounceIn'}
animation={"bounceIn"}
isSelected={address.selected}
onPress={() => {
onSelectAddress(address)
onSelectAddress(address);
}}
/>
</View>
<TextDefault style={{ width: '70%' }} H5 bold>
<TextDefault style={{ width: "70%" }} H5 bold>
{address.label}
</TextDefault>
<TouchableOpacity
@ -93,9 +94,10 @@ function CartAddresses() {
style={styles.editButton}
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.EditAddress, {
...address
...address,
})
}>
}
>
<CustomIcon
name={ICONS_NAME.Pencil}
size={scale(20)}
@ -108,13 +110,15 @@ function CartAddresses() {
<TextDefault
line={4}
textColor={colors.fontSecondColor}
bold>
bold
>
{address.delivery_address}
</TextDefault>
<TextDefault
line={3}
textColor={colors.fontSecondColor}
bold>
bold
>
{address.details}
</TextDefault>
</View>
@ -125,7 +129,7 @@ function CartAddresses() {
/>
</View>
</WrapperView>
)
);
}
export default CartAddresses
export default CartAddresses;

View File

@ -1,90 +1,90 @@
import { Feather, FontAwesome } from '@expo/vector-icons'
import { useNavigation, useTheme } from '@react-navigation/native'
import React, { useCallback, useEffect, useState } from 'react'
import { Keyboard, View } from 'react-native'
import { Feather, FontAwesome } from "@expo/vector-icons";
import { useNavigation, useTheme } from "@react-navigation/native";
import React, { useCallback, useEffect, useState } from "react";
import { Keyboard, View } from "react-native";
import {
Bubble,
GiftedChat,
InputToolbar,
Send
} from 'react-native-gifted-chat'
import { TextDefault, WrapperView } from '../../components'
import { alignment } from '../../utils/alignment'
import { scale } from '../../utils/scaling'
import useStyle from './styles'
Send,
} from "react-native-gifted-chat";
import { TextDefault, WrapperView } from "../../components";
import { alignment } from "../../utils/alignment";
import { scale } from "../../utils/scaling";
import useStyle from "./styles";
const UserInfo = {
_id: 1,
name: 'Jason',
active: true
}
name: "Jason",
active: true,
};
function Chat() {
const styles = useStyle()
const { colors } = useTheme()
const navigation = useNavigation()
const [messages, setMessages] = useState([])
const [isTyping, setIsTyping] = useState(false)
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const [messages, setMessages] = useState([]);
const [isTyping, setIsTyping] = useState(false);
useEffect(() => {
Keyboard.addListener('keyboardDidShow', _keyboardDidShow)
Keyboard.addListener('keyboardDidHide', _keyboardDidHide)
Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
Keyboard.addListener("keyboardDidHide", _keyboardDidHide);
// cleanup function
return () => {
Keyboard.removeListener('keyboardDidShow', _keyboardDidShow)
Keyboard.removeListener('keyboardDidHide', _keyboardDidHide)
}
}, [])
Keyboard.remove("keyboardDidShow", _keyboardDidShow);
Keyboard.remove("keyboardDidHide", _keyboardDidHide);
};
}, []);
const _keyboardDidShow = () => setIsTyping(true)
const _keyboardDidHide = () => setIsTyping(false)
const _keyboardDidShow = () => setIsTyping(true);
const _keyboardDidHide = () => setIsTyping(false);
useEffect(() => {
navigation.setOptions({
title: 'Chat'
})
title: "Chat",
});
setMessages([
{
_id: 1,
text: 'How can I help you?',
text: "How can I help you?",
sent: true,
received: true,
createdAt: new Date(),
user: {
_id: 2,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any'
}
}
])
}, [navigation])
name: "React Native",
avatar: "https://placeimg.com/140/140/any",
},
},
]);
}, [navigation]);
const onSend = useCallback((messages = []) => {
setMessages(previousMessages =>
setMessages((previousMessages) =>
GiftedChat.append(previousMessages, messages)
)
}, [])
);
}, []);
const renderBubble = props => {
const renderBubble = (props) => {
return (
<Bubble
{...props}
textStyle={{
right: {
color: colors.fontMainColor
color: colors.fontMainColor,
},
left: {
color: colors.fontMainColor
}
color: colors.fontMainColor,
},
}}
bottomContainerStyle={{
right: {
...alignment.PTxSmall
...alignment.PTxSmall,
},
left: {
...alignment.PTxSmall
}
...alignment.PTxSmall,
},
}}
wrapperStyle={{
right: {
@ -99,11 +99,11 @@ function Chat() {
shadowColor: colors.shadowColor,
shadowOffset: {
width: 0,
height: 1
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 2,
elevation: 3
elevation: 3,
},
left: {
minWidth: 150,
@ -117,36 +117,36 @@ function Chat() {
shadowColor: colors.shadowColor,
shadowOffset: {
width: 0,
height: 1
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 2,
elevation: 3
}
elevation: 3,
},
}}
/>
)
}
);
};
const renderSend = props => (
const renderSend = (props) => (
<Send {...props} containerStyle={styles.sendBtn}>
<View style={styles.rightBtn}>
<Feather
name={'send'}
name={"send"}
color={colors.buttonText}
size={scale(17)}
style={{
transform: [
{ rotateZ: '45deg' },
{ rotateZ: "45deg" },
{ translateY: 2 },
{ translateX: -1 }
]
{ translateX: -1 },
],
}}
/>
</View>
</Send>
)
const customtInputToolbar = props => {
);
const customtInputToolbar = (props) => {
return (
<InputToolbar
{...props}
@ -154,8 +154,8 @@ function Chat() {
renderSend={renderSend}
render
/>
)
}
);
};
return (
<WrapperView>
@ -166,7 +166,7 @@ function Chat() {
color={UserInfo.active ? colors.active : colors.fontSecondColor}
/>
<TextDefault medium H5 style={alignment.PLsmall}>
{UserInfo.active ? UserInfo.name : 'Offline'}
{UserInfo.active ? UserInfo.name : "Offline"}
</TextDefault>
</View>
<GiftedChat
@ -175,7 +175,7 @@ function Chat() {
user={UserInfo}
isTyping={isTyping}
messages={messages}
onSend={messages => onSend(messages)}
onSend={(messages) => onSend(messages)}
renderAvatar={() => null}
renderBubble={renderBubble}
renderInputToolbar={customtInputToolbar}
@ -192,20 +192,20 @@ function Chat() {
// }
timeTextStyle={{
left: {
width: '100%',
width: "100%",
color: colors.fontMainColor,
fontSize: 11,
textAlign: 'right'
textAlign: "right",
},
right: {
color: colors.fontMainColor,
fontSize: 11
}
fontSize: 11,
},
}}
/>
</View>
</WrapperView>
)
);
}
export default Chat
export default Chat;

View File

@ -1,17 +1,18 @@
import { useMutation } from '@apollo/react-hooks'
import { FontAwesome } from '@expo/vector-icons'
import { useNavigation, useTheme } from '@react-navigation/native'
import * as AppAuth from 'expo-app-auth'
import * as AppleAuthentication from 'expo-apple-authentication'
import Constants from 'expo-constants'
import * as Facebook from 'expo-facebook'
import * as Google from 'expo-google-app-auth'
import * as Notifications from 'expo-notifications'
import gql from 'graphql-tag'
import React, { useContext, useEffect, useState } from 'react'
import { Platform, TouchableOpacity, View } from 'react-native'
import getEnvVars from '../../../environment'
import { login } from '../../apollo/server'
import { useMutation } from "@apollo/react-hooks";
import { FontAwesome } from "@expo/vector-icons";
import { useNavigation, useTheme } from "@react-navigation/native";
import * as AppAuth from "expo-app-auth";
import * as AppleAuthentication from "expo-apple-authentication";
import Constants from "expo-constants";
import * as Facebook from "expo-facebook";
//import * as Google from 'expo-google-app-auth'
import * as Google from "expo-auth-session/providers/google";
import * as Notifications from "expo-notifications";
import gql from "graphql-tag";
import React, { useContext, useEffect, useState } from "react";
import { Platform, TouchableOpacity, View } from "react-native";
import getEnvVars from "../../../environment";
import { login } from "../../apollo/server";
import {
EnategaImage,
FdEmailBtn,
@ -21,132 +22,137 @@ import {
RegistrationHeader,
Spinner,
TextDefault,
WrapperView
} from '../../components'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import Analytics from '../../utils/analytics'
import { NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import useStyle from './styles'
WrapperView,
} from "../../components";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import Analytics from "../../utils/analytics";
import { NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import useStyle from "./styles";
const { IOS_CLIENT_ID_GOOGLE, ANDROID_CLIENT_ID_GOOGLE, FACEBOOK_APP_ID } =
getEnvVars()
const {
IOS_CLIENT_ID_GOOGLE,
ANDROID_CLIENT_ID_GOOGLE,
FACEBOOK_APP_ID,
Expo_CLIENT_ID_GOOGLE,
} = getEnvVars();
const LOGIN = gql`
${login}
`
`;
const Logo = require('../../../assets/logo.png')
const Logo = require("../../../assets/logo.png");
const CreateAccount = () => {
const styles = useStyle()
const { colors } = useTheme()
const navigation = useNavigation()
const [enableApple, setEnableApple] = useState(false)
const [loginButton, loginButtonSetter] = useState(null)
const [loading, setLoading] = useState(false)
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const [enableApple, setEnableApple] = useState(false);
const [loginButton, loginButtonSetter] = useState(null);
const [loading, setLoading] = useState(false);
const { setTokenAsync } = useContext(UserContext)
const { setTokenAsync } = useContext(UserContext);
useEffect(() => {
checkIfSupportsAppleAuthentication()
}, [])
checkIfSupportsAppleAuthentication();
}, []);
const [mutate] = useMutation(LOGIN, { onCompleted, onError })
const [mutate] = useMutation(LOGIN, { onCompleted, onError });
async function checkIfSupportsAppleAuthentication() {
setEnableApple(await AppleAuthentication.isAvailableAsync())
setEnableApple(await AppleAuthentication.isAvailableAsync());
}
async function onCompleted(data) {
try {
const trackingOpts = {
id: data.login.userId,
usernameOrEmail: data.login.email
}
Analytics.identify(data.login.userId, trackingOpts)
Analytics.track(Analytics.events.USER_CREATED_ACCOUNT, trackingOpts)
setTokenAsync(data.login.token)
navigation.navigate(NAVIGATION_SCREEN.Menu)
usernameOrEmail: data.login.email,
};
Analytics.identify(data.login.userId, trackingOpts);
Analytics.track(Analytics.events.USER_CREATED_ACCOUNT, trackingOpts);
setTokenAsync(data.login.token);
navigation.navigate(NAVIGATION_SCREEN.Menu);
} catch (e) {
console.log(e)
console.log(e);
} finally {
setLoading(false)
setLoading(false);
}
}
function onError(error) {
try {
console.log(JSON.stringify(error))
console.log(JSON.stringify(error));
FlashMessage({
message: error.graphQLErrors[0].message
})
loginButtonSetter(null)
message: error.graphQLErrors[0].message,
});
loginButtonSetter(null);
} catch (e) {
console.log(e)
console.log(e);
} finally {
setLoading(false)
setLoading(false);
}
}
async function mutateLogin(user) {
setLoading(true)
let notificationToken = null
setLoading(true);
let notificationToken = null;
if (Constants.isDevice) {
const { status: existingStatus } =
await Notifications.getPermissionsAsync()
if (existingStatus === 'granted') {
notificationToken = (await Notifications.getExpoPushTokenAsync()).data
await Notifications.getPermissionsAsync();
if (existingStatus === "granted") {
notificationToken = (await Notifications.getExpoPushTokenAsync()).data;
}
}
mutate({ variables: { ...user, notificationToken } })
mutate({ variables: { ...user, notificationToken } });
}
function renderAppleAction() {
if (loading && loginButton === 'Apple') {
if (loading && loginButton === "Apple") {
return (
<View style={styles.buttonBackground}>
<Spinner backColor="rgba(0,0,0,0.1)" spinnerColor={colors.tagColor} />
</View>
)
);
}
return (
<TouchableOpacity
style={styles.appleBtn}
onPress={async() => {
onPress={async () => {
try {
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL
]
})
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});
if (credential) {
const user = {
appleId: credential.user,
phone: '',
phone: "",
email: credential.email,
password: '',
password: "",
name:
credential.fullName.givenName +
' ' +
" " +
credential.fullName.familyName,
picture: '',
type: 'apple'
picture: "",
type: "apple",
};
mutateLogin(user);
}
mutateLogin(user)
}
loginButtonSetter('Apple')
loginButtonSetter("Apple");
// signed in
} catch (e) {
if (e.code === 'ERR_CANCELLED') {
if (e.code === "ERR_CANCELLED") {
// handle that the user canceled the sign-in flow
loginButtonSetter(null)
loginButtonSetter(null);
} else {
// handle other errors
loginButtonSetter(null)
loginButtonSetter(null);
}
}
}}>
}}
>
<FontAwesome
style={styles.marginLeft5}
name="apple"
@ -157,116 +163,127 @@ const CreateAccount = () => {
Signup with Apple
</TextDefault>
</TouchableOpacity>
)
);
}
async function _facebookSignup() {
try {
await Facebook.initializeAsync({ appId: FACEBOOK_APP_ID })
await Facebook.initializeAsync({ appId: FACEBOOK_APP_ID });
} catch (err) {
console.log('err', err)
console.log("err", err);
}
try {
const { type, token } = await Facebook.logInWithReadPermissionsAsync({
permissions: ['public_profile', 'email']
})
if (type === 'success') {
permissions: ["public_profile", "email"],
});
if (type === "success") {
// Get the user's name using Facebook's Graph API
const response = await fetch(
`https://graph.facebook.com/me?access_token=${token}&fields=email,name`
)
const user = await response.json()
return user
);
const user = await response.json();
return user;
}
} catch (err) {
console.log('error', err)
console.log("error", err);
}
}
async function _googleSignup() {
try {
const { type, user } = await Google.logInAsync({
const [googleRequest, googleResponse, googlePromptAsync] =
Google.useAuthRequest({
expoClientId: Expo_CLIENT_ID_GOOGLE,
iosClientId: IOS_CLIENT_ID_GOOGLE,
iosStandaloneAppClientId: IOS_CLIENT_ID_GOOGLE,
androidClientId: ANDROID_CLIENT_ID_GOOGLE,
androidStandaloneAppClientId: ANDROID_CLIENT_ID_GOOGLE,
redirectUrl: `${AppAuth.OAuthRedirect}:/oauth2redirect/google`,
scopes: ['profile', 'email']
})
if (type === 'success') {
/* `accessToken` is now valid and can be used to get data from the Google API with HTTP requests */
return user
}
} catch (err) {
console.log('err', err)
//redirectUrl: `${AuthSession.OAuthRedirect}:/oauth2redirect/google`,
scopes: ["profile", "email"],
...{ useProxy: true },
});
const googleSignUp = () => {
if (googleResponse?.type === "success") {
const { authentication } = googleResponse;
console.log(authentication.accessToken);
(async () => {
const userInfoResponse = await fetch(
"https://www.googleapis.com/oauth2/v1/userinfo?alt=json",
{
headers: { Authorization: `Bearer ${authentication.accessToken}` },
}
);
const googleUser = await userInfoResponse.json();
const user = {
phone: "",
email: googleUser.email,
password: "",
name: googleUser.name,
picture: googleUser.picture,
type: "google",
};
mutateLogin(user);
})();
}
};
useEffect(() => {
googleSignUp();
}, [googleResponse]);
function renderFacebookAction() {
return (
<FdFacebookBtn
loadingIcon={loading && loginButton === 'Facebook'}
loadingIcon={loading && loginButton === "Facebook"}
onPressIn={() => {
loginButtonSetter('Facebook')
loginButtonSetter("Facebook");
}}
onPress={async() => {
const facebookUser = await _facebookSignup()
onPress={async () => {
const facebookUser = await _facebookSignup();
if (facebookUser) {
const user = {
facebookId: facebookUser.id,
phone: '',
phone: "",
email: facebookUser.email,
password: '',
password: "",
name: facebookUser.name,
picture: '',
type: 'facebook'
}
mutateLogin(user)
picture: "",
type: "facebook",
};
mutateLogin(user);
}
}}
/>
)
);
}
function renderGoogleAction() {
return (
<FdGoogleBtn
loadingIcon={loading && loginButton === 'Google'}
loadingIcon={loading && loginButton === "Google"}
onPressIn={() => {
loginButtonSetter('Google')
}}
onPress={async() => {
const googleUser = await _googleSignup()
if (googleUser) {
const user = {
phone: '',
email: googleUser.email,
password: '',
name: googleUser.name,
picture: googleUser.photoUrl,
type: 'google'
}
mutateLogin(user)
}
loginButtonSetter("Google");
}}
disabled={!googleRequest}
onPress={() => googlePromptAsync()}
/>
)
);
}
function renderEmailAction() {
return (
<FdEmailBtn
loadingIcon={loading && loginButton === 'Email'}
loadingIcon={loading && loginButton === "Email"}
onPress={() => {
loginButtonSetter('Email')
navigation.navigate(NAVIGATION_SCREEN.Register)
loginButtonSetter("Email");
navigation.navigate(NAVIGATION_SCREEN.Register);
}}
/>
)
);
}
return (
<WrapperView>
<View style={[styles.mainContainer, styles.flex]}>
<RegistrationHeader title={'Get Started'} />
<RegistrationHeader title={"Get Started"} />
<View style={styles.subContainer}>
<View style={[styles.flex, styles.upperContainer]}>
<EnategaImage
@ -276,7 +293,7 @@ const CreateAccount = () => {
/>
</View>
<View style={styles.width100}>
{Platform.OS === 'ios' && renderFacebookAction()}
{Platform.OS === "ios" && renderFacebookAction()}
<View style={alignment.MTmedium}>{renderGoogleAction()}</View>
{enableApple && (
<View style={alignment.MTmedium}>{renderAppleAction()}</View>
@ -286,7 +303,8 @@ const CreateAccount = () => {
<TouchableOpacity
activeOpacity={0.7}
style={styles.alreadyBtn}
onPress={() => navigation.navigate(NAVIGATION_SCREEN.Login)}>
onPress={() => navigation.navigate(NAVIGATION_SCREEN.Login)}
>
<TextDefault style={[alignment.MLsmall]} bold>
Already a member? Log in
</TextDefault>
@ -295,6 +313,6 @@ const CreateAccount = () => {
</View>
</View>
</WrapperView>
)
}
export default CreateAccount
);
};
export default CreateAccount;

View File

@ -1,51 +1,51 @@
import { useQuery } from '@apollo/react-hooks'
import { useNavigation } from '@react-navigation/native'
import gql from 'graphql-tag'
import React, { useContext, useLayoutEffect } from 'react'
import { FlatList, View } from 'react-native'
import { categories } from '../../apollo/server'
import EmptyFood from '../../assets/images/SVG/imageComponents/EmptyFood'
import { useQuery } from "@apollo/react-hooks";
import { useNavigation } from "@react-navigation/native";
import gql from "graphql-tag";
import React, { useContext, useLayoutEffect } from "react";
import { FlatList, View } from "react-native";
import { categories } from "../../apollo/server";
import EmptyFood from "../../assets/images/SVG/imageComponents/EmptyFood";
import {
MenuCard,
Spinner,
StatusCard,
TextDefault,
TextError,
WrapperView
} from '../../components'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import { NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import useStyle from './styles'
WrapperView,
} from "../../components";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import { NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import useStyle from "./styles";
// constants
const CATEGORIES = gql`
${categories}
`
`;
function Menu() {
const styles = useStyle()
const navigation = useNavigation()
const { isLoggedIn, profile } = useContext(UserContext)
const { data, refetch, networkStatus, loading, error } = useQuery(CATEGORIES)
const styles = useStyle();
const navigation = useNavigation();
const { isLoggedIn, profile } = useContext(UserContext);
const { data, refetch, networkStatus, loading, error } = useQuery(CATEGORIES);
useLayoutEffect(() => {
navigation.setOptions({
title: 'Home'
})
}, [])
title: "Home",
});
}, []);
function emptyView() {
if (loading) {
return <Spinner />
return <Spinner />;
} else if (error) {
return (
<TextError
text={error ? error.message : 'No Foods'}
text={error ? error.message : "No Foods"}
backColor="transparent"
/>
)
);
} else {
return (
<View style={styles.emptyContainer}>
@ -54,7 +54,7 @@ function Menu() {
No item found
</TextDefault>
</View>
)
);
}
}
@ -65,7 +65,7 @@ function Menu() {
style={styles.flex}
contentContainerStyle={styles.contentContainer}
showsVerticalScrollIndicator={false}
keyExtractor={item => item._id}
keyExtractor={(item, index) => String(index)}
ListEmptyComponent={emptyView()}
data={loading ? [] : error ? [] : data.categories}
refreshing={networkStatus === 4}
@ -80,28 +80,28 @@ function Menu() {
Featured
</TextDefault>
</>
)
);
}
return null
return null;
}}
renderItem={({ item }) => (
<View key={item._id} style={styles.cardViewContainer}>
<MenuCard
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.MenuItems, {
...item
...item,
})
}
title={item.title}
description={item.description}
image={item.img_menu || ''}
image={item.img_menu || ""}
/>
</View>
)}
/>
</View>
</WrapperView>
)
);
}
export default React.memo(Menu)
export default React.memo(Menu);

View File

@ -247,7 +247,7 @@ function MenuItems() {
contentContainerStyle={styles.contentContaienr}
showsVerticalScrollIndicator={false}
ListHeaderComponent={renderListHeader()}
keyExtractor={(item) => item._id}
keyExtractor={(item, index) => String(index)}
ListEmptyComponent={emptyView}
data={loading ? [] : error ? [] : sortData(data.foodByCategory)}
refreshing={networkStatus === 4}

View File

@ -1,10 +1,10 @@
import { useApolloClient } from '@apollo/react-hooks'
import { useNavigation, useTheme } from '@react-navigation/native'
import React, { useContext, useLayoutEffect } from 'react'
import { FlatList, TouchableOpacity, View } from 'react-native'
import uuid from 'uuid'
import i18n from '../../../i18n'
import EmptyOrder from '../../assets/images/SVG/imageComponents/EmptyOrder'
import { useApolloClient } from "@apollo/react-hooks";
import { useNavigation, useTheme } from "@react-navigation/native";
import React, { useContext, useLayoutEffect } from "react";
import { FlatList, TouchableOpacity, View } from "react-native";
import uuid from "uuid";
import i18n from "../../../i18n";
import EmptyOrder from "../../assets/images/SVG/imageComponents/EmptyOrder";
import {
ActiveOrders,
CustomIcon,
@ -12,24 +12,24 @@ import {
Spinner,
TextDefault,
TextError,
WrapperView
} from '../../components'
import ConfigurationContext from '../../context/Configuration'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME, NAVIGATION_SCREEN } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import useStyle from './style'
WrapperView,
} from "../../components";
import ConfigurationContext from "../../context/Configuration";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME, NAVIGATION_SCREEN } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import useStyle from "./style";
const orderStatusActive = ['PENDING', 'PICKED', 'ACCEPTED']
const orderStatusInactive = ['DELIVERED', 'COMPLETED']
const orderStatusActive = ["PENDING", "PICKED", "ACCEPTED"];
const orderStatusInactive = ["DELIVERED", "COMPLETED"];
function MyOrders() {
const styles = useStyle()
const { colors } = useTheme()
const client = useApolloClient()
const navigation = useNavigation()
const configuration = useContext(ConfigurationContext)
const styles = useStyle();
const { colors } = useTheme();
const client = useApolloClient();
const navigation = useNavigation();
const configuration = useContext(ConfigurationContext);
const {
orders,
loadingOrders,
@ -37,47 +37,47 @@ function MyOrders() {
fetchOrders,
fetchMoreOrdersFunc,
networkStatusOrders,
updateCart
} = useContext(UserContext)
updateCart,
} = useContext(UserContext);
useLayoutEffect(() => {
navigation.setOptions({
headerTitle: i18n.t('titleOrders'),
headerRight: null
})
}, [navigation])
headerTitle: i18n.t("titleOrders"),
headerRight: null,
});
}, [navigation]);
// add items to cart and navigate to cart screen
async function onReOrder({ order }) {
const data = {
cartItems: order.items.map(item => {
cartItems: order.items.map((item) => {
return {
...item.food,
key: uuid.v4(),
__typename: 'CartItem',
__typename: "CartItem",
variation: {
__typename: 'ItemVariation',
_id: item.variation._id
__typename: "ItemVariation",
_id: item.variation._id,
},
quantity: item.quantity,
addons: item.addons.map(addon => ({
addons: item.addons.map((addon) => ({
...addon,
__typename: 'ItemAddon',
__typename: "ItemAddon",
options: addon.options.map(({ _id }) => ({
_id,
__typename: 'ItemOption'
}))
}))
}
})
}
await updateCart(data.cartItems)
navigation.navigate(NAVIGATION_SCREEN.Cart)
__typename: "ItemOption",
})),
})),
};
}),
};
await updateCart(data.cartItems);
navigation.navigate(NAVIGATION_SCREEN.Cart);
}
function emptyView() {
if (loadingOrders) return <Spinner visible={loadingOrders} />
if (errorOrders) return <TextError text={errorOrders.message} />
if (loadingOrders) return <Spinner visible={loadingOrders} />;
if (errorOrders) return <TextError text={errorOrders.message} />;
else {
return (
<View style={styles.subContainerImage}>
@ -92,13 +92,14 @@ function MyOrders() {
<TouchableOpacity
activeOpacity={0.7}
style={styles.emptyButton}
onPress={() => navigation.navigate(NAVIGATION_SCREEN.Menu)}>
onPress={() => navigation.navigate(NAVIGATION_SCREEN.Menu)}
>
<TextDefault textColor={colors.buttonText} bold H5 center>
Start Shopping
</TextDefault>
</TouchableOpacity>
</View>
)
);
}
}
@ -108,7 +109,7 @@ function MyOrders() {
data={
loadingOrders || errorOrders
? []
: orders.filter(o => orderStatusInactive.includes(o.order_status))
: orders.filter((o) => orderStatusInactive.includes(o.order_status))
}
style={styles.container}
contentContainerStyle={styles.contentContainer}
@ -116,17 +117,18 @@ function MyOrders() {
ListHeaderComponent={
<ActiveOrders
navigation={navigation}
activeOrders={orders.filter(o =>
activeOrders={orders.filter((o) =>
orderStatusActive.includes(o.order_status)
)}
pastOrders={orders.filter(o =>
pastOrders={orders.filter((o) =>
orderStatusInactive.includes(o.order_status)
)}
loading={loadingOrders}
error={errorOrders}
/>
}
keyExtractor={item => item._id}
//keyExtractor={(item) => item._id}
keyExtractor={(item, index) => String(index)}
refreshing={networkStatusOrders === 4}
onRefresh={() => networkStatusOrders === 7 && fetchOrders()}
renderItem={({ item }) => (
@ -135,9 +137,10 @@ function MyOrders() {
onPress={() =>
navigation.navigate(NAVIGATION_SCREEN.OrderDetail, {
_id: item._id,
currency_symbol: configuration.currency_symbol
currency_symbol: configuration.currency_symbol,
})
}>
}
>
<View style={styles.subContainer}>
<View style={styles.imgContainer}>
<EnategaImage
@ -148,7 +151,7 @@ function MyOrders() {
</View>
<View style={styles.infoContainer}>
<TextDefault H5 bold style={alignment.MBxSmall}>
{'ID: '}
{"ID: "}
{item.order_id}
</TextDefault>
<TextDefault line={3} textColor={colors.tagColor} H5 medium>
@ -163,9 +166,10 @@ function MyOrders() {
<TouchableOpacity
activeOpacity={0.8}
onPress={() => onReOrder({ order: item, client })}
style={styles.subContainerRight}>
style={styles.subContainerRight}
>
<View>
<View style={{ alignSelf: 'center' }}>
<View style={{ alignSelf: "center" }}>
<CustomIcon
name={ICONS_NAME.Refresh}
size={scale(28)}
@ -176,8 +180,9 @@ function MyOrders() {
textColor={colors.text}
style={alignment.MTxSmall}
bold
center>
{'Re-Order'}
center
>
{"Re-Order"}
</TextDefault>
</View>
</TouchableOpacity>
@ -187,7 +192,7 @@ function MyOrders() {
onEndReached={fetchMoreOrdersFunc}
/>
</WrapperView>
)
);
}
export default MyOrders
export default MyOrders;

View File

@ -1,207 +1,207 @@
import { useMutation } from '@apollo/react-hooks'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { useNavigation, useTheme } from '@react-navigation/native'
import Constants from 'expo-constants'
import * as Device from 'expo-device'
import * as Localization from 'expo-localization'
import * as Notifications from 'expo-notifications'
import * as Updates from 'expo-updates'
import gql from 'graphql-tag'
import React, { useContext, useEffect, useRef, useState } from 'react'
import { useMutation } from "@apollo/react-hooks";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useNavigation, useTheme } from "@react-navigation/native";
import Constants from "expo-constants";
import * as Device from "expo-device";
import * as Localization from "expo-localization";
import * as Notifications from "expo-notifications";
import * as Updates from "expo-updates";
import gql from "graphql-tag";
import React, { useContext, useEffect, useRef, useState } from "react";
import {
AppState,
Linking,
Platform,
StyleSheet,
TouchableOpacity,
View
} from 'react-native'
import { Modalize } from 'react-native-modalize'
import i18n from '../../../i18n'
View,
} from "react-native";
import { Modalize } from "react-native-modalize";
import i18n from "../../../i18n";
import {
profile,
pushToken,
updateNotificationStatus
} from '../../apollo/server'
updateNotificationStatus,
} from "../../apollo/server";
import {
CustomIcon,
FlashMessage,
Spinner,
TextDefault,
WrapperView
} from '../../components'
import SwitchBtn from '../../components/FdSwitch/SwitchBtn'
import UserContext from '../../context/User'
import { alignment } from '../../utils/alignment'
import { ICONS_NAME } from '../../utils/constant'
import { scale } from '../../utils/scaling'
import SettingModal from './components/SettingModal'
import useStyle from './styles'
WrapperView,
} from "../../components";
import SwitchBtn from "../../components/FdSwitch/SwitchBtn";
import UserContext from "../../context/User";
import { alignment } from "../../utils/alignment";
import { ICONS_NAME } from "../../utils/constant";
import { scale } from "../../utils/scaling";
import SettingModal from "./components/SettingModal";
import useStyle from "./styles";
const languageTypes = [
{ value: 'English', code: 'en', index: 0 },
{ value: 'français', code: 'fr', index: 1 },
{ value: 'ភាសាខ្មែរ', code: 'km', index: 2 },
{ value: '中文', code: 'zh', index: 3 },
{ value: 'Deutsche', code: 'de', index: 4 }
]
{ value: "English", code: "en", index: 0 },
{ value: "français", code: "fr", index: 1 },
{ value: "ភាសាខ្មែរ", code: "km", index: 2 },
{ value: "中文", code: "zh", index: 3 },
{ value: "Deutsche", code: "de", index: 4 },
];
const PUSH_TOKEN = gql`
${pushToken}
`
`;
const UPDATE_NOTIFICATION_TOKEN = gql`
${updateNotificationStatus}
`
`;
const PROFILE = gql`
${profile}
`
`;
function Settings() {
const styles = useStyle()
const { colors } = useTheme()
const navigation = useNavigation()
const { profile } = useContext(UserContext)
const styles = useStyle();
const { colors } = useTheme();
const navigation = useNavigation();
const { profile } = useContext(UserContext);
const [languageName, languageNameSetter] = useState('English')
const [languageName, languageNameSetter] = useState("English");
const [offerNotification, offerNotificationSetter] = useState(
profile.is_offer_notification
)
);
const [orderNotification, orderNotificationSetter] = useState(
profile.is_order_notification
)
const [activeRadio, activeRadioSetter] = useState(languageTypes[0].index)
);
const [activeRadio, activeRadioSetter] = useState(languageTypes[0].index);
// eslint-disable-next-line no-unused-vars
const [appState, setAppState] = useState(AppState.currentState)
const [uploadToken] = useMutation(PUSH_TOKEN)
const [appState, setAppState] = useState(AppState.currentState);
const [uploadToken] = useMutation(PUSH_TOKEN);
const [mutate, { loading }] = useMutation(UPDATE_NOTIFICATION_TOKEN, {
onCompleted,
onError,
refetchQueries: [{ query: PROFILE }]
})
const modalizeRef = useRef(null)
refetchQueries: [{ query: PROFILE }],
});
const modalizeRef = useRef(null);
useEffect(() => {
navigation.setOptions({
headerTitle: i18n.t('titleSettings'),
headerRight: null
})
selectLanguage()
checkPermission()
}, [navigation])
headerTitle: i18n.t("titleSettings"),
headerRight: null,
});
selectLanguage();
checkPermission();
}, [navigation]);
const _handleAppStateChange = async nextAppState => {
if (nextAppState === 'active') {
let token = null
const permission = await getPermission()
if (permission === 'granted') {
const _handleAppStateChange = async (nextAppState) => {
if (nextAppState === "active") {
let token = null;
const permission = await getPermission();
if (permission === "granted") {
if (!profile.notificationToken) {
token = (await Notifications.getExpoPushTokenAsync()).data
uploadToken({ variables: { token } })
token = (await Notifications.getExpoPushTokenAsync()).data;
uploadToken({ variables: { token } });
}
offerNotificationSetter(profile.is_offer_notification)
orderNotificationSetter(profile.is_order_notification)
offerNotificationSetter(profile.is_offer_notification);
orderNotificationSetter(profile.is_order_notification);
} else {
offerNotificationSetter(false)
orderNotificationSetter(false)
offerNotificationSetter(false);
orderNotificationSetter(false);
}
}
setAppState(nextAppState)
}
setAppState(nextAppState);
};
useEffect(() => {
AppState.addEventListener('change', _handleAppStateChange)
AppState.addEventListener("change", _handleAppStateChange);
return () => {
AppState.removeEventListener('change', _handleAppStateChange)
}
}, [])
AppState.remove("change", _handleAppStateChange);
};
}, []);
async function checkPermission() {
const permission = await getPermission()
if (permission !== 'granted') {
offerNotificationSetter(false)
orderNotificationSetter(false)
const permission = await getPermission();
if (permission !== "granted") {
offerNotificationSetter(false);
orderNotificationSetter(false);
} else {
offerNotificationSetter(profile.is_offer_notification)
orderNotificationSetter(profile.is_order_notification)
offerNotificationSetter(profile.is_offer_notification);
orderNotificationSetter(profile.is_order_notification);
}
}
async function getPermission() {
const { status } = await Notifications.getPermissionsAsync()
return status
const { status } = await Notifications.getPermissionsAsync();
return status;
}
async function selectLanguage() {
const lang = await AsyncStorage.getItem('enatega-language')
const lang = await AsyncStorage.getItem("enatega-language");
if (lang) {
const defLang = languageTypes.findIndex(el => el.code === lang)
const langName = languageTypes[defLang].value
activeRadioSetter(defLang)
languageNameSetter(langName)
const defLang = languageTypes.findIndex((el) => el.code === lang);
const langName = languageTypes[defLang].value;
activeRadioSetter(defLang);
languageNameSetter(langName);
}
}
const onSelectedLanguage = async active => {
const languageInd = active
if (Platform.OS === 'android') {
const localization = await Localization.getLocalizationAsync()
localization.locale = languageTypes[languageInd].code
const onSelectedLanguage = async (active) => {
const languageInd = active;
if (Platform.OS === "android") {
const localization = await Localization.getLocalizationAsync();
localization.locale = languageTypes[languageInd].code;
await AsyncStorage.setItem(
'enatega-language',
"enatega-language",
languageTypes[languageInd].code
)
Updates.reloadAsync()
}
);
Updates.reloadAsync();
}
};
const onClose = () => {
modalizeRef.current.close()
}
modalizeRef.current.close();
};
function onCompleted() {
FlashMessage({
message: 'Notification Status Updated'
})
message: "Notification Status Updated",
});
}
function onError(error) {
try {
FlashMessage({
message: error.networkError.result.errors[0].message
})
message: error.networkError.result.errors[0].message,
});
} catch (err) {}
}
async function updateNotificationStatus(notificationCheck) {
let orderNotify, offerNotify
let orderNotify, offerNotify;
if (!Device.isDevice) {
FlashMessage({
message: 'Notification do not work on simulator'
})
return
message: "Notification do not work on simulator",
});
return;
}
const permission = await getPermission()
if (!profile.notificationToken || permission !== 'granted') {
Linking.openSettings()
const permission = await getPermission();
if (!profile.notificationToken || permission !== "granted") {
Linking.openSettings();
}
if (notificationCheck === 'offer') {
offerNotificationSetter(!offerNotification)
orderNotify = orderNotification
offerNotify = !offerNotification
if (notificationCheck === "offer") {
offerNotificationSetter(!offerNotification);
orderNotify = orderNotification;
offerNotify = !offerNotification;
}
if (notificationCheck === 'order') {
orderNotificationSetter(!orderNotification)
orderNotify = !orderNotification
offerNotify = offerNotification
if (notificationCheck === "order") {
orderNotificationSetter(!orderNotification);
orderNotify = !orderNotification;
offerNotify = offerNotification;
}
mutate({
variables: {
offerNotification: offerNotify,
orderNotification: orderNotify
}
})
orderNotification: orderNotify,
},
});
}
return (
@ -213,7 +213,7 @@ function Settings() {
)}
<View style={[styles.flex, styles.mainContainer]}>
<View style={alignment.Plarge}>
{Platform.OS === 'android' && (
{Platform.OS === "android" && (
<View style={[styles.languageContainer, styles.shadow]}>
<View style={styles.changeLanguage}>
<View style={styles.headingLanguage}>
@ -221,7 +221,8 @@ function Settings() {
numberOfLines={1}
textColor={colors.fontSecondColor}
medium
H5>
H5
>
Language
</TextDefault>
<TextDefault medium H5>
@ -230,8 +231,9 @@ function Settings() {
</View>
<TouchableOpacity
activeOpacity={0.5}
onPress={() => modalizeRef.current.open('top')}
style={styles.button}>
onPress={() => modalizeRef.current.open("top")}
style={styles.button}
>
<CustomIcon
name={ICONS_NAME.Pencil}
size={scale(22)}
@ -244,20 +246,22 @@ function Settings() {
<TouchableOpacity
activeOpacity={0.7}
onPress={() => {
updateNotificationStatus('offer')
updateNotificationStatus("offer");
}}
style={[styles.notificationContainer, styles.shadow]}>
style={[styles.notificationContainer, styles.shadow]}
>
<View style={styles.notificationChekboxContainer}>
<TextDefault
numberOfLines={1}
textColor={colors.statusSecondColor}>
{' '}
Receive Special Offers{' '}
textColor={colors.statusSecondColor}
>
{" "}
Receive Special Offers{" "}
</TextDefault>
<SwitchBtn
isEnabled={offerNotification}
onPress={() => {
updateNotificationStatus('offer')
updateNotificationStatus("offer");
}}
/>
</View>
@ -265,20 +269,22 @@ function Settings() {
<TouchableOpacity
activeOpacity={0.7}
onPress={() => {
updateNotificationStatus('order')
updateNotificationStatus("order");
}}
style={[styles.notificationContainer, styles.shadow]}>
style={[styles.notificationContainer, styles.shadow]}
>
<View style={styles.notificationChekboxContainer}>
<TextDefault
numberOfLines={1}
textColor={colors.statusSecondColor}>
{' '}
Get updates on your order status!{' '}
textColor={colors.statusSecondColor}
>
{" "}
Get updates on your order status!{" "}
</TextDefault>
<SwitchBtn
isEnabled={orderNotification}
onPress={() => {
updateNotificationStatus('order')
updateNotificationStatus("order");
}}
/>
</View>
@ -293,7 +299,8 @@ function Settings() {
<TextDefault
textColor={colors.fontSecondColor}
style={alignment.MBsmall}
center>
center
>
All rights are reserved by Enatega
</TextDefault>
@ -304,10 +311,11 @@ function Settings() {
handlePosition="inside"
avoidKeyboardLikeIOS={Platform.select({
ios: true,
android: false
android: false,
})}
keyboardAvoidingOffset={2}
keyboardAvoidingBehavior="height">
keyboardAvoidingBehavior="height"
>
<SettingModal
onClose={onClose}
onSelectedLanguage={onSelectedLanguage}
@ -315,6 +323,6 @@ function Settings() {
/>
</Modalize>
</WrapperView>
)
);
}
export default Settings
export default Settings;

View File

@ -1,15 +1,16 @@
import * as Amplitude from 'expo-analytics-amplitude'
import { normalizeTrackingOptions } from './analyticsUtils'
import getEnvVars from '../../environment'
import { getTrackingPermissions } from './useAppTrackingTransparency'
const { AMPLITUDE_API_KEY } = getEnvVars()
//import * as Amplitude from 'expo-analytics-amplitude'
import * as Amplitude from "@amplitude/analytics-react-native";
import { normalizeTrackingOptions } from "./analyticsUtils";
import getEnvVars from "../../environment";
import { getTrackingPermissions } from "./useAppTrackingTransparency";
const { AMPLITUDE_API_KEY } = getEnvVars();
let isInitialized = false
let isInitialized = false;
export const events = {
USER_LOGGED_IN: 'USER_LOGGED_IN',
USER_LOGGED_OUT: 'USER_LOGGED_OUT',
USER_CREATED_ACCOUNT: 'USER_CREATED_ACCOUNT',
USER_LOGGED_IN: "USER_LOGGED_IN",
USER_LOGGED_OUT: "USER_LOGGED_OUT",
USER_CREATED_ACCOUNT: "USER_CREATED_ACCOUNT",
// USER_RESET_PASSWORD: 'USER_RESET_PASSWORD',
// USER_LINKED_SOCIAL: 'USER_LINKED_SOCIAL',
// USER_UPDATED_EMAIL: 'USER_UPDATED_EMAIL',
@ -20,40 +21,41 @@ export const events = {
// USER_REMOVED_PROJECT: 'USER_REMOVED_PROJECT',
// USER_OPENED_CREATION: 'USER_OPENED_CREATION',
// USER_UPDATED_SETTINGS: 'USER_UPDATED_SETTINGS',
USER_PLACED_ORDER: 'USER_PLACED_ORDER'
}
USER_PLACED_ORDER: "USER_PLACED_ORDER",
};
export async function initialize() {
const trackingStatus = await getTrackingPermissions()
if (isInitialized || !AMPLITUDE_API_KEY || trackingStatus !== 'granted') {
return
const trackingStatus = await getTrackingPermissions();
if (isInitialized || !AMPLITUDE_API_KEY || trackingStatus !== "granted") {
return;
}
await Amplitude.initializeAsync(AMPLITUDE_API_KEY)
isInitialized = true
Amplitude.init(AMPLITUDE_API_KEY);
isInitialized = true;
}
export async function identify(id, options) {
initialize()
const properties = normalizeTrackingOptions(options)
initialize();
const properties = normalizeTrackingOptions(options);
if (id) {
await Amplitude.setUserIdAsync(id)
if (properties) {
await Amplitude.setUserPropertiesAsync(properties)
}
Amplitude.Identify(properties);
//await Amplitude.setUserPropertiesAsync(properties)
} else {
await Amplitude.clearUserPropertiesAsync()
//await Amplitude.clearUserPropertiesAsync()
const identifyObj = new Amplitude.Identify();
identifyObj.remove(properties);
Amplitude.Identify(identifyObj);
}
}
export async function track(event, options) {
initialize()
const properties = normalizeTrackingOptions(options)
initialize();
const properties = normalizeTrackingOptions(options);
if (properties) {
await Amplitude.logEventWithPropertiesAsync(event, properties)
Amplitude.track(event, properties);
} else {
await Amplitude.logEventAsync(event)
Amplitude.track(event);
}
}
@ -61,5 +63,5 @@ export default {
events,
initialize,
identify,
track
}
track,
};

View File

@ -1,34 +1,35 @@
// packages
import { BackHandler, Alert } from 'react-native'
import { BackHandler, Alert } from "react-native";
/**
* Attaches an event listener that handles the android-only hardware
* back button
* @param {Function} callback The function to call on click
*/
const handleAndroidBackButton = callback => {
BackHandler.addEventListener('hardwareBackPress', () => {
callback()
return true
})
}
const handleAndroidBackButton = (callback) => {
BackHandler.addEventListener("hardwareBackPress", () => {
callback();
return true;
});
};
/**
* Removes the event listener in order not to add a new one
* every time the view component re-mounts
*/
const removeAndroidBackButtonHandler = () => {
BackHandler.removeEventListener('hardwareBackPress')
}
// BackHandler.removeEventListener('hardwareBackPress')
BackHandler.remove("hardwareBackPress");
};
const exitAlert = () => {
Alert.alert('Confirm exit', 'Do you want to quit the app?', [
{ text: 'CANCEL', style: 'cancel' },
Alert.alert("Confirm exit", "Do you want to quit the app?", [
{ text: "CANCEL", style: "cancel" },
{
text: 'OK',
text: "OK",
onPress: () => {
BackHandler.exitApp()
}
}
])
return true
}
BackHandler.exitApp();
},
},
]);
return true;
};
export { handleAndroidBackButton, removeAndroidBackButtonHandler, exitAlert }
export { handleAndroidBackButton, removeAndroidBackButtonHandler, exitAlert };