123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- import { useEffect, useRef } from 'react';
- import { Text, TouchableOpacity, View, StyleSheet, Image, Animated } from 'react-native';
- interface Region {
- id: number;
- name: string;
- region_photos: string;
- visitors_count: number;
- }
- interface RegionPopupProps {
- region: Region;
- userAvatars: string[];
- onMarkVisited: () => void;
- }
- const RegionPopup: React.FC<RegionPopupProps> = ({ region, userAvatars, onMarkVisited }) => {
- const fadeAnim = useRef(new Animated.Value(0)).current;
- useEffect(() => {
- Animated.timing(fadeAnim, {
- toValue: 1,
- duration: 300,
- useNativeDriver: true,
- }).start();
- }, [fadeAnim]);
-
- const splitRegionName = (fullName: string) => {
- const parts = fullName.split(/ – | - /);
- return {
- regionTitle: parts[0],
- regionSubtitle: parts.length > 1 ? parts[1] : '',
- };
- };
- const { regionTitle, regionSubtitle } = splitRegionName(region.name);
- const regionImg = JSON.parse(region.region_photos)[0];
- function formatNumber(number: number) {
- if (number >= 1000) {
- return (number / 1000).toFixed(1) + 'k';
- }
- return number.toString();
- }
-
- const formattedCount = formatNumber(region.visitors_count);
- return (
- <Animated.View style={[styles.popupContainer, {opacity: fadeAnim}]}>
- <View style={styles.regionInfoContainer}>
- {regionImg && (
- <Image source={{ uri: regionImg}} style={styles.regionImage} />
- )}
- <View style={styles.regionTextContainer}>
- <Text style={styles.regionTitle}>{regionTitle}</Text>
- <Text style={styles.regionSubtitle}>{regionSubtitle}</Text>
- </View>
- </View>
- <View style={styles.separator} />
- <View style={styles.bottomContainer}>
- <View style={styles.userContainer}>
- <View style={styles.userImageContainer}>
- {userAvatars?.map((avatar, index) => (
- <Image key={index} source={{ uri: avatar }} style={styles.userImage} />
- ))}
- <View style={styles.userCountContainer}>
- <Text style={styles.userCount}>{formattedCount}</Text>
- </View>
- </View>
- </View>
- <TouchableOpacity style={styles.markVisitedButton} onPress={onMarkVisited}>
- <Text style={styles.markVisitedText}>Mark Visited</Text>
- </TouchableOpacity>
- </View>
- </Animated.View>
- );
- };
- export default RegionPopup;
- const styles = StyleSheet.create({
- popupContainer: {
- position: 'absolute',
- bottom: 22,
- left: 0,
- right: 0,
- backgroundColor: 'white',
- padding: 16,
- borderRadius: 8,
- alignItems: 'center',
- justifyContent: 'center',
- height: 152,
- marginHorizontal: 24,
- shadowColor: 'rgba(33, 37, 41, 0.12)',
- shadowOffset: { width: 0, height: 4 },
- shadowRadius: 8,
- elevation: 5,
- zIndex: 2,
- },
- regionInfoContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'flex-start',
- width: '100%',
- },
- regionImage: {
- width: 60,
- height: 60,
- borderRadius: 6,
- marginRight: 10,
- },
- regionTextContainer: {
- justifyContent: 'center',
- flex: 1,
- },
- regionTitle: {
- fontSize: 16,
- fontWeight: 'bold',
- color: '#0F3F4F'
- },
- regionSubtitle: {
- fontSize: 13,
- color: '#3E6471',
- },
- separator: {
- borderBottomWidth: 1,
- borderBottomColor: '#E5E5E5',
- width: '100%',
- marginVertical: 16,
- },
- bottomContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- width: '100%',
- },
- userContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- marginLeft: 6,
- },
- userImageContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- marginRight: 10,
- },
- userImage: {
- width: 28,
- height: 28,
- borderRadius: 14,
- marginLeft: -6,
- borderWidth: 1,
- borderColor: '#E6E6E6',
- resizeMode: 'cover',
- },
- userCountContainer: {
- width: 28,
- height: 28,
- borderRadius: 14,
- backgroundColor: '#E5E5E5',
- alignItems: 'center',
- justifyContent: 'center',
- marginLeft: -6,
- },
- userCount: {
- fontSize: 12,
- color: '#0F3F4F',
- lineHeight: 24,
- },
- markVisitedButton: {
- backgroundColor: '#ED9334',
- paddingHorizontal: 12,
- paddingVertical: 8,
- borderRadius: 6,
- alignItems: 'center',
- justifyContent: 'center',
- height: 32,
- },
- markVisitedText: {
- fontSize: 12,
- color: 'white',
- fontWeight: '700',
- letterSpacing: 0.01,
- lineHeight: 16,
- },
- });
|