|
@@ -1,5 +1,5 @@
|
|
|
-import React, { useCallback } from 'react';
|
|
|
-import { View, Text, Image, TouchableOpacity, ScrollView, Dimensions } from 'react-native';
|
|
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
|
+import { View, Text, Image, TouchableOpacity, ScrollView, Dimensions, Switch } from 'react-native';
|
|
|
import { Colors } from 'src/theme';
|
|
|
import { styles } from './styles';
|
|
|
import { Loading } from 'src/components';
|
|
@@ -8,6 +8,8 @@ import CheckSvg from 'assets/icons/mark.svg';
|
|
|
import CloseSVG from 'assets/icons/close.svg';
|
|
|
import { API_HOST } from 'src/constants';
|
|
|
import { FlashList } from '@shopify/flash-list';
|
|
|
+import { useNavigation } from '@react-navigation/native';
|
|
|
+import { NAVIGATION_PAGES } from 'src/types';
|
|
|
|
|
|
interface Mega {
|
|
|
id: number;
|
|
@@ -20,6 +22,7 @@ interface Mega {
|
|
|
}[];
|
|
|
transits: number[];
|
|
|
visits: number[];
|
|
|
+ total?: number;
|
|
|
}
|
|
|
|
|
|
interface Region {
|
|
@@ -39,12 +42,69 @@ const RegionsRenderer = ({
|
|
|
regions: any;
|
|
|
setIsModalVisible: (value: boolean) => void;
|
|
|
}) => {
|
|
|
+ const navigation = useNavigation();
|
|
|
const flashlistConfig = {
|
|
|
waitForInteraction: true,
|
|
|
itemVisiblePercentThreshold: 50,
|
|
|
minimumViewTime: 1000
|
|
|
};
|
|
|
const isSmallWidth = Dimensions.get('window').width < 383;
|
|
|
+ const [showAll, setShowAll] = useState(true);
|
|
|
+ const [filteredRegions, setFilteredRegions] = useState<any[]>([]);
|
|
|
+ const [filteredMegaregions, setFilteredMegaregions] = useState<any[]>([]);
|
|
|
+ const disabled =
|
|
|
+ type === 'whs' || type === 'tcc' || type === 'un' || type === 'unp' ? true : false;
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (!regions?.data) return;
|
|
|
+
|
|
|
+ if (showAll) {
|
|
|
+ switch (type) {
|
|
|
+ case 'nm':
|
|
|
+ case 'mqp':
|
|
|
+ setFilteredMegaregions(regions.data.megaregions);
|
|
|
+ break;
|
|
|
+ case 'un':
|
|
|
+ case 'unp':
|
|
|
+ case 'slow':
|
|
|
+ case 'yes':
|
|
|
+ case 'tcc':
|
|
|
+ setFilteredRegions(regions.data[0]);
|
|
|
+ break;
|
|
|
+ case 'whs':
|
|
|
+ setFilteredRegions(regions.data);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ switch (type) {
|
|
|
+ case 'nm':
|
|
|
+ case 'mqp':
|
|
|
+ const filteredMegaregions = regions.data?.megaregions
|
|
|
+ ?.map((item: Mega) => ({
|
|
|
+ ...item,
|
|
|
+ regions: item.regions.filter((region) => item.visits.includes(region.id)),
|
|
|
+ total: item.regions.length
|
|
|
+ }))
|
|
|
+ ?.filter((item: Mega) => item.regions.length > 0);
|
|
|
+
|
|
|
+ setFilteredMegaregions(filteredMegaregions);
|
|
|
+ break;
|
|
|
+ case 'un':
|
|
|
+ case 'unp':
|
|
|
+ case 'tcc':
|
|
|
+ setFilteredRegions(
|
|
|
+ regions.data[0].filter((item: Region) => regions.data[1].includes(item.name))
|
|
|
+ );
|
|
|
+ break;
|
|
|
+ case 'slow':
|
|
|
+ setFilteredRegions(regions.data[0].filter((item: any) => item.visited === 1));
|
|
|
+ break;
|
|
|
+ case 'whs':
|
|
|
+ setFilteredRegions(regions.data.filter((item: any) => item.visited));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [showAll, regions]);
|
|
|
|
|
|
const getOpacity = useCallback(
|
|
|
(item: any, mega?: Mega) => {
|
|
@@ -67,10 +127,49 @@ const RegionsRenderer = ({
|
|
|
[type, regions?.data]
|
|
|
);
|
|
|
|
|
|
+ const handlePress = (item: any) => {
|
|
|
+ switch (type) {
|
|
|
+ case 'nm':
|
|
|
+ case 'mqp':
|
|
|
+ setIsModalVisible(false);
|
|
|
+ navigation.navigate(
|
|
|
+ ...([
|
|
|
+ NAVIGATION_PAGES.REGION_PREVIEW,
|
|
|
+ {
|
|
|
+ regionId: item.id,
|
|
|
+ type: type === 'nm' ? 'nm' : 'dare',
|
|
|
+ disabled: false,
|
|
|
+ isProfileScreen: true
|
|
|
+ }
|
|
|
+ ] as never)
|
|
|
+ );
|
|
|
+ break;
|
|
|
+ case 'slow':
|
|
|
+ case 'yes':
|
|
|
+ setIsModalVisible(false);
|
|
|
+ navigation.navigate(
|
|
|
+ ...([
|
|
|
+ NAVIGATION_PAGES.COUNTRY_PREVIEW,
|
|
|
+ {
|
|
|
+ regionId: type === 'slow' ? item.country_id : item.id,
|
|
|
+ type: 'country',
|
|
|
+ disabled: false,
|
|
|
+ isProfileScreen: true
|
|
|
+ }
|
|
|
+ ] as never)
|
|
|
+ );
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
const renderRegion = useCallback(
|
|
|
(item: any, mega?: Mega) => {
|
|
|
return (
|
|
|
- <View style={[styles.regionRow, { opacity: getOpacity(item, mega) }]}>
|
|
|
+ <TouchableOpacity
|
|
|
+ style={[styles.regionRow, { opacity: getOpacity(item, mega) }]}
|
|
|
+ onPress={() => handlePress(item)}
|
|
|
+ disabled={disabled}
|
|
|
+ >
|
|
|
<View
|
|
|
style={[
|
|
|
styles.flags,
|
|
@@ -164,7 +263,7 @@ const RegionsRenderer = ({
|
|
|
</View>
|
|
|
</View>
|
|
|
)}
|
|
|
- </View>
|
|
|
+ </TouchableOpacity>
|
|
|
);
|
|
|
},
|
|
|
[getOpacity, regions?.data, type]
|
|
@@ -180,8 +279,8 @@ const RegionsRenderer = ({
|
|
|
{item.name}
|
|
|
<Text style={{ fontWeight: '600' }}>
|
|
|
{' '}
|
|
|
- - {item.visits.length}/{item.regions.length} (
|
|
|
- {((item.visits.length * 100) / item.regions.length).toFixed(2)}%)
|
|
|
+ - {item.visits.length}/{item?.total ?? item.regions.length} (
|
|
|
+ {((item.visits.length * 100) / (item?.total ?? item.regions.length)).toFixed(2)}%)
|
|
|
</Text>
|
|
|
</Text>
|
|
|
{type === 'nm' && (
|
|
@@ -231,8 +330,27 @@ const RegionsRenderer = ({
|
|
|
);
|
|
|
|
|
|
const renderContent = () => {
|
|
|
- const renderHeader = (headerText: string) => (
|
|
|
- <RegionsModalHeader textHeader={headerText} onRequestClose={() => setIsModalVisible(false)} />
|
|
|
+ const renderHeader = (headerText: string, rightElement: boolean) => (
|
|
|
+ <RegionsModalHeader
|
|
|
+ textHeader={headerText}
|
|
|
+ onRequestClose={() => setIsModalVisible(false)}
|
|
|
+ rightElement={
|
|
|
+ rightElement ? (
|
|
|
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
|
+ <Text style={{ color: Colors.DARK_BLUE, fontSize: 12, fontWeight: '600' }}>
|
|
|
+ Show/Hide All
|
|
|
+ </Text>
|
|
|
+ <Switch
|
|
|
+ trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
|
|
|
+ thumbColor={Colors.WHITE}
|
|
|
+ onValueChange={() => setShowAll(!showAll)}
|
|
|
+ value={showAll}
|
|
|
+ style={{ transform: 'scale(0.8)' }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ ) : null
|
|
|
+ }
|
|
|
+ />
|
|
|
);
|
|
|
|
|
|
switch (type) {
|
|
@@ -240,11 +358,11 @@ const RegionsRenderer = ({
|
|
|
case 'mqp':
|
|
|
return (
|
|
|
<>
|
|
|
- {renderHeader(type === 'nm' ? 'NM' : 'DARE')}
|
|
|
+ {renderHeader(type === 'nm' ? 'NM' : 'DARE', true)}
|
|
|
<FlashList
|
|
|
viewabilityConfig={flashlistConfig}
|
|
|
estimatedItemSize={4000}
|
|
|
- data={regions.data.megaregions}
|
|
|
+ data={filteredMegaregions}
|
|
|
renderItem={renderMegaregion}
|
|
|
keyExtractor={(megaregion) => megaregion?.id?.toString()}
|
|
|
showsVerticalScrollIndicator={false}
|
|
@@ -258,11 +376,11 @@ const RegionsRenderer = ({
|
|
|
case 'tcc':
|
|
|
return (
|
|
|
<>
|
|
|
- {renderHeader(type === 'un' ? 'UN' : type === 'unp' ? 'UN+' : 'TCC')}
|
|
|
+ {renderHeader(type === 'un' ? 'UN' : type === 'unp' ? 'UN+' : 'TCC', true)}
|
|
|
<FlashList
|
|
|
viewabilityConfig={flashlistConfig}
|
|
|
estimatedItemSize={50}
|
|
|
- data={regions.data[0]}
|
|
|
+ data={filteredRegions}
|
|
|
renderItem={(region) => renderRegion(region.item)}
|
|
|
keyExtractor={(region: Region) => region.name}
|
|
|
showsVerticalScrollIndicator={false}
|
|
@@ -285,11 +403,11 @@ const RegionsRenderer = ({
|
|
|
case 'slow':
|
|
|
return (
|
|
|
<>
|
|
|
- {renderHeader('SLOW')}
|
|
|
+ {renderHeader('SLOW', true)}
|
|
|
<FlashList
|
|
|
viewabilityConfig={flashlistConfig}
|
|
|
estimatedItemSize={50}
|
|
|
- data={regions.data[0]}
|
|
|
+ data={filteredRegions}
|
|
|
renderItem={(region) => renderRegion(region.item)}
|
|
|
keyExtractor={(region: Region) => region.country_id.toString()}
|
|
|
showsVerticalScrollIndicator={false}
|
|
@@ -301,29 +419,17 @@ const RegionsRenderer = ({
|
|
|
<View style={{ flexDirection: 'row', flex: 1 }}>
|
|
|
<View style={styles.slow}>
|
|
|
<Text style={styles.alignCenter}>
|
|
|
- <Text
|
|
|
- style={[styles.megaregionTitle, { fontSize: 12 }]}
|
|
|
- >
|
|
|
- 11+
|
|
|
- </Text>
|
|
|
+ <Text style={[styles.megaregionTitle, { fontSize: 12 }]}>11+</Text>
|
|
|
</Text>
|
|
|
</View>
|
|
|
<View style={styles.slow}>
|
|
|
<Text style={styles.alignCenter}>
|
|
|
- <Text
|
|
|
- style={[styles.megaregionTitle, { fontSize: 12 }]}
|
|
|
- >
|
|
|
- 31+
|
|
|
- </Text>
|
|
|
+ <Text style={[styles.megaregionTitle, { fontSize: 12 }]}>31+</Text>
|
|
|
</Text>
|
|
|
</View>
|
|
|
<View style={styles.slow}>
|
|
|
<Text style={styles.alignCenter}>
|
|
|
- <Text
|
|
|
- style={[styles.megaregionTitle, { fontSize: 12 }]}
|
|
|
- >
|
|
|
- 101+
|
|
|
- </Text>
|
|
|
+ <Text style={[styles.megaregionTitle, { fontSize: 12 }]}>101+</Text>
|
|
|
</Text>
|
|
|
</View>
|
|
|
</View>
|
|
@@ -348,7 +454,7 @@ const RegionsRenderer = ({
|
|
|
};
|
|
|
return (
|
|
|
<>
|
|
|
- {renderHeader('YES')}
|
|
|
+ {renderHeader('YES', false)}
|
|
|
<FlashList
|
|
|
viewabilityConfig={flashlistConfig}
|
|
|
estimatedItemSize={50}
|
|
@@ -390,11 +496,11 @@ const RegionsRenderer = ({
|
|
|
case 'whs':
|
|
|
return (
|
|
|
<>
|
|
|
- {renderHeader('WHS')}
|
|
|
+ {renderHeader('WHS', true)}
|
|
|
<FlashList
|
|
|
viewabilityConfig={flashlistConfig}
|
|
|
estimatedItemSize={50}
|
|
|
- data={regions.data}
|
|
|
+ data={filteredRegions}
|
|
|
renderItem={(region) => renderRegion(region.item)}
|
|
|
keyExtractor={(region: Region) => region.name}
|
|
|
showsVerticalScrollIndicator={false}
|