浏览代码

members chat screen

Viktoriia 1 月之前
父节点
当前提交
dc22d6b062

+ 2 - 0
src/modules/api/chat/chat-api.ts

@@ -1,6 +1,7 @@
 import { request } from '../../../utils';
 import { API } from '../../../types';
 import { ResponseType } from '../response-type';
+import { User } from '@api/regions';
 
 export interface PostSearchUsersReturn extends ResponseType {
   data: {
@@ -59,6 +60,7 @@ export interface PostGetGroupMembersReturn extends ResponseType {
     avatar: string | null;
     admin: 0 | 1;
     added: string;
+    ranking_data: User;
   }[];
 }
 

+ 239 - 0
src/screens/InAppScreens/MessagesScreen/Components/Profile.tsx

@@ -0,0 +1,239 @@
+import React, { FC, useState } from 'react';
+import { Text, TouchableOpacity, View } from 'react-native';
+import { Image } from 'expo-image';
+import { useNavigation } from '@react-navigation/native';
+
+import { storage, StoreType } from 'src/storage';
+import { AvatarWithInitials, WarningModal } from 'src/components';
+
+import TickIcon from 'assets/icons/tick.svg';
+import UNIcon from 'assets/icons/un_icon.svg';
+import UN25Icon from 'assets/icons/un-25.svg';
+import UN50Icon from 'assets/icons/un-50.svg';
+import UN75Icon from 'assets/icons/un-75.svg';
+import UN100Icon from 'assets/icons/un-100.svg';
+import UN150Icon from 'assets/icons/un-150.svg';
+import NMIcon from 'assets/icons/nm_icon.svg';
+import DotsIcon from 'assets/icons/messages/dots-vertical.svg';
+
+import { useConnection } from 'src/contexts/ConnectionContext';
+import { NAVIGATION_PAGES } from 'src/types';
+import { API_HOST } from 'src/constants';
+import { adaptiveStyle, Colors } from 'src/theme';
+import {
+  ProfileStyles,
+  ScoreStyles
+} from 'src/screens/InAppScreens/TravellersScreen/Components/styles';
+import { getFontSize } from 'src/utils';
+import { SheetManager } from 'react-native-actions-sheet';
+
+type Props = {
+  admin: 0 | 1;
+  canChangeAdmin: boolean;
+  groupToken: string;
+  refetch: () => void;
+  refetchMembers: () => void;
+  setIsWarningVisible: (data: any) => void;
+  avatar: string | null;
+  first_name: string;
+  last_name: string;
+  date_of_birth: number;
+  homebase_flag: string;
+  homebase2_flag: string | null;
+  index: number;
+  score: any[];
+  active_score: number;
+  tbt_score?: number;
+  tbt_rank?: number;
+  badge_tbt?: number;
+  badge_1281: number;
+  badge_un: number;
+  badge_un_25: number;
+  badge_un_50: number;
+  badge_un_75: number;
+  badge_un_100: number;
+  badge_un_150: number;
+  auth: number;
+  userId: number;
+};
+
+export const Profile: FC<Props> = ({
+  admin,
+  canChangeAdmin,
+  groupToken,
+  refetch,
+  refetchMembers,
+  setIsWarningVisible,
+  avatar,
+  first_name,
+  last_name,
+  date_of_birth,
+  homebase_flag,
+  homebase2_flag,
+  index,
+  score,
+  active_score,
+  tbt_rank,
+  badge_tbt,
+  badge_1281,
+  badge_un,
+  badge_un_25,
+  badge_un_50,
+  badge_un_75,
+  badge_un_100,
+  badge_un_150,
+  auth,
+  userId
+}) => {
+  const navigation = useNavigation();
+
+  const scoreNames = ['NM', 'UN', 'UN+', 'DARE', 'TCC', 'DEEP', 'SLOW', 'YES', 'KYE', 'WHS', 'TBT'];
+  const netInfo = useConnection();
+  const token = storage.get('token', StoreType.STRING);
+  const currentUserId = storage.get('uid', StoreType.STRING) as string;
+
+  const [modalType, setModalType] = useState<string | null>(null);
+
+  const handlePress = () => {
+    if (!netInfo?.isInternetReachable) {
+      setModalType('offline');
+    } else if (!token) {
+      setModalType('unauthorized');
+    } else {
+      navigation.navigate(
+        ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId, hideTabBar: true }] as never)
+      );
+    }
+  };
+
+  return (
+    <View style={ProfileStyles.wrapper}>
+      <TouchableOpacity
+        onPress={() => handlePress()}
+        style={{ flex: 1, paddingHorizontal: 8, paddingVertical: 3 }}
+      >
+        <View style={adaptiveStyle(ProfileStyles.profileRoot, {})}>
+          {avatar ? (
+            <Image
+              style={adaptiveStyle(ProfileStyles.profileAvatar, {})}
+              source={{ uri: API_HOST + avatar }}
+            />
+          ) : homebase_flag ? (
+            <AvatarWithInitials
+              text={`${first_name[0] ?? ''}${last_name[0] ?? ''}`}
+              flag={API_HOST + homebase_flag}
+              size={48}
+            />
+          ) : null}
+          <View style={adaptiveStyle(ProfileStyles.profileDataRoot, {})}>
+            <Text
+              style={adaptiveStyle(
+                [ProfileStyles.profileFirstLastName, { fontSize: getFontSize(14), flex: 0 }],
+                {}
+              )}
+            >
+              {first_name ?? ''} {last_name ?? ''}
+            </Text>
+            <View style={adaptiveStyle(ProfileStyles.profileDataContainer, {})}>
+              <View style={adaptiveStyle(ProfileStyles.profileDataWrapper, {})}>
+                <Text style={adaptiveStyle(ProfileStyles.profileAge, {})}>
+                  Age: {date_of_birth ?? ''}
+                </Text>
+                {homebase_flag && (
+                  <Image
+                    source={{ uri: API_HOST + homebase_flag }}
+                    style={adaptiveStyle(ProfileStyles.countryFlag, {})}
+                  />
+                )}
+                {homebase2_flag && homebase2_flag !== homebase_flag ? (
+                  <Image
+                    source={{ uri: API_HOST + homebase2_flag }}
+                    style={adaptiveStyle([ProfileStyles.countryFlag, { marginLeft: -15 }], {})}
+                  />
+                ) : null}
+                <View style={adaptiveStyle(ProfileStyles.badgesWrapper, {})}>
+                  {auth ? <TickIcon /> : null}
+                  {badge_un ? <UNIcon /> : null}
+                  {badge_1281 ? <NMIcon /> : null}
+                  {badge_un_150 ? <UN150Icon /> : null}
+                  {badge_un_100 ? <UN100Icon /> : null}
+                  {badge_un_75 ? <UN75Icon /> : null}
+                  {badge_un_50 ? <UN50Icon /> : null}
+                  {badge_un_25 ? <UN25Icon /> : null}
+                </View>
+              </View>
+            </View>
+          </View>
+          {admin === 1 && (
+            <View
+              style={{
+                justifyContent: 'center',
+                alignItems: 'center',
+                width: 12,
+                height: '100%'
+              }}
+            >
+              <View
+                style={{
+                  transform: [{ rotate: '-90deg' }],
+                  justifyContent: 'center',
+                  alignItems: 'center',
+                  backgroundColor: Colors.ORANGE,
+                  height: 12,
+                  width: 38,
+                  borderRadius: 3
+                }}
+              >
+                <Text
+                  style={{
+                    color: Colors.WHITE,
+                    fontSize: getFontSize(10),
+                    fontWeight: '600',
+                    textAlign: 'center'
+                  }}
+                >
+                  Admin
+                </Text>
+              </View>
+            </View>
+          )}
+
+          <View style={{ alignItems: 'center' }}>
+            <Text style={adaptiveStyle(ScoreStyles.activeScoreRanking, {})}>
+              {score[active_score]}
+            </Text>
+            <Text style={adaptiveStyle(ScoreStyles.activeScoreName, {})}>
+              {scoreNames[active_score]}
+            </Text>
+          </View>
+
+          {userId !== +currentUserId && canChangeAdmin && (
+            <TouchableOpacity
+              style={{ padding: 6 }}
+              onPress={() =>
+                SheetManager.show('user-options-modal', {
+                  payload: {
+                    admin: admin,
+                    uid: userId,
+                    name: first_name + last_name,
+                    canChangeAdmin,
+                    token,
+                    groupToken,
+                    refetch,
+                    refetchMembers,
+                    setIsWarningVisible
+                  } as any
+                })
+              }
+            >
+              <DotsIcon />
+            </TouchableOpacity>
+          )}
+        </View>
+      </TouchableOpacity>
+      {modalType && (
+        <WarningModal type={modalType} isVisible={true} onClose={() => setModalType(null)} />
+      )}
+    </View>
+  );
+};

