瀏覽代碼

feat: travellers screens refactor | ended migrations to another screens

Oleksandr Honcharov 1 年之前
父節點
當前提交
48aa4fb84c

+ 2 - 0
src/modules/api/ranking/queries/index.ts

@@ -5,3 +5,5 @@ export * from './use-post-get-in-history';
 export * from './use-post-get-in-memoriam';
 export * from './use-post-get-un-masters';
 export * from './use-post-get-countries-ranking';
+export * from './use-post-get-countries-ranking-lpi';
+export * from './use-post-get-countries-ranking-memoriam';

+ 16 - 0
src/modules/api/ranking/queries/use-post-get-countries-ranking-lpi.tsx

@@ -0,0 +1,16 @@
+import { useQuery } from '@tanstack/react-query';
+
+import { rankingQueryKeys } from '../ranking-query-keys';
+import { type PostGetCountriesRanking, rankingApi } from '../ranking-api';
+
+import type { BaseAxiosError } from '../../../../types';
+
+export const usePostGetCountriesRankingLPI = () => {
+  return useQuery<PostGetCountriesRanking, BaseAxiosError>({
+    queryKey: rankingQueryKeys.getCountriesRankingLPI(),
+    queryFn: async () => {
+      const response = await rankingApi.getCountriesRankingLPI();
+      return response.data;
+    }
+  });
+};

+ 16 - 0
src/modules/api/ranking/queries/use-post-get-countries-ranking-memoriam.tsx

@@ -0,0 +1,16 @@
+import { useQuery } from '@tanstack/react-query';
+
+import { rankingQueryKeys } from '../ranking-query-keys';
+import { type PostGetCountriesRanking, rankingApi } from '../ranking-api';
+
+import type { BaseAxiosError } from '../../../../types';
+
+export const usePostGetCountriesRankingMemoriam = () => {
+  return useQuery<PostGetCountriesRanking, BaseAxiosError>({
+    queryKey: rankingQueryKeys.getCountriesRankingMemoriam(),
+    queryFn: async () => {
+      const response = await rankingApi.getCountriesRankingMemoriam();
+      return response.data;
+    }
+  });
+};

+ 0 - 1
src/modules/api/ranking/queries/use-post-get-countries-ranking.tsx

@@ -10,7 +10,6 @@ export const usePostGetCountriesRanking = () => {
     queryKey: rankingQueryKeys.getCountriesRanking(),
     queryFn: async () => {
       const response = await rankingApi.getCountriesRanking();
-
       return response.data;
     }
   });

+ 4 - 1
src/modules/api/ranking/ranking-api.tsx

@@ -127,5 +127,8 @@ export const rankingApi = {
   getUNMastersTypes: () => request.postForm<PostGetUNTypes>(API.GET_UN_MASTERS_TYPES),
   getUNMastersType: (type: number) =>
     request.postForm<PostGetUNType>(API.GET_UN_MASTERS_TYPE, { type }),
-  getCountriesRanking: () => request.get<PostGetCountriesRanking>(API.GET_COUNTRIES_RANKING)
+  getCountriesRanking: () => request.get<PostGetCountriesRanking>(API.GET_COUNTRIES_RANKING),
+  getCountriesRankingLPI: () => request.get<PostGetCountriesRanking>(API.GET_COUNTRIES_RANKING_LPI),
+  getCountriesRankingMemoriam: () =>
+    request.get<PostGetCountriesRanking>(API.GET_COUNTRIES_RANKING_MEMORIAM)
 };

+ 3 - 1
src/modules/api/ranking/ranking-query-keys.tsx

@@ -6,5 +6,7 @@ export const rankingQueryKeys = {
   getInMemoriam: () => ['getInMemoriam'] as const,
   getUNMastersTypes: () => ['getUNMastersTypes'] as const,
   getUNMastersType: (type: number) => ['getUNMastersType', { type }] as const,
-  getCountriesRanking: () => ['getCountriesRanking'] as const
+  getCountriesRanking: () => ['getCountriesRanking'] as const,
+  getCountriesRankingLPI: () => ['getCountriesRankingLPI'] as const,
+  getCountriesRankingMemoriam: () => ['getCountriesRankingMemoriam'] as const
 };

+ 137 - 0
src/screens/InAppScreens/TravellersScreen/Components/FilterModal.tsx

