index.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { useEffect, useRef } from 'react';
  2. import {
  3. Text,
  4. TouchableOpacity,
  5. View,
  6. Image,
  7. Animated
  8. } from 'react-native';
  9. import { styles } from './style';
  10. interface Region {
  11. id: number;
  12. name: string;
  13. region_photos: string;
  14. visitors_count: number;
  15. }
  16. interface RegionPopupProps {
  17. region: Region;
  18. userAvatars: string[];
  19. onMarkVisited: () => void;
  20. }
  21. const RegionPopup: React.FC<RegionPopupProps> = ({ region, userAvatars, onMarkVisited }) => {
  22. const fadeAnim = useRef(new Animated.Value(0)).current;
  23. useEffect(() => {
  24. Animated.timing(fadeAnim, {
  25. toValue: 1,
  26. duration: 300,
  27. useNativeDriver: true,
  28. }).start();
  29. }, [fadeAnim]);
  30. const splitRegionName = (fullName: string) => {
  31. const parts = fullName.split(/ – | - /);
  32. return {
  33. regionTitle: parts[0],
  34. regionSubtitle: parts.length > 1 ? parts[1] : '',
  35. };
  36. };
  37. const { regionTitle, regionSubtitle } = splitRegionName(region.name);
  38. const regionImg = JSON.parse(region.region_photos)[0];
  39. function formatNumber(number: number) {
  40. if (number >= 1000) {
  41. return (number / 1000).toFixed(1) + 'k';
  42. }
  43. return number.toString();
  44. }
  45. const formattedCount = formatNumber(region.visitors_count);
  46. return (
  47. <Animated.View style={[styles.popupContainer, {opacity: fadeAnim}]}>
  48. <View style={styles.regionInfoContainer}>
  49. {regionImg && (
  50. <Image source={{ uri: regionImg}} style={styles.regionImage} />
  51. )}
  52. <View style={styles.regionTextContainer}>
  53. <Text style={styles.regionTitle}>{regionTitle}</Text>
  54. <Text style={styles.regionSubtitle}>{regionSubtitle}</Text>
  55. </View>
  56. </View>
  57. <View style={styles.separator} />
  58. <View style={styles.bottomContainer}>
  59. <View style={styles.userContainer}>
  60. <View style={styles.userImageContainer}>
  61. {userAvatars?.map((avatar, index) => (
  62. <Image
  63. key={index}
  64. source={{ uri: avatar }}
  65. style={styles.userImage}
  66. />
  67. ))}
  68. <View style={styles.userCountContainer}>
  69. <Text style={styles.userCount}>
  70. {formattedCount}
  71. </Text>
  72. </View>
  73. </View>
  74. </View>
  75. <TouchableOpacity style={styles.markVisitedButton} onPress={onMarkVisited}>
  76. <Text style={styles.markVisitedText}>
  77. Mark Visited
  78. </Text>
  79. </TouchableOpacity>
  80. </View>
  81. </Animated.View>
  82. );
  83. };
  84. export default RegionPopup;