+ 17 - 39
src/screens/InAppScreens/MessagesScreen/Components/UserOptionsModal.tsx

@@ -101,49 +101,27 @@ const UserOptionsModal = () => {
       {userData && (
         <View style={[styles.container, { paddingBottom: 8 }]}>
           <View style={styles.optionsContainer}>
+            <TouchableOpacity style={styles.option} onPress={handleChangeAdmin}>
+              <Text style={styles.optionText}>
+                {userData.admin === 1 ? 'Dismiss as admin' : 'Make group chat admin'}
+              </Text>
+              {userData.admin === 1 ? (
+                <RemoveUserTieIcon fill={Colors.DARK_BLUE} width={20} />
+              ) : (
+                <UserTieIcon fill={Colors.DARK_BLUE} width={20} />
+              )}
+            </TouchableOpacity>
+          </View>
+
+          <View style={[styles.optionsContainer, { paddingVertical: 0, gap: 0 }]}>
             <TouchableOpacity
-              style={styles.option}
-              onPress={() => {
-                SheetManager.hide('user-options-modal');
-                if (userData?.uid) {
-                  navigation.navigate(
-                    ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: userData.uid }] as never)
-                  );
-                }
-              }}
+              style={[styles.option, styles.dangerOption]}
+              onPress={handleRemoveFromGroup}
             >
