import { FC, useCallback, useEffect, useState } from 'react'; import { TouchableOpacity, View, Text, Image, Dimensions } from 'react-native'; import { Series, usePostGetProfileRegions } from '@api/user'; import { NavigationProp } from '@react-navigation/native'; import Modal from 'react-native-modal'; import Tooltip from 'react-native-walkthrough-tooltip'; import RegionsRenderer from '../RegionsRenderer'; import CompassIcon from 'assets/icons/travels-section/compass.svg'; import FriendsIcon from 'assets/icons/user-group.svg'; import FlagsIcon from 'assets/icons/travels-section/flags.svg'; import PhotosIcon from 'assets/icons/travels-section/images.svg'; import RegionsIcon from 'assets/icons/travels-section/regions.svg'; import SeriesIcon from 'assets/icons/travels-section/series.svg'; import WHSIcon from 'assets/icons/travels-section/whs.svg'; import ArrowIcon from 'assets/icons/next.svg'; import { styles } from './styles'; import { InfoItem } from './InfoItem'; import { Colors } from 'src/theme'; import { API_HOST } from 'src/constants'; import { NAVIGATION_PAGES } from 'src/types'; import { AvatarWithInitials, WarningModal } from 'src/components'; import { usePostFriendRequestMutation, usePostUpdateFriendStatusMutation } from '@api/friends'; import FriendStatus from './FriendStatus'; type PersonalInfoProps = { data: { bio: string; scores: { [key: string]: number | string }; homebase: string; series: Series[]; friends: { avatar: string | null; user_id: number; first_name: string; last_name: string; flag: string; }[]; firstName: string; lastName: string; friendRequestSent: 0 | 1; friendRequestReceived: 0 | 1; isFriend: 0 | 1; friendDbId: number; ownProfile: 0 | 1; }; updates: { countries: number; dare: number; friends: number; new_nm: number; photos: number; series: number; visited_regions: number; whs: number; }; userId: number; navigation: NavigationProp; isPublicView: boolean; token: string | null; }; const AVATAR_SIZE = 28; const AVATAR_MARGIN = 8; const SCREEN_PADDING_PERCENT = 0.05; export const PersonalInfo: FC = ({ data, userId, updates, navigation, isPublicView, token }) => { const [showMoreSeries, setShowMoreSeries] = useState(false); const [type, setType] = useState('nm'); const [isModalVisible, setIsModalVisible] = useState(false); const [toolTipVisible, setToolTipVisible] = useState(null); const [tooltipUser, setTooltipUser] = useState(null); const { mutateAsync: sendFriendRequest } = usePostFriendRequestMutation(); const { mutateAsync: updateFriendStatus } = usePostUpdateFriendStatusMutation(); const [friendStatus, setFriendStatus] = useState(null); const [modalInfo, setModalInfo] = useState({ type: 'friend', message: '', isVisible: false, action: () => {}, title: '' }); const { data: regions } = usePostGetProfileRegions(userId, type); useEffect(() => { if (data.isFriend === 1) { setFriendStatus(1); } else if (data.friendRequestReceived === 1) { setFriendStatus(2); } else if (data.friendRequestSent === 1) { setFriendStatus(3); } else { setFriendStatus(4); } }, [data]); const scores = [ { name: 'score_nm', score: 'NM' }, { name: 'score_mqp', score: 'DARE' }, { name: 'score_un', score: 'UN' }, { name: 'score_unp', score: 'UN+' }, { name: 'score_tcc', score: 'TCC' }, { name: 'score_deep', score: 'DEEP' }, { name: 'score_yes', score: 'YES' }, { name: 'score_slow', score: 'SLOW' }, { name: 'score_whs', score: 'WHS' }, { name: 'score_kye', score: 'KYE' } ]; const handleOpenModal = (type: string) => { switch (type) { case 'NM': setType('nm'); break; case 'DARE': setType('mqp'); break; case 'UN': setType('un'); break; case 'UN+': setType('unp'); break; case 'TCC': setType('tcc'); break; case 'SLOW': setType('slow'); break; case 'YES': setType('yes'); break; case 'WHS': setType('whs'); break; case 'KYE': setType('kye'); case 'DEEP': setType('deep'); } setIsModalVisible(true); }; const hasUpdates = () => { return ( (updates.countries && updates.countries > 0) || (updates.visited_regions && updates.visited_regions > 0) || (updates.dare && updates.dare > 0) || (updates.series && updates.series > 0) || (updates.whs && updates.whs > 0) || (updates.new_nm && updates.new_nm > 0) || (updates.photos && updates.photos > 0) || (updates.friends && updates.friends > 0) ); }; const handleSendFriendRequest = useCallback(async () => { await sendFriendRequest( { token: token as string, uid: userId }, { onSuccess: () => { setFriendStatus(3); } } ); }, [sendFriendRequest, token, userId]); const handleUpdateFriendStatus = useCallback( async (status: number) => { await updateFriendStatus( { token: token as string, id: data.friendDbId, status }, { onSuccess: () => { status === -1 || status === 2 ? setFriendStatus(4) : setFriendStatus(status); } } ); }, [updateFriendStatus, token, data.friendDbId] ); const screenWidth = Dimensions.get('window').width; const availableWidth = screenWidth * (1 - 2 * SCREEN_PADDING_PERCENT); const maxAvatars = Math.floor(availableWidth / (AVATAR_SIZE - AVATAR_MARGIN)) - 2; return ( <> {scores.map((score, index) => { let scoreRank = +data.scores[score.name] > 0 ? data.scores[score.name] : '-'; if (score.score === 'YES' && +scoreRank >= 4500) { scoreRank = '-'; } return ( handleOpenModal(score.score)} > {scoreRank} {score.score} ); })} {isPublicView && token ? ( ) : null} {data.friends.length > 0 ? ( {data.friends.slice(0, maxAvatars).map((friend, index) => ( navigation.navigate( ...([ NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW, { userId: friend.user_id } ] as never) ) } > {friend.first_name} {friend.last_name} } contentStyle={{ backgroundColor: Colors.FILL_LIGHT }} placement="top" onClose={() => setTooltipUser(null)} key={index} backgroundColor="transparent" > setTooltipUser(index)} style={{ marginLeft: index === 0 ? 0 : -AVATAR_MARGIN }} > {friend.avatar ? ( ) : ( )} ))} Only friends can see details.} contentStyle={{ backgroundColor: Colors.FILL_LIGHT, justifyContent: 'flex-end' }} placement="top" onClose={() => setTooltipUser(null)} backgroundColor="transparent" allowChildInteraction={false} > { if (friendStatus !== 1 && isPublicView) { setTooltipUser(-1); } else { data.ownProfile === 0 ? navigation.navigate( ...([ NAVIGATION_PAGES.FRIENDS_LIST, { id: userId, type: 'friends' } ] as never) ) : navigation.navigate(NAVIGATION_PAGES.MY_FRIENDS); } }} > ) : null} {hasUpdates() ? ( {updates.countries && updates.countries > 0 ? ( +{updates.countries} visited countries ) : null} {updates.visited_regions && updates.visited_regions > 0 ? ( +{updates.visited_regions} visited regions ) : null} {updates.dare && updates.dare > 0 ? ( +{updates.dare} new DARE places ) : null} {updates.series && updates.series > 0 ? ( +{updates.series} new series ) : null} {updates.whs && updates.whs > 0 ? ( +{updates.whs} new WHS sites ) : null} {updates.new_nm && updates.new_nm > 0 ? ( +{updates.new_nm} new NM regions ) : null} {updates.photos && updates.photos > 0 ? ( +{updates.photos} new photos ) : null} {updates.friends && updates.friends > 0 ? ( +{updates.friends} new friends ) : null} ) : null} {data.series?.length > 0 && ( {data.series?.slice(0, showMoreSeries ? data.series.length : 8).map((data, index) => ( {data.name}} contentStyle={{ backgroundColor: Colors.FILL_LIGHT }} placement="top" onClose={() => setToolTipVisible(null)} key={index} backgroundColor="transparent" allowChildInteraction={false} > setToolTipVisible(index)}> {data.score} ))} )} {data.series?.length > 8 ? ( setShowMoreSeries(!showMoreSeries)}> ) : null} REGION OF ORIGIN {data.homebase} {data.bio && data.bio.length > 0 && ( {data.bio} )} setIsModalVisible(false)} onBackButtonPress={() => setIsModalVisible(false)} style={styles.modal} statusBarTranslucent={true} presentationStyle="overFullScreen" > setModalInfo({ ...modalInfo, isVisible: false })} title="" /> ); };