@@ -0,0 +1,137 @@
+import React, { FC, useState } from 'react';
+import Modal from 'react-native-modal';
+import { Dropdown } from 'react-native-searchable-dropdown-kj';
+import { Text, TouchableOpacity, View } from 'react-native';
+
+import { getOnlineStatus } from '../../../../storage';
+
+import { ModalStyles } from './styles';
+import { Colors } from '../../../../theme';
+
+import { Button } from '../../../../components';
+import { ButtonVariants } from '../../../../types/components';
+
+import { dataAge, dataRanking } from '../utils';
+
+import CloseIcon from '../../../../../assets/icons/close.svg';
+import {
+  filterAgeType,
+  FilterButtonProps,
+  filterCountryType,
+  filterRankingType,
+  ModalProps
+} from '../utils/types';
+import FilterIcon from '../../../../../assets/icons/filter.svg';
+
+export const FilterModal: FC<ModalProps> = ({
+  isModalVisible,
+  setModalVisible,
+  countriesData,
+  applyFilter
+}) => {
+  const [filterAge, setFilterAge] = useState<filterAgeType>(null);
+  const [filterRanking, setFilterRanking] = useState<filterRankingType>(null);
+  const [filterCountry, setFilterCountry] = useState<filterCountryType>(null);
+
+  return (
+    <Modal isVisible={isModalVisible}>
+      <View style={{ height: 270, backgroundColor: 'white', borderRadius: 15 }}>
+        <View style={{ marginLeft: '5%', marginRight: '5%', marginTop: '5%' }}>
+          <View style={{ alignSelf: 'flex-end' }}>
+            <TouchableOpacity onPress={() => setModalVisible(!isModalVisible)}>
+              <CloseIcon />
+            </TouchableOpacity>
+          </View>
+          <View style={{ display: 'flex', alignItems: 'center' }}>
+            <Text style={{ color: Colors.DARK_BLUE, fontSize: 20, fontWeight: '700' }}>Filter</Text>
+            <View style={ModalStyles.ageAndRankingWrapper}>
+              <Dropdown
+                style={ModalStyles.dropdown}
+                placeholderStyle={ModalStyles.placeholderStyle}
+                selectedTextStyle={ModalStyles.selectedTextStyle}
+                data={dataAge}
+                disable={!getOnlineStatus()}
+                labelField="label"
+                valueField="value"
+                value={filterAge?.value}
+                placeholder="Select age"
+                onChange={(item) => {
+                  setFilterAge(item);
+                }}
+              />
+              <Dropdown
+                style={ModalStyles.dropdown}
+                placeholderStyle={ModalStyles.placeholderStyle}
+                selectedTextStyle={ModalStyles.selectedTextStyle}
+                data={dataRanking}
+                labelField="label"
+                valueField="value"
+                value={filterRanking?.value}
+                placeholder="Select ranking"
+                onChange={(item) => {
+                  setFilterRanking(item);
+                }}
+              />
+            </View>
+            <Dropdown
+              style={[ModalStyles.dropdown, { width: '100%', marginTop: 15 }]}
+              placeholderStyle={ModalStyles.placeholderStyle}
+              selectedTextStyle={ModalStyles.selectedTextStyle}
+              data={countriesData}
+              disable={!getOnlineStatus()}
+              labelField="name"
+              valueField="two"
+              value={filterCountry?.two}
+              placeholder="Select country"
+              onChange={(item) => {
+                setFilterCountry(item);
+              }}
+            />
+            <View style={ModalStyles.buttonsWrapper}>
+              <Button
+                variant={ButtonVariants.OPACITY}
+                containerStyles={{
+                  borderColor: Colors.DARK_BLUE,
+                  backgroundColor: 'white',
+                  width: '45%'
+                }}
+                textStyles={{
+                  color: Colors.DARK_BLUE
+                }}
+                onPress={() => {
+                  setFilterAge(null);
+                  setFilterRanking(null);
+                  setFilterCountry(null);
+                }}
+                children={'Clear'}
+              />
+              <Button
+                variant={ButtonVariants.FILL}
+                containerStyles={{
+                  borderColor: Colors.DARK_BLUE,
+                  backgroundColor: Colors.DARK_BLUE,
+                  width: '45%'
+                }}
+                textStyles={{
+                  color: Colors.WHITE
+                }}
+                onPress={() => {
+                  applyFilter(filterAge, filterRanking, filterCountry);
+                }}
+                children={'Filter'}
+              />
+            </View>
+          </View>
+        </View>
+      </View>
+    </Modal>
+  );
+};
+
+export const FilterButton: FC<FilterButtonProps> = ({ onPress }) => {
+  return (
+    <TouchableOpacity style={{ padding: 5 }} onPress={onPress}>
+      <FilterIcon />
+    </TouchableOpacity>
+  );
+};