-              <Text style={styles.optionText}>Profile</Text>
-              <UserIcon fill={Colors.DARK_BLUE} width={20} />
+              <Text style={[styles.optionText, styles.dangerText]}>Remove from group chat</Text>
+              <BanIcon fill={Colors.RED} />
             </TouchableOpacity>
-            {userData?.canChangeAdmin ? (
-              <>
-                <View style={{ height: 1, backgroundColor: Colors.WHITE }}></View>
-
-                <TouchableOpacity style={styles.option} onPress={handleChangeAdmin}>
-                  <Text style={styles.optionText}>
-                    {userData.admin === 1 ? 'Dismiss as admin' : 'Make group chat admin'}
-                  </Text>
-                  {userData.admin === 1 ? (
-                    <RemoveUserTieIcon fill={Colors.DARK_BLUE} width={20} />
-                  ) : (
-                    <UserTieIcon fill={Colors.DARK_BLUE} width={20} />
-                  )}
-                </TouchableOpacity>
-              </>
-            ) : null}
           </View>
-
-          {userData?.canChangeAdmin ? (
-            <View style={[styles.optionsContainer, { paddingVertical: 0, gap: 0 }]}>
-              <TouchableOpacity
-                style={[styles.option, styles.dangerOption]}
-                onPress={handleRemoveFromGroup}
-              >
-                <Text style={[styles.optionText, styles.dangerText]}>Remove from group chat</Text>
-                <BanIcon fill={Colors.RED} />
-              </TouchableOpacity>
-            </View>
-          ) : null}
         </View>
       )}
     </ActionSheet>

