فهرست منبع

feat: statistics

Oleksandr Honcharov 1 سال پیش
والد
کامیت
3eb87f2a5b

+ 4 - 2
src/components/HorizontalTabView/index.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { Text, View } from 'react-native';
+import { Text, TouchableOpacity, View } from 'react-native';
 import { Route, TabBar, TabView } from 'react-native-tab-view';
 
 import { styles } from './styles';
@@ -12,13 +12,15 @@ export const HorizontalTabView = ({
   setIndex,
   routes,
   renderScene,
-  withMark
+  withMark,
+  onDoubleClick
 }: {
   index: number;
   setIndex: React.Dispatch<React.SetStateAction<number>>;
   routes: Route[];
   renderScene: (props: any) => React.ReactNode;
   withMark?: boolean;
+  onDoubleClick?: () => void;
 }) => {
   const renderTabBar = (props: any) => (
     <TabBar

+ 13 - 4
src/database/statisticsService/index.ts

@@ -106,7 +106,7 @@ interface StructuredData {
   [key: string]: List;
 }
 
-interface Statistic {
+export interface Statistic {
   data: {
     url1: string;
     url2: string;
@@ -117,7 +117,16 @@ interface Statistic {
   }[];
 }
 
-interface Type1 {
+export type StatisticType = {
+  url1: string;
+  url2: string;
+  type: number;
+  name: string;
+  comment: string;
+  ranking: Type1[] | Type2[] | Type3[];
+};
+
+export interface Type1 {
   region_id: number;
   cnt: number;
   region_name: string;
@@ -125,7 +134,7 @@ interface Type1 {
   flag: string;
 }
 
-interface Type2 {
+export interface Type2 {
   cnt: number;
   mega_id: number;
   mega_name: string;
@@ -134,7 +143,7 @@ interface Type2 {
   dare_id: number;
 }
 
-interface Type3 {
+export interface Type3 {
   year: number;
   user: number;
   cnt: number;

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

@@ -38,10 +38,6 @@ 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);
@@ -89,12 +85,9 @@ export function getMastersByCountryOfOrigin() {
   const countrySortData = loadData('countryOfOrigin');
   if (!countrySortData) return null;
 
-  console.log(countrySortData);
-
-  const countryBlocks: { country: string; count: number; masters: Master[]; flag: string }[] = [];
+  const countryBlocks: { country: string; count: number; masters: Master[] }[] = [];
 
   for (const [country, masterIds] of Object.entries(countrySortData)) {
-    if (country === 'flag') continue;
     const mastersList: Master[] = [];
     masterIds.forEach((id: number) => {
       const master = getMasterById(id);
@@ -106,8 +99,7 @@ export function getMastersByCountryOfOrigin() {
     countryBlocks.push({
       country,
       count: mastersList.length,
-      masters: mastersList,
-      flag: countrySortData.flag
+      masters: mastersList
     });
   }
 

+ 155 - 2
src/screens/InAppScreens/TravellersScreen/StatisticsScreen/index.tsx

@@ -1,7 +1,20 @@
 import React, { useEffect, useState } from 'react';
-import { getList } from '../../../../database/statisticsService';
+import {
+  getList,
+  getStatistic,
+  StatisticType,
+  Type2,
+  Type1,
+  Type3
+} from '../../../../database/statisticsService';
 import { Header, HorizontalTabView, Loading, PageWrapper } from '../../../../components';
 
+import { FlatList, Text, View } from 'react-native';
+import { Colors } from '../../../../theme';
+import { getFontSize } from '../../../../utils';
+import { Image } from 'expo-image';
+import { API_HOST } from '../../../../constants';
+
 const StatisticsScreen = () => {
   const [index, setIndex] = useState(0);
   const [routes, setRoutes] = useState<{ key: string; title: string }[]>([]);
@@ -32,11 +45,151 @@ const StatisticsScreen = () => {
           setIndex={setIndex}
           withMark={true}
           routes={routes}
-          renderScene={({ route }: { route: { key: string; title: string } }) => <></>}
+          renderScene={({ route }: Data) => <StatisticsList list={route.list} />}
+          onDoubleClick={() => console.log('double click')}
         />
       </PageWrapper>
     </>
   );
 };
 
+const StatisticsList = React.memo(({ list }: { list: { name: string; url1: string }[] }) => {
+  const [isLoading, setIsLoading] = useState(true);
+  const [statistic, setStatistic] = useState<StatisticType | null>(null);
+
+  useEffect(() => {
+    const data = getStatistic(list ? list[0]?.url1 : '');
+
+    if (!data) return;
+
+    setStatistic(JSON.parse(data as unknown as string) as unknown as StatisticType);
+    setIsLoading(false);
+  }, []);
+
+  if (isLoading) return <Loading />;
+  if (!statistic) return null;
+
+  const renderItem = ({ item, index }: { index: number; item: Type1 | Type2 | Type3 }) => {
+    if ('region_id' in item) {
+      return (
+        <View
+          style={{
+            display: 'flex',
+            alignItems: 'center',
+            flexDirection: 'row',
+            flex: 1,
+            gap: 8
+          }}
+        >
+          <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
+            {index + 1}
+          </Text>
+          <Image
+            style={{ width: 36, height: 36, borderRadius: 18 }}
+            source={{ uri: API_HOST + '/img/flags_new/' + item.flag }}
+          />
+          <View
+            style={{
+              flex: 1,
+              display: 'flex',
+              flexDirection: 'row',
+              justifyContent: 'space-between',
+              alignItems: 'center'
+            }}
+          >
+            <Text style={{ width: '75%', color: Colors.DARK_BLUE, fontWeight: '700' }}>
+              {item.region_name}
+            </Text>
+            <Text style={{ color: Colors.DARK_BLUE, fontWeight: '700' }}>{item.cnt}</Text>
+          </View>
+        </View>
+      );
+    } else if ('mega_id' in item) {
+      return (
+        <View
+          style={{
+            display: 'flex',
+            alignItems: 'center',
+            flexDirection: 'row',
+            flex: 1,
+            gap: 8
+          }}
+        >
+          <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
+            {index + 1}
+          </Text>
+          <Image
+            style={{ width: 36, height: 36, borderRadius: 18 }}
+            source={{ uri: API_HOST + '/img/flags_new/' + item.dare_flag }}
+          />
+          <View
+            style={{
+              flex: 1,
+              display: 'flex',
+              flexDirection: 'row',
+              justifyContent: 'space-between',
+              alignItems: 'center'
+            }}
+          >
+            <Text style={{ width: '75%', color: Colors.DARK_BLUE, fontWeight: '700' }}>
+              {item.dare_name}
+            </Text>
+            <Text style={{ color: Colors.DARK_BLUE, fontWeight: '700' }}>{item.cnt}</Text>
+          </View>
+        </View>
+      );
+    } else if ('user' in item) {
+      return (
+        <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
+          <Text>
+            {item.first_name} {item.last_name}
+          </Text>
+        </View>
+      );
+    }
+  };
+
+  return (
+    <>
+      <View
+        style={{
+          width: '100%',
+          display: 'flex',
+          justifyContent: 'center',
+          alignItems: 'center',
+          marginTop: 10,
+          marginBottom: 10
+        }}
+      >
+        <Text
+          style={{
+            color: Colors.DARK_BLUE,
+            fontSize: getFontSize(16),
+            fontWeight: '700',
+            textAlign: 'center'
+          }}
+        >
+          {statistic?.name}
+        </Text>
+      </View>
+      <FlatList
+        contentContainerStyle={{ gap: 10 }}
+        horizontal={false}
+        data={statistic.ranking}
+        renderItem={renderItem}
+        showsVerticalScrollIndicator={false}
+      />
+    </>
+  );
+});
+
+type Data = {
+  route: {
+    key: string;
+    title: string;
+    list: { name: string; url1: string }[];
+    sublist: [] | undefined;
+  };
+};
+
 export default StatisticsScreen;

+ 3 - 13
src/screens/InAppScreens/TravellersScreen/UNMasters/index.tsx

@@ -1,5 +1,5 @@
 import React, { useEffect, useState } from 'react';
-import { FlatList, Text, TouchableOpacity, View } from 'react-native';
+import { FlatList, Text, View } from 'react-native';
 import { Image } from 'expo-image';
 
 import { Header, HorizontalTabView, Loading, PageWrapper } from '../../../../components';
@@ -13,8 +13,6 @@ import { API_HOST } from '../../../../constants';
 
 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';
@@ -124,20 +122,17 @@ const UNMastersList = React.memo(({ type }: { type: string }) => {
     const CountryItem = ({
       country,
       masters,
-      count,
-      flag
+      count
     }: {
       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>
@@ -184,12 +179,7 @@ const UNMastersList = React.memo(({ type }: { type: string }) => {
       type !== '-1' ? (
         <UserItem user={item as Master} />
       ) : (
-        <CountryItem
-          country={item.country}
-          masters={item.masters}
-          count={item.count}
-          flag={item.flag}
-        />
+        <CountryItem country={item.country} masters={item.masters} count={item.count} />
       )
     ) : (
       <YearItem year={item.year} masters={item.masters} count={item.count} />