+ 33 - 0
src/screens/InAppScreens/TravellersScreen/Components/styles.ts

@@ -171,3 +171,36 @@ export const HorizontalSelectStyles = StyleSheet.create({
     backgroundColor: Colors.ORANGE
   }
 });
+
+export const ModalStyles = StyleSheet.create({
+  dropdown: {
+    width: '47%',
+    height: 40,
+    backgroundColor: '#F4F4F4',
+    borderRadius: 4,
+    paddingHorizontal: 8
+  },
+  placeholderStyle: {
+    fontSize: 16,
+    color: Colors.DARK_BLUE
+  },
+  selectedTextStyle: {
+    fontSize: 16,
+    color: Colors.DARK_BLUE
+  },
+  ageAndRankingWrapper: {
+    width: '100%',
+    display: 'flex',
+    flexDirection: 'row',
+    alignItems: 'center',
+    justifyContent: 'space-between',
+    marginTop: 20
+  },
+  buttonsWrapper: {
+    width: '100%',
+    display: 'flex',
+    justifyContent: 'space-between',
+    flexDirection: 'row',
+    marginTop: 15
+  }
+});

+ 35 - 5
src/screens/InAppScreens/TravellersScreen/InHistoryScreen/index.tsx

@@ -6,12 +6,21 @@ import { Header, PageWrapper, Loading } from '../../../../components';
 import { storage, StoreType } from '../../../../storage';
 
 import { Profile } from '../Components/Profile';
+import { FilterButton, FilterModal } from '../Components/FilterModal';
+
+import { applyModalSort, dataRanking } from '../utils';
+import { RankingDropdown } from '../utils/types';
 
 import type { Ranking } from '..';
