Browse Source

statistics for trips

Viktoriia 4 days ago
parent
commit
f0479cf368

+ 5 - 0
Route.tsx

@@ -115,6 +115,7 @@ import { testConnectionSpeed } from 'src/database/speedService';
 import Trips2025Screen from 'src/screens/InAppScreens/TravelsScreen/Trips2025Screen';
 import AddNewTrip2025Screen from 'src/screens/InAppScreens/TravelsScreen/AddNewTrip2025Screen';
 import AddRegionsNewScreen from 'src/screens/InAppScreens/TravelsScreen/AddRegionsNewScreen';
+import RegionsVisitedScreen from 'src/screens/InAppScreens/TravelsScreen/RegionsVisitedScreen';
 
 enableScreens();
 
@@ -373,6 +374,10 @@ const Route = () => {
               name={NAVIGATION_PAGES.ADD_REGIONS_NEW}
               component={AddRegionsNewScreen}
             />
+            <ScreenStack.Screen
+              name={NAVIGATION_PAGES.REGIONS_VISITED}
+              component={RegionsVisitedScreen}
+            />
             <ScreenStack.Screen name={NAVIGATION_PAGES.COUNTRIES} component={CountriesScreen} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.REGIONS} component={RegionsScreen} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.DARE} component={DareScreen} />

+ 127 - 0
src/screens/InAppScreens/TravelsScreen/RegionsVisitedScreen/index.tsx

@@ -0,0 +1,127 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import { FlatList, Text, View, Image, TouchableOpacity } from 'react-native';
+import { useFocusEffect, useNavigation } from '@react-navigation/native';
+
+import { Header, Loading, PageWrapper } from '../../../../components';
+
+import { getFontSize } from 'src/utils';
+import { ItemStyles } from '../../TravellersScreen/Components/styles';
+import { API_HOST } from 'src/constants';
+import { Colors } from 'src/theme';
+import { NAVIGATION_PAGES } from 'src/types';
+
+const RegionsVisitedScreen = ({ route }: { route: any }) => {
+  const title = route.params.title;
+  const data = route.params.data ?? [];
+  const isRegion = route.params.isRegion;
+  const navigation = useNavigation();
+
+  const [sorted, setSorted] = useState(data);
+  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');
+
+  useEffect(() => {
+    setSorted([...data].sort((a, b) => b.days_spent - a.days_spent));
+    setSortDirection('desc');
+  }, [data]);
+
+  const sortList = () => {
+    if (sortDirection === 'desc') {
+      setSorted((prev: any) => [...prev].sort((a, b) => a.days_spent - b.days_spent));
+      setSortDirection('asc');
+    } else {
+      setSorted((prev: any) => [...prev].sort((a, b) => b.days_spent - a.days_spent));
+      setSortDirection('desc');
+    }
+  };
+
+  return (
+    <PageWrapper style={{ flex: 1 }}>
+      <Header label={title} />
+      {sorted ? (
+        <FlatList
+          contentContainerStyle={{ gap: 12, paddingBottom: 16 }}
+          style={{ flex: 1 }}
+          horizontal={false}
+          data={sorted as any}
+          keyExtractor={(item, index) => index.toString()}
+          initialNumToRender={20}
+          renderItem={({ item, index }) => {
+            return (
+              <TouchableOpacity
+                onPress={() =>
+                  isRegion
+                    ? navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.REGION_PREVIEW,
+                          {
+                            regionId: item.id,
+                            isTravelsScreen: true,
+                            type: 'nm',
+                            disabled: false
+                          }
+                        ] as never)
+                      )
+                    : navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.COUNTRY_PREVIEW,
+                          {
+                            regionId: item.id,
+                            isTravelsScreen: true,
+                            type: 'country',
+                            disabled: false
+                          }
+                        ] as never)
+                      )
+                }
+                style={[ItemStyles.wrapper, { paddingHorizontal: 8 }]}
+              >
+                <Image style={ItemStyles.bigFlag} source={{ uri: API_HOST + item.flag }} />
+                <View style={[ItemStyles.contentWrapper, { gap: 4 }]}>
+                  <Text style={[{ flex: 1, color: Colors.DARK_BLUE, fontWeight: '600' }]}>
+                    {isRegion ? item.region : item.country}
+                  </Text>
+                  <Text
+                    style={[ItemStyles.nameAndCnt, { fontFamily: 'montserrat-700', fontSize: 15 }]}
+                  >
+                    {item.days_spent}
+                  </Text>
+                </View>
+              </TouchableOpacity>
+            );
+          }}
+          showsVerticalScrollIndicator={false}
+          ListHeaderComponent={
+            <View
+              style={{
+                flexDirection: 'row',
+                justifyContent: 'space-between',
+                alignItems: 'center'
+              }}
+            >
+              <TouchableOpacity
+                onPress={sortList}
+                style={{
+                  paddingHorizontal: 12,
+                  paddingVertical: 6,
+                  borderRadius: 6,
+                  borderColor: Colors.DARK_BLUE,
+                  borderWidth: 1
+                }}
+              >
+                <Text style={{ color: Colors.DARK_BLUE, fontWeight: '600', fontSize: 13 }}>
+                  {sortDirection === 'desc' ? 'Sort ↑' : 'Sort ↓'}
+                </Text>
+              </TouchableOpacity>
+
+              <Text style={{ color: Colors.DARK_BLUE, fontWeight: '600', fontSize: 13 }}>
+                Days spent
+              </Text>
+            </View>
+          }
+        />
+      ) : null}
+    </PageWrapper>
+  );
+};
+
+export default RegionsVisitedScreen;

