index.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import { NavigationProp } from '@react-navigation/native';
  2. import React, { FC, useCallback, useEffect, useState } from 'react';
  3. import { ActivityIndicator } from 'react-native';
  4. import { Header, Loading, PageWrapper } from 'src/components';
  5. import { Colors } from 'src/theme';
  6. import { FlashList } from '@shopify/flash-list';
  7. import { StoreType, storage } from 'src/storage';
  8. import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
  9. import {
  10. useGetUsersFromRegionMutation,
  11. useGetUsersWhoVisitedDareMutation,
  12. useGetUsersWhoVisitetRegionMutation
  13. } from '@api/regions';
  14. import { Profile } from './Profile';
  15. import { RankingDropdown } from '../../TravellersScreen/utils/types';
  16. import { dataRanking } from '../../TravellersScreen/utils';
  17. import { Ranking } from '../../TravellersScreen';
  18. type Props = {
  19. navigation: NavigationProp<any>;
  20. route: any;
  21. };
  22. const UsersListScreen: FC<Props> = ({ navigation, route }) => {
  23. const regionId = route.params?.regionId;
  24. const type = route.params?.type;
  25. const { mutateAsync: getUsersFromRegion } = useGetUsersFromRegionMutation();
  26. const { mutateAsync: getUsersWhoVisitedRegion } = useGetUsersWhoVisitetRegionMutation();
  27. const { mutateAsync: getUsersWhoVisitedDare } = useGetUsersWhoVisitedDareMutation();
  28. const token = storage.get('token', StoreType.STRING);
  29. const [users, setUsers] = useState<Ranking[]>([]);
  30. const [loading, setLoading] = useState(true);
  31. const [selectedUsers, setSelectedUsers] = useState<Ranking[]>([]);
  32. const [filteredUsers, setFilteredUsers] = useState<Ranking[]>([]);
  33. const isFromHere = route.params?.isFromHere;
  34. const [isModalVisible, setModalVisible] = useState(false);
  35. const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
  36. const [masterCountries, setMasterCountries] = useState<any>([]);
  37. const [maxPages, setMaxPages] = useState(1);
  38. const [page, setPage] = useState(0);
  39. const [isLoadingMore, setIsLoadingMore] = useState(false);
  40. const [filter, setFilter] = useState<{
  41. age: number | undefined;
  42. ranking: string | undefined;
  43. country: string | undefined;
  44. }>({ age: undefined, ranking: undefined, country: undefined });
  45. useEffect(() => {
  46. setFilteredUsers(selectedUsers);
  47. }, [selectedUsers]);
  48. useEffect(() => {
  49. applySort();
  50. }, [filter]);
  51. useEffect(() => {
  52. const getNextPage = async () => {
  53. if (isFromHere) {
  54. await getUsersFromRegion(
  55. {
  56. id: regionId,
  57. page,
  58. sort: filter.ranking,
  59. age: filter.age
  60. },
  61. {
  62. onSuccess: (data) => {
  63. setIsLoadingMore(false);
  64. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  65. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  66. }
  67. }
  68. );
  69. } else if (type === 'nm') {
  70. await getUsersWhoVisitedRegion(
  71. {
  72. id: regionId,
  73. page,
  74. sort: filter.ranking,
  75. age: filter.age,
  76. country: filter.country
  77. },
  78. {
  79. onSuccess: (data) => {
  80. setIsLoadingMore(false);
  81. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  82. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  83. }
  84. }
  85. );
  86. } else {
  87. await getUsersWhoVisitedDare(
  88. {
  89. id: regionId,
  90. page,
  91. sort: filter.ranking,
  92. age: filter.age,
  93. country: filter.country
  94. },
  95. {
  96. onSuccess: (data) => {
  97. setIsLoadingMore(false);
  98. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  99. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  100. }
  101. }
  102. );
  103. }
  104. };
  105. if (page !== 0) {
  106. getNextPage();
  107. }
  108. }, [page]);
  109. const applySort = async () => {
  110. if (isFromHere) {
  111. await getUsersFromRegion(
  112. {
  113. id: regionId,
  114. page,
  115. sort: filter.ranking,
  116. age: filter.age
  117. },
  118. {
  119. onSuccess: (data) => {
  120. setUsers(data?.data?.users);
  121. setSelectedUsers(data?.data?.users);
  122. setMaxPages(data?.data?.max_pages);
  123. setLoading(false);
  124. }
  125. }
  126. );
  127. } else if (type === 'nm') {
  128. await getUsersWhoVisitedRegion(
  129. {
  130. id: regionId,
  131. page,
  132. sort: filter.ranking,
  133. age: filter.age,
  134. country: filter.country
  135. },
  136. {
  137. onSuccess: (data) => {
  138. setUsers(data?.data?.users);
  139. setSelectedUsers(data?.data?.users);
  140. setMaxPages(data?.data?.max_pages);
  141. setMasterCountries(convertData(data?.data?.countries) ?? []);
  142. setLoading(false);
  143. }
  144. }
  145. );
  146. } else {
  147. await getUsersWhoVisitedDare(
  148. {
  149. id: regionId,
  150. page,
  151. sort: filter.ranking,
  152. age: filter.age,
  153. country: filter.country
  154. },
  155. {
  156. onSuccess: (data) => {
  157. setUsers(data?.data?.users);
  158. setSelectedUsers(data?.data?.users);
  159. setMaxPages(data?.data?.max_pages);
  160. setMasterCountries(convertData(data?.data?.countries) ?? []);
  161. setLoading(false);
  162. }
  163. }
  164. );
  165. }
  166. };
  167. const convertData = (data: { [key: string]: { country: string; flag: string } }) => {
  168. return Object.entries(data).map(([key, value]) => ({
  169. two: key,
  170. name: value.country,
  171. flag: value.flag
  172. }));
  173. };
  174. const handleEndReached = useCallback(() => {
  175. if (users && page < maxPages && !isLoadingMore) {
  176. setIsLoadingMore(true);
  177. setPage((prevPage) => prevPage + 1);
  178. }
  179. }, [users, page]);
  180. if (loading) return <Loading />;
  181. const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
  182. isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;
  183. return (
  184. <PageWrapper>
  185. <Header
  186. label={isFromHere ? 'From here' : 'Been here'}
  187. rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
  188. />
  189. <FlashList
  190. viewabilityConfig={{
  191. waitForInteraction: true,
  192. itemVisiblePercentThreshold: 50,
  193. minimumViewTime: 1000
  194. }}
  195. estimatedItemSize={50}
  196. data={filteredUsers}
  197. renderItem={({ item, index }) => (
  198. <Profile
  199. userId={item.user_id}
  200. key={index}
  201. index={index}
  202. first_name={item.first_name}
  203. last_name={item.last_name}
  204. avatar={item.avatar}
  205. date_of_birth={item.age}
  206. homebase_flag={item.flag1}
  207. homebase2_flag={item.flag2}
  208. score={[
  209. item.score_nm,
  210. item.score_dare,
  211. item.score_un,
  212. item.score_unp,
  213. item.score_tcc,
  214. item.score_deep,
  215. item.score_yes,
  216. item.score_slow,
  217. item.score_whs,
  218. item.score_kye,
  219. item.score_tbt
  220. ]}
  221. active_score={
  222. confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
  223. }
  224. tbt_score={item.score_tbt}
  225. tbt_rank={item.rank_tbt}
  226. badge_tbt={item.badge_tbt}
  227. badge_1281={item.badge_1281}
  228. badge_un={item.badge_un}
  229. auth={item.auth}
  230. />
  231. )}
  232. keyExtractor={(item) => item.user_id.toString()}
  233. contentContainerStyle={{ paddingBottom: 16, paddingTop: 8 }}
  234. showsVerticalScrollIndicator={false}
  235. onEndReached={handleEndReached}
  236. onEndReachedThreshold={0.2}
  237. ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
  238. />
  239. <FilterModal
  240. isModalVisible={isModalVisible}
  241. setModalVisible={(value) => setModalVisible(value)}
  242. applyFilter={(filterAge, filterRanking, filterCountry) => {
  243. setConfirmedValueRanking(filterRanking);
  244. setPage(0);
  245. setFilter({
  246. age: filterAge?.value ? +filterAge?.value : undefined,
  247. ranking: filterRanking?.name,
  248. country: filterCountry?.two
  249. });
  250. setModalVisible(false);
  251. }}
  252. countriesData={masterCountries}
  253. />
  254. </PageWrapper>
  255. );
  256. };
  257. export default UsersListScreen;