index.tsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import React, { useEffect, useState } from 'react';
  2. import { FlatList, Text, TouchableOpacity, View } from 'react-native';
  3. import { Image } from 'expo-image';
  4. import { Header, HorizontalTabView, Loading, PageWrapper } from '../../../../components';
  5. import {
  6. getMastersByCountryOfOrigin,
  7. getMastersByType,
  8. getMastersByYearOfCompletion,
  9. getUNMastersTypes
  10. } from '../../../../database/unMastersService';
  11. import { API_HOST } from '../../../../constants';
  12. import { UNMastersListStyles } from './styles';
  13. import ArrowUpWideIcon from '../../../../../assets/icons/arrow-up-wide-short.svg';
  14. import type { Master } from '../../../../database/unMastersService';
  15. import { Colors } from '../../../../theme';
  16. import { getFontSize } from '../../../../utils';
  17. const UNMastersScreen = () => {
  18. const [index, setIndex] = useState(0);
  19. const [routes, setRoutes] = useState<{ key: string; title: string }[]>([]);
  20. const [loading, setLoading] = useState(true);
  21. useEffect(() => {
  22. const types = getUNMastersTypes();
  23. const parseRoutes = types?.map((item) => ({
  24. key: item.type.toString(),
  25. title: item.name
  26. }));
  27. setRoutes([
  28. { key: '-1', title: 'Sorted by country of origin' },
  29. { key: '-2', title: 'Sorted by year of completion' },
  30. ...(parseRoutes || [])
  31. ]);
  32. setLoading(false);
  33. }, []);
  34. if (loading) return <Loading />;
  35. return (
  36. <PageWrapper>
  37. <Header label={'UN Masters'} />
  38. <HorizontalTabView
  39. index={index}
  40. setIndex={setIndex}
  41. routes={routes}
  42. renderScene={({ route }: { route: { key: string; title: string } }) => (
  43. <UNMastersList type={route.key} />
  44. )}
  45. />
  46. </PageWrapper>
  47. );
  48. };
  49. const UNMastersList = React.memo(({ type }: { type: string }) => {
  50. const [isLoading, setIsLoading] = useState(true);
  51. const [masters, setMasters] = useState<
  52. | Master[]
  53. | { country: string; count: number; masters: Master[] }[]
  54. | { year: string; count: number; masters: Master[] }[]
  55. | null
  56. >([]);
  57. useEffect(() => {
  58. const fetchType = async () => {
  59. if (type === '-2') {
  60. const data = getMastersByYearOfCompletion();
  61. setMasters(data);
  62. } else if (type === '-1') {
  63. const data = getMastersByCountryOfOrigin();
  64. setMasters(data);
  65. } else {
  66. const data = getMastersByType(Number(type) || 1);
  67. setMasters(data);
  68. }
  69. };
  70. fetchType();
  71. setIsLoading(false);
  72. }, [type]);
  73. if (isLoading) return <Loading />;
  74. const renderItem = ({ item }: { item: any }) => {
  75. const UserItem = ({ user }: { user: Master }) => {
  76. return (
  77. <View style={UNMastersListStyles.wrapper}>
  78. <View style={{ gap: 3, marginLeft: 5 }}>
  79. <Text style={UNMastersListStyles.firstAndLastName}>{user.full_name}</Text>
  80. <View style={UNMastersListStyles.wrapper}>
  81. <Text style={UNMastersListStyles.descriptionText}>
  82. Born: {user.born} / Age when done: {user.age} /
  83. </Text>
  84. <Image
  85. style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
  86. source={{ uri: API_HOST + '/img/flags_new/' + user.origin1_flag }}
  87. />
  88. {user.origin2_flag && user.origin2_flag !== user.origin1_flag ? (
  89. <Image
  90. style={[UNMastersListStyles.countryFlag, { marginLeft: -5 }]}
  91. source={{ uri: API_HOST + '/img/flags_new/' + user.origin2_flag }}
  92. />
  93. ) : null}
  94. </View>
  95. <View style={UNMastersListStyles.wrapper}>
  96. <Text style={UNMastersListStyles.descriptionText}>
  97. Year / final country: {user.final_year}
  98. </Text>
  99. <Image
  100. style={[UNMastersListStyles.countryFlag, { marginLeft: 5 }]}
  101. source={{ uri: API_HOST + '/img/flags_new/' + user.final_flag }}
  102. />
  103. </View>
  104. </View>
  105. </View>
  106. );
  107. };
  108. const CountryItem = ({
  109. country,
  110. masters,
  111. count,
  112. flag
  113. }: {
  114. country: string;
  115. masters: Master[];
  116. count: number;
  117. flag: string;
  118. }) => {
  119. if (masters.length === 0) return;
  120. return (
  121. <View style={UNMastersListStyles.countryAndYearItemWrapper}>
  122. <View style={UNMastersListStyles.countryAndYearHeader}>
  123. <Image source={{ uri: API_HOST + flag }} style={{ width: 24, height: 16 }} />
  124. <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
  125. {country} ({count})
  126. </Text>
  127. </View>
  128. <FlatList
  129. contentContainerStyle={{ gap: 10 }}
  130. horizontal={false}
  131. showsVerticalScrollIndicator={false}
  132. data={masters}
  133. renderItem={({ item }) => <UserItem user={item} />}
  134. />
  135. </View>
  136. );
  137. };
  138. const YearItem = ({
  139. year,
  140. masters,
  141. count
  142. }: {
  143. year: string;
  144. masters: Master[];
  145. count: number;
  146. }) => {
  147. return (
  148. <View style={UNMastersListStyles.countryAndYearItemWrapper}>
  149. <View style={UNMastersListStyles.countryAndYearHeader}>
  150. <Text style={{ color: Colors.DARK_BLUE, fontSize: getFontSize(18), fontWeight: '700' }}>
  151. {year} ({count})
  152. </Text>
  153. </View>
  154. <FlatList
  155. contentContainerStyle={{ gap: 10 }}
  156. horizontal={false}
  157. showsVerticalScrollIndicator={false}
  158. data={masters}
  159. renderItem={({ item }) => <UserItem user={item} />}
  160. />
  161. </View>
  162. );
  163. };
  164. return type !== '-2' ? (
  165. type !== '-1' ? (
  166. <UserItem user={item as Master} />
  167. ) : (
  168. <CountryItem
  169. country={item.country}
  170. masters={item.masters}
  171. count={item.count}
  172. flag={item.flag}
  173. />
  174. )
  175. ) : (
  176. <YearItem year={item.year} masters={item.masters} count={item.count} />
  177. );
  178. };
  179. return (
  180. <FlatList
  181. contentContainerStyle={{ gap: 10 }}
  182. horizontal={false}
  183. data={masters}
  184. renderItem={renderItem}
  185. showsVerticalScrollIndicator={false}
  186. />
  187. );
  188. });
  189. export default UNMastersScreen;