123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- import React, { useCallback, useEffect, useState } from 'react';
- import { View, Text, TouchableOpacity, ScrollView, FlatList, Platform } from 'react-native';
- import ReactModal from 'react-native-modal';
- import * as Progress from 'react-native-progress';
- import { useFocusEffect, useNavigation } from '@react-navigation/native';
- import CountryItem from '../Components/CountryItem';
- import EditModal from '../Components/EditSlowModal';
- import { Header, Input, PageWrapper, WarningModal } from 'src/components';
- import { useGetSlowQuery, usePostSetSlowMutation } from '@api/countries';
- import { StoreType, storage } from 'src/storage';
- import { SlowData } from '../utils/types';
- import { Colors } from 'src/theme';
- import { styles } from './styles';
- import ChevronIcon from 'assets/icons/travels-screens/down-arrow.svg';
- import IngoSvg from 'assets/icons/travels-screens/info.svg';
- import SearchIcon from '../../../../../assets/icons/search.svg';
- import InfoIcon from 'assets/icons/info-solid.svg';
- import { NAVIGATION_PAGES } from 'src/types';
- import { useRegion } from 'src/contexts/RegionContext';
- const CountriesScreen = () => {
- const token = storage.get('token', StoreType.STRING) as string;
- const { data, refetch } = useGetSlowQuery(String(token));
- const [megaSelectorVisible, setMegaSelectorVisible] = useState(false);
- const [selectedMega, setSelectedMega] = useState<{ name: string; id: number }>({
- name: 'ALL MEGAREGIONS',
- id: -1
- });
- const [total, setTotal] = useState({ slow: 0, visited: 0 });
- const [isEditModalVisible, setIsEditModalVisible] = useState(false);
- const [currentItem, setCurrentItem] = useState<SlowData | null>(null);
- const [infoModalVisible, setInfoModalVisible] = useState(false);
- const [search, setSearch] = useState<string>('');
- const [filteredSlow, setFilteredSlow] = useState<SlowData[] | null>(null);
- const navigation = useNavigation();
- const { handleUpdateSlowList: handleUpdateSlow, slow, setSlow, setUserData } = useRegion();
- const handleOpenEditModal = (item: SlowData) => {
- setCurrentItem(item);
- setIsEditModalVisible(true);
- };
- useEffect(() => {
- if (slow && slow.length) {
- token && calcTotalScore();
- let newSlowData = slow;
- if (search) {
- newSlowData =
- slow?.filter((item: any) => {
- const itemData = item.country ? item.country.toLowerCase() : ''.toLowerCase();
- const textData = search.toLowerCase();
- return itemData.indexOf(textData) > -1;
- }) ?? [];
- }
- setFilteredSlow(newSlowData);
- }
- }, [slow]);
- useEffect(() => {
- const refetchData = async () => {
- await refetch().then((res) => {
- if (res.data) {
- setSlow(res.data.slow);
- }
- });
- };
- if (data && data.result === 'OK') {
- setSearch('');
- if (selectedMega.id === -1) {
- refetchData();
- } else {
- setSlow(data?.slow?.filter((item) => item.mega.includes(selectedMega.id)));
- }
- }
- }, [selectedMega]);
- useEffect(() => {
- if (data && data.result === 'OK') {
- setSlow(data?.slow);
- }
- }, [data]);
- const searchFilter = (text: string) => {
- if (text) {
- const newData: SlowData[] | null =
- slow?.filter((item: any) => {
- const itemData = item.country ? item.country.toLowerCase() : ''.toLowerCase();
- const textData = text.toLowerCase();
- return itemData.indexOf(textData) > -1;
- }) ?? [];
- setFilteredSlow(newData);
- setSearch(text);
- } else {
- setFilteredSlow(slow);
- setSearch(text);
- }
- };
- const calcTotalScore = () => {
- let visited = 0;
- let slow11 = 0;
- let slow31 = 0;
- let slow101 = 0;
- slow?.forEach((item: SlowData) => {
- visited += item.visited;
- slow11 += item.slow11;
- slow31 += item.slow31;
- slow101 += item.slow101;
- });
- setTotal({ slow: slow11 + slow31 + slow101, visited });
- };
- const renderCountryItem = ({ item }: { item: SlowData }) => (
- <CountryItem
- item={item}
- updateSlow={handleUpdateSlow}
- openEditModal={handleOpenEditModal}
- token={token}
- setUserData={setUserData}
- navigation={navigation}
- />
- );
- return (
- <PageWrapper>
- <Header
- label="Countries"
- // rightElement={
- // <TouchableOpacity
- // onPress={() => navigation.navigate(NAVIGATION_PAGES.COUNTRIES_INFO as never)}
- // style={{ width: 30 }}
- // >
- // <InfoIcon />
- // </TouchableOpacity>
- // }
- />
- <TouchableOpacity style={styles.megaSelector} onPress={() => setMegaSelectorVisible(true)}>
- <Text style={styles.megaButtonText}>{selectedMega.name}</Text>
- <ChevronIcon width={18} height={18} />
- </TouchableOpacity>
- <View style={{ marginBottom: 16 }}>
- <Input
- inputMode={'search'}
- placeholder={'Search'}
- onChange={(text) => searchFilter(text)}
- value={search}
- icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
- height={34}
- />
- </View>
- <View style={styles.progressHeader}>
- <Text style={styles.visitedCountriesCount}>Visited countries</Text>
- <Text style={styles.visitedCountriesCount}>
- {slow?.length
- ? `${total.visited}/${slow.length} • ${((total.visited * 100) / slow.length).toFixed(2)}%`
- : '0/0 • 100%'}
- </Text>
- </View>
- <Progress.Bar
- progress={slow?.length ? total.visited / slow.length : 1}
- width={null}
- height={4}
- color={Colors.DARK_BLUE}
- borderWidth={0}
- borderRadius={5}
- unfilledColor={Colors.FILL_LIGHT}
- />
- <View style={styles.slowScoreSection}>
- <Text style={styles.visitedCountriesCount}>SLOW score: {total.slow}</Text>
- <TouchableOpacity style={styles.infoBtn} onPress={() => setInfoModalVisible(true)}>
- <IngoSvg />
- </TouchableOpacity>
- </View>
- {filteredSlow && filteredSlow?.length ? (
- <FlatList
- data={filteredSlow}
- renderItem={renderCountryItem}
- keyExtractor={(item) => item.country_id.toString()}
- showsVerticalScrollIndicator={false}
- style={{ paddingTop: 8 }}
- />
- ) : null}
- <ReactModal
- isVisible={megaSelectorVisible}
- onBackdropPress={() => setMegaSelectorVisible(false)}
- style={styles.modal}
- statusBarTranslucent={true}
- presentationStyle="overFullScreen"
- >
- <View style={styles.wrapper}>
- <ScrollView style={{ paddingBottom: 16 }} showsVerticalScrollIndicator={false}>
- <TouchableOpacity
- style={styles.btnOption}
- onPress={() => {
- setMegaSelectorVisible(false);
- setSelectedMega({ name: 'ALL MEGAREGIONS', id: -1 });
- }}
- >
- <Text style={styles.btnOptionText}>ALL MEGAREGIONS</Text>
- </TouchableOpacity>
- {data?.megaregions?.map((mega) => (
- <TouchableOpacity
- key={mega.id}
- style={styles.btnOption}
- onPress={() => {
- setMegaSelectorVisible(false);
- setSelectedMega(mega);
- }}
- >
- <Text style={styles.btnOptionText}>{mega.name}</Text>
- </TouchableOpacity>
- ))}
- </ScrollView>
- </View>
- </ReactModal>
- {currentItem && (
- <EditModal
- isVisible={isEditModalVisible}
- onClose={() => setIsEditModalVisible(false)}
- item={currentItem}
- updateSlow={(id, v, s11, s31, s101) => handleUpdateSlow(id, v, s11, s31, s101)}
- />
- )}
- <WarningModal
- isVisible={infoModalVisible}
- onClose={() => setInfoModalVisible(false)}
- type="success"
- title="SLOW score"
- message={`Mark countries as visited.\nTell us if you stayed longer (11, 31, 101) days, this will increase your SLOW score, each longer stay should include at least 11 days countinuous stay in a country.`}
- />
- </PageWrapper>
- );
- };
- export default CountriesScreen;
|