Ver Fonte

country + region

Viktoriia há 3 dias atrás
pai
commit
5a545f18d4

+ 9 - 0
Route.tsx

@@ -108,6 +108,7 @@ import OfflineMapsScreen from 'src/screens/OfflineMapsScreen';
 import EventsNotificationsScreen from 'src/screens/NotificationsScreen/EventsNotificationsScreen';
 import SelectOwnMapScreen from 'src/screens/OfflineMapsScreen/SelectOwnMapScreen';
 import { SelectRegionScreen } from 'src/screens/OfflineMapsScreen/SelectRegionsScreen';
+import EditCountryDataScreen from 'src/screens/InAppScreens/TravelsScreen/EditCountryDataScreen';
 
 enableScreens();
 
@@ -311,6 +312,10 @@ const Route = () => {
             <ScreenStack.Screen name={NAVIGATION_PAGES.SETTINGS} component={Settings} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.MY_FRIENDS} component={MyFriendsScreen} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.SHARE_PROFILE} component={PreviewScreen} />
+            <ScreenStack.Screen
+              name={NAVIGATION_PAGES.EDIT_COUNTRY_DATA}
+              component={EditCountryDataScreen}
+            />
           </ScreenStack.Navigator>
         )}
       </BottomTab.Screen>
@@ -334,6 +339,10 @@ const Route = () => {
             <ScreenStack.Screen name={NAVIGATION_PAGES.ADD_FIXER} component={AddNewFixerScreen} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.EVENTS} component={EventsScreen} />
             <ScreenStack.Screen name={NAVIGATION_PAGES.EVENT} component={EventScreen} />
+            <ScreenStack.Screen
+              name={NAVIGATION_PAGES.EDIT_COUNTRY_DATA}
+              component={EditCountryDataScreen}
+            />
             <ScreenStack.Screen
               name={NAVIGATION_PAGES.PARTICIPANTS_LIST}
               component={ParticipantsListScreen}

+ 1 - 1
src/components/CheckBox/index.tsx