+ 85 - 61
src/screens/InAppScreens/TravelsScreen/Trips2025Screen/index.tsx

@@ -16,6 +16,7 @@ import AddIcon from '../../../../../assets/icons/travels-screens/circle-plus.svg
 import TripSvg from '../../../../../assets/icons/travels-screens/trip.svg';
 import InfoIcon from 'assets/icons/info-solid.svg';
 import { Colors } from 'src/theme';
+import ChevronLeftIcon from 'assets/icons/chevron-left.svg';
 
 const TripsScreen = ({ route }: { route: any }) => {
   const token = storage.get('token', StoreType.STRING) as string;
@@ -64,6 +65,7 @@ const TripsScreen = ({ route }: { route: any }) => {
   >([]);
 
   const [isWarningModalVisible, setIsWarningModalVisible] = useState(false);
+  const [isExpanded, setIsExpanded] = useState(false);
 
   useFocusEffect(
     useCallback(() => {
@@ -151,80 +153,102 @@ const TripsScreen = ({ route }: { route: any }) => {
           ListHeaderComponent={
             <View
               style={{
-                paddingHorizontal: 16,
-                paddingVertical: 16,
-                marginVertical: 8,
+                marginTop: 12,
+                marginBottom: 8,
                 backgroundColor: Colors.FILL_LIGHT,
                 borderRadius: 8,
-                gap: 4
+                paddingHorizontal: 8
               }}
             >
-              <Text
+              <TouchableOpacity
+                onPress={() => setIsExpanded(!isExpanded)}
                 style={{
-                  fontSize: 14,
-                  fontFamily: 'montserrat-700',
-                  color: Colors.DARK_BLUE,
-                  paddingBottom: 4
+                  flexDirection: 'row',
+                  alignItems: 'center',
+                  paddingVertical: 12,
+                  paddingHorizontal: 4,
+                  justifyContent: 'space-between',
+                  flex: 1
                 }}
               >
-                Annual statistics:
-              </Text>
-
-              <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}>
-                {statistics?.general}
-              </Text>
+                <View style={{ flexDirection: 'row', alignItems: 'center', flex: 1 }}>
+                  <Text
+                    style={{
+                      fontSize: 14,
+                      fontWeight: 'bold',
+                      color: Colors.DARK_BLUE,
+                      flexShrink: 1
+                    }}
+                  >
+                    Your travel statistics for {selectedYear}
+                  </Text>
+                </View>
 
-              <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}>
-                {statistics?.countries?.description}
-              </Text>
+                <View style={{ width: 18, height: 18, alignItems: 'center' }}>
+                  <ChevronLeftIcon
+                    fill={Colors.DARK_BLUE}
+                    style={[
+                      { transform: [{ rotate: '-90deg' }] },
+                      isExpanded ? { transform: [{ rotate: '90deg' }] } : null
+                    ]}
+                  />
+                </View>
+              </TouchableOpacity>
 
-              <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}>
-                {statistics?.regions?.description}
-              </Text>
+              {isExpanded ? (
+                <View
+                  style={{
+                    paddingHorizontal: 16,
+                    paddingBottom: 16,
+                    borderRadius: 8,
+                    gap: 4
+                  }}
+                >
+                  <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}>
+                    {statistics?.general}
+                  </Text>
 
-              <Text
-                style={{
-                  fontSize: 14,
-                  fontFamily: 'montserrat-700',
-                  color: Colors.DARK_BLUE,
-                  paddingBottom: 2,
-                  paddingTop: 6
-                }}
-              >
-                Countries by time spent:
-              </Text>
-              <View style={{ paddingHorizontal: 6, gap: 4 }}>
-                {countriesByTime.map((c, index) => (
-                  <Text
-                    key={`${c.country}-${index}`}
-                    style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}
+                  <TouchableOpacity
+                    onPress={() =>
+                      navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.REGIONS_VISITED,
+                          {
+                            title: statistics?.countries?.description,
+                            isRegion: false,
+                            data: statistics?.countries?.list
+                          }
+                        ] as never)
+                      )
+                    }
+                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                   >
-                    • {c.days_spent} days spent in {c.country}
-                  </Text>
-                ))}
-              </View>
+                    <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.ORANGE }}>
+                      {statistics?.countries?.description}
+                    </Text>
+                  </TouchableOpacity>
 
