// @flow import * as React from 'react'; import {FlatList, StyleSheet, View} from "react-native"; import { ActivityIndicator, Avatar, Button, Card, List, Paragraph, ProgressBar, RadioButton, Subheading, withTheme } from 'react-native-paper'; import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen"; import {getTimeOnlyString, stringToDate} from "../../utils/Planning"; import LoadingConfirmDialog from "../../components/Dialog/LoadingConfirmDialog"; import ConnectionManager from "../../managers/ConnectionManager"; import ErrorDialog from "../../components/Dialog/ErrorDialog"; const ICON_AMICALE = require('../../../assets/amicale.png'); const FAKE_DATE = { "date_begin": "2020-04-06 21:50", "date_end": "2020-04-07 23:50", "date_result_begin": "2020-04-07 21:50", "date_result_end": "2020-04-07 21:50", }; const FAKE_DATE2 = { "date_begin": null, "date_end": null, "date_result_begin": null, "date_result_end": null, }; const FAKE_TEAMS = { has_voted: false, teams: [ { id: 1, name: "TEST TEAM1", }, { id: 2, name: "TEST TEAM2", }, ], }; const FAKE_TEAMS2 = { has_voted: false, teams: [ { id: 1, name: "TEST TEAM1", votes: 1, }, { id: 2, name: "TEST TEAM2", votes: 9, }, ], }; type Props = { navigation: Object, theme: Object, } type State = { selectedTeam: string, hasVoted: boolean, voteDialogVisible: boolean, errorDialogVisible: boolean, currentError: number, } class VoteScreen extends React.Component { state = { selectedTeam: "none", voteDialogVisible: false, errorDialogVisible: false, currentError: 0, hasVoted: false, }; colors: Object; teams: Array; hasVoted: boolean; datesString: Object; dates: Object; today: Date; mainFlatListData: Array; totalVotes: number; authRef: Object; constructor(props) { super(props); this.colors = props.theme.colors; this.hasVoted = false; this.today = new Date(); this.authRef = React.createRef(); this.mainFlatListData = [ {key: 'main'}, {key: 'info'}, ] } reloadData = () => this.authRef.current.reload(); generateDateObject() { this.dates = { date_begin: stringToDate(this.datesString.date_begin), date_end: stringToDate(this.datesString.date_end), date_result_begin: stringToDate(this.datesString.date_result_begin), date_result_end: stringToDate(this.datesString.date_result_end), }; } getDateString(date: Date, dateString: string) { if (this.today.getDate() === date.getDate()) return getTimeOnlyString(dateString); else return dateString; } isVoteAvailable() { return this.dates.date_begin !== null; } isVoteRunning() { return this.today > this.dates.date_begin && this.today < this.dates.date_end; } isVoteStarted() { return this.today > this.dates.date_begin; } isResultRunning() { return this.today > this.dates.date_result_begin && this.today < this.dates.date_result_end; } isResultStarted() { return this.today > this.dates.date_result_begin; } mainRenderItem = ({item}: Object) => { if (item.key === 'info') return this.getTitleCard(); else if (item.key === 'main' && this.isVoteAvailable()) return this.getContent(); else return null; }; getScreen = (data: Array) => { data[0] = FAKE_TEAMS2; data[1] = FAKE_DATE; if (data[0] !== null) { this.teams = data[0].teams; this.hasVoted = data[0].has_voted; } this.datesString = data[1]; this.generateDateObject(); return ( {/*$FlowFixMe*/} ); }; showVoteDialog = () => this.setState({voteDialogVisible: true}); onVoteDialogDismiss = (voteStatus: boolean) => { voteStatus = voteStatus === undefined ? false : voteStatus; this.setState({ voteDialogVisible: false, hasVoted: voteStatus, }) }; onVoteDialogAccept = async () => { return new Promise((resolve, reject) => { ConnectionManager.getInstance().authenticatedRequest( "elections/vote", ["vote"], [parseInt(this.state.selectedTeam)]) .then(() => { this.onVoteDialogDismiss(true); resolve(); }) .catch((error: number) => { this.onVoteDialogDismiss(false); this.showErrorDialog(error); resolve(); }); }); }; showErrorDialog = (error: number) => this.setState({ errorDialogVisible: true, currentError: error, }); onErrorDialogDismiss = () => { this.setState({errorDialogVisible: false}); this.reloadData(); }; getContent() { if (!this.isVoteStarted()) return this.getTeaseVoteCard(); else if (this.isVoteRunning() && (!this.hasVoted && !this.state.hasVoted)) return this.getVoteCard(); else if (!this.isResultStarted()) return this.getWaitVoteCard(); else if (this.isResultRunning()) return this.getVoteResultCard(); else return null; } getTitleCard() { return ( } /> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rhoncus porttitor suscipit. Quisque hendrerit, quam id vestibulum vestibulum, lorem nisi hendrerit nisi, a eleifend sapien diam ut elit. Curabitur sit amet vulputate lectus. Donec semper cursus sapien vel finibus. Sed et venenatis turpis. Fusce malesuada magna urna, sed vehicula sem luctus in. Vivamus faucibus vel eros a ultricies. In sed laoreet ante, luctus mattis tellus. Etiam vitae ipsum sagittis, consequat purus sed, blandit risus. ); } onVoteSelectionChange = (team: string) => { this.setState({selectedTeam: team}) }; onVotePress = () => { this.showVoteDialog(); }; voteKeyExtractor = (item: Object) => item.id.toString(); voteRenderItem = ({item}: Object) => ; /** * The user has not voted yet, and the votes are open */ getVoteCard() { return ( } /> {/*$FlowFixMe*/} ); } sortByVotes = (a: Object, b: Object) => b.votes - a.votes; getTotalVotes() { let count = 0; for (let i = 0; i < this.teams.length; i++) { count += this.teams[i].votes; } return count; } getWinnerId() { return this.teams[0].id; } /** * Votes have ended, results can be displayed */ getVoteResultCard() { this.totalVotes = this.getTotalVotes(); this.teams.sort(this.sortByVotes); return ( } /> TOTAL VOTES : {this.totalVotes} {/*$FlowFixMe*/} ); } resultRenderItem = ({item}: Object) => { const isWinner = this.getWinnerId() === item.id; return ( isWinner ? : null} titleStyle={{ color: isWinner ? this.colors.primary : this.colors.text }} style={{padding: 0}} /> ); }; /** * Vote will open shortly */ getTeaseVoteCard() { return ( } /> VOTE STARTS AT {this.getDateString(this.dates.date_begin, this.datesString.date_begin)} ); } /** * Votes have ended waiting for results */ getWaitVoteCard() { return ( } /> { this.state.hasVoted ? VOTE SUBMITTED. THX FOR YOUR PARTICIPATION : null } { this.hasVoted ? THX FOR THE VOTE : null } { this.dates.date_result_begin !== null ? RESULTS AVAILABLE AT {this.getDateString(this.dates.date_result_begin, this.datesString.date_result_begin)} : RESULTS AVAILABLE SHORTLY } ); } render() { return ( ); } } const styles = StyleSheet.create({ card: { margin: 10, }, icon: { backgroundColor: 'transparent' }, }); export default withTheme(VoteScreen);