@@ -17,7 +17,7 @@ export const CheckBox: FC<Props> = ({ value, onChange, label, color, disabled })
   return (
     <View style={styles.wrapper}>
       <Checkbox
-        style={{ backgroundColor: Colors.WHITE }}
+        style={{ backgroundColor: Colors.WHITE, borderRadius: 4 }}
         color={color || Colors.ORANGE}
         value={value}
         onValueChange={onChange}

+ 1 - 1
src/components/Header/index.tsx

@@ -10,7 +10,7 @@ import { NAVIGATION_PAGES } from 'src/types';
 import { Colors } from 'src/theme';
 
 type Props = {
-  label: string;
+  label: any;
   rightElement?: ReactNode;
   shouldClose?: boolean;
   textColor?: string;

+ 91 - 8
src/components/RegionPopup/index.tsx

@@ -1,4 +1,4 @@
-import { useEffect, useRef } from 'react';
+import { useCallback, useEffect, useRef } from 'react';
 import { Text, TouchableOpacity, View, Image, Animated, Dimensions } from 'react-native';
 import MarkIcon from 'assets/icons/mark.svg';
 import EditSvg from 'assets/icons/travels-screens/pen-to-square.svg';
@@ -10,7 +10,7 @@ import CheckRegularSvg from 'assets/icons/travels-screens/circle-check-regular.s
 import { styles } from './style';
 import React from 'react';
 import { Colors } from 'src/theme';
-import { useNavigation } from '@react-navigation/native';
+import { useFocusEffect, useNavigation } from '@react-navigation/native';
 import { NAVIGATION_PAGES } from 'src/types';
 
 interface Region {
@@ -117,6 +117,37 @@ const RegionPopup: React.FC<RegionPopupProps> = ({
           <View style={styles.regionTextContainer}>
             <Text style={styles.regionTitle}>{regionTitle}</Text>
             {regionSubtitle && <Text style={styles.regionSubtitle}>{regionSubtitle}</Text>}
+            {userData?.type === 'countries' && (
+              <View style={styles.infoContainer}>
+                <Text style={styles.infoText} numberOfLines={2}>
+                  {userData?.info_text}
+                </Text>
+                {!userData?.visited && (
+                  <TouchableOpacity
+                    onPress={() =>
+                      navigation.navigate(
+                        ...([
+                          NAVIGATION_PAGES.EDIT_COUNTRY_DATA,
+                          {
+                            countryId: region.id,
+                            countryName: regionTitle,
+                            countryFlag: userData?.flag,
+                            slow11: userData?.slow11,
+                            slow31: userData?.slow31,
+                            slow101: userData?.slow101,
+                            isSlowList: false
+                          }
+                        ] as never)
+                      )
+                    }
+                    style={styles.editRegionBtn}
+                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
+                  >
+                    <EditSvg width={14} height={14} />
+                  </TouchableOpacity>
+                )}
+              </View>
+            )}
           </View>
         </View>
 
@@ -179,9 +210,30 @@ const RegionPopup: React.FC<RegionPopupProps> = ({
             )}
           </View>
           <View style={styles.btnContainer}>
-            {userData?.visited && userData?.type !== 'dare' && !disabled ? (
+            {userData?.visited &&
+            userData?.type !== 'dare' &&
+            !disabled &&
+            userData?.visited_regions <= 1 ? (
               <TouchableOpacity
-                onPress={userData?.type === 'countries' ? openEditSlowModal : openEditModal}
+                onPress={
+                  userData?.type === 'countries'
+                    ? () =>
+                        navigation.navigate(
+                          ...([
+                            NAVIGATION_PAGES.EDIT_COUNTRY_DATA,
+                            {
+                              countryId: region.id,
+                              countryName: regionTitle,
+                              countryFlag: userData?.flag,
+                              slow11: userData?.slow11,
+                              slow31: userData?.slow31,
+                              slow101: userData?.slow101,
+                              isSlowList: false
+                            }
+                          ] as never)
+                        )
+                    : openEditModal
+                }
                 style={styles.editBtn}
               >
                 <EditSvg width={14} height={14} />
@@ -192,7 +244,30 @@ const RegionPopup: React.FC<RegionPopupProps> = ({
                 styles.btn,
                 userData?.visited && !disabled ? styles.visitedButton : styles.markVisitedButton
               ]}
-              onPress={() =>
+              onPress={() => {
+                if (
+                  userData?.visited &&
+                  !disabled &&
+                  userData?.type === 'countries' &&
+                  userData?.visited_regions > 1
+                ) {
+                  navigation.navigate(
+                    ...([
+                      NAVIGATION_PAGES.EDIT_COUNTRY_DATA,
+                      {
+                        countryId: region.id,
+                        countryName: regionTitle,
+                        countryFlag: userData?.flag,
+                        slow11: userData?.slow11,
+                        slow31: userData?.slow31,
+                        slow101: userData?.slow101,
+                        isSlowList: false
+                      }
+                    ] as never)
+                  );
+                  return;
+                }
+
                 userData?.type === 'nm'
                   ? updateNM(
                       region.id,
@@ -209,10 +284,18 @@ const RegionPopup: React.FC<RegionPopupProps> = ({
                         Boolean(userData.slow31),
                         Boolean(userData.slow101)
                       )
-                    : updateDare(region.id, userData.visited ? 0 : 1)
-              }
+                    : updateDare(region.id, userData.visited ? 0 : 1);
+              }}
             >
-              {userData?.visited && !disabled ? (
+              {userData?.visited &&
+              !disabled &&
+              userData?.type === 'countries' &&
+              userData?.visited_regions > 1 ? (
+                <View style={styles.visitedContainer}>
+                  <EditSvg width={14} height={14} />
+                  <Text style={styles.visitedButtonText}>Edit</Text>
+                </View>
+              ) : userData?.visited && !disabled ? (
                 <View style={styles.visitedContainer}>
                   <MarkIcon width={16} height={16} />
                   <Text style={styles.visitedButtonText}>Visited</Text>

+ 15 - 0
src/components/RegionPopup/style.tsx

@@ -168,5 +168,20 @@ export const styles = StyleSheet.create({
     flexDirection: 'row',
     alignItems: 'center',
     justifyContent: 'center'
+  },
+  infoContainer: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 8
+  },
+  infoText: {
+    fontWeight: '600',
+    fontSize: 12,
+    color: Colors.DARK_BLUE,
+    flexShrink: 1
+  },
+  editRegionBtn: {
+    alignItems: 'center',
+    justifyContent: 'center'
   }
 });

+ 93 - 37
src/contexts/RegionContext.tsx

@@ -1,4 +1,4 @@
-import { usePostSetSlowMutation } from '@api/countries';
+import { fetchCountryUserData, usePostSetSlowMutation } from '@api/countries';
 import { usePostSetDareRegionMutation } from '@api/myDARE';
 import { usePostSetNmRegionMutation } from '@api/myRegions';
 import React, { createContext, useContext, useState, useCallback } from 'react';
@@ -18,6 +18,7 @@ export const RegionProvider = ({ children }: { children: React.ReactNode }) => {
   const { mutate: updateNM } = usePostSetNmRegionMutation();
   const { mutate: updateDARE } = usePostSetDareRegionMutation();
   const { mutate: updateSlow } = usePostSetSlowMutation();
+  const { mutateAsync: mutateCountriesData } = fetchCountryUserData();
 
   const handleUpdateNM = useCallback(
     (region: number, first: number, last: number, visits: number, quality: number) => {
@@ -62,26 +63,59 @@ export const RegionProvider = ({ children }: { children: React.ReactNode }) => {
   );
 
   const handleUpdateSlow = useCallback(
-    (id: number, v: boolean, s11: boolean, s31: boolean, s101: boolean) => {
-      const updatedSlow = {
+    async (id: number, v?: boolean, s11?: boolean, s31?: boolean, s101?: boolean) => {
+      const updatedSlow: any = {
         type: 'countries',
-        visited: v,
-        slow11: !v ? 0 : (Number(s11) as 0 | 1),
-        slow31: !v ? 0 : (Number(s31) as 0 | 1),
-        slow101: !v ? 0 : (Number(s101) as 0 | 1)
+        visited: true
       };
 
-      const updatedSlowData = {
+      if (v !== undefined) {
+        updatedSlow.visited = v;
+      }
+      if (s11 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlow.slow11 = !visitedValue ? 0 : (Number(s11) as 0 | 1);
+      }
+      if (s31 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlow.slow31 = !visitedValue ? 0 : (Number(s31) as 0 | 1);
+      }
+      if (s101 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlow.slow101 = !visitedValue ? 0 : (Number(s101) as 0 | 1);
+      }
+
+      const updatedSlowData: any = {
         token,
-        id,
-        v,
-        s11: !v ? false : s11,
-        s31: !v ? false : s31,
-        s101: !v ? false : s101
+        id
       };
 
+      if (v !== undefined) {
+        updatedSlowData.v = v;
+      }
+      if (s11 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s11 = !visitedValue ? false : s11;
+      }
+      if (s31 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s31 = !visitedValue ? false : s31;
+      }
+      if (s101 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s101 = !visitedValue ? false : s101;
+      }
+
       updateSlow(updatedSlowData);
-      setUserData(updatedSlow);
+
+      await mutateCountriesData(
+        { id, token },
+        {
+          onSuccess: (data) => {
+            setUserData({ type: 'countries', id, ...data.data });
+          }
+        }
+      );
     },
     [userData, token]
   );
@@ -142,32 +176,54 @@ export const RegionProvider = ({ children }: { children: React.ReactNode }) => {
   );
 
   const handleUpdateSlowList = useCallback(
-    (id: number, v: boolean, s11: boolean, s31: boolean, s101: boolean) => {
-      const updatedSlow = slow?.map((item) => {
-        if (item.country_id === id) {
-          return {
-            ...item,
-            visited: Number(v) as 0 | 1,
-            slow11: !v ? 0 : (Number(s11) as 0 | 1),
-            slow31: !v ? 0 : (Number(s31) as 0 | 1),
-            slow101: !v ? 0 : (Number(s101) as 0 | 1)
-          };
-        }
-
-        return item;
-      });
-
-      const updatedSlowData = {
+    (id: number, v?: boolean, s11?: boolean, s31?: boolean, s101?: boolean) => {
+      const updatedSlowData: any = {
         token,
-        id,
-        v,
-        s11: !v ? false : s11,
-        s31: !v ? false : s31,
-        s101: !v ? false : s101
+        id
       };
 
-      updateSlow(updatedSlowData);
-      updatedSlow && setSlow(updatedSlow);
+      if (v !== undefined) {
+        updatedSlowData.v = v;
+      }
+      if (s11 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s11 = !visitedValue ? false : s11;
+      }
+      if (s31 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s31 = !visitedValue ? false : s31;
+      }
+      if (s101 !== undefined) {
+        const visitedValue = v !== undefined ? v : true;
+        updatedSlowData.s101 = !visitedValue ? false : s101;
+      }
+
+      updateSlow(updatedSlowData, {
+        onSuccess: async () => {
+          await mutateCountriesData(
+            { id, token },
+            {
+              onSuccess: (data) => {
+                const updatedSlow = slow?.map((item) => {
+                  if (item.country_id === id) {
+                    const dataItem = data.data;
+                    const updatedItem = { ...item };
+
+                    updatedItem.visited = Number(dataItem.visited) as 0 | 1;
+                    updatedItem.slow11 = Number(dataItem.slow11) as 0 | 1;
+                    updatedItem.slow31 = Number(dataItem.slow31) as 0 | 1;
+                    updatedItem.slow101 = Number(dataItem.slow101) as 0 | 1;
+
+                    return updatedItem;
+                  }
+                  return item;
+                });
+                updatedSlow && setSlow(updatedSlow);
+              }
+            }
+          );
+        }
+      });
     },
     [slow]
   );

+ 7 - 4
src/modules/api/countries/countries-api.tsx

@@ -14,6 +14,9 @@ export interface PostGetSlowReturn extends ResponseType {
     slow31: 0 | 1;
     slow101: 0 | 1;
     yes: number;
+    info_text: string;
+    visited_regions: number;
+    default_region_id: number;
   }[];
   megaregions: {
     id: number;
@@ -24,10 +27,10 @@ export interface PostGetSlowReturn extends ResponseType {
 export interface PostSetSlow {
   token: string;
   id: number;
-  v: boolean;
-  s11: boolean;
-  s31: boolean;
-  s101: boolean;
+  v: boolean | undefined;
+  s11: boolean | undefined;
+  s31: boolean | undefined;
+  s101: boolean | undefined;
 }
 
 export interface PostGetCountryDataReturn extends ResponseType {

+ 8 - 3
src/modules/api/myRegions/queries/use-post-get-regions-qe.tsx

@@ -5,11 +5,16 @@ import { regionsApi, type PostGetRegionsQeReturn } from '../regions-api';
 
 import type { BaseAxiosError } from '../../../../types';
 
-export const useGetRegionQeQuery = (megaregion: number, token: string, enabled: boolean) => {
+export const useGetRegionQeQuery = (
+  megaregion: number | undefined,
+  country: number | undefined,
+  token: string,
+  enabled: boolean
+) => {
   return useQuery<PostGetRegionsQeReturn, BaseAxiosError>({
-    queryKey: regionsQueryKeys.getRegionsQe(megaregion, token),
+    queryKey: regionsQueryKeys.getRegionsQe(token, megaregion, country),
     queryFn: async () => {
-      const response = await regionsApi.getRegionsQe(megaregion, token);
+      const response = await regionsApi.getRegionsQe(token, megaregion, country);
       return response.data;
     },
     enabled

+ 2 - 2
src/modules/api/myRegions/regions-api.tsx

@@ -57,8 +57,8 @@ export interface PostSetTCCRegion {
 export const regionsApi = {
   getMegaregions: (token: string) =>
     request.postForm<PostGetMegaReturn>(API.GET_MEGAREGIONS, { token }),
-  getRegionsQe: (megaregion: number, token: string) =>
-    request.postForm<PostGetRegionsQeReturn>(API.GET_REGIONS_QE, { megaregion, token }),
+  getRegionsQe: (token: string, megaregion?: number, country?: number) =>
+    request.postForm<PostGetRegionsQeReturn>(API.GET_REGIONS_QE, { megaregion, country, token }),
   setNmRegion: (data: PostSetNmRegion) => request.postForm<ResponseType>(API.SET_NM_REGION, data),
   setTCCRegion: (data: PostSetTCCRegion) => request.postForm<ResponseType>(API.SET_TCC_REGION, data)
 };

+ 3 - 2
src/modules/api/myRegions/regions-query-keys.tsx

@@ -1,6 +1,7 @@
 export const regionsQueryKeys = {
   getMegaregions: (token: string) => ['getMegaregions', { token }] as const,
-  getRegionsQe: (megaregion: number, token: string) => ['getRegionsQe', { megaregion, token }] as const,
+  getRegionsQe: (token: string, megaregion: number | undefined, country: number | undefined) =>
+    ['getRegionsQe', { megaregion, country, token }] as const,
   setNmRegion: () => ['setNmRegion'] as const,
-  setTCCRegion: () => ['setTCCRegion'] as const,
+  setTCCRegion: () => ['setTCCRegion'] as const
 };

+ 33 - 10
src/screens/InAppScreens/MapScreen/CountryViewScreen/index.tsx

@@ -56,7 +56,7 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
     handleUpdateSlowList
   } = useRegion();
 
-  useEffect(() => {
+  useFocusEffect(() => {
     navigation.getParent()?.setOptions({
       tabBarStyle: {
         display: 'flex',
@@ -67,7 +67,7 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
         })
       }
     });
-  }, [navigation]);
+  });
 
   useFocusEffect(
     useCallback(() => {
@@ -296,14 +296,24 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
           <View style={styles.nameContainer}>
             <Text style={styles.title}>{name}</Text>
             <View style={ButtonStyles.btnContainer}>
-              {regionData?.visited && !disabled ? (
+              {/* {regionData?.visited && !disabled ? (
                 <TouchableOpacity
-                  onPress={() => setIsEditSlowModalVisible(true)}
+                  // onPress={() => setIsEditSlowModalVisible(true)}
+                  onPress={() =>
+                    navigation.navigate(NAVIGATION_PAGES.EDIT_COUNTRY_DATA, {
+                      countryId: countryId,
+                      countryName: name,
+                      countryFlag: regionData?.flag,
+                      slow11: regionData?.slow11,
+                      slow31: regionData?.slow31,
+                      slow101: regionData?.slow101
+                    })
+                  }
                   style={ButtonStyles.editBtn}
                 >
                   <EditSvg width={14} height={14} />
                 </TouchableOpacity>
-              ) : null}
+              ) : null} */}
               {!disabled ? (
                 <TouchableOpacity
                   style={[
@@ -312,12 +322,25 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
                       ? ButtonStyles.visitedButton
                       : ButtonStyles.markVisitedButton
                   ]}
-                  onPress={handleUpdateSlow}
+                  onPress={
+                    regionData?.visited
+                      ? () =>
+                          navigation.navigate(NAVIGATION_PAGES.EDIT_COUNTRY_DATA, {
+                            countryId: countryId,
+                            countryName: name,
+                            countryFlag: regionData?.flag,
+                            slow11: regionData?.slow11,
+                            slow31: regionData?.slow31,
+                            slow101: regionData?.slow101,
+                            isSlowList: false
+                          })
+                      : handleUpdateSlow
+                  }
                 >
                   {regionData?.visited ? (
                     <View style={ButtonStyles.visitedContainer}>
-                      <MarkIcon width={16} height={16} />
-                      <Text style={ButtonStyles.visitedButtonText}>Visited</Text>
+                      <EditSvg width={16} height={16} />
+                      <Text style={ButtonStyles.visitedButtonText}>Edit</Text>
                     </View>
                   ) : (
                     <Text style={[ButtonStyles.markVisitedButtonText]}>Mark Visited</Text>
@@ -330,7 +353,7 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
           <View style={styles.divider} />
 
           <View style={styles.stats}>
-            {data?.data.users_from_country_count ?? 0 > 0 ? (
+            {(data?.data.users_from_country_count ?? 0 > 0) ? (
               <TouchableOpacity
                 style={[styles.statItem, { justifyContent: 'flex-start' }]}
                 onPress={() =>
@@ -378,7 +401,7 @@ const CountryViewScreen: FC<Props> = ({ navigation, route }) => {
               <View style={[styles.statItem, { justifyContent: 'flex-start' }]} />
             )}
 
-            {data?.data.users_who_visited_country_count ?? 0 > 0 ? (
+            {(data?.data.users_who_visited_country_count ?? 0 > 0) ? (
               <TouchableOpacity
                 style={[styles.statItem, { justifyContent: 'flex-end' }]}
                 onPress={() =>

+ 1 - 1
src/screens/InAppScreens/MapScreen/index.tsx

@@ -1799,7 +1799,7 @@ const MapScreen: any = ({ navigation, route }: { navigation: any; route: any })
                 setIsWarningModalVisible(true);
                 return;
               }
-              handleUpdateSlow(id, v, s11, s31, s101);
+              handleUpdateSlow(id, v, undefined, undefined, undefined);
 
               const updatedIds = countriesVisited.includes(id)
                 ? countriesVisited.filter((visitedId) => visitedId !== id)

+ 67 - 12
src/screens/InAppScreens/TravelsScreen/Components/CountryItem/index.tsx

@@ -41,7 +41,8 @@ const CountryItem = React.memo(
             visited: Boolean(item.visited),
             slow11: item.slow11,
             slow31: item.slow31,
-            slow101: item.slow101
+            slow101: item.slow101,
+            flag: item.flag
           });
           navigation.navigate(NAVIGATION_PAGES.COUNTRY_PREVIEW, {
             regionId: item.country_id,
@@ -53,7 +54,33 @@ const CountryItem = React.memo(
       >
         <View style={styles.headerContainer}>
           <Image source={{ uri: API_HOST + item.flag }} style={styles.flag} />
-          <Text style={styles.countryName}>{item.country}</Text>
+          <View style={{ flex: 1, gap: 4 }}>
+            <Text style={styles.countryName}>{item.country}</Text>
+            <View style={styles.infoContainer}>
+              <Text style={styles.infoText} numberOfLines={2}>
+                {item.info_text}
+              </Text>
+              {item.visited === 0 && (
+                <TouchableOpacity
+                  onPress={() =>
+                    navigation.navigate(NAVIGATION_PAGES.EDIT_COUNTRY_DATA, {
+                      countryId: item.country_id,
+                      countryName: item.country,
+                      countryFlag: item.flag,
+                      slow11: item.slow11,
+                      slow31: item.slow31,
+                      slow101: item.slow101,
+                      isSlowList: true
+                    })
+                  }
+                  style={styles.editRegionBtn}
+                  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
+                >
+                  <EditSvg width={14} height={14} />
+                </TouchableOpacity>
+              )}
+            </View>
+          </View>
         </View>
         <View style={styles.divider}></View>
 
@@ -80,8 +107,21 @@ const CountryItem = React.memo(
 
           {token && (
             <View style={styles.btnContainer}>
-              {item.visited ? (
-                <TouchableOpacity onPress={() => openEditModal(item)} style={styles.editScoreBtn}>
+              {item.visited && item.visited_regions <= 1 ? (
+                <TouchableOpacity
+                  onPress={() =>
+                    navigation.navigate(NAVIGATION_PAGES.EDIT_COUNTRY_DATA, {
+                      countryId: item.country_id,
+                      countryName: item.country,
+                      countryFlag: item.flag,
+                      slow11: item.slow11,
+                      slow31: item.slow31,
+                      slow101: item.slow101,
+                      isSlowList: true
+                    })
+                  }
+                  style={styles.editScoreBtn}
+                >
                   <EditSvg width={14} height={14} />
                 </TouchableOpacity>
               ) : null}
@@ -89,20 +129,35 @@ const CountryItem = React.memo(
               <TouchableOpacity
                 style={item.visited ? styles.visitedButton : styles.markVisitedButton}
                 onPress={() =>
-                  updateSlow(
-                    item.country_id,
-                    item.visited === 1 ? false : true,
-                    Boolean(item.slow11),
-                    Boolean(item.slow31),
-                    Boolean(item.slow101)
-                  )
+                  item.visited && item.visited_regions > 1
+                    ? navigation.navigate(NAVIGATION_PAGES.EDIT_COUNTRY_DATA, {
+                        countryId: item.country_id,
+                        countryName: item.country,
+                        countryFlag: item.flag,
+                        slow11: item.slow11,
+                        slow31: item.slow31,
+                        slow101: item.slow101,
+                        isSlowList: true
+                      })
+                    : updateSlow(
+                        item.country_id,
+                        item.visited === 1 ? false : true,
+                        Boolean(item.slow11),
+                        Boolean(item.slow31),
+                        Boolean(item.slow101)
+                      )
                 }
               >
-                {item.visited ? (
+                {item.visited && item.visited_regions <= 1 ? (
                   <View style={styles.visitedContainer}>
                     <MarkIcon width={16} height={16} />
                     <Text style={styles.visitedButtonText}>Visited</Text>
                   </View>
+                ) : item.visited ? (
+                  <View style={styles.visitedContainer}>
+                    <EditSvg width={14} height={14} />
+                    <Text style={styles.visitedButtonText}>Edit</Text>
+                  </View>
                 ) : (
                   <Text style={[styles.markVisitedButtonText]}>Mark visited</Text>
                 )}

+ 21 - 2
src/screens/InAppScreens/TravelsScreen/Components/CountryItem/styles.tsx

@@ -9,7 +9,11 @@ export const styles = StyleSheet.create({
     marginBottom: 12,
     borderRadius: 8
   },
-  headerContainer: { flexDirection: 'row', alignItems: 'center', gap: 12 },
+  headerContainer: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 12
+  },
   flag: {
     width: 48,
     height: 48,
@@ -29,11 +33,22 @@ export const styles = StyleSheet.create({
     fontSize: 14,
     color: Colors.DARK_BLUE
   },
+  infoContainer: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    gap: 8
+  },
+  infoText: {
+    fontWeight: '600',
+    fontSize: 12,
+    color: Colors.DARK_BLUE,
+    flexShrink: 1
+  },
   divider: { height: 1, backgroundColor: Colors.DARK_LIGHT, marginVertical: 12 },
   durationContainer: {
     flexDirection: 'row',
     justifyContent: 'center',
-    gap: 8,
+    gap: 6,
     flexWrap: 'wrap',
     flex: Dimensions.get('window').width < 385 ? 1 : 0
   },
@@ -97,5 +112,9 @@ export const styles = StyleSheet.create({
     alignItems: 'center',
     justifyContent: 'center',
     padding: 7
+  },
+  editRegionBtn: {
+    alignItems: 'center',
+    justifyContent: 'center'
   }
 });

+ 21 - 13
src/screens/InAppScreens/TravelsScreen/Components/MyRegionsItems/NmRegionItem.tsx

@@ -18,7 +18,8 @@ export const NmRegionItem = React.memo(
     item,
     openEditModal,
     updateNM,
-    token
+    token,
+    hideCountry = false
   }: {
     item: NmRegion;
     openEditModal: (item: NmRegion) => void;
@@ -30,6 +31,7 @@ export const NmRegionItem = React.memo(
       quality: number
     ) => void;
     token: string;
+    hideCountry?: boolean;
   }) => {
     const [name, ...rest] = item.region_name?.split(/ – | - /);
     const subname = rest?.join(' - ');
@@ -45,21 +47,27 @@ export const NmRegionItem = React.memo(
             <Image source={{ uri: regionImg, cache: 'force-cache' }} style={styles.regionImage} />
           )}
           <View style={{ gap: 6, flex: 1 }}>
-            <Text style={styles.regionItemName}>{name}</Text>
-            <Text style={styles.regionItemSubname}>{subname}</Text>
+            {!hideCountry && <Text style={styles.regionItemName}>{name}</Text>}
+            <Text
+              style={[styles.regionItemSubname, hideCountry && { fontSize: 14, fontWeight: '600' }]}
+            >
+              {subname}
+            </Text>
           </View>
-          <View style={{ flexDirection: 'row', alignSelf: 'flex-start' }}>
-            <Image
-              source={{ uri: `${API_HOST}/img/flags_new/${item.flag_1}` }}
-              style={styles.flag}
-            />
-            {item.flag_2 && (
+          {!hideCountry && (
+            <View style={{ flexDirection: 'row', alignSelf: 'flex-start' }}>
               <Image
-                source={{ uri: `${API_HOST}/img/flags_new/${item.flag_2}` }}
-                style={[styles.flag, { marginLeft: -5 }]}
+                source={{ uri: `${API_HOST}/img/flags_new/${item.flag_1}` }}
+                style={styles.flag}
               />
-            )}
-          </View>
+              {item.flag_2 && (
+                <Image
+                  source={{ uri: `${API_HOST}/img/flags_new/${item.flag_2}` }}
+                  style={[styles.flag, { marginLeft: -5 }]}
+                />
+              )}
+            </View>
+          )}
         </View>
 
         <View style={styles.divider} />

+ 26 - 0
src/screens/InAppScreens/TravelsScreen/CountriesScreen/index.tsx

@@ -43,6 +43,32 @@ const CountriesScreen = () => {
     setIsEditModalVisible(true);
   };
 
+  useFocusEffect(
+    useCallback(() => {
+      const refetchData = async () => {
+        await refetch().then((res) => {
+          if (res.data) {
+            setSlow(res.data.slow);
+          }
+        });
+      };
+
+      if (token) {
+        refetchData();
+        navigation.getParent()?.setOptions({
+          tabBarStyle: {
+            display: 'flex',
+            ...Platform.select({
+              android: {
+                height: 58
+              }
+            })
+          }
+        });
+      }
+    }, [token, refetch, navigation])
+  );
+
   useEffect(() => {
     if (slow && slow.length) {
       token && calcTotalScore();

+ 332 - 0
src/screens/InAppScreens/TravelsScreen/EditCountryDataScreen/index.tsx

@@ -0,0 +1,332 @@
+import React, { useCallback, useEffect, useState } from 'react';
+import { View, Text, TouchableOpacity, FlatList, Image } from 'react-native';
+import * as Progress from 'react-native-progress';
+import { useFocusEffect, useNavigation } from '@react-navigation/native';
+import moment from 'moment';
+
+import { Button, CheckBox, EditNmModal, Header, PageWrapper } from 'src/components';
+import { NmRegionItem } from '../Components/MyRegionsItems/NmRegionItem';
+
+import { StoreType, storage } from 'src/storage';
+import { NmRegion } from '../utils/types';
+import { Colors } from 'src/theme';
+import { styles } from './styles';
+import { useGetRegionQeQuery, usePostSetTCCRegionMutation } from '@api/myRegions';
+import { qualityOptions } from '../utils/constants';
+
+import { NAVIGATION_PAGES } from 'src/types';
+import { useRegion } from 'src/contexts/RegionContext';
+import { API_HOST } from 'src/constants';
+import { getFontSize } from 'src/utils';
+import { fetchCountryUserData } from '@api/countries';
+
+const EditCountryDataScreen = ({ route }: { route: any }) => {
+  const countryId = route?.params?.countryId;
+  const countryName = route?.params?.countryName;
+  const countryFlag = route?.params?.countryFlag;
+  const slow11 = route?.params?.slow11;
+  const slow31 = route?.params?.slow31;
+  const slow101 = route?.params?.slow101;
+  const isSlowList = route?.params?.isSlowList;
+
+  const token = storage.get('token', StoreType.STRING) as string;
+  const { data: regionsQe } = useGetRegionQeQuery(undefined, countryId, String(token), true);
+  const [isEnabled11, setIsEnabled11] = useState(Boolean(slow11));
+  const [isEnabled31, setIsEnabled31] = useState(Boolean(slow31));
+  const [isEnabled101, setIsEnabled101] = useState(Boolean(slow101));
+  const [total, setTotal] = useState(0);
+  const [isEditModalVisible, setIsEditModalVisible] = useState(false);
+  const [filteredNmRegions, setFilteredNmRegions] = useState<NmRegion[] | null>(null);
+  const [modalState, setModalState] = useState({
+    selectedFirstYear: 2021,
+    selectedLastYear: 2021,
+    selectedQuality: qualityOptions[2],
+    selectedNoOfVisits: 1,
+    years: [],
+    id: null
+  });
+  const [dataLoaded, setDataLoaded] = useState(false);
+  const navigation = useNavigation();
+  const {
+    handleUpdateNMList: handleUpdateNM,
+    handleUpdateSlowList: handleUpdateSlowList,
+    handleUpdateSlow: handleUpdateSlow,
+    nmRegions,
+    setNmRegions,
+    setUserData
+  } = useRegion();
+  const { mutateAsync: mutateCountriesData } = fetchCountryUserData();
+
+  useEffect(() => {
+    navigation.getParent()?.setOptions({
+      tabBarStyle: {
+        display: 'none'
+      }
+    });
+  }, [navigation]);
+
+  useEffect(() => {
+    const currentYear = moment().year();
+    let yearSelector: { label: string; value: number }[] = [{ label: 'visited', value: 1 }];
+    for (let i = currentYear; i >= 1951; i--) {
+      yearSelector.push({ label: i.toString(), value: i });
+    }
+    handleModalStateChange({ years: yearSelector });
+  }, []);
+
+  useFocusEffect(
+    useCallback(() => {
+      const refetchData = async () => {
+        await mutateCountriesData(
+          { id: countryId, token },
+          {
+            onSuccess: (data) => {
+              setUserData({ type: 'countries', id: countryId, ...data.data });
+            }
+          }
+        );
+      };
+
+      refetchData();
+    }, [token, countryId, navigation])
+  );
+
+  const updateRegion = async (nm: any) => {
+    handleUpdateNM(nm.id, nm.visits > 0 ? 0 : 1, nm.visits > 0 ? 0 : 1, nm.visits > 0 ? 0 : 1, 3);
+    setTimeout(async () => {
+      await mutateCountriesData(
+        { id: countryId, token },
+        {
+          onSuccess: (data) => {
+            setUserData({ type: 'countries', id: countryId, ...data.data });
+          }
+        }
+      );
+    }, 1000);
+  };
+
+  const handleModalStateChange = (updates: { [key: string]: any }) => {
+    setModalState((prevState) => ({ ...prevState, ...updates }));
+  };
+
+  const handleOpenEditModal = (item: NmRegion) => {
+    handleModalStateChange({
+      selectedFirstYear: item.year,
+      selectedLastYear: item.last,
+      selectedQuality:
+        qualityOptions.find((quality) => quality.id === item.quality) || qualityOptions[2],
+      selectedNoOfVisits: item.visits || 1,
+      id: item.id
+    });
+    setIsEditModalVisible(true);
+  };
+
+  useEffect(() => {
+    if (nmRegions && nmRegions.length && token && dataLoaded) {
+      calcTotalCountries();
+    }
+  }, [nmRegions, dataLoaded]);
+
+  useEffect(() => {
+    if (regionsQe && regionsQe.result === 'OK') {
+      setNmRegions(regionsQe.data.out_regs);
+      setDataLoaded(true);
+    }
+  }, [regionsQe]);
+
+  useEffect(() => {
+    setFilteredNmRegions(nmRegions ?? []);
+  }, [nmRegions]);
+
+  const calcTotalCountries = async () => {
+    const visited = nmRegions?.filter((item: NmRegion) => item.visits > 0).length || 0;
+
+    if (visited === 0 && dataLoaded) {
+      setIsEnabled11(false);
+      setIsEnabled31(false);
+      setIsEnabled101(false);
+    }
+    setTotal(visited);
+  };
+
+  const renderItem = ({ item }: { item: NmRegion }) => (
+    <TouchableOpacity
+      onPress={() => {
+        setUserData({
+          type: 'nm',
+          id: item.id,
+          region_flag: item.flag_1,
+          region_name: item.region_name,
+          best_visit_quality: item.quality,
+          first_visit_year: item.year,
+          last_visit_year: item.last,
+          no_of_visits: item.visits,
+          visited: item.visits > 0
+        });
+        navigation.navigate(
+          ...([
+            NAVIGATION_PAGES.REGION_PREVIEW,
+            {
+              regionId: item.id,
+              isTravelsScreen: true,
+              type: 'nm',
+              disabled: token ? false : true
+            }
+          ] as never)
+        );
+      }}
+    >
+      <NmRegionItem
+        item={item}
+        openEditModal={handleOpenEditModal}
+        updateNM={() => updateRegion(item)}
+        token={token}
+        hideCountry={true}
+      />
+    </TouchableOpacity>
+  );
+
+  return (
+    <PageWrapper>
+      <Header
+        label={
+          <View style={{ flexDirection: 'row', alignItems: 'center' }}>
+            <Text
+              style={{
+                fontFamily: 'redhat-700',
+                fontSize: getFontSize(14),
+                color: Colors.DARK_BLUE
+              }}
+            >
+              {countryName}
+            </Text>
+            <Image
+              source={{ uri: API_HOST + countryFlag }}
+              style={{
+                width: 24,
+                height: 24,
+                marginLeft: 8,
+                borderRadius: 12,
+                borderWidth: 0.5,
+                borderColor: Colors.BORDER_LIGHT
+              }}
+            />
+          </View>
+        }
+      />
+      <View style={styles.progressHeader}>
+        <Text style={styles.textSmall}>Visited regions</Text>
+        <Text style={styles.textSmall}>
+          {nmRegions?.length
+            ? `${total}/${nmRegions.length} • ${((total * 100) / nmRegions.length).toFixed(2)}%`
+            : '0/0 • 100%'}
+        </Text>
+      </View>
+
+      <Progress.Bar
+        progress={nmRegions?.length ? total / nmRegions.length : 1}
+        width={null}
+        height={4}
+        color={Colors.DARK_BLUE}
+        borderWidth={0}
+        borderRadius={5}
+        unfilledColor={Colors.FILL_LIGHT}
+      />
+
+      {filteredNmRegions && filteredNmRegions?.length ? (
+        <FlatList
+          data={filteredNmRegions}
+          renderItem={renderItem}
+          keyExtractor={(item) => item.id.toString()}
+          showsVerticalScrollIndicator={false}
+          style={{ paddingVertical: 8 }}
+        />
+      ) : null}
+
+      <View style={styles.optionsContainer}>
+        <TouchableOpacity
+          disabled={isEnabled31 || isEnabled101 || total === 0}
+          onPress={() => {
+            setIsEnabled11(!isEnabled11);
+            setIsEnabled31(isEnabled11 ? false : isEnabled31);
+          }}
+          style={styles.optionBtn}
+          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
+        >
+          <CheckBox
+            onChange={() => {
+              setIsEnabled11(!isEnabled11);
+              setIsEnabled31(isEnabled11 ? false : isEnabled31);
+            }}
+            value={isEnabled11}
+            color={Colors.DARK_BLUE}
+            disabled={isEnabled31 || isEnabled101 || total === 0}
+          />
+          <Text style={styles.optionText}>11+ days</Text>
+        </TouchableOpacity>
+        <TouchableOpacity
+          disabled={!isEnabled11 || isEnabled101}
+          onPress={() => {
+            setIsEnabled31(!isEnabled31);
+            setIsEnabled101(isEnabled31 ? false : isEnabled101);
+          }}
+          style={styles.optionBtn}
+          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
+        >
+          <CheckBox
+            onChange={() => {
+              setIsEnabled31(!isEnabled31);
+              setIsEnabled101(isEnabled31 ? false : isEnabled101);
+            }}
+            value={isEnabled31}
+            color={Colors.DARK_BLUE}
+            disabled={!isEnabled11 || isEnabled101}
+          />
+          <Text style={styles.optionText}>31+ days</Text>
+        </TouchableOpacity>
+        <TouchableOpacity
+          disabled={!isEnabled11 || !isEnabled31}
+          onPress={() => setIsEnabled101(!isEnabled101)}
+          style={styles.optionBtn}
+          hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
+        >
+          <CheckBox
+            onChange={() => setIsEnabled101(!isEnabled101)}
+            value={isEnabled101}
+            color={Colors.DARK_BLUE}
+            disabled={!isEnabled11 || !isEnabled31}
+          />
+          <Text style={styles.optionText}>101+ days</Text>
+        </TouchableOpacity>
+      </View>
+      <View style={{ marginBottom: 24 }}>
+        <Button
+          children="Done"
+          onPress={() => {
+            if (total === 0) {
+              navigation.goBack();
+              isSlowList
+                ? handleUpdateSlowList(countryId, false, undefined, undefined, undefined)
+                : handleUpdateSlow(countryId, false, undefined, undefined, undefined);
+              return;
+            }
+            isSlowList
+              ? handleUpdateSlowList(countryId, undefined, isEnabled11, isEnabled31, isEnabled101)
+              : handleUpdateSlow(countryId, undefined, isEnabled11, isEnabled31, isEnabled101);
+            navigation.goBack();
+          }}
+        />
+      </View>
+
+      <EditNmModal
+        isVisible={isEditModalVisible}
+        onClose={() => setIsEditModalVisible(false)}
+        modalState={modalState}
+        updateModalState={handleModalStateChange}
+        updateNM={handleUpdateNM}
+      />
+    </PageWrapper>
+  );
+};
+
+export default EditCountryDataScreen;

+ 63 - 0
src/screens/InAppScreens/TravelsScreen/EditCountryDataScreen/styles.tsx

@@ -0,0 +1,63 @@
+import { StyleSheet } from 'react-native';
+import { Colors } from 'src/theme';
+
+export const styles = StyleSheet.create({
+  megaSelector: {
+    flexDirection: 'row',
+    alignItems: 'center',
+    paddingHorizontal: 12,
+    paddingVertical: 8,
+    borderRadius: 6,
+    backgroundColor: Colors.FILL_LIGHT,
+    justifyContent: 'space-between',
+    marginBottom: 8
+  },
+  megaButtonText: {
+    color: Colors.DARK_BLUE,
+    fontWeight: 'bold',
+    fontSize: 13
+  },
+  progressHeader: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    alignItems: 'center',
+    marginBottom: 8
+  },
+  textSmall: {
+    color: Colors.DARK_BLUE,
+    fontWeight: '600',
+    fontSize: 12
+  },
+  buttonContainer: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    alignItems: 'center',
+    marginBottom: 16
+  },
+  textMedium: { fontWeight: 'bold', fontSize: 14, color: Colors.DARK_BLUE },
+  optionsContainer: {
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    alignItems: 'center',
+    gap: 12,
+    paddingVertical: 12,
+    marginBottom: 8
+  },
+  optionBtn: { flexDirection: 'row', alignItems: 'center', gap: 8 },
+  optionText: {
+    fontSize: 13,
+    fontWeight: 'bold'
+  },
+  doneButton: {
+    backgroundColor: Colors.ORANGE,
+    padding: 12,
+    borderRadius: 4,
+    marginTop: 20,
+    alignItems: 'center'
+  },
+  doneButtonText: {
+    fontSize: 16,
+    color: 'white',
+    fontWeight: '600'
+  }
+});

+ 1 - 1
src/screens/InAppScreens/TravelsScreen/RegionsScreen/index.tsx

@@ -34,7 +34,7 @@ const RegionsScreen = () => {
     id: 1,
     name: 'SOUTHERN EUROPE'
   });
-  const { data: regionsQe } = useGetRegionQeQuery(selectedMega.id, String(token), true);
+  const { data: regionsQe } = useGetRegionQeQuery(selectedMega.id, undefined, String(token), true);
   const [total, setTotal] = useState(0);
   const [isEditModalVisible, setIsEditModalVisible] = useState(false);
   const [contentIndex, setContentIndex] = useState(0);

+ 3 - 0
src/screens/InAppScreens/TravelsScreen/utils/types.ts

@@ -88,6 +88,9 @@ export interface SlowData {
   slow31: 0 | 1;
   slow101: 0 | 1;
   yes: number;
+  info_text: string;
+  visited_regions: number;
+  default_region_id: number;
 }
 
 export interface NmRegion {

+ 2 - 1
src/types/navigation.ts

@@ -84,5 +84,6 @@ export enum NAVIGATION_PAGES {
   OFFLINE_MAPS = 'inAppOfflineMaps',
   OFFLINE_SELECT_MAP = 'inAppOfflineSelectMap',
   OFFLINE_SELECT_REGIONS = 'inAppOfflineSelectRegions',
-  OFFLINE_DOWNLOAD_PROGRESS = 'inAppOfflineDownloadProgress'
+  OFFLINE_DOWNLOAD_PROGRESS = 'inAppOfflineDownloadProgress',
+  EDIT_COUNTRY_DATA = 'inAppEditCountryData',
 }