+
 const InHistoryScreen = () => {
   const [historyRanking, setHistoryRanking] = useState<Ranking[]>([]);
   const [isLoading, setIsLoading] = useState(true);
 
+  const [filteredData, setFilteredData] = useState<Ranking[]>([]);
+  const [isModalActive, setIsModalActive] = useState(false);
+  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
+
   useFocusEffect(
     useCallback(() => {
       const fetchRanking = async () => {
@@ -30,13 +39,29 @@ const InHistoryScreen = () => {
 
   return (
     <PageWrapper>
+      <FilterModal
+        isModalVisible={isModalActive}
+        setModalVisible={(value) => setIsModalActive(value)}
+        applyFilter={(filterAge, filterRanking, filterCountry) => {
+          setConfirmedValueRanking(filterRanking);
+          setFilteredData(applyModalSort(historyRanking, filterAge, filterRanking, filterCountry));
+          setIsModalActive(false);
+        }}
+        countriesData={[]}
+      />
+
+      <Header
+        label="In History"
+        rightElement={<FilterButton onPress={() => setIsModalActive(!isModalActive)} />}
+      />
+
       <FlatList
         showsVerticalScrollIndicator={false}
-        ListHeaderComponent={<Header label="In History" />}
-        data={historyRanking}
+        data={filteredData.length > 0 ? filteredData : historyRanking}
         keyExtractor={(item) => item.user_id.toString()}
         renderItem={({ item, index }) => (
           <Profile
+            userId={item.user_id}
             key={index}
             index={index}
             first_name={item.first_name}
@@ -45,24 +70,29 @@ const InHistoryScreen = () => {
             date_of_birth={item.age}
             homebase_flag={item.flag1}
             homebase2_flag={item.flag2}
-            tbt_score={item.score_tbt}
             score={[
               item.score_nm,
               item.score_dare,
               item.score_un,
               item.score_unp,
               item.score_tcc,
+              item.score_deep,
               item.score_yes,
               item.score_slow,
               item.score_whs,
               item.score_kye
             ]}
-            auth={item.auth}
+            active_score={
+              confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
+            }
+            tbt_score={item.score_tbt}
+            tbt_rank={item.rank_tbt}
+            badge_tbt={item.badge_tbt}
             badge_1281={item.badge_1281}
             badge_un={item.badge_un}
+            auth={item.auth}
           />
         )}
-        onEndReachedThreshold={0.1}
       />
     </PageWrapper>
   );

+ 33 - 3
src/screens/InAppScreens/TravellersScreen/InMemoriamScreen/index.tsx

@@ -1,11 +1,16 @@
 import React, { useCallback, useState } from 'react';
 import { FlatList } from 'react-native';
 import { useFocusEffect } from '@react-navigation/native';
+import { usePostGetCountriesRankingMemoriam } from '@api/ranking';
 
 import { Header, Loading, PageWrapper } from '../../../../components';
 import { storage, StoreType } from '../../../../storage';
 
 import { Profile } from '../Components/Profile';
+import { FilterButton, FilterModal } from '../Components/FilterModal';
+
+import { applyModalSort, dataRanking } from '../utils';
+import { RankingDropdown } from '../utils/types';
 
 import type { Ranking } from '..';
 
@@ -13,6 +18,12 @@ const InMemoriamScreen = () => {
   const [memoriamRanking, setMemoriamRanking] = useState<Ranking[]>([]);
   const [isLoading, setIsLoading] = useState(true);
 
+  const [filteredData, setFilteredData] = useState<Ranking[]>([]);
+  const [isModalActive, setIsModalActive] = useState(false);
+  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
+
+  const { data: inMemoriamCountries } = usePostGetCountriesRankingMemoriam();
+
   useFocusEffect(
     useCallback(() => {
       const fetchRanking = async () => {
@@ -31,13 +42,29 @@ const InMemoriamScreen = () => {
 
   return (
     <PageWrapper>
+      <FilterModal
+        isModalVisible={isModalActive}
+        setModalVisible={(value) => setIsModalActive(value)}
+        applyFilter={(filterAge, filterRanking, filterCountry) => {
+          setConfirmedValueRanking(filterRanking);
+          setFilteredData(applyModalSort(memoriamRanking, filterAge, filterRanking, filterCountry));
+          setIsModalActive(false);
+        }}
+        countriesData={inMemoriamCountries ? inMemoriamCountries.data : []}
+      />
+
+      <Header
+        label="In Memoriam"
+        rightElement={<FilterButton onPress={() => setIsModalActive(!isModalActive)} />}
+      />
+
       <FlatList
         showsVerticalScrollIndicator={false}
-        data={memoriamRanking}
-        ListHeaderComponent={<Header label="In Memoriam" />}
+        data={filteredData.length > 0 ? filteredData : memoriamRanking}
         keyExtractor={(item) => item.user_id.toString()}
         renderItem={({ item, index }) => (
           <Profile
+            userId={item.user_id}
             key={index}
             index={index}
             first_name={item.first_name}
@@ -52,11 +79,15 @@ const InMemoriamScreen = () => {
               item.score_un,
               item.score_unp,
               item.score_tcc,
+              item.score_deep,
               item.score_yes,
               item.score_slow,
               item.score_whs,
               item.score_kye
             ]}
+            active_score={
+              confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
+            }
             tbt_score={item.score_tbt}
             tbt_rank={item.rank_tbt}
             badge_tbt={item.badge_tbt}
@@ -65,7 +96,6 @@ const InMemoriamScreen = () => {
             auth={item.auth}
           />
         )}
-        onEndReachedThreshold={0.1}
       />
     </PageWrapper>
   );

+ 33 - 2
src/screens/InAppScreens/TravellersScreen/LPIRankingScreen/index.tsx

@@ -1,11 +1,16 @@
 import React, { useCallback, useState } from 'react';
 import { FlatList } from 'react-native';
 import { useFocusEffect } from '@react-navigation/native';
+import { usePostGetCountriesRankingLPI } from '@api/ranking';
 
 import { Header, Loading, PageWrapper } from '../../../../components';
 import { storage, StoreType } from '../../../../storage';
 
 import { Profile } from '../Components/Profile';
+import { FilterButton, FilterModal } from '../Components/FilterModal';
+
+import { applyModalSort, dataRanking } from '../utils';
+import { RankingDropdown } from '../utils/types';
 
 import type { Ranking } from '..';
 
@@ -13,6 +18,12 @@ const LPIRankingScreen = () => {
   const [LPIRanking, setLPIRanking] = useState<Ranking[]>([]);
   const [isLoading, setIsLoading] = useState(true);
 
+  const [filteredData, setFilteredData] = useState<Ranking[]>([]);
+  const [isModalActive, setIsModalActive] = useState(false);
+  const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
+
+  const { data: lpiCountries } = usePostGetCountriesRankingLPI();
+
   useFocusEffect(
     useCallback(() => {
       const fetchRanking = async () => {
@@ -29,14 +40,30 @@ const LPIRankingScreen = () => {
 
   return (
     <PageWrapper>
+      <FilterModal
+        isModalVisible={isModalActive}
+        setModalVisible={(value) => setIsModalActive(value)}
+        applyFilter={(filterAge, filterRanking, filterCountry) => {
+          setConfirmedValueRanking(filterRanking);
+          setFilteredData(applyModalSort(LPIRanking, filterAge, filterRanking, filterCountry));
+          setIsModalActive(false);
+        }}
+        countriesData={lpiCountries ? lpiCountries.data : []}
+      />
+
+      <Header
+        label="LPI Ranking"
+        rightElement={<FilterButton onPress={() => setIsModalActive(!isModalActive)} />}
+      />
+
       <FlatList
-        data={LPIRanking}
+        data={filteredData.length > 0 ? filteredData : LPIRanking}
         showsVerticalScrollIndicator={false}
-        ListHeaderComponent={<Header label="LPI Ranking" />}
         keyExtractor={(item) => item.user_id.toString()}
         onEndReachedThreshold={0.1}
         renderItem={({ item, index }) => (
           <Profile
+            userId={item.user_id}
             key={index}
             index={index}
             first_name={item.first_name}
@@ -51,11 +78,15 @@ const LPIRankingScreen = () => {
               item.score_un,
               item.score_unp,
               item.score_tcc,
+              item.score_deep,
               item.score_yes,
               item.score_slow,
               item.score_whs,
               item.score_kye
             ]}
+            active_score={
+              confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
+            }
             tbt_score={item.score_tbt}
             tbt_rank={item.rank_tbt}
             badge_tbt={item.badge_tbt}

+ 22 - 214
src/screens/InAppScreens/TravellersScreen/MasterRankingScreen/index.tsx

@@ -1,50 +1,31 @@
 import React, { useCallback, useState } from 'react';
 import { useFocusEffect } from '@react-navigation/native';
-import { FlatList, Text, TouchableOpacity, View } from 'react-native';
-import { Dropdown } from 'react-native-searchable-dropdown-kj';
-import Modal from 'react-native-modal';
+import { FlatList } from 'react-native';
 
 import { fetchFullRanking, usePostGetCountriesRanking } from '@api/ranking';
 
-import { styles } from './styles';
-import { Colors } from '../../../../theme';
-
-import { dataAge, dataRanking } from './values';
-
-import { Button, Header, Loading, PageWrapper } from '../../../../components';
+import { Header, Loading, PageWrapper } from '../../../../components';
 import { getOnlineStatus, storage, StoreType } from '../../../../storage';
 
 import { Profile } from '../Components/Profile';
+import { FilterModal, FilterButton } from '../Components/FilterModal';
 
-import { ButtonVariants } from '../../../../types/components';
-
-import FilterIcon from '../../../../../assets/icons/filter.svg';
-import CloseIcon from '../../../../../assets/icons/close.svg';
+import { applyModalSort, dataRanking } from '../utils';
+import type { RankingDropdown } from '../utils/types';
 
 import type { Ranking } from '..';
 
-type RankingDropdown = { value: number; label: string };
-
 const MasterRankingScreen = () => {
-  const [masterRanking, setMasterRanking] = useState<Ranking[]>([]);
-  const [filteredData, setFilteredData] = useState<Ranking[]>([]);
   const { mutateAsync } = fetchFullRanking();
-  const [isLoading, setIsLoading] = useState(true);
-  const [isModalVisible, setModalVisible] = useState(false);
+  const { data: masterCountries } = usePostGetCountriesRanking();
 
-  const [valueAge, setValueAge] = useState<{
-    value: string;
-    label: string;
-    min: number;
-    max: number;
-  } | null>();
-  const [valueCountry, setValueCountry] = useState<{ two: string; name: string } | null>();
+  const [masterRanking, setMasterRanking] = useState<Ranking[]>([]);
+  const [isLoading, setIsLoading] = useState(true);
 
-  const [valueRanking, setValueRanking] = useState<RankingDropdown | null>();
+  const [filteredData, setFilteredData] = useState<Ranking[]>([]);
+  const [isModalVisible, setModalVisible] = useState(false);
   const [confirmedValueRanking, setConfirmedValueRanking] = useState<RankingDropdown | null>();
 
-  const { data: masterCountries } = usePostGetCountriesRanking();
-
   useFocusEffect(
     useCallback(() => {
       const fetchRanking = async () => {
@@ -71,195 +52,22 @@ const MasterRankingScreen = () => {
     }
   };
 
-  const applySort = () => {
-    setConfirmedValueRanking(valueRanking);
-
-    let filteredLocalData = masterRanking;
-
-    if (valueAge) {
-      filteredLocalData = filteredLocalData.filter(
-        (user) => user.age >= valueAge.min && user.age <= valueAge.max
-      );
-    }
-
-    if (valueCountry) {
-      filteredLocalData = filteredLocalData.filter(
-        (user) => user.country === valueCountry.two.toLowerCase()
-      );
-    }
-
-    if (valueRanking) {
-      switch (valueRanking?.label) {
-        case 'NM':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_nm - a.score_nm)
-          );
-          break;
-        case 'DARE':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_dare - a.score_dare)
-          );
-          break;
-        case 'UN':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_un - a.score_un)
-          );
-          break;
-        case 'UN+':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_unp - a.score_unp)
-          );
-          break;
-        case 'TCC':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_tcc - a.score_tcc)
-          );
-          break;
-        case 'DEEP':
-          //TODO: Crash
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_deep - a.score_deep)
-          );
-          break;
-        case 'YES':
-          const validUsers = masterRanking.filter((user) => user.score_yes !== 10000);
-          setFilteredData(validUsers.sort((a: Ranking, b: Ranking) => a.score_yes - b.score_yes));
-          break;
-        case 'SLOW':
-          const valiidUsers = masterRanking.filter(
-            (user) => user.score_slow < 4500 && user.score_slow > 0
-          );
-          setFilteredData(
-            valiidUsers.sort((a: Ranking, b: Ranking) => b.score_slow - a.score_slow)
-          );
-          break;
-        case 'WHS':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_whs - a.score_whs)
-          );
-          break;
-        case 'KYE':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_kye - a.score_kye)
-          );
-          break;
-        case 'TBT':
-          setFilteredData(
-            filteredLocalData.sort((a: Ranking, b: Ranking) => b.score_tbt - a.score_tbt)
-          );
-          break;
-        default:
-          setFilteredData(filteredLocalData);
-      }
-    }
-
-    setFilteredData(filteredLocalData);
-  };
-
   return (
     <PageWrapper>
-      <Modal isVisible={isModalVisible}>
-        <View style={{ height: 270, backgroundColor: 'white', borderRadius: 15 }}>
-          <View style={{ marginLeft: '5%', marginRight: '5%', marginTop: '5%' }}>
-            <View style={{ alignSelf: 'flex-end' }}>
-              <TouchableOpacity onPress={() => setModalVisible(!isModalVisible)}>
-                <CloseIcon />
-              </TouchableOpacity>
-            </View>
-            <View style={{ display: 'flex', alignItems: 'center' }}>
-              <Text style={{ color: Colors.DARK_BLUE, fontSize: 20, fontWeight: '700' }}>
-                Filter
-              </Text>
-              <View style={styles.ageAndRankingWrapper}>
-                <Dropdown
-                  style={styles.dropdown}
-                  placeholderStyle={styles.placeholderStyle}
-                  selectedTextStyle={styles.selectedTextStyle}
-                  data={dataAge}
-                  disable={!getOnlineStatus()}
-                  labelField="label"
-                  valueField="value"
-                  placeholder="Select age"
-                  value={valueAge?.value}
-                  onChange={(item) => {
-                    setValueAge(item);
-                  }}
-                />
-                <Dropdown
-                  style={styles.dropdown}
-                  placeholderStyle={styles.placeholderStyle}
-                  selectedTextStyle={styles.selectedTextStyle}
-                  data={dataRanking}
-                  labelField="label"
-                  valueField="value"
-                  placeholder="Select ranking"
-                  value={valueRanking?.value}
-                  onChange={(item) => {
-                    setValueRanking(item);
-                  }}
-                />
-              </View>
-              <Dropdown
-                style={[styles.dropdown, { width: '100%', marginTop: 15 }]}
-                placeholderStyle={styles.placeholderStyle}
-                selectedTextStyle={styles.selectedTextStyle}
-                data={masterCountries ? masterCountries.data : []}
-                disable={!getOnlineStatus()}
-                labelField="name"
-                valueField="two"
-                placeholder="Select country"
-                value={valueCountry?.two}
-                onChange={(item) => {
-                  setValueCountry(item);
-                }}
-              />
-              <View style={styles.buttonsWrapper}>
-                <Button
-                  variant={ButtonVariants.OPACITY}
-                  containerStyles={{
-                    borderColor: Colors.DARK_BLUE,
-                    backgroundColor: 'white',
-                    width: '45%'
-                  }}
-                  textStyles={{
-                    color: Colors.DARK_BLUE
-                  }}
-                  onPress={() => {
-                    setValueAge(null);
-                    setValueCountry(null);
-                    setValueRanking(null);
-                  }}
-                  children={'Clear'}
-                />
-                <Button
-                  variant={ButtonVariants.FILL}
-                  containerStyles={{
-                    borderColor: Colors.DARK_BLUE,
-                    backgroundColor: Colors.DARK_BLUE,
-                    width: '45%'
-                  }}
-                  textStyles={{
-                    color: Colors.WHITE
-                  }}
-                  onPress={() => {
-                    setModalVisible(!isModalVisible);
-                    applySort();
-                  }}
-                  children={'Filter'}
-                />
-              </View>
-            </View>
-          </View>
-        </View>
-      </Modal>
+      <FilterModal
+        isModalVisible={isModalVisible}
+        setModalVisible={(value) => setModalVisible(value)}
+        applyFilter={(filterAge, filterRanking, filterCountry) => {
+          setConfirmedValueRanking(filterRanking);
+          setFilteredData(applyModalSort(masterRanking, filterAge, filterRanking, filterCountry));
+          setModalVisible(false);
+        }}
+        countriesData={masterCountries ? masterCountries.data : []}
+      />
 
       <Header
         label="Master Ranking"
-        rightElement={
-          <TouchableOpacity style={{ padding: 5 }} onPress={() => setModalVisible(!isModalVisible)}>
-            <FilterIcon />
-          </TouchableOpacity>
-        }
+        rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
       />
 
       <FlatList
@@ -289,10 +97,10 @@ const MasterRankingScreen = () => {
               item.score_whs,
               item.score_kye
             ]}
-            tbt_score={item.score_tbt}
             active_score={
               confirmedValueRanking ? confirmedValueRanking.value - 1 : dataRanking[0].value - 1
             }
+            tbt_score={item.score_tbt}
             tbt_rank={item.rank_tbt}
             badge_tbt={item.badge_tbt}
             badge_1281={item.badge_1281}

+ 0 - 35
src/screens/InAppScreens/TravellersScreen/MasterRankingScreen/styles.ts

@@ -1,35 +0,0 @@
-import { StyleSheet } from 'react-native';
-import { Colors } from '../../../../theme';
-
-export const styles = StyleSheet.create({
-  dropdown: {
-    width: '47%',
-    height: 40,
-    backgroundColor: '#F4F4F4',
-    borderRadius: 4,
-    paddingHorizontal: 8
-  },
-  placeholderStyle: {
-    fontSize: 16,
-    color: Colors.DARK_BLUE
-  },
-  selectedTextStyle: {
-    fontSize: 16,
-    color: Colors.DARK_BLUE
-  },
-  ageAndRankingWrapper: {
-    width: '100%',
-    display: 'flex',
-    flexDirection: 'row',
-    alignItems: 'center',
-    justifyContent: 'space-between',
-    marginTop: 20
-  },
-  buttonsWrapper: {
-    width: '100%',
-    display: 'flex',
-    justifyContent: 'space-between',
-    flexDirection: 'row',
-    marginTop: 15
-  }
-});

+ 2 - 0
src/screens/InAppScreens/TravellersScreen/utils/index.ts

@@ -0,0 +1,2 @@
+export * from './sort';
+export * from './values';

+ 90 - 0
src/screens/InAppScreens/TravellersScreen/utils/sort.ts

@@ -0,0 +1,90 @@
+import { Ranking } from '..';
+import { filterAgeType, filterCountryType, filterRankingType } from './types';
+
+export const applyModalSort = (
+  allRanking: Ranking[],
+  age: filterAgeType,
+  ranking: filterRankingType,
+  country: filterCountryType
+) => {
+  let filteredLocalData = allRanking;
+
+  if (age) {
+    filteredLocalData = filteredLocalData.filter(
+      (user) => user.age >= age.min && user.age <= age.max
+    );
+  }
+
+  if (country) {
+    filteredLocalData = filteredLocalData.filter(
+      (user) => user.country === country.two.toLowerCase()
+    );
+  }
+
+  if (ranking) {
+    switch (ranking?.label) {
+      case 'NM':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_nm - a.score_nm
+        );
+        break;
+      case 'DARE':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_dare - a.score_dare
+        );
+        break;
+      case 'UN':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_un - a.score_un
+        );
+        break;
+      case 'UN+':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_unp - a.score_unp
+        );
+        break;
+      case 'TCC':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_tcc - a.score_tcc
+        );
+        break;
+      case 'DEEP':
+        //TODO: Crash
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_deep - a.score_deep
+        );
+        break;
+      case 'YES':
+        const YESFilteredUsers = filteredLocalData.filter((user) => user.score_yes !== 10000);
+        filteredLocalData = YESFilteredUsers.sort(
+          (a: Ranking, b: Ranking) => a.score_yes - b.score_yes
+        );
+        break;
+      case 'SLOW':
+        const SLOWFilteredUsers = allRanking.filter(
+          (user) => user.score_slow < 4500 && user.score_slow > 0
+        );
+        filteredLocalData = SLOWFilteredUsers.sort(
+          (a: Ranking, b: Ranking) => b.score_slow - a.score_slow
+        );
+        break;
+      case 'WHS':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_whs - a.score_whs
+        );
+        break;
+      case 'KYE':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_kye - a.score_kye
+        );
+        break;
+      case 'TBT':
+        filteredLocalData = filteredLocalData.sort(
+          (a: Ranking, b: Ranking) => b.score_tbt - a.score_tbt
+        );
+        break;
+    }
+  }
+
+  return filteredLocalData;
+};

+ 27 - 0
src/screens/InAppScreens/TravellersScreen/utils/types.ts

@@ -0,0 +1,27 @@
+export type filterAgeType = {
+  value: string;
+  label: string;
+  min: number;
+  max: number;
+} | null;
+
+export type filterRankingType = { value: number; label: string } | null;
+
+export type filterCountryType = { two: string; name: string } | null;
+
+export type RankingDropdown = { value: number; label: string };
+
+export type ModalProps = {
+  isModalVisible: boolean;
+  setModalVisible: (value: boolean) => void;
+  applyFilter: (
+    filterAge: filterAgeType,
+    filterRanking: filterRankingType,
+    filterCountry: filterCountryType
+  ) => void;
+  countriesData: { two: string; name: string }[];
+};
+
+export type FilterButtonProps = {
+  onPress: () => void;
+};

+ 0 - 0
src/screens/InAppScreens/TravellersScreen/MasterRankingScreen/values.ts → src/screens/InAppScreens/TravellersScreen/utils/values.ts


+ 6 - 2
src/types/api.ts

@@ -32,7 +32,9 @@ export enum API_ENDPOINT {
   GET_UPDATED_AVATARS = 'get-updates',
   GET_LIST = 'get-list',
   GET_STATISTIC = 'get-stat',
-  GET_COUNTRIES_RANKING = 'get-countries-ranking'
+  GET_COUNTRIES_RANKING = 'get-countries-ranking',
+  GET_COUNTRIES_RANKING_LPI = 'get-countries-ranking-lpi',
+  GET_COUNTRIES_RANKING_MEMORIAM = 'get-countries-ranking-in-memoriam'
 }
 
 export enum API {
@@ -56,7 +58,9 @@ export enum API {
   GET_UPDATED_AVATARS = `${API_ROUTE.AVATARS}/${API_ENDPOINT.GET_UPDATED_AVATARS}`,
   GET_LIST = `${API_ROUTE.STATISTICS}/${API_ENDPOINT.GET_LIST}`,
   GET_STATISTIC = `${API_ROUTE.STATISTICS}/${API_ENDPOINT.GET_STATISTIC}`,
-  GET_COUNTRIES_RANKING = `${API_ROUTE.RANKING}/${API_ENDPOINT.GET_COUNTRIES_RANKING}`
+  GET_COUNTRIES_RANKING = `${API_ROUTE.RANKING}/${API_ENDPOINT.GET_COUNTRIES_RANKING}`,
+  GET_COUNTRIES_RANKING_LPI = `${API_ROUTE.RANKING}/${API_ENDPOINT.GET_COUNTRIES_RANKING_LPI}`,
+  GET_COUNTRIES_RANKING_MEMORIAM = `${API_ROUTE.RANKING}/${API_ENDPOINT.GET_COUNTRIES_RANKING_MEMORIAM}`
 }
 
 export type BaseAxiosError = AxiosError;