index.tsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import React, { FC, useEffect, useState, useRef } from 'react';
  2. import { View, StyleSheet, Dimensions } from 'react-native';
  3. import { NavigationProp, useFocusEffect } from '@react-navigation/native';
  4. import { storage, StoreType } from 'src/storage';
  5. import { PageWrapper, Header, Input, WarningModal } from 'src/components';
  6. import { usePostGetGroupMembersQuery, usePostGetGroupSettingsQuery } from '@api/chat';
  7. import { Colors } from 'src/theme';
  8. import UserOptionsModal from '../Components/UserOptionsModal';
  9. import { FlashList } from '@shopify/flash-list';
  10. import SearchIcon from 'assets/icons/search.svg';
  11. import { dataRanking } from '../../TravellersScreen/utils';
  12. import { RankingDropdown, FilterModalRef } from '../../TravellersScreen/utils/types';
  13. import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
  14. import { usePostGetCountriesRanking } from '@api/ranking';
  15. import { Profile } from '../Components/Profile';
  16. import { applyModalSort } from '../applySort';
  17. type Props = {
  18. navigation: NavigationProp<any>;
  19. route: any;
  20. };
  21. const MembersListScreen: FC<Props> = ({ navigation, route }) => {
  22. const token = storage.get('token', StoreType.STRING) as string;
  23. const { groupToken, canChangeAdmin } = route.params;
  24. const [modalState, setModalState] = useState({
  25. isWarningVisible: false,
  26. title: '',
  27. buttonTitle: '',
  28. message: '',
  29. action: () => {}
  30. });
  31. const [searchQuery, setSearchQuery] = useState('');
  32. const [filteredData, setFilteredData] = useState<any[]>([]);
  33. const { data, refetch } = usePostGetGroupSettingsQuery(token, groupToken, true);
  34. const { data: members, refetch: refetchMembers } = usePostGetGroupMembersQuery(
  35. token,
  36. groupToken,
  37. true
  38. );
  39. const { data: masterCountries } = usePostGetCountriesRanking();
  40. const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
  41. const filterRef = useRef<FilterModalRef>(null);
  42. useFocusEffect(() => {
  43. navigation.getParent()?.setOptions({
  44. tabBarStyle: {
  45. display: 'none'
  46. }
  47. });
  48. });
  49. useEffect(() => {
  50. if (members && members.settings && members.settings) {
  51. setFilteredData(members.settings);
  52. }
  53. }, [members]);
  54. const handleSearch = (text: string) => {
  55. if (text && members) {
  56. const searchData =
  57. members?.settings?.filter((item: any) => {
  58. const itemData = item.ranking_data
  59. ? item.ranking_data.first_name.toLowerCase() +
  60. ' ' +
  61. item.ranking_data.last_name.toLowerCase()
  62. : ''.toLowerCase();
  63. const textData = text.toLowerCase();
  64. return itemData.indexOf(textData) > -1;
  65. }) ?? [];
  66. setFilteredData(searchData);
  67. setSearchQuery(text);
  68. } else {
  69. setFilteredData(members?.settings ?? []);
  70. setSearchQuery(text);
  71. }
  72. };
  73. return (
  74. <PageWrapper>
  75. <Header
  76. label="Nomads"
  77. rightElement={<FilterButton onPress={() => filterRef.current?.toggle()} />}
  78. />
  79. <View style={{ zIndex: 100 }}>
  80. <View
  81. style={{
  82. position: 'absolute',
  83. top: 0,
  84. left: -Dimensions.get('window').width * 0.05,
  85. width: Dimensions.get('window').width,
  86. height: Dimensions.get('window').height,
  87. overflow: 'hidden'
  88. }}
  89. pointerEvents="box-none"
  90. >
  91. <FilterModal
  92. ref={filterRef}
  93. applyFilter={(filterAge, filterRanking, filterCountry) => {
  94. setConfirmedValueRanking(filterRanking);
  95. setFilteredData(
  96. applyModalSort(
  97. (members?.settings as any) ?? [],
  98. filterAge,
  99. filterRanking ?? dataRanking[0],
  100. filterCountry
  101. )
  102. );
  103. }}
  104. countriesData={masterCountries ? masterCountries.data : []}
  105. />
  106. </View>
  107. </View>
  108. <View style={styles.container}>
  109. <Input
  110. inputMode={'search'}
  111. placeholder={'Search nomads'}
  112. onChange={handleSearch}
  113. value={searchQuery}
  114. icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
  115. />
  116. <FlashList
  117. viewabilityConfig={{
  118. waitForInteraction: true,
  119. itemVisiblePercentThreshold: 50,
  120. minimumViewTime: 1000
  121. }}
  122. data={filteredData || []}
  123. renderItem={({ item, index }) => (
  124. <Profile
  125. admin={item.admin}
  126. canChangeAdmin={canChangeAdmin}
  127. groupToken={groupToken}
  128. refetch={refetch}
  129. refetchMembers={refetchMembers}
  130. setIsWarningVisible={setModalState}
  131. userId={item.uid}
  132. key={index}
  133. index={index}
  134. first_name={item.ranking_data?.first_name ?? item.name}
  135. last_name={item.ranking_data?.last_name ?? ''}
  136. avatar={
  137. item.ranking_data?.avatar
  138. ? '/img/avatars/' + item.ranking_data?.avatar
  139. : (item.avatar ?? null)
  140. }
  141. date_of_birth={item.ranking_data?.age}
  142. homebase_flag={'/img/flags_new/' + item.ranking_data?.flag1}
  143. homebase2_flag={
  144. item.ranking_data?.flag2 ? '/img/flags_new/' + item.ranking_data?.flag2 : null
  145. }
  146. score={[
  147. item.ranking_data?.score_nm ?? 1,
  148. item.ranking_data?.score_un ?? 1,
  149. item.ranking_data?.score_unp ?? 1,
  150. item.ranking_data?.score_dare,
  151. item.ranking_data?.score_tcc,
  152. item.ranking_data?.score_deep,
  153. item.ranking_data?.score_slow,
  154. item.ranking_data?.score_yes,
  155. item.ranking_data?.score_kye,
  156. item.ranking_data?.score_whs,
  157. item.ranking_data?.score_tbt
  158. ]}
  159. active_score={
  160. confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
  161. }
  162. tbt_score={item.ranking_data?.score_tbt}
  163. tbt_rank={item.ranking_data?.rank_tbt}
  164. badge_tbt={item.ranking_data?.badge_tbt}
  165. badge_1281={item.ranking_data?.badge_1281}
  166. badge_un={item.ranking_data?.badge_un}
  167. badge_un_25={item.ranking_data?.badge_un_25}
  168. badge_un_50={item.ranking_data?.badge_un_50}
  169. badge_un_75={item.ranking_data?.badge_un_75}
  170. badge_un_100={item.ranking_data?.badge_un_100}
  171. badge_un_150={item.ranking_data?.badge_un_150}
  172. badge_premium={item.ranking_data?.badge_premium}
  173. auth={item.ranking_data?.auth}
  174. />
  175. )}
  176. keyExtractor={(item) => item.uid.toString()}
  177. contentContainerStyle={{ paddingBottom: 16, paddingTop: 8 }}
  178. showsVerticalScrollIndicator={false}
  179. />
  180. </View>
  181. <WarningModal
  182. type={'delete'}
  183. isVisible={modalState.isWarningVisible}
  184. buttonTitle={modalState.buttonTitle}
  185. message={modalState.message}
  186. action={modalState.action}
  187. onClose={() => setModalState({ ...modalState, isWarningVisible: false })}
  188. title={modalState.title}
  189. />
  190. <UserOptionsModal />
  191. </PageWrapper>
  192. );
  193. };
  194. const styles = StyleSheet.create({
  195. container: {
  196. backgroundColor: 'white',
  197. gap: 16,
  198. flex: 1
  199. },
  200. avatar: {
  201. width: 30,
  202. height: 30,
  203. borderRadius: 15,
  204. borderWidth: 1,
  205. borderColor: Colors.LIGHT_GRAY
  206. },
  207. header: {
  208. paddingTop: 16,
  209. paddingHorizontal: 6,
  210. width: 68
  211. },
  212. userItem: {
  213. flexDirection: 'row',
  214. alignItems: 'center',
  215. paddingVertical: 8,
  216. paddingHorizontal: 12,
  217. backgroundColor: Colors.FILL_LIGHT,
  218. gap: 8,
  219. borderRadius: 8,
  220. marginBottom: 6
  221. }
  222. });
  223. export default MembersListScreen;