123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- import React, { FC, useState } from 'react';
- import { Text, TouchableOpacity, View } from 'react-native';
- import { Image } from 'expo-image';
- import { useNavigation } from '@react-navigation/native';
- import * as FileSystem from 'expo-file-system';
- import { ProfileStyles, ScoreStyles, TBTStyles } from './styles';
- import { storage, StoreType } from 'src/storage';
- import { AvatarWithInitials, WarningModal } from 'src/components';
- import { API_HOST } from '../../../../constants';
- import { getFontSize } from '../../../../utils';
- import { adaptiveStyle, Colors } from '../../../../theme';
- import TickIcon from '../../../../../assets/icons/tick.svg';
- import UNIcon from '../../../../../assets/icons/un_icon.svg';
- import NMIcon from '../../../../../assets/icons/nm_icon.svg';
- import TBTIcon from '../../../../../assets/icons/tbt.svg';
- import { NAVIGATION_PAGES } from '../../../../types';
- import { useConnection } from 'src/contexts/ConnectionContext';
- import Tooltip from 'react-native-walkthrough-tooltip';
- type Props = {
- avatar: string | null;
- first_name: string;
- last_name: string;
- date_of_birth: number;
- homebase_flag: string;
- homebase2_flag: string | null;
- index: number;
- score: any[];
- active_score: number;
- tbt_score?: number;
- tbt_rank?: number;
- badge_tbt?: number;
- badge_1281: number;
- badge_un: number;
- auth: number;
- userId: number;
- };
- //TODO: Profile
- export const Profile: FC<Props> = ({
- avatar,
- first_name,
- last_name,
- date_of_birth,
- homebase_flag,
- homebase2_flag,
- index,
- score,
- active_score,
- tbt_rank,
- badge_tbt,
- badge_1281,
- badge_un,
- auth,
- userId
- }) => {
- const navigation = useNavigation();
- const scoreNames = ['NM', 'DARE', 'UN', 'UN+', 'TCC', 'DEEP', 'YES', 'SLOW', 'WHS', 'KYE'];
- const netInfo = useConnection();
- const token = storage.get('token', StoreType.STRING);
- const [modalType, setModalType] = useState<string | null>(null);
- const [toolTipVisible, setToolTipVisible] = useState<number | string | null>(null);
- const handlePress = () => {
- if (!netInfo?.isInternetReachable) {
- setModalType('offline');
- } else if (!token) {
- setModalType('unauthorized');
- } else {
- navigation.navigate(...([NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId }] as never));
- }
- };
- const avatarBaseUri = netInfo?.isInternetReachable
- ? `${API_HOST}/img/avatars/`
- : `${FileSystem.documentDirectory}avatars/`;
- const flagBaseUri = netInfo?.isInternetReachable
- ? `${API_HOST}/img/flags_new/`
- : `${FileSystem.documentDirectory}flags/`;
- const TBRanking = () => {
- const colors = [
- 'rgba(237, 147, 52, 1)',
- 'rgba(128, 128, 128, 1)',
- 'rgba(211, 211, 211, 1)',
- 'rgba(187, 95, 5, 1)',
- '#808080'
- ];
- const Rank = ({ color }: { color: string }) => (
- <View style={adaptiveStyle([ProfileStyles.badge, { backgroundColor: color }], {})}>
- <TBTIcon />
- </View>
- );
- return (
- <Tooltip
- isVisible={toolTipVisible === 'TBT'}
- content={<Text style={{ color: Colors.DARK_BLUE }}>{handleGetTooltip('TBT')}</Text>}
- contentStyle={{ backgroundColor: Colors.WHITE }}
- placement="top"
- onClose={() => setToolTipVisible(null)}
- backgroundColor="transparent"
- allowChildInteraction={false}
- parentWrapperStyle={adaptiveStyle(TBTStyles.badgeRoot, {})}
- >
- <TouchableOpacity
- style={{ flex: 1 }}
- disabled={!tbt_rank || tbt_rank < 1}
- onPress={() => setToolTipVisible('TBT')}
- >
- <View style={adaptiveStyle(TBTStyles.badgeWrapper, {})}>
- {badge_tbt && tbt_rank ? (
- <Rank color={colors[tbt_rank - 1]} />
- ) : (
- <View style={adaptiveStyle(ProfileStyles.badge, {})} />
- )}
- {tbt_rank && tbt_rank >= 1 ? (
- <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>TBT # {tbt_rank}</Text>
- ) : (
- <View style={{ height: 11 }} />
- )}
- </View>
- </TouchableOpacity>
- </Tooltip>
- );
- };
- const EmptyScore: FC<{ scoreName: string; index: number }> = ({ scoreName, index }) => {
- return (
- <Tooltip
- isVisible={toolTipVisible === index}
- content={<Text style={{ color: Colors.DARK_BLUE }}>{handleGetTooltip(scoreName)}</Text>}
- contentStyle={{ backgroundColor: Colors.WHITE }}
- placement="top"
- onClose={() => setToolTipVisible(null)}
- backgroundColor="transparent"
- allowChildInteraction={false}
- parentWrapperStyle={adaptiveStyle(ScoreStyles.scoreWrapper, {})}
- >
- <TouchableOpacity onPress={() => setToolTipVisible(index)}>
- <Text style={adaptiveStyle([ScoreStyles.scoreHeaderText], {})}>-</Text>
- <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>{scoreName}</Text>
- </TouchableOpacity>
- </Tooltip>
- );
- };
- const handleGetTooltip = (score: string) => {
- switch (score) {
- case 'NM':
- return 'NM list of regions';
- case 'DARE':
- return (
- <Text>
- <Text style={{ fontWeight: '700' }}>D</Text>istinctive{' '}
- <Text style={{ fontWeight: '700' }}>A</Text>lternative{' '}
- <Text style={{ fontWeight: '700' }}>R</Text>emote{' '}
- <Text style={{ fontWeight: '700' }}>E</Text>
- xtreme places
- </Text>
- );
- case 'UN':
- return 'UN countries';
- case 'UN+':
- return 'UN countries and territories';
- case 'TCC':
- return (
- <Text>
- <Text style={{ fontStyle: 'italic' }}>Travelers’ Century Club</Text> list
- </Text>
- );
- case 'DEEP':
- return (
- <Text>
- <Text style={{ fontWeight: '700' }}>D</Text>efinite{' '}
- <Text style={{ fontWeight: '700' }}>E</Text>xhaustive{'\n'}
- <Text style={{ fontWeight: '700' }}>E</Text>xploring{' '}
- <Text style={{ fontWeight: '700' }}>P</Text>
- roportion{'\n'}NM regions to UN countries ratio{'\n'}
- <Text style={{ fontSize: 11 }}>
- For travellers with minimum 30 UN countries visited.
- </Text>
- </Text>
- );
- case 'YES':
- return 'Years Elapsed Since list';
- case 'SLOW':
- return 'SLOW travel list';
- case 'WHS':
- return 'World Heritage Sites';
- case 'KYE':
- return 'Know Your Earth geographic based list';
- case 'TBT':
- return 'The Biggest Travellers based on all rankings';
- }
- return score;
- };
- return (
- <View style={ProfileStyles.wrapper}>
- <View
- style={[
- ProfileStyles.index,
- {
- width: index + 1 < 100 ? 26 : 38
- }
- ]}
- >
- <Text style={adaptiveStyle(ScoreStyles.rankText, {})}>{index + 1}</Text>
- </View>
- <View style={{ flex: 1, paddingLeft: 8, paddingRight: 3, paddingBottom: 3 }}>
- <TouchableOpacity onPress={() => handlePress()}>
- <View style={adaptiveStyle(ProfileStyles.profileRoot, {})}>
- <View style={ProfileStyles.avatarContainer}>
- {avatar ? (
- <Image
- style={adaptiveStyle(ProfileStyles.profileAvatar, {})}
- source={{ uri: avatarBaseUri + avatar }}
- />
- ) : homebase_flag ? (
- <AvatarWithInitials
- text={`${first_name[0] ?? ''}${last_name[0] ?? ''}`}
- flag={flagBaseUri + homebase_flag}
- size={48}
- />
- ) : null}
- </View>
- <View style={adaptiveStyle(ProfileStyles.profileDataRoot, {})}>
- <Text
- style={adaptiveStyle(
- [ProfileStyles.profileFirstLastName, { fontSize: getFontSize(14), flex: 0 }],
- {}
- )}
- >
- {first_name ?? ''} {last_name ?? ''}
- </Text>
- <View style={adaptiveStyle(ProfileStyles.profileDataContainer, {})}>
- <View style={adaptiveStyle(ProfileStyles.profileDataWrapper, {})}>
- <Text style={adaptiveStyle(ProfileStyles.profileAge, {})}>
- Age: {date_of_birth ?? ''}
- </Text>
- {homebase_flag && (
- <Image
- source={{ uri: flagBaseUri + homebase_flag }}
- style={adaptiveStyle(ProfileStyles.countryFlag, {})}
- />
- )}
- {homebase2_flag && homebase2_flag !== homebase_flag ? (
- <Image
- source={{ uri: flagBaseUri + homebase2_flag }}
- style={adaptiveStyle([ProfileStyles.countryFlag, { marginLeft: -15 }], {})}
- />
- ) : null}
- <View style={adaptiveStyle(ProfileStyles.badgesWrapper, {})}>
- {auth ? <TickIcon /> : null}
- {badge_un ? <UNIcon /> : null}
- {badge_1281 ? <NMIcon /> : null}
- </View>
- </View>
- </View>
- </View>
- </View>
- </TouchableOpacity>
- <View style={adaptiveStyle(ScoreStyles.rankingWrapper, {})}>
- <View style={adaptiveStyle(ScoreStyles.nmWrapper, {})}>
- <View style={ScoreStyles.score}>
- <Text style={adaptiveStyle(ScoreStyles.activeScoreRanking, {})}>
- {score[active_score]}
- </Text>
- <Text style={adaptiveStyle(ScoreStyles.activeScoreName, {})}>
- {scoreNames[active_score]}
- </Text>
- </View>
- <TBRanking />
- </View>
- <View style={adaptiveStyle(ScoreStyles.rankingScoresWrapper, {})}>
- {score.map((number, index) => {
- if (scoreNames[index] === 'SLOW' && number >= 4500)
- return <EmptyScore key={index} scoreName={scoreNames[index]} index={index} />;
- if (scoreNames[index] === 'YES' && number >= 10000)
- return <EmptyScore key={index} scoreName={scoreNames[index]} index={index} />;
- if (!number)
- return <EmptyScore key={index} scoreName={scoreNames[index]} index={index} />;
- return (
- <Tooltip
- isVisible={toolTipVisible === index}
- content={
- <Text style={{ color: Colors.DARK_BLUE }}>
- {handleGetTooltip(scoreNames[index])}
- </Text>
- }
- contentStyle={{ backgroundColor: Colors.WHITE }}
- placement="top"
- onClose={() => setToolTipVisible(null)}
- backgroundColor="transparent"
- allowChildInteraction={false}
- key={index}
- parentWrapperStyle={adaptiveStyle(ScoreStyles.scoreWrapper, {})}
- >
- <TouchableOpacity onPress={() => setToolTipVisible(index)}>
- <Text style={adaptiveStyle([ScoreStyles.scoreHeaderText], {})}>{number}</Text>
- <Text style={adaptiveStyle([ScoreStyles.scoreNameText], {})}>
- {scoreNames[index]}
- </Text>
- </TouchableOpacity>
- </Tooltip>
- );
- })}
- </View>
- </View>
- </View>
- {modalType && (
- <WarningModal type={modalType} isVisible={true} onClose={() => setModalType(null)} />
- )}
- </View>
- );
- };
|