index.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import React, { useCallback, useEffect, useState } from 'react';
  2. import { View, Text, TouchableOpacity, FlatList } from 'react-native';
  3. import * as Progress from 'react-native-progress';
  4. import { useFocusEffect, useNavigation } from '@react-navigation/native';
  5. import { Header, PageWrapper } from 'src/components';
  6. import { CustomButton } from '../Components';
  7. import MegaregionsModal from '../Components/MegaregionsModal';
  8. import { StoreType, storage } from 'src/storage';
  9. import { DareRegion } from '../utils/types';
  10. import { Colors } from 'src/theme';
  11. import { styles } from '../RegionsScreen/styles';
  12. import { RegionItem } from '../Components/MyRegionsItems/RegionItem';
  13. import {
  14. useGetMegaregionsDareQuery,
  15. useGetRegionDareQuery,
  16. usePostSetDareRegionMutation
  17. } from '@api/myDARE';
  18. import ChevronIcon from 'assets/icons/travels-screens/down-arrow.svg';
  19. import InfoIcon from 'assets/icons/info-solid.svg';
  20. import { NAVIGATION_PAGES } from 'src/types';
  21. const DareScreen = () => {
  22. const token = storage.get('token', StoreType.STRING) as string || '';
  23. const { data: megaregions } = useGetMegaregionsDareQuery(token, true);
  24. const [megaSelectorVisible, setMegaSelectorVisible] = useState(false);
  25. const [selectedMega, setSelectedMega] = useState<{ name: string; id: number }>({
  26. id: 1,
  27. name: 'SOUTHERN EUROPE'
  28. });
  29. const { data: dareData } = useGetRegionDareQuery(selectedMega.id, String(token), true);
  30. const [dareRegions, setDareRegions] = useState<DareRegion[] | null>(null);
  31. const [filteredDareRegions, setFilteredDareRegions] = useState<DareRegion[] | null>(null);
  32. const [total, setTotal] = useState(0);
  33. const [contentIndex, setContentIndex] = useState(0);
  34. const { mutate: updateDARE } = usePostSetDareRegionMutation();
  35. const navigation = useNavigation();
  36. useFocusEffect(
  37. useCallback(() => {
  38. if (megaregions && megaregions.result === 'OK') {
  39. setSelectedMega(megaregions.data[1]);
  40. }
  41. }, [megaregions])
  42. );
  43. useEffect(() => {
  44. if (dareRegions && dareRegions.length) {
  45. token && calcTotalCountries();
  46. }
  47. }, [dareRegions]);
  48. useEffect(() => {
  49. if (dareData && dareData.result === 'OK') {
  50. setDareRegions(dareData.data);
  51. }
  52. }, [dareData]);
  53. useEffect(() => {
  54. if (megaregions && megaregions.result === 'OK') {
  55. setContentIndex(0);
  56. }
  57. }, [selectedMega]);
  58. useEffect(() => {
  59. switch (contentIndex) {
  60. case 1:
  61. setFilteredDareRegions(dareRegions?.filter((item) => +item.visited <= 0) || []);
  62. break;
  63. case 2:
  64. setFilteredDareRegions(dareRegions?.filter((item) => +item.visited > 0) || []);
  65. break;
  66. case 3:
  67. setFilteredDareRegions(dareRegions?.filter((item) => item.new === 1) || []);
  68. break;
  69. default:
  70. setFilteredDareRegions(dareRegions);
  71. }
  72. }, [contentIndex, dareRegions]);
  73. const calcTotalCountries = () => {
  74. const visited = dareRegions?.filter((item) => +item.visited > 0).length || 0;
  75. setTotal(visited);
  76. };
  77. const handleUpdateDare = useCallback(
  78. (region: number, visits: 0 | 1) => {
  79. const updatedDARE = dareRegions?.map((item) => {
  80. if (item.id === region) {
  81. return {
  82. ...item,
  83. visited: String(visits)
  84. };
  85. }
  86. return item;
  87. });
  88. const updatedDareData = {
  89. token,
  90. region,
  91. visits
  92. };
  93. updateDARE(updatedDareData);
  94. updatedDARE && setDareRegions(updatedDARE);
  95. },
  96. [dareRegions]
  97. );
  98. const renderItem = ({ item }: { item: DareRegion }) => (
  99. <RegionItem item={item} dare={true} updateRegion={handleUpdateDare} token={token} />
  100. );
  101. return (
  102. <PageWrapper>
  103. <Header
  104. label="DARE"
  105. // rightElement={
  106. // <TouchableOpacity
  107. // onPress={() => navigation.navigate(NAVIGATION_PAGES.DARE_INFO as never)}
  108. // style={{ width: 30 }}
  109. // >
  110. // <InfoIcon />
  111. // </TouchableOpacity>
  112. // }
  113. />
  114. <TouchableOpacity style={styles.megaSelector} onPress={() => setMegaSelectorVisible(true)}>
  115. <Text style={styles.megaButtonText}>{selectedMega?.name}</Text>
  116. <ChevronIcon width={18} height={18} />
  117. </TouchableOpacity>
  118. {token && (
  119. <View style={styles.buttonContainer}>
  120. <CustomButton
  121. title="All"
  122. onPress={() => setContentIndex(0)}
  123. isActive={contentIndex === 0}
  124. />
  125. <CustomButton
  126. title="Not visited"
  127. onPress={() => setContentIndex(1)}
  128. isActive={contentIndex === 1}
  129. />
  130. <CustomButton
  131. title="Visited"
  132. onPress={() => setContentIndex(2)}
  133. isActive={contentIndex === 2}
  134. />
  135. <CustomButton
  136. title="New"
  137. onPress={() => setContentIndex(3)}
  138. isActive={contentIndex === 3}
  139. flex={0.6}
  140. />
  141. </View>
  142. )}
  143. <View style={styles.progressHeader}>
  144. <Text style={styles.textSmall}>Visited places</Text>
  145. <Text style={styles.textSmall}>
  146. {dareRegions?.length
  147. ? `${total}/${dareRegions.length} • ${((total * 100) / dareRegions.length).toFixed(2)}%`
  148. : '0/0 • 100%'}
  149. </Text>
  150. </View>
  151. <Progress.Bar
  152. progress={dareRegions?.length ? total / dareRegions.length : 1}
  153. width={null}
  154. height={4}
  155. color={Colors.DARK_BLUE}
  156. borderWidth={0}
  157. borderRadius={5}
  158. unfilledColor={Colors.FILL_LIGHT}
  159. />
  160. {filteredDareRegions && (filteredDareRegions?.length || filteredDareRegions?.length) ? (
  161. <FlatList
  162. data={filteredDareRegions}
  163. renderItem={renderItem}
  164. keyExtractor={(item) => item.id.toString()}
  165. showsVerticalScrollIndicator={false}
  166. style={{ paddingTop: 8 }}
  167. contentContainerStyle={{ paddingBottom: 16 }}
  168. />
  169. ) : null}
  170. <MegaregionsModal
  171. isVisible={megaSelectorVisible}
  172. onClose={() => setMegaSelectorVisible(false)}
  173. onSelect={(object) => {
  174. setMegaSelectorVisible(false);
  175. setSelectedMega(object);
  176. }}
  177. data={megaregions?.data ?? []}
  178. />
  179. </PageWrapper>
  180. );
  181. };
  182. export default DareScreen;