浏览代码

feat: unmasters fix static headr tabs

Oleksandr Honcharov 1 年之前
父节点
当前提交
1cef1d0f99

+ 10 - 2
src/database/unMastersService/index.ts

@@ -38,6 +38,10 @@ function saveSort(filtersData: any, filterType: 'yearOfCompletion' | 'countryOfO
     const key = filterType === 'yearOfCompletion' ? item.year : item.country;
     obj[key] = item.masters.map((master: Master) => master.id);
 
+    if (filterType === 'countryOfOrigin') {
+      obj['flag'] = item.flag;
+    }
+
     return obj;
   }, {});
   saveData<SortData>(filterType, filters);
@@ -85,9 +89,12 @@ export function getMastersByCountryOfOrigin() {
   const countrySortData = loadData('countryOfOrigin');
   if (!countrySortData) return null;
 
-  const countryBlocks: { country: string; count: number; masters: Master[] }[] = [];
+  console.log(countrySortData);
+
+  const countryBlocks: { country: string; count: number; masters: Master[]; flag: string }[] = [];
 
   for (const [country, masterIds] of Object.entries(countrySortData)) {
+    if (country === 'flag') continue;
     const mastersList: Master[] = [];
     masterIds.forEach((id: number) => {
       const master = getMasterById(id);
@@ -99,7 +106,8 @@ export function getMastersByCountryOfOrigin() {
     countryBlocks.push({
       country,
       count: mastersList.length,
-      masters: mastersList
+      masters: mastersList,
+      flag: countrySortData.flag
     });
   }
 

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

@@ -104,6 +104,7 @@ export interface CountryUNType extends ResponseType {
     country: string;
     code: string;
     masters: Masters[];
+    flag: string;
   }[];
 }
 

+ 130 - 31
src/screens/InAppScreens/TravellersScreen/UNMasters/index.tsx

@@ -3,7 +3,12 @@ import { FlatList, Text, TouchableOpacity, View } from 'react-native';
 import { Image } from 'expo-image';
 
 import { Header, HorizontalTabView, Loading, PageWrapper } from '../../../../components';
-import { getMastersByType, getUNMastersTypes } from '../../../../database/unMastersService';
+import {
+  getMastersByCountryOfOrigin,
+  getMastersByType,
+  getMastersByYearOfCompletion,
+  getUNMastersTypes
+} from '../../../../database/unMastersService';
 import { API_HOST } from '../../../../constants';
 
 import { UNMastersListStyles } from './styles';
@@ -11,6 +16,8 @@ import { UNMastersListStyles } from './styles';
 import ArrowUpWideIcon from '../../../../../assets/icons/arrow-up-wide-short.svg';
 
 import type { Master } from '../../../../database/unMastersService';
+import { Colors } from '../../../../theme';
+import { getFontSize } from '../../../../utils';
 
 const UNMastersScreen = () => {
   const [index, setIndex] = useState(0);
@@ -25,7 +32,11 @@ const UNMastersScreen = () => {
       title: item.name
     }));
 
-    setRoutes(parseRoutes || []);
+    setRoutes([
+      { key: '-1', title: 'Sorted by country of origin' },
+      { key: '-2', title: 'Sorted by year of completion' },
+      ...(parseRoutes || [])
+    ]);
     setLoading(false);
   }, []);
 
