index.tsx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import React, { useEffect, useState } from 'react';
  2. import { View, Text, Switch, Platform, Linking } from 'react-native';
  3. import * as Notifications from 'expo-notifications';
  4. import { Header, PageWrapper, MenuButton, WarningModal } from '../../../../components';
  5. import { NAVIGATION_PAGES } from '../../../../types';
  6. import { Colors } from '../../../../theme';
  7. import UserPenIcon from '../../../../../assets/icons/user-pen.svg';
  8. import UserPlusIcon from '../../../../../assets/icons/user-plus.svg';
  9. import BellIcon from '../../../../../assets/icons/bell.svg';
  10. import MailIcon from '../../../../../assets/icons/mail.svg';
  11. import FAQIcon from '../../../../../assets/icons/faq.svg';
  12. import DocumentIcon from '../../../../../assets/icons/document.svg';
  13. import ShieldIcon from '../../../../../assets/icons/shield.svg';
  14. import ExitIcon from '../../../../../assets/icons/exit.svg';
  15. import UserXMark from '../../../../../assets/icons/user-xmark.svg';
  16. import type { MenuButtonType } from '../../../../types/components';
  17. import { StoreType, storage } from 'src/storage';
  18. import { CommonActions, useNavigation } from '@react-navigation/native';
  19. import { useDeleteUserMutation } from '@api/app';
  20. const Settings = () => {
  21. const { mutate: deleteUser } = useDeleteUserMutation();
  22. const token = storage.get('token', StoreType.STRING) as string;
  23. const [isSubscribed, setIsSubscribed] = useState(false);
  24. const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState(false);
  25. const navigation = useNavigation();
  26. const [modalInfo, setModalInfo] = useState({
  27. visible: false,
  28. type: 'confirm',
  29. message: '',
  30. action: () => {}
  31. });
  32. const openModal = (type: string, message: string, action: any) => {
  33. setModalInfo({
  34. visible: true,
  35. type,
  36. message,
  37. action
  38. });
  39. };
  40. const closeModal = () => {
  41. setModalInfo({ ...modalInfo, visible: false });
  42. };
  43. const buttons: MenuButtonType[] = [
  44. {
  45. label: 'Edit Profile',
  46. icon: <UserPenIcon fill={Colors.DARK_BLUE} width={20} height={20} />,
  47. buttonFn: (navigation) => {
  48. navigation.navigate(NAVIGATION_PAGES.EDIT_PERSONAL_INFO);
  49. }
  50. },
  51. // {
  52. // label: 'Invite a Friend',
  53. // icon: <UserPlusIcon fill={Colors.DARK_BLUE} width={20} height={20} />
  54. // },
  55. // {
  56. // label: 'Notification',
  57. // icon: <BellIcon fill={Colors.DARK_BLUE} width={20} height={20} />
  58. // },
  59. {
  60. label: 'Contact Us',
  61. icon: <MailIcon fill={Colors.DARK_BLUE} width={20} height={20} />,
  62. buttonFn: () => Linking.openURL('https://nomadmania.com/contact/')
  63. },
  64. // {
  65. // label: 'FAQs',
  66. // icon: <FAQIcon fill={Colors.DARK_BLUE} width={20} height={20} />
  67. // },
  68. {
  69. label: 'Terms & Conditions',
  70. icon: <DocumentIcon fill={Colors.DARK_BLUE} width={20} height={20} />,
  71. buttonFn: () => Linking.openURL('https://nomadmania.com/terms/')
  72. },
  73. // {
  74. // label: 'Privacy Notice',
  75. // icon: <ShieldIcon fill={Colors.DARK_BLUE} width={20} height={20} />
  76. // },
  77. {
  78. label: 'Logout',
  79. icon: <ExitIcon fill={Colors.RED} width={20} height={20} />,
  80. red: true,
  81. buttonFn: () => openModal('confirm', 'Are you sure you want to logout?', handleLogout)
  82. },
  83. {
  84. label: 'Delete account',
  85. icon: <UserXMark fill={Colors.RED} width={20} height={20} />,
  86. red: true,
  87. buttonFn: () =>
  88. openModal('confirm', 'Are you sure you want to delete your account?', handleDeleteAccount)
  89. }
  90. ];
  91. useEffect(() => {
  92. const subscribed = (storage.get('subscribed', StoreType.BOOLEAN) as boolean) ?? false;
  93. setIsSubscribed(subscribed);
  94. }, []);
  95. const handleLogout = () => {
  96. storage.remove('token');
  97. storage.remove('uid');
  98. navigation.dispatch(
  99. CommonActions.reset({
  100. index: 1,
  101. routes: [{ name: NAVIGATION_PAGES.WELCOME }]
  102. })
  103. );
  104. };
  105. const handleDeleteAccount = () => {
  106. deleteUser({ token }, { onSuccess: handleLogout });
  107. };
  108. const handleSubscribe = async () => {
  109. const token = await registerForPushNotificationsAsync();
  110. if (token) {
  111. console.log(token);
  112. storage.set('subscribed', true);
  113. setIsSubscribed(true);
  114. Notifications.addNotificationReceivedListener((notification) => {
  115. console.log('notification', notification);
  116. });
  117. Notifications.addNotificationResponseReceivedListener((response) => {
  118. const data = response.notification.request.content.data;
  119. console.log('data', data);
  120. });
  121. }
  122. };
  123. const toggleSwitch = () => {
  124. if (isSubscribed) {
  125. storage.set('subscribed', false);
  126. storage.remove('deviceToken');
  127. setIsSubscribed(false);
  128. } else {
  129. setModalInfo({
  130. visible: true,
  131. type: 'success',
  132. message:
  133. 'To use this feature we need your permission to access your notifications. If you press OK your system will ask you to confirm permission to receive notifications from NomadMania.',
  134. action: () => setShouldOpenWarningModal(true)
  135. });
  136. }
  137. };
  138. async function registerForPushNotificationsAsync() {
  139. let token;
  140. const { status: existingStatus } = await Notifications.getPermissionsAsync();
  141. let finalStatus = existingStatus;
  142. if (existingStatus !== 'granted') {
  143. const { status } = await Notifications.requestPermissionsAsync();
  144. finalStatus = status;
  145. }
  146. if (finalStatus !== 'granted') {
  147. setModalInfo({
  148. visible: true,
  149. type: 'success',
  150. message:
  151. 'NomadMania app needs notification permissions to function properly. Open settings?',
  152. action: () =>
  153. Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
  154. });
  155. return null;
  156. }
  157. token = (await Notifications.getDevicePushTokenAsync()).data;
  158. if (Platform.OS === 'android') {
  159. Notifications.setNotificationChannelAsync('default', {
  160. name: 'default',
  161. importance: Notifications.AndroidImportance.MAX,
  162. vibrationPattern: [0, 250, 250, 250],
  163. lightColor: '#FF231F7C'
  164. });
  165. }
  166. storage.set('deviceToken', token);
  167. return token;
  168. }
  169. return (
  170. <PageWrapper>
  171. <Header label={'Settings'} />
  172. {buttons.map((button, index) => (
  173. <MenuButton
  174. key={index}
  175. label={button.label}
  176. icon={button.icon}
  177. red={button.red}
  178. buttonFn={button.buttonFn}
  179. />
  180. ))}
  181. {/* <View
  182. style={{
  183. display: 'flex',
  184. flexDirection: 'row',
  185. justifyContent: 'space-between',
  186. marginTop: 20,
  187. alignItems: 'center'
  188. }}
  189. >
  190. <Text style={{ color: Colors.DARK_BLUE, fontSize: 16, fontWeight: 'bold' }}>
  191. Notifications
  192. </Text>
  193. <Switch
  194. trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
  195. thumbColor={Colors.WHITE}
  196. onValueChange={toggleSwitch}
  197. value={isSubscribed}
  198. />
  199. </View> */}
  200. <WarningModal
  201. isVisible={modalInfo.visible}
  202. onClose={closeModal}
  203. onModalHide={() => {
  204. if (shouldOpenWarningModal) {
  205. setShouldOpenWarningModal(false);
  206. handleSubscribe();
  207. }
  208. }}
  209. type={modalInfo.type}
  210. message={modalInfo.message}
  211. action={() => {
  212. modalInfo.action();
  213. closeModal();
  214. }}
  215. />
  216. </PageWrapper>
  217. );
  218. };
  219. export default Settings;