-              <Text
-                style={{
-                  fontSize: 14,
-                  fontFamily: 'montserrat-700',
-                  color: Colors.DARK_BLUE,
-                  paddingBottom: 2,
-                  paddingTop: 6
-                }}
-              >
-                Regions by time spent:
-              </Text>
-              <View style={{ paddingHorizontal: 6, gap: 4 }}>
-                {regionsByTime.map((r, index) => (
-                  <Text
-                    key={`${r.region}-${index}`}
-                    style={{ fontSize: 14, fontWeight: '600', color: Colors.DARK_BLUE }}
+                  <TouchableOpacity
+                    onPress={() =>
+                      navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.REGIONS_VISITED,
+                          {
+                            title: statistics?.regions?.description,
+                            isRegion: true,
+                            data: statistics?.regions?.list
+                          }
+                        ] as never)
+                      )
+                    }
+                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                   >
-                    • {r.days_spent} days spent in {r.region}
-                  </Text>
-                ))}
-              </View>
+                    <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.ORANGE }}>
+                      {statistics?.regions?.description}
+                    </Text>
+                  </TouchableOpacity>
+                </View>
+              ) : null}
             </View>
           }
         />

+ 2 - 1
src/types/navigation.ts

@@ -91,5 +91,6 @@ export enum NAVIGATION_PAGES {
   EDIT_COUNTRY_DATA = 'inAppEditCountryData',
   IN_APP_EVENTS_TAB = 'Events',
   CREATE_SHARED_TRIP = 'inAppCreateSharedTrip',
-  EDIT_NM_DATA = 'inAppEditNmData'
+  EDIT_NM_DATA = 'inAppEditNmData',
+  REGIONS_VISITED = 'inAppRegionsVisited'
 }