index.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import React, { useCallback, useEffect, useState } from 'react';
  2. import { View, Text, TouchableOpacity, FlatList, Platform } from 'react-native';
  3. import * as Progress from 'react-native-progress';
  4. import { useFocusEffect, useNavigation } from '@react-navigation/native';
  5. import moment from 'moment';
  6. import { EditNmModal, Header, PageWrapper } from 'src/components';
  7. import { CustomButton } from '../Components';
  8. import { NmRegionItem } from '../Components/MyRegionsItems/NmRegionItem';
  9. import { RegionItem } from '../Components/MyRegionsItems/RegionItem';
  10. import MegaregionsModal from '../Components/MegaregionsModal';
  11. import { StoreType, storage } from 'src/storage';
  12. import { NmRegion, TCCRegion } from '../utils/types';
  13. import { Colors } from 'src/theme';
  14. import { styles } from './styles';
  15. import {
  16. useGetMegaregionsQuery,
  17. useGetRegionQeQuery,
  18. usePostSetTCCRegionMutation
  19. } from '@api/myRegions';
  20. import { qualityOptions } from '../utils/constants';
  21. import ChevronIcon from 'assets/icons/travels-screens/down-arrow.svg';
  22. import { NAVIGATION_PAGES } from 'src/types';
  23. import { useRegion } from 'src/contexts/RegionContext';
  24. const RegionsScreen = () => {
  25. const token = storage.get('token', StoreType.STRING) as string;
  26. const { data: megaregions } = useGetMegaregionsQuery(String(token), true);
  27. const [megaSelectorVisible, setMegaSelectorVisible] = useState(false);
  28. const [selectedMega, setSelectedMega] = useState<{ name: string; id: number }>({
  29. id: 1,
  30. name: 'SOUTHERN EUROPE'
  31. });
  32. const { data: regionsQe } = useGetRegionQeQuery(selectedMega.id, String(token), true);
  33. const [total, setTotal] = useState(0);
  34. const [isEditModalVisible, setIsEditModalVisible] = useState(false);
  35. const [contentIndex, setContentIndex] = useState(0);
  36. const [filteredNmRegions, setFilteredNmRegions] = useState<NmRegion[] | null>(null);
  37. const [tccRegions, setTccRegions] = useState<TCCRegion[] | null>(null);
  38. const [filteredTccRegions, setFilteredTccRegions] = useState<TCCRegion[] | null>(null);
  39. const { mutate: updateTCC } = usePostSetTCCRegionMutation();
  40. const [modalState, setModalState] = useState({
  41. selectedFirstYear: 2021,
  42. selectedLastYear: 2021,
  43. selectedQuality: qualityOptions[2],
  44. selectedNoOfVisits: 1,
  45. years: [],
  46. id: null
  47. });
  48. const navigation = useNavigation();
  49. const { handleUpdateNMList: handleUpdateNM, nmRegions, setNmRegions, setUserData } = useRegion();
  50. useFocusEffect(
  51. useCallback(() => {
  52. navigation.getParent()?.setOptions({
  53. tabBarStyle: {
  54. display: 'flex',
  55. ...Platform.select({
  56. android: {
  57. height: 58
  58. }
  59. })
  60. }
  61. });
  62. }, [navigation])
  63. );
  64. useEffect(() => {
  65. const currentYear = moment().year();
  66. let yearSelector: { label: string; value: number }[] = [{ label: 'visited', value: 1 }];
  67. for (let i = currentYear; i >= 1951; i--) {
  68. yearSelector.push({ label: i.toString(), value: i });
  69. }
  70. handleModalStateChange({ years: yearSelector });
  71. }, []);
  72. const handleModalStateChange = (updates: { [key: string]: any }) => {
  73. setModalState((prevState) => ({ ...prevState, ...updates }));
  74. };
  75. const handleOpenEditModal = (item: NmRegion) => {
  76. handleModalStateChange({
  77. selectedFirstYear: item.year,
  78. selectedLastYear: item.last,
  79. selectedQuality:
  80. qualityOptions.find((quality) => quality.id === item.quality) || qualityOptions[2],
  81. selectedNoOfVisits: item.visits || 1,
  82. id: item.id
  83. });
  84. setIsEditModalVisible(true);
  85. };
  86. const handleUpdateTCC = useCallback(
  87. (region: number, visits: 0 | 1) => {
  88. const updatedTCC = tccRegions?.map((item) => {
  89. if (item.id === region) {
  90. return {
  91. ...item,
  92. visited: visits
  93. };
  94. }
  95. return item;
  96. });
  97. const updatedTCCData = {
  98. token,
  99. region,
  100. visits
  101. };
  102. updateTCC(updatedTCCData);
  103. updatedTCC && setTccRegions(updatedTCC);
  104. },
  105. [tccRegions]
  106. );
  107. useEffect(() => {
  108. if (nmRegions && nmRegions.length && token) {
  109. calcTotalCountries();
  110. }
  111. }, [nmRegions]);
  112. useEffect(() => {
  113. if (regionsQe && regionsQe.result === 'OK') {
  114. setNmRegions(regionsQe.data.out_regs);
  115. setTccRegions(regionsQe.data.out_tcc);
  116. }
  117. }, [regionsQe]);
  118. useEffect(() => {
  119. if (megaregions && megaregions.result === 'OK') {
  120. setContentIndex(0);
  121. }
  122. }, [selectedMega]);
  123. useEffect(() => {
  124. switch (contentIndex) {
  125. case 0:
  126. setFilteredNmRegions(nmRegions);
  127. setFilteredTccRegions(tccRegions);
  128. break;
  129. case 1:
  130. setFilteredNmRegions(nmRegions?.filter((item: NmRegion) => item.visits <= 0) || []);
  131. setFilteredTccRegions(tccRegions?.filter((item) => item.visited <= 0) || []);
  132. break;
  133. case 2:
  134. setFilteredNmRegions(nmRegions?.filter((item: NmRegion) => item.visits > 0) || []);
  135. setFilteredTccRegions(tccRegions?.filter((item) => item.visited > 0) || []);
  136. break;
  137. }
  138. }, [contentIndex, nmRegions, tccRegions]);
  139. useEffect(() => {
  140. if (megaregions && megaregions.result === 'OK') {
  141. setSelectedMega(megaregions.data[1]);
  142. }
  143. }, [megaregions])
  144. const calcTotalCountries = () => {
  145. const visited = nmRegions?.filter((item: NmRegion) => item.visits > 0).length || 0;
  146. setTotal(visited);
  147. };
  148. const renderItem = ({ item }: { item: NmRegion }) => (
  149. <TouchableOpacity onPress={() => {
  150. setUserData({
  151. type: 'nm',
  152. region_flag: item.flag_1,
  153. region_name: item.region_name,
  154. best_visit_quality: item.quality,
  155. first_visit_year: item.year,
  156. last_visit_year: item.last,
  157. no_of_visits: item.visits,
  158. visited: item.visits > 0,
  159. });
  160. navigation.navigate(
  161. ...([
  162. NAVIGATION_PAGES.REGION_PREVIEW,
  163. {
  164. regionId: item.id,
  165. isTravelsScreen: true,
  166. type: 'nm',
  167. disabled: token ? false : true,
  168. }
  169. ] as never)
  170. )}}>
  171. <NmRegionItem
  172. item={item}
  173. openEditModal={handleOpenEditModal}
  174. updateNM={handleUpdateNM}
  175. token={token}
  176. />
  177. </TouchableOpacity>
  178. );
  179. return (
  180. <PageWrapper>
  181. <Header
  182. label="Regions"
  183. // rightElement={
  184. // <TouchableOpacity
  185. // onPress={() => navigation.navigate(NAVIGATION_PAGES.REGIONS_INFO as never)}
  186. // style={{ width: 30 }}
  187. // >
  188. // <InfoIcon />
  189. // </TouchableOpacity>
  190. // }
  191. />
  192. <TouchableOpacity style={styles.megaSelector} onPress={() => setMegaSelectorVisible(true)}>
  193. <Text style={styles.megaButtonText}>{selectedMega?.name}</Text>
  194. <ChevronIcon width={18} height={18} />
  195. </TouchableOpacity>
  196. {token && (
  197. <View style={styles.buttonContainer}>
  198. <CustomButton
  199. title="All"
  200. onPress={() => setContentIndex(0)}
  201. isActive={contentIndex === 0}
  202. />
  203. <CustomButton
  204. title="Not visited"
  205. onPress={() => setContentIndex(1)}
  206. isActive={contentIndex === 1}
  207. />
  208. <CustomButton
  209. title="Visited"
  210. onPress={() => setContentIndex(2)}
  211. isActive={contentIndex === 2}
  212. />
  213. </View>
  214. )}
  215. <View style={styles.progressHeader}>
  216. <Text style={styles.textSmall}>Visited regions</Text>
  217. <Text style={styles.textSmall}>
  218. {nmRegions?.length
  219. ? `${total}/${nmRegions.length} • ${((total * 100) / nmRegions.length).toFixed(2)}%`
  220. : '0/0 • 100%'}
  221. </Text>
  222. </View>
  223. <Progress.Bar
  224. progress={nmRegions?.length ? total / nmRegions.length : 1}
  225. width={null}
  226. height={4}
  227. color={Colors.DARK_BLUE}
  228. borderWidth={0}
  229. borderRadius={5}
  230. unfilledColor={Colors.FILL_LIGHT}
  231. />
  232. {filteredNmRegions && (filteredNmRegions?.length || filteredTccRegions?.length) ? (
  233. <FlatList
  234. data={filteredNmRegions}
  235. renderItem={renderItem}
  236. keyExtractor={(item) => item.id.toString()}
  237. showsVerticalScrollIndicator={false}
  238. style={{ paddingVertical: 8 }}
  239. ListFooterComponent={
  240. filteredTccRegions && filteredTccRegions.length ? (
  241. <View style={{ marginVertical: 8 }}>
  242. <Text style={[styles.textMedium, { textAlign: 'center' }]}>TCC regions</Text>
  243. {filteredTccRegions?.map((item) => (
  244. <RegionItem
  245. item={item}
  246. updateRegion={handleUpdateTCC}
  247. key={item.id}
  248. token={token}
  249. />
  250. ))}
  251. </View>
  252. ) : null
  253. }
  254. />
  255. ) : null}
  256. <MegaregionsModal
  257. isVisible={megaSelectorVisible}
  258. onClose={() => setMegaSelectorVisible(false)}
  259. onSelect={(object) => {
  260. setMegaSelectorVisible(false);
  261. setSelectedMega(object);
  262. }}
  263. data={megaregions?.data ?? []}
  264. />
  265. <EditNmModal
  266. isVisible={isEditModalVisible}
  267. onClose={() => setIsEditModalVisible(false)}
  268. modalState={modalState}
  269. updateModalState={handleModalStateChange}
  270. updateNM={handleUpdateNM}
  271. />
  272. </PageWrapper>
  273. );
  274. };
  275. export default RegionsScreen;