|
@@ -0,0 +1,204 @@
|
|
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
|
+import { View, Text, TouchableOpacity, ScrollView, FlatList } from 'react-native';
|
|
|
+import ReactModal from 'react-native-modal';
|
|
|
+import * as Progress from 'react-native-progress';
|
|
|
+
|
|
|
+import CountryItem from '../Components/CountryItem';
|
|
|
+import EditModal from '../Components/EditSlowModal';
|
|
|
+import { Header, 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';
|
|
|
+
|
|
|
+const CountriesScreen = () => {
|
|
|
+ const token = storage.get('token', StoreType.STRING) as string;
|
|
|
+ const { data } = useGetSlowQuery(token, true);
|
|
|
+ const { mutate: updateSlow } = usePostSetSlowMutation();
|
|
|
+ const [slow, setSlow] = useState<SlowData[] | null>(null);
|
|
|
+ const [megaSelectorVisible, setMegaSelectorVisible] = useState(false);
|
|
|
+ const [selectedMega, setSelectedMega] = useState<{ name: string; id: number }>({
|
|
|
+ name: 'ALL',
|
|
|
+ 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 handleOpenEditModal = (item: SlowData) => {
|
|
|
+ setCurrentItem(item);
|
|
|
+ setIsEditModalVisible(true);
|
|
|
+ };
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (slow && slow.length) {
|
|
|
+ calcTotalScore();
|
|
|
+ }
|
|
|
+ }, [slow]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (data && data.result === 'OK') {
|
|
|
+ if (selectedMega.id === -1) {
|
|
|
+ setSlow(data?.slow);
|
|
|
+ } else {
|
|
|
+ setSlow(data?.slow?.filter((item) => item.mega.includes(selectedMega.id)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [selectedMega, data]);
|
|
|
+
|
|
|
+ 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 handleUpdateSlow = 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: Number(s11) as 0 | 1,
|
|
|
+ slow31: Number(s31) as 0 | 1,
|
|
|
+ slow101: Number(s101) as 0 | 1
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+
|
|
|
+ const updatedSlowData = {
|
|
|
+ token,
|
|
|
+ id,
|
|
|
+ v,
|
|
|
+ s11,
|
|
|
+ s31,
|
|
|
+ s101
|
|
|
+ };
|
|
|
+
|
|
|
+ updateSlow(updatedSlowData);
|
|
|
+ updatedSlow && setSlow(updatedSlow);
|
|
|
+ },
|
|
|
+ [slow]
|
|
|
+ );
|
|
|
+
|
|
|
+ const renderCountryItem = ({ item }: { item: SlowData }) => (
|
|
|
+ <CountryItem item={item} updateSlow={handleUpdateSlow} openEditModal={handleOpenEditModal} />
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <PageWrapper>
|
|
|
+ <Header label="Countries" />
|
|
|
+ <TouchableOpacity style={styles.megaSelector} onPress={() => setMegaSelectorVisible(true)}>
|
|
|
+ <Text style={styles.megaButtonText}>{selectedMega.name}</Text>
|
|
|
+ <ChevronIcon width={18} height={18} />
|
|
|
+ </TouchableOpacity>
|
|
|
+
|
|
|
+ <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}%`
|
|
|
+ : '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.DARK_LIGHT}
|
|
|
+ />
|
|
|
+
|
|
|
+ <View style={styles.slowScoreSection}>
|
|
|
+ <Text style={styles.visitedCountriesCount}>
|
|
|
+ SLOW score: {slow?.length ? total.slow : 0}
|
|
|
+ </Text>
|
|
|
+ <TouchableOpacity style={styles.infoBtn} onPress={() => setInfoModalVisible(true)}>
|
|
|
+ <IngoSvg />
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ {slow && (
|
|
|
+ <FlatList
|
|
|
+ data={slow}
|
|
|
+ renderItem={renderCountryItem}
|
|
|
+ keyExtractor={(item) => item.country_id.toString()}
|
|
|
+ showsVerticalScrollIndicator={false}
|
|
|
+ style={{ paddingTop: 8 }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+
|
|
|
+ <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', id: -1 });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Text style={styles.btnOptionText}>ALL</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 (7, 31, 101) days, this will increase your SLOW score, each longer stay should include at least 7 days countinuous stay in a country.`}
|
|
|
+ />
|
|
|
+ </PageWrapper>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default CountriesScreen;
|