index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. import { useGetFriendsMutation } from '@api/friends';
  19. import { useGetUsersFromCountryMutation, useGetUsersWhoVisitedCountryMutation } from '@api/countries';
  20. type Props = {
  21. navigation: NavigationProp<any>;
  22. route: any;
  23. };
  24. const UsersListScreen: FC<Props> = ({ navigation, route }) => {
  25. const id = route.params?.id;
  26. const type = route.params?.type;
  27. const { mutateAsync: getUsersFromRegion } = useGetUsersFromRegionMutation();
  28. const { mutateAsync: getUsersWhoVisitedRegion } = useGetUsersWhoVisitetRegionMutation();
  29. const { mutateAsync: getUsersWhoVisitedDare } = useGetUsersWhoVisitedDareMutation();
  30. const { mutateAsync: getUsersFromCountry } = useGetUsersFromCountryMutation();
  31. const { mutateAsync: getUsersWhoVisitedCountry } = useGetUsersWhoVisitedCountryMutation();
  32. const { mutateAsync: getFriends } = useGetFriendsMutation();
  33. const [users, setUsers] = useState<any[]>([]);
  34. const [loading, setLoading] = useState(true);
  35. const [selectedUsers, setSelectedUsers] = useState<any[]>([]);
  36. const [filteredUsers, setFilteredUsers] = useState<Ranking[]>([]);
  37. const isFromHere = route.params?.isFromHere;
  38. const [isModalVisible, setModalVisible] = useState(false);
  39. const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
  40. const [masterCountries, setMasterCountries] = useState<any>([]);
  41. const [maxPages, setMaxPages] = useState(1);
  42. const [page, setPage] = useState(0);
  43. const [isLoadingMore, setIsLoadingMore] = useState(false);
  44. const [filter, setFilter] = useState<{
  45. age: number | undefined;
  46. ranking: string | undefined;
  47. country: string | undefined;
  48. }>({ age: undefined, ranking: undefined, country: undefined });
  49. useEffect(() => {
  50. setFilteredUsers(selectedUsers);
  51. }, [selectedUsers]);
  52. useEffect(() => {
  53. applySort();
  54. }, [filter]);
  55. useEffect(() => {
  56. const getNextPage = async () => {
  57. if (isFromHere && type === 'nm') {
  58. await getUsersFromRegion(
  59. {
  60. id,
  61. page,
  62. sort: filter.ranking,
  63. age: filter.age
  64. },
  65. {
  66. onSuccess: (data) => {
  67. setIsLoadingMore(false);
  68. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  69. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  70. }
  71. }
  72. );
  73. } else if (type === 'nm') {
  74. await getUsersWhoVisitedRegion(
  75. {
  76. id,
  77. page,
  78. sort: filter.ranking,
  79. age: filter.age,
  80. country: filter.country
  81. },
  82. {
  83. onSuccess: (data) => {
  84. setIsLoadingMore(false);
  85. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  86. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  87. }
  88. }
  89. );
  90. } else if (type === 'friends') {
  91. await getFriends(
  92. {
  93. id,
  94. page,
  95. sort: filter.ranking,
  96. age: filter.age,
  97. country: filter.country
  98. },
  99. {
  100. onSuccess: (data) => {
  101. setIsLoadingMore(false);
  102. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  103. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  104. }
  105. }
  106. );
  107. } else if (isFromHere && type === 'country') {
  108. await getUsersFromCountry(
  109. {
  110. id,
  111. page,
  112. sort: filter.ranking,
  113. age: filter.age
  114. },
  115. {
  116. onSuccess: (data) => {
  117. setIsLoadingMore(false);
  118. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  119. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  120. }
  121. }
  122. );
  123. } else if (type === 'country') {
  124. await getUsersWhoVisitedCountry(
  125. {
  126. id,
  127. page,
  128. sort: filter.ranking,
  129. age: filter.age,
  130. country: filter.country
  131. },
  132. {
  133. onSuccess: (data) => {
  134. setIsLoadingMore(false);
  135. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  136. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  137. }
  138. }
  139. );
  140. } else {
  141. await getUsersWhoVisitedDare(
  142. {
  143. id,
  144. page,
  145. sort: filter.ranking,
  146. age: filter.age,
  147. country: filter.country
  148. },
  149. {
  150. onSuccess: (data) => {
  151. setIsLoadingMore(false);
  152. setUsers((prevState) => [...prevState, ...data?.data?.users]);
  153. setSelectedUsers((prevState) => [...prevState, ...data?.data?.users]);
  154. }
  155. }
  156. );
  157. }
  158. };
  159. if (page !== 0) {
  160. getNextPage();
  161. }
  162. }, [page]);
  163. const applySort = async () => {
  164. if (isFromHere && type === 'nm') {
  165. await getUsersFromRegion(
  166. {
  167. id,
  168. page,
  169. sort: filter.ranking,
  170. age: filter.age
  171. },
  172. {
  173. onSuccess: (data) => {
  174. setUsers(data?.data?.users);
  175. setSelectedUsers(data?.data?.users);
  176. setMaxPages(data?.data?.max_pages);
  177. setLoading(false);
  178. }
  179. }
  180. );
  181. } else if (type === 'nm') {
  182. await getUsersWhoVisitedRegion(
  183. {
  184. id,
  185. page,
  186. sort: filter.ranking,
  187. age: filter.age,
  188. country: filter.country
  189. },
  190. {
  191. onSuccess: (data) => {
  192. setUsers(data?.data?.users);
  193. setSelectedUsers(data?.data?.users);
  194. setMaxPages(data?.data?.max_pages);
  195. !masterCountries.length && setMasterCountries(convertData(data?.data?.countries) ?? []);
  196. setLoading(false);
  197. }
  198. }
  199. );
  200. } else if (isFromHere && type === 'country') {
  201. await getUsersFromCountry(
  202. {
  203. id,
  204. page,
  205. sort: filter.ranking,
  206. age: filter.age
  207. },
  208. {
  209. onSuccess: (data) => {
  210. setUsers(data?.data?.users);
  211. setSelectedUsers(data?.data?.users);
  212. setMaxPages(data?.data?.max_pages);
  213. setLoading(false);
  214. }
  215. }
  216. );
  217. } else if (type === 'country') {
  218. await getUsersWhoVisitedCountry(
  219. {
  220. id,
  221. page,
  222. sort: filter.ranking,
  223. age: filter.age,
  224. country: filter.country
  225. },
  226. {
  227. onSuccess: (data) => {
  228. setUsers(data?.data?.users);
  229. setSelectedUsers(data?.data?.users);
  230. setMaxPages(data?.data?.max_pages);
  231. !masterCountries.length && setMasterCountries(convertData(data?.data?.countries) ?? []);
  232. setLoading(false);
  233. }
  234. }
  235. );
  236. } else if (type === 'friends') {
  237. await getFriends(
  238. {
  239. id,
  240. page,
  241. sort: filter.ranking,
  242. age: filter.age,
  243. country: filter.country
  244. },
  245. {
  246. onSuccess: (data) => {
  247. setUsers(data?.data?.users);
  248. setSelectedUsers(data?.data?.users);
  249. setMaxPages(data?.data?.max_pages);
  250. !masterCountries.length && setMasterCountries(convertData(data?.data?.countries) ?? []);
  251. setLoading(false);
  252. }
  253. }
  254. );
  255. } else {
  256. await getUsersWhoVisitedDare(
  257. {
  258. id,
  259. page,
  260. sort: filter.ranking,
  261. age: filter.age,
  262. country: filter.country
  263. },
  264. {
  265. onSuccess: (data) => {
  266. setUsers(data?.data?.users);
  267. setSelectedUsers(data?.data?.users);
  268. setMaxPages(data?.data?.max_pages);
  269. !masterCountries.length && setMasterCountries(convertData(data?.data?.countries) ?? []);
  270. setLoading(false);
  271. }
  272. }
  273. );
  274. }
  275. };
  276. const convertData = (data: { [key: string]: { country: string; flag: string } }) => {
  277. let formatedCountries = [{ two: 'all', name: 'ALL', flag: '' }];
  278. formatedCountries.push(
  279. ...Object.entries(data).map(([key, value]) => ({
  280. two: key,
  281. name: value.country,
  282. flag: value.flag
  283. }))
  284. );
  285. return formatedCountries;
  286. };
  287. const handleEndReached = useCallback(() => {
  288. if (users && page < maxPages && !isLoadingMore) {
  289. setIsLoadingMore(true);
  290. setPage((prevPage) => prevPage + 1);
  291. }
  292. }, [users, page]);
  293. if (loading) return <Loading />;
  294. const ListFooter = ({ isLoading }: { isLoading: boolean }) =>
  295. isLoading ? <ActivityIndicator size="large" color={Colors.DARK_BLUE} /> : null;
  296. return (
  297. <PageWrapper>
  298. <Header
  299. label={isFromHere ? 'From here' : type === 'friends' ? 'Friends' : 'Been here'}
  300. rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
  301. />
  302. <FlashList
  303. viewabilityConfig={{
  304. waitForInteraction: true,
  305. itemVisiblePercentThreshold: 50,
  306. minimumViewTime: 1000
  307. }}
  308. estimatedItemSize={50}
  309. data={filteredUsers}
  310. renderItem={({ item, index }) => (
  311. <Profile
  312. userId={item.user_id}
  313. key={index}
  314. index={index}
  315. first_name={item.first_name}
  316. last_name={item.last_name}
  317. avatar={item.avatar}
  318. date_of_birth={item.age}
  319. homebase_flag={item.flag1}
  320. homebase2_flag={item.flag2}
  321. score={[
  322. item.score_nm,
  323. item.score_un,
  324. item.score_unp,
  325. item.score_dare,
  326. item.score_tcc,
  327. item.score_deep,
  328. item.score_slow,
  329. item.score_yes,
  330. item.score_kye,
  331. item.score_whs,
  332. item.score_tbt
  333. ]}
  334. active_score={
  335. confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
  336. }
  337. tbt_score={item.score_tbt}
  338. tbt_rank={item.rank_tbt}
  339. badge_tbt={item.badge_tbt}
  340. badge_1281={item.badge_1281}
  341. badge_un={item.badge_un}
  342. auth={item.auth}
  343. />
  344. )}
  345. keyExtractor={(item) => item.user_id.toString()}
  346. contentContainerStyle={{ paddingBottom: 16, paddingTop: 8 }}
  347. showsVerticalScrollIndicator={false}
  348. onEndReached={handleEndReached}
  349. onEndReachedThreshold={0.2}
  350. ListFooterComponent={<ListFooter isLoading={isLoadingMore} />}
  351. />
  352. <FilterModal
  353. isModalVisible={isModalVisible}
  354. setModalVisible={(value) => setModalVisible(value)}
  355. applyFilter={(filterAge, filterRanking, filterCountry) => {
  356. setConfirmedValueRanking(filterRanking);
  357. setPage(0);
  358. setFilter({
  359. age: filterAge?.value ? +filterAge?.value : undefined,
  360. ranking: filterRanking?.name,
  361. country:
  362. filterCountry?.two && filterCountry?.two !== 'all' ? filterCountry?.two : undefined
  363. });
  364. setModalVisible(false);
  365. }}
  366. countriesData={masterCountries}
  367. isCountryHidden={isFromHere}
  368. />
  369. </PageWrapper>
  370. );
  371. };
  372. export default UsersListScreen;