index.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import React, { useState } from 'react';
  2. import { View, Text, TouchableOpacity, Image } from 'react-native';
  3. import { useNavigation } from '@react-navigation/native';
  4. import moment from 'moment';
  5. import { TripsData } from '../../utils/types';
  6. import { API_HOST } from 'src/constants';
  7. import { Colors } from 'src/theme';
  8. import { NAVIGATION_PAGES } from 'src/types';
  9. import { styles } from './styles';
  10. import CalendarIcon from 'assets/icons/travels-screens/calendar.svg';
  11. import EditIcon from 'assets/icons/travels-screens/pen-to-square.svg';
  12. import ArrowIcon from 'assets/icons/chevron-left.svg';
  13. import WarningIcon from 'assets/icons/warning.svg';
  14. const TripItem = ({ item, isNew }: { item: TripsData; isNew?: boolean }) => {
  15. const navigation = useNavigation();
  16. const [showAllRegions, setShowAllRegions] = useState(false);
  17. const formatDate = (dateString: string) => {
  18. const date = moment(dateString);
  19. const formattedDate = date.format('MMM DD');
  20. const year = date.format('YYYY');
  21. return (
  22. <Text style={styles.alignCenter}>
  23. <Text style={styles.tripDateText}>{formattedDate}</Text>
  24. {'\n'}
  25. <Text style={styles.tripDateText}>{year}</Text>
  26. </Text>
  27. );
  28. };
  29. const MAX_VISIBLE_REGIONS = 3;
  30. const totalRegions = item.regions?.length || 0;
  31. const visibleRegions = showAllRegions
  32. ? item.regions
  33. : item.regions?.slice(0, MAX_VISIBLE_REGIONS);
  34. return (
  35. <View style={styles.tripItemContainer}>
  36. {isNew && item.dates_missing === 1 ? (
  37. <View style={{ flexDirection: 'row', gap: 6, alignItems: 'center', marginBottom: 10 }}>
  38. <WarningIcon color={Colors.RED} width={16} height={16} />
  39. <Text style={{ fontSize: 14, fontWeight: '600', color: Colors.RED }}>
  40. Fill in exact dates.
  41. </Text>
  42. </View>
  43. ) : null}
  44. <View style={styles.tripHeaderContainer}>
  45. <View style={styles.tripDateContainer}>
  46. <CalendarIcon fill={Colors.DARK_BLUE} />
  47. <Text style={[styles.tripDateText, { marginLeft: 8 }]}>{formatDate(item.date_from)}</Text>
  48. <Text style={styles.tripDateText}>-</Text>
  49. <Text style={styles.tripDateText}>{formatDate(item.date_to)}</Text>
  50. </View>
  51. <TouchableOpacity
  52. style={styles.editButton}
  53. onPress={() =>
  54. navigation.navigate(
  55. ...([NAVIGATION_PAGES.ADD_TRIP_2025, { editTripId: item.id }] as never)
  56. )
  57. }
  58. >
  59. <EditIcon />
  60. <Text style={styles.editButtonText}>Edit</Text>
  61. </TouchableOpacity>
  62. </View>
  63. <View style={styles.divider} />
  64. {item.description && (
  65. <>
  66. <Text style={styles.descriptionTitle}>Description</Text>
  67. <Text style={styles.descriptionText}>{item.description}</Text>
  68. </>
  69. )}
  70. <Text style={styles.visitedRegionsTitle}>Visited regions</Text>
  71. <View style={styles.regionsContainer}>
  72. {visibleRegions?.map((region, index) => {
  73. if (!region.id || !region.region_name) return null;
  74. const [name, ...rest] = region.region_name?.split(/ – | - /);
  75. const subname = rest?.join(' - ');
  76. return (
  77. <View key={`${region.id}-${index}`} style={styles.regionItem}>
  78. <Image source={{ uri: API_HOST + region.flag1 }} style={styles.flagIcon} />
  79. {region.flag2 && (
  80. <Image
  81. source={{ uri: API_HOST + region.flag2 }}
  82. style={[styles.flagIcon, { marginLeft: -5 }]}
  83. />
  84. )}
  85. <View style={styles.nameContainer}>
  86. <Text style={styles.regionName}>{name}</Text>
  87. <Text style={styles.regionSubname}>{subname}</Text>
  88. </View>
  89. </View>
  90. );
  91. })}
  92. </View>
  93. {totalRegions > MAX_VISIBLE_REGIONS && (
  94. <TouchableOpacity
  95. style={styles.showMoreButton}
  96. hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
  97. onPress={() => setShowAllRegions(!showAllRegions)}
  98. >
  99. <ArrowIcon
  100. fill={Colors.DARK_BLUE}
  101. style={[styles.headerIcon, showAllRegions ? styles.rotate : null]}
  102. />
  103. <Text style={styles.showMoreText}>
  104. {showAllRegions ? 'Show less' : `Show more (${totalRegions - MAX_VISIBLE_REGIONS})`}
  105. </Text>
  106. </TouchableOpacity>
  107. )}
  108. </View>
  109. );
  110. };
  111. export default TripItem;