@@ -48,12 +59,25 @@ const UNMastersScreen = () => {
 
 const UNMastersList = React.memo(({ type }: { type: string }) => {
   const [isLoading, setIsLoading] = useState(true);
-  const [masters, setMasters] = useState<Master[] | null>([]);
+  const [masters, setMasters] = useState<
+    | Master[]
+    | { country: string; count: number; masters: Master[] }[]
+    | { year: string; count: number; masters: Master[] }[]
+    | null
+  >([]);
 
   useEffect(() => {
     const fetchType = async () => {
-      const data = getMastersByType(Number(type) || 1);
-      setMasters(data);
+      if (type === '-2') {
+        const data = getMastersByYearOfCompletion();
+        setMasters(data);
+      } else if (type === '-1') {
+        const data = getMastersByCountryOfOrigin();
+        setMasters(data);
+      } else {
+        const data = getMastersByType(Number(type) || 1);
+        setMasters(data);
+      }
     };
 
     fetchType();
@@ -62,37 +86,113 @@ const UNMastersList = React.memo(({ type }: { type: string }) => {
 
   if (isLoading) return <Loading />;
 
-  const renderItem = ({ item }: { item: Master }) => {
-    return (
-      <View style={UNMastersListStyles.wrapper}>
-        <View style={{ gap: 3, marginLeft: 5 }}>
-          <Text style={UNMastersListStyles.firstAndLastName}>{item.full_name}</Text>
-          <View style={UNMastersListStyles.wrapper}>
-            <Text style={UNMastersListStyles.descriptionText}>
-              Born: {item.born} / Age when done: {item.age} /
-            </Text>
-            <Image
-              style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
-              source={{ uri: API_HOST + '/img/flags_new/' + item.origin1_flag }}
-            />
-            {item.origin2_flag && item.origin2_flag !== item.origin1_flag ? (
+  const renderItem = ({ item }: { item: any }) => {
+    const UserItem = ({ user }: { user: Master }) => {
+      return (
+        <View style={UNMastersListStyles.wrapper}>
+          <View style={{ gap: 3, marginLeft: 5 }}>
+            <Text style={UNMastersListStyles.firstAndLastName}>{user.full_name}</Text>
+            <View style={UNMastersListStyles.wrapper}>
+              <Text style={UNMastersListStyles.descriptionText}>
+                Born: {user.born} / Age when done: {user.age} /
+              </Text>
+              <Image
+                style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
+                source={{ uri: API_HOST + '/img/flags_new/' + user.origin1_flag }}
+              />
+              {user.origin2_flag && user.origin2_flag !== user.origin1_flag ? (
+                <Image
+                  style={[UNMastersListStyles.countryFlag, { marginLeft: -5 }]}
+                  source={{ uri: API_HOST + '/img/flags_new/' + user.origin2_flag }}
+                />
+              ) : null}
+            </View>
+            <View style={UNMastersListStyles.wrapper}>
+              <Text style={UNMastersListStyles.descriptionText}>
+                Year / final country: {user.final_year}
+              </Text>
               <Image
-                style={[UNMastersListStyles.countryFlag, { marginLeft: -5 }]}
-                source={{ uri: API_HOST + '/img/flags_new/' + item.origin2_flag }}
+                style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
+                source={{ uri: API_HOST + '/img/flags_new/' + user.final_flag }}
               />
-            ) : null}
+            </View>
           </View>
-          <View style={UNMastersListStyles.wrapper}>
-            <Text style={UNMastersListStyles.descriptionText}>
-              Year / final country: {item.final_year}
+        </View>
+      );
+    };
+
+    const CountryItem = ({
+      country,
+      masters,
+      count,
+      flag
+    }: {
+      country: string;
+      masters: Master[];
+      count: number;
+      flag: string;
+    }) => {
+      if (masters.length === 0) return;
+
+      return (
+        <View style={UNMastersListStyles.countryAndYearItemWrapper}>
+          <View style={UNMastersListStyles.countryAndYearHeader}>
+            <Image source={{ uri: API_HOST + flag }} style={{ width: 24, height: 16 }} />
+            <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
+              {country} ({count})
             </Text>
-            <Image
-              style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
-              source={{ uri: API_HOST + '/img/flags_new/' + item.final_flag }}
-            />
           </View>
+          <FlatList
+            contentContainerStyle={{ gap: 10 }}
+            horizontal={false}
+            showsVerticalScrollIndicator={false}
+            data={masters}
+            renderItem={({ item }) => <UserItem user={item} />}
+          />
         </View>
-      </View>
+      );
+    };
+
+    const YearItem = ({
+      year,
+      masters,
+      count
+    }: {
+      year: string;
+      masters: Master[];
+      count: number;
+    }) => {
+      return (
+        <View style={UNMastersListStyles.countryAndYearItemWrapper}>
+          <View style={UNMastersListStyles.countryAndYearHeader}>
+            <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
+              {year} ({count})
+            </Text>
+          </View>
+          <FlatList
+            contentContainerStyle={{ gap: 10 }}
+            horizontal={false}
+            showsVerticalScrollIndicator={false}
+            data={masters}
+            renderItem={({ item }) => <UserItem user={item} />}
+          />
+        </View>
+      );
+    };
+
+    return type !== '-2' ? (
+      type !== '-1' ? (
+        <UserItem user={item as Master} />
+      ) : (
+        <CountryItem
+          country={item.country}
+          masters={item.masters}
+          count={item.count}
+          flag={item.flag}
+        />
+      )
+    ) : (
+      <YearItem year={item.year} masters={item.masters} count={item.count} />
     );
   };
 
@@ -102,7 +202,6 @@ const UNMastersList = React.memo(({ type }: { type: string }) => {
       horizontal={false}
       data={masters}
       renderItem={renderItem}
-      keyExtractor={(item) => item.id.toString()}
       showsVerticalScrollIndicator={false}
     />
   );

+ 14 - 0
src/screens/InAppScreens/TravellersScreen/UNMasters/styles.ts

@@ -8,6 +8,20 @@ export const UNMastersListStyles = StyleSheet.create({
     flexDirection: 'row',
     alignItems: 'center'
   },
+  countryAndYearItemWrapper: {
+    display: 'flex',
+    flexDirection: 'column'
+  },
+  countryAndYearHeader: {
+    width: '100%',
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center',
+    flexDirection: 'row',
+    marginTop: 8,
+    marginBottom: 8,
+    gap: 5
+  },
   firstAndLastName: {
     fontFamily: 'redhat-700',
     color: Colors.DARK_BLUE,