+ 81 - 82
src/screens/InAppScreens/MessagesScreen/GroupSettingsScreen/index.tsx

@@ -19,14 +19,7 @@ import ImageView from 'react-native-image-viewing';
 import RenderHtml, { defaultHTMLElementModels } from 'react-native-render-html';
 
 import { storage, StoreType } from 'src/storage';
-import {
-  PageWrapper,
-  Header,
-  Loading,
-  Input,
-  AvatarWithInitials,
-  WarningModal
-} from 'src/components';
+import { PageWrapper, Header, Loading, Input, WarningModal } from 'src/components';
 import {
   usePostGetGroupMembersQuery,
   usePostGetGroupSettingsQuery,
@@ -49,8 +42,11 @@ import { SheetManager } from 'react-native-actions-sheet';
 import EditGroupModal from '../Components/EditGroupModal';
 import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
 import AddNomadsModal from '../Components/AddNomadsModal';
-import DotsIcon from 'assets/icons/messages/dots-vertical.svg';
 import UserOptionsModal from '../Components/UserOptionsModal';
+import { RankingDropdown } from '../../TravellersScreen/utils/types';
+import { FlashList } from '@shopify/flash-list';
+import { Profile } from '../Components/Profile';
+import { dataRanking } from '../../TravellersScreen/utils';
 
 type Props = {
   navigation: NavigationProp<any>;
@@ -59,7 +55,6 @@ type Props = {
 
 const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
   const token = storage.get('token', StoreType.STRING) as string;
-  const currentUserId = storage.get('uid', StoreType.STRING) as string;
   const groupToken = route.params.groupToken;
   const insets = useSafeAreaInsets();
   const tabBarHeight = useBottomTabBarHeight();
@@ -85,6 +80,8 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
   const { mutateAsync: leaveGroup } = usePostLeaveGroupMutation();
   const { mutateAsync: removeGroupFromList } = usePostRemoveGroupFromListMutation();
 
+  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
+
   useFocusEffect(
     useCallback(() => {
       navigation.getParent()?.setOptions({
@@ -285,80 +282,82 @@ const GroupSettingScreen: FC<Props> = ({ navigation, route }) => {
             </View>
 
             {canSeeMembers && members ? (
-              <View style={{ gap: 6 }}>
-                {(data.settings.member_count > 4
-                  ? members.settings.slice(0, 4)
-                  : (members.settings ?? [])
-                ).map((member, index) => (
-                  <TouchableOpacity
-                    key={index}
-                    onPress={() =>
-                      navigation.navigate(
-                        ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: member.uid }] as never)
-                      )
-                    }
-                    style={styles.userItem}
-                  >
-                    {member.avatar ? (
-                      <Image source={{ uri: API_HOST + member.avatar }} style={styles.avatar} />
-                    ) : (
-                      <AvatarWithInitials
-                        text={`${member.name?.split(' ')[0][0]}${member.name?.split(' ')[1][0] ?? ''}`}
-                        flag={API_HOST + member?.flag}
-                        size={36}
-                        fontSize={16}
-                        borderColor={Colors.LIGHT_GRAY}
-                        borderWidth={1}
-                      />
-                    )}
-                    <View style={{ flex: 1 }}>
-                      <Text style={styles.userName}>{member.name}</Text>
-                    </View>
-                    <View
-                      style={{
-                        justifyContent: 'center',
-                        alignItems: 'center'
-                      }}
-                    >
-                      {member.admin === 1 && (
-                        <Text
-                          style={{
-                            fontSize: getFontSize(10),
-                            fontWeight: '600',
-                            color: Colors.LIGHT_GRAY
-                          }}
-                        >
-                          Admin
-                        </Text>
-                      )}
-                    </View>
-                    {member.uid !== +currentUserId && (
-                      <TouchableOpacity
-                        style={{ padding: 6 }}
-                        onPress={() =>
-                          SheetManager.show('user-options-modal', {
-                            payload: {
-                              admin: member.admin,
-                              uid: member.uid,
-                              name: member.name,
-                              canChangeAdmin: data.settings.admin === 1,
-                              token,
-                              groupToken,
-                              refetch,
-                              refetchMembers,
-                              setIsWarningVisible: setModalState
-                            } as any
-                          })
-                        }
-                      >
-                        <DotsIcon />
-                      </TouchableOpacity>
-                    )}
-                  </TouchableOpacity>
-                ))}
+              <View>
+                <FlashList
+                  viewabilityConfig={{
+                    waitForInteraction: true,
+                    itemVisiblePercentThreshold: 50,
+                    minimumViewTime: 1000
+                  }}
+                  estimatedItemSize={50}
+                  data={
+                    data.settings.member_count > 4
+                      ? members.settings.slice(0, 4)
+                      : (members.settings ?? [])
+                  }
+                  renderItem={({ item, index }) => (
+                    <Profile
+                      admin={item.admin}
+                      canChangeAdmin={data.settings.admin === 1}
+                      groupToken={groupToken}
+                      refetch={refetch}
+                      refetchMembers={refetchMembers}
+                      setIsWarningVisible={setModalState}
+                      userId={item.uid}
+                      key={index}
+                      index={index}
+                      first_name={item.ranking_data?.first_name ?? item.name}
+                      last_name={item.ranking_data?.last_name ?? ''}
+                      avatar={
+                        item.ranking_data?.avatar
+                          ? '/img/avatars/' + item.ranking_data?.avatar
+                          : (item.avatar ?? null)
+                      }
+                      date_of_birth={item.ranking_data?.age}
+                      homebase_flag={'/img/flags_new/' + item.ranking_data?.flag1}
+                      homebase2_flag={
+                        item.ranking_data?.flag2
+                          ? '/img/flags_new/' + item.ranking_data?.flag2
+                          : null
+                      }
+                      score={[
+                        item.ranking_data?.score_nm ?? 1,
+                        item.ranking_data?.score_un ?? 1,
+                        item.ranking_data?.score_unp ?? 1,
+                        item.ranking_data?.score_dare,
+                        item.ranking_data?.score_tcc,
+                        item.ranking_data?.score_deep,
+                        item.ranking_data?.score_slow,
+                        item.ranking_data?.score_yes,
+                        item.ranking_data?.score_kye,
+                        item.ranking_data?.score_whs,
+                        item.ranking_data?.score_tbt
+                      ]}
+                      active_score={
+                        confirmedValueRanking
+                          ? confirmedValueRanking.value - 1
+                          : dataRanking[0].value - 1
+                      }
+                      tbt_score={item.ranking_data?.score_tbt}
+                      tbt_rank={item.ranking_data?.rank_tbt}
+                      badge_tbt={item.ranking_data?.badge_tbt}
+                      badge_1281={item.ranking_data?.badge_1281}
+                      badge_un={item.ranking_data?.badge_un}
+                      badge_un_25={item.ranking_data?.badge_un_25}
+                      badge_un_50={item.ranking_data?.badge_un_50}
+                      badge_un_75={item.ranking_data?.badge_un_75}
+                      badge_un_100={item.ranking_data?.badge_un_100}
+                      badge_un_150={item.ranking_data?.badge_un_150}
+                      auth={item.ranking_data?.auth}
+                    />
+                  )}
+                  keyExtractor={(item) => item.uid.toString()}
+                  showsVerticalScrollIndicator={false}
+                />
+
                 {data.settings.member_count > 4 ? (
                   <TouchableOpacity
-                    style={{ padding: 8, alignItems: 'center' }}
+                    style={{ padding: 8, alignItems: 'center', paddingTop: 0 }}
                     onPress={() =>
                       navigation.navigate(
                         ...([

+ 93 - 77
src/screens/InAppScreens/MessagesScreen/MembersListScreen/index.tsx

@@ -1,20 +1,20 @@
 import React, { FC, useEffect, useState } from 'react';
-import { Text, TouchableOpacity, View, Image, StyleSheet } from 'react-native';
+import { View, StyleSheet } from 'react-native';
 import { NavigationProp, useFocusEffect } from '@react-navigation/native';
 import { storage, StoreType } from 'src/storage';
-import { PageWrapper, Header, Input, AvatarWithInitials, WarningModal } from 'src/components';
+import { PageWrapper, Header, Input, WarningModal } from 'src/components';
 import { usePostGetGroupMembersQuery, usePostGetGroupSettingsQuery } from '@api/chat';
 import { Colors } from 'src/theme';
-import { API_HOST } from 'src/constants';
-import { getFontSize } from 'src/utils';
-import { SheetManager } from 'react-native-actions-sheet';
 import UserOptionsModal from '../Components/UserOptionsModal';
-import { chatStyles } from '../Components/styles';
 import { FlashList } from '@shopify/flash-list';
 
 import SearchIcon from 'assets/icons/search.svg';
-import DotsIcon from 'assets/icons/messages/dots-vertical.svg';
-import { NAVIGATION_PAGES } from 'src/types';
+import { dataRanking } from '../../TravellersScreen/utils';
+import { RankingDropdown } from '../../TravellersScreen/utils/types';
+import { FilterButton, FilterModal } from '../../TravellersScreen/Components/FilterModal';
+import { usePostGetCountriesRanking } from '@api/ranking';
+import { Profile } from '../Components/Profile';
+import { applyModalSort } from '../applySort';
 
 type Props = {
   navigation: NavigationProp<any>;
@@ -23,7 +23,6 @@ type Props = {
 
 const MembersListScreen: FC<Props> = ({ navigation, route }) => {
   const token = storage.get('token', StoreType.STRING) as string;
-  const currentUserId = storage.get('uid', StoreType.STRING) as string;
   const { groupToken, canChangeAdmin } = route.params;
 
   const [modalState, setModalState] = useState({
@@ -41,6 +40,10 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
     groupToken,
     true
   );
+  const { data: masterCountries } = usePostGetCountriesRanking();
+
+  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
+  const [isModalVisible, setModalVisible] = useState(false);
 
   useFocusEffect(() => {
     navigation.getParent()?.setOptions({
@@ -51,7 +54,7 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
   });
 
   useEffect(() => {
-    if (members && members.settings) {
+    if (members && members.settings && members.settings) {
       setFilteredData(members.settings);
     }
   }, [members]);
@@ -60,7 +63,11 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
     if (text && members) {
       const searchData =
         members?.settings?.filter((item: any) => {
-          const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
+          const itemData = item.ranking_data
+            ? item.ranking_data.first_name.toLowerCase() +
+              ' ' +
+              item.ranking_data.last_name.toLowerCase()
+            : ''.toLowerCase();
           const textData = text.toLowerCase();
           return itemData.indexOf(textData) > -1;
         }) ?? [];
@@ -72,70 +79,12 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
     }
   };
 
-  const renderItem = ({ item }: { item: any }) => (
-    <TouchableOpacity
-      onPress={() =>
-        navigation.navigate(
-          ...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: item.uid }] as never)
-        )
-      }
-      style={styles.userItem}
-    >
-      {item.avatar ? (
-        <Image source={{ uri: API_HOST + item.avatar }} style={chatStyles.avatar} />
-      ) : (
-        <AvatarWithInitials
-          text={item.name?.split(' ')[0][0] + (item.name?.split(' ')[1][0] ?? '')}
-          flag={API_HOST + item?.flag1}
-          size={36}
-          fontSize={12}
-          borderColor={Colors.LIGHT_GRAY}
-          borderWidth={1}
-        />
-      )}
-
-      <View style={chatStyles.textContainer}>
-        <Text style={chatStyles.name}>{item.name}</Text>
-      </View>
-      {item.admin === 1 && (
-        <Text
-          style={{
-            fontSize: getFontSize(10),
-            fontWeight: '600',
-            color: Colors.LIGHT_GRAY
-          }}
-        >
-          Admin
-        </Text>
-      )}
-      {item.uid !== +currentUserId && (
-        <TouchableOpacity
-          style={{ padding: 6 }}
-          onPress={() =>
-            SheetManager.show('user-options-modal', {
-              payload: {
-                admin: item.admin,
-                uid: item.uid,
-                name: item.name,
-                canChangeAdmin,
-                token,
-                groupToken,
-                refetch,
-                refetchMembers,
-                setIsWarningVisible: setModalState
-              } as any
-            })
-          }
-        >
-          <DotsIcon />
-        </TouchableOpacity>
-      )}
-    </TouchableOpacity>
-  );
-
   return (
     <PageWrapper>
-      <Header label="Nomads" />
+      <Header
+        label="Nomads"
+        rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
+      />
       <View style={styles.container}>
         <Input
           inputMode={'search'}
@@ -151,13 +100,63 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
             itemVisiblePercentThreshold: 50,
             minimumViewTime: 1000
           }}
+          estimatedItemSize={50}
           data={filteredData || []}
-          renderItem={renderItem}
+          renderItem={({ item, index }) => (
+            <Profile
+              admin={item.admin}
+              canChangeAdmin={canChangeAdmin}
+              groupToken={groupToken}
+              refetch={refetch}
+              refetchMembers={refetchMembers}
+              setIsWarningVisible={setModalState}
+              userId={item.uid}
+              key={index}
+              index={index}
+              first_name={item.ranking_data?.first_name ?? item.name}
+              last_name={item.ranking_data?.last_name ?? ''}
+              avatar={
+                item.ranking_data?.avatar
+                  ? '/img/avatars/' + item.ranking_data?.avatar
+                  : (item.avatar ?? null)
+              }
+              date_of_birth={item.ranking_data?.age}
+              homebase_flag={'/img/flags_new/' + item.ranking_data?.flag1}
+              homebase2_flag={
+                item.ranking_data?.flag2 ? '/img/flags_new/' + item.ranking_data?.flag2 : null
+              }
+              score={[
+                item.ranking_data?.score_nm ?? 1,
+                item.ranking_data?.score_un ?? 1,
+                item.ranking_data?.score_unp ?? 1,
+                item.ranking_data?.score_dare,
+                item.ranking_data?.score_tcc,
+                item.ranking_data?.score_deep,
+                item.ranking_data?.score_slow,
+                item.ranking_data?.score_yes,
+                item.ranking_data?.score_kye,
+                item.ranking_data?.score_whs,
+                item.ranking_data?.score_tbt
+              ]}
+              active_score={
+                confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
+              }
+              tbt_score={item.ranking_data?.score_tbt}
+              tbt_rank={item.ranking_data?.rank_tbt}
+              badge_tbt={item.ranking_data?.badge_tbt}
+              badge_1281={item.ranking_data?.badge_1281}
+              badge_un={item.ranking_data?.badge_un}
+              badge_un_25={item.ranking_data?.badge_un_25}
+              badge_un_50={item.ranking_data?.badge_un_50}
+              badge_un_75={item.ranking_data?.badge_un_75}
+              badge_un_100={item.ranking_data?.badge_un_100}
+              badge_un_150={item.ranking_data?.badge_un_150}
+              auth={item.ranking_data?.auth}
+            />
+          )}
           keyExtractor={(item) => item.uid.toString()}
-          estimatedItemSize={100}
-          extraData={filteredData}
+          contentContainerStyle={{ paddingBottom: 16, paddingTop: 8 }}
           showsVerticalScrollIndicator={false}
-          contentContainerStyle={{ paddingBottom: 16 }}
         />
       </View>
 
@@ -171,6 +170,23 @@ const MembersListScreen: FC<Props> = ({ navigation, route }) => {
         title={modalState.title}
       />
       <UserOptionsModal />
+      <FilterModal
+        isModalVisible={isModalVisible}
+        setModalVisible={(value) => setModalVisible(value)}
+        applyFilter={(filterAge, filterRanking, filterCountry) => {
+          setConfirmedValueRanking(filterRanking);
+          setFilteredData(
+            applyModalSort(
+              (members?.settings as any) ?? [],
+              filterAge,
+              filterRanking ?? dataRanking[0],
+              filterCountry
+            )
+          );
+          setModalVisible(false);
+        }}
+        countriesData={masterCountries ? masterCountries.data : []}
+      />
     </PageWrapper>
   );
 };

+ 161 - 0
src/screens/InAppScreens/MessagesScreen/applySort.tsx

@@ -0,0 +1,161 @@
+import { PostGetGroupMembersReturn } from '@api/chat';
+import { Ranking } from '../TravellersScreen';
+import {
+  filterAgeType,
+  filterCountryType,
+  filterRankingType
+} from '../TravellersScreen/utils/types';
+import { User } from '@api/regions';
+
+export const applyModalSort = (
+  allRanking: {
+    uid: number;
+    name: string;
+    avatar: string | null;
+    admin: 0 | 1;
+    added: string;
+    ranking_data: User;
+  }[],
+  age: filterAgeType,
+  ranking: filterRankingType,
+  country: filterCountryType
+) => {
+  let filteredLocalData = allRanking;
+  let indexCounter = 0;
+
+  if (age) {
+    filteredLocalData = filteredLocalData.filter(
+      (user) => user.ranking_data?.age >= age.min && user.ranking_data?.age <= age.max
+    );
+  }
+
+  if (country) {
+    filteredLocalData = filteredLocalData.filter(
+      (user) => user.ranking_data?.country === country.two.toLowerCase()
+    );
+  }
+
+  if (ranking) {
+    switch (ranking?.label) {
+      case 'NM':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'DARE':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_dare - a.ranking_data?.score_dare ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'UN':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'UN+':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_unp - a.ranking_data?.score_unp ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.ageany
+        );
+        break;
+      case 'TCC':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_tcc - a.ranking_data?.score_tcc ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'DEEP':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_deep - a.ranking_data?.score_deep ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'YES':
+        const YESFilteredUsers = filteredLocalData.filter(
+          (user) => user.ranking_data?.score_yes !== 10000
+        );
+        filteredLocalData = YESFilteredUsers.sort(
+          (a: any, b: any) =>
+            a.ranking_data?.score_yes - b.ranking_data?.score_yes ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'SLOW':
+        const SLOWFilteredUsers = filteredLocalData.filter(
+          (user) => user.ranking_data?.score_slow < 4500 && user.ranking_data?.score_slow > 0
+        );
+        filteredLocalData = SLOWFilteredUsers.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_slow - a.ranking_data?.score_slow ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'WHS':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_whs - a.ranking_data?.score_whs ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'KYE':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_kye - a.ranking_data?.score_kye ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      case 'TBT':
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_tbt - a.ranking_data?.score_tbt ||
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+      default:
+        filteredLocalData = filteredLocalData.sort(
+          (a: any, b: any) =>
+            b.ranking_data?.score_nm - a.ranking_data?.score_nm ||
+            b.ranking_data?.score_un - a.ranking_data?.score_un ||
+            a.ranking_data?.age - b.ranking_data?.age
+        );
+        break;
+    }
+  }
+
+  filteredLocalData = filteredLocalData.map((item) => {
+    return item.ranking_data?.dod !== 1
+      ? { ...item, displayIndex: indexCounter++ }
+      : { ...item, displayIndex: -1 };
+  });
+
+  return filteredLocalData;
+};