Application Android et IOS pour l'amicale des élèves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VoteResults.tsx 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import * as React from 'react';
  20. import {
  21. Avatar,
  22. Card,
  23. List,
  24. ProgressBar,
  25. Subheading,
  26. withTheme,
  27. } from 'react-native-paper';
  28. import {FlatList, StyleSheet} from 'react-native';
  29. import i18n from 'i18n-js';
  30. import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen';
  31. type PropsType = {
  32. teams: Array<VoteTeamType>;
  33. dateEnd: string;
  34. theme: ReactNativePaper.Theme;
  35. };
  36. const styles = StyleSheet.create({
  37. card: {
  38. margin: 10,
  39. },
  40. icon: {
  41. backgroundColor: 'transparent',
  42. },
  43. });
  44. class VoteResults extends React.Component<PropsType> {
  45. totalVotes: number;
  46. winnerIds: Array<number>;
  47. constructor(props: PropsType) {
  48. super(props);
  49. props.teams.sort(this.sortByVotes);
  50. this.totalVotes = this.getTotalVotes(props.teams);
  51. this.winnerIds = this.getWinnerIds(props.teams);
  52. }
  53. shouldComponentUpdate(): boolean {
  54. return false;
  55. }
  56. getTotalVotes(teams: Array<VoteTeamType>) {
  57. let totalVotes = 0;
  58. for (let i = 0; i < teams.length; i += 1) {
  59. totalVotes += teams[i].votes;
  60. }
  61. return totalVotes;
  62. }
  63. getWinnerIds(teams: Array<VoteTeamType>) {
  64. const max = teams[0].votes;
  65. let winnerIds = [];
  66. for (let i = 0; i < teams.length; i += 1) {
  67. if (teams[i].votes === max) {
  68. winnerIds.push(teams[i].id);
  69. } else {
  70. break;
  71. }
  72. }
  73. return winnerIds;
  74. }
  75. sortByVotes = (a: VoteTeamType, b: VoteTeamType): number => b.votes - a.votes;
  76. voteKeyExtractor = (item: VoteTeamType): string => item.id.toString();
  77. resultRenderItem = ({item}: {item: VoteTeamType}) => {
  78. const isWinner = this.winnerIds.indexOf(item.id) !== -1;
  79. const isDraw = this.winnerIds.length > 1;
  80. const {props} = this;
  81. return (
  82. <Card
  83. style={{
  84. marginTop: 10,
  85. elevation: isWinner ? 5 : 3,
  86. }}>
  87. <List.Item
  88. title={item.name}
  89. description={`${item.votes} ${i18n.t('screens.vote.results.votes')}`}
  90. left={(iconProps) =>
  91. isWinner ? (
  92. <List.Icon
  93. style={iconProps.style}
  94. icon={isDraw ? 'trophy-outline' : 'trophy'}
  95. color={props.theme.colors.primary}
  96. />
  97. ) : null
  98. }
  99. titleStyle={{
  100. color: isWinner
  101. ? props.theme.colors.primary
  102. : props.theme.colors.text,
  103. }}
  104. style={{padding: 0}}
  105. />
  106. <ProgressBar
  107. progress={item.votes / this.totalVotes}
  108. color={props.theme.colors.primary}
  109. />
  110. </Card>
  111. );
  112. };
  113. render() {
  114. const {props} = this;
  115. return (
  116. <Card style={styles.card}>
  117. <Card.Title
  118. title={i18n.t('screens.vote.results.title')}
  119. subtitle={`${i18n.t('screens.vote.results.subtitle')} ${
  120. props.dateEnd
  121. }`}
  122. left={(iconProps) => (
  123. <Avatar.Icon size={iconProps.size} icon="podium-gold" />
  124. )}
  125. />
  126. <Card.Content>
  127. <Subheading>
  128. {`${i18n.t('screens.vote.results.totalVotes')} ${this.totalVotes}`}
  129. </Subheading>
  130. <FlatList
  131. data={props.teams}
  132. keyExtractor={this.voteKeyExtractor}
  133. renderItem={this.resultRenderItem}
  134. />
  135. </Card.Content>
  136. </Card>
  137. );
  138. }
  139. }
  140. export default withTheme(VoteResults);