forked from vergnet/application-amicale
Improve vote screens to match linter
This commit is contained in:
parent
0a9e0eb0ca
commit
142b861ccb
5 changed files with 394 additions and 359 deletions
|
@ -2,36 +2,38 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {View} from 'react-native';
|
import {View} from 'react-native';
|
||||||
import {Headline, withTheme} from "react-native-paper";
|
import {Headline, withTheme} from 'react-native-paper';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from '../../../managers/ThemeManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
theme: CustomTheme
|
theme: CustomTheme,
|
||||||
}
|
};
|
||||||
|
|
||||||
class VoteNotAvailable extends React.Component<Props> {
|
class VoteNotAvailable extends React.Component<PropsType> {
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
render(): React.Node {
|
||||||
return false;
|
const {props} = this;
|
||||||
}
|
return (
|
||||||
|
<View
|
||||||
render() {
|
style={{
|
||||||
return (
|
width: '100%',
|
||||||
<View style={{
|
marginTop: 10,
|
||||||
width: "100%",
|
marginBottom: 10,
|
||||||
marginTop: 10,
|
}}>
|
||||||
marginBottom: 10,
|
<Headline
|
||||||
}}>
|
style={{
|
||||||
<Headline
|
color: props.theme.colors.textDisabled,
|
||||||
style={{
|
textAlign: 'center',
|
||||||
color: this.props.theme.colors.textDisabled,
|
}}>
|
||||||
textAlign: "center",
|
{i18n.t('screens.vote.noVote')}
|
||||||
}}
|
</Headline>
|
||||||
>{i18n.t("screens.vote.noVote")}</Headline>
|
</View>
|
||||||
</View>
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(VoteNotAvailable);
|
export default withTheme(VoteNotAvailable);
|
||||||
|
|
|
@ -1,116 +1,134 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Avatar, Card, List, ProgressBar, Subheading, withTheme} from "react-native-paper";
|
import {
|
||||||
import {FlatList, StyleSheet} from "react-native";
|
Avatar,
|
||||||
|
Card,
|
||||||
|
List,
|
||||||
|
ProgressBar,
|
||||||
|
Subheading,
|
||||||
|
withTheme,
|
||||||
|
} from 'react-native-paper';
|
||||||
|
import {FlatList, StyleSheet} from 'react-native';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import type {team} from "../../../screens/Amicale/VoteScreen";
|
import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen';
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from '../../../managers/ThemeManager';
|
||||||
|
|
||||||
|
type PropsType = {
|
||||||
type Props = {
|
teams: Array<VoteTeamType>,
|
||||||
teams: Array<team>,
|
dateEnd: string,
|
||||||
dateEnd: string,
|
theme: CustomTheme,
|
||||||
theme: CustomTheme,
|
};
|
||||||
}
|
|
||||||
|
|
||||||
class VoteResults extends React.Component<Props> {
|
|
||||||
|
|
||||||
totalVotes: number;
|
|
||||||
winnerIds: Array<number>;
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super();
|
|
||||||
props.teams.sort(this.sortByVotes);
|
|
||||||
this.getTotalVotes(props.teams);
|
|
||||||
this.getWinnerIds(props.teams);
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortByVotes = (a: team, b: team) => b.votes - a.votes;
|
|
||||||
|
|
||||||
getTotalVotes(teams: Array<team>) {
|
|
||||||
this.totalVotes = 0;
|
|
||||||
for (let i = 0; i < teams.length; i++) {
|
|
||||||
this.totalVotes += teams[i].votes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getWinnerIds(teams: Array<team>) {
|
|
||||||
let max = teams[0].votes;
|
|
||||||
this.winnerIds = [];
|
|
||||||
for (let i = 0; i < teams.length; i++) {
|
|
||||||
if (teams[i].votes === max)
|
|
||||||
this.winnerIds.push(teams[i].id);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
voteKeyExtractor = (item: team) => item.id.toString();
|
|
||||||
|
|
||||||
resultRenderItem = ({item}: { item: team }) => {
|
|
||||||
const isWinner = this.winnerIds.indexOf(item.id) !== -1;
|
|
||||||
const isDraw = this.winnerIds.length > 1;
|
|
||||||
const colors = this.props.theme.colors;
|
|
||||||
return (
|
|
||||||
<Card style={{
|
|
||||||
marginTop: 10,
|
|
||||||
elevation: isWinner ? 5 : 3,
|
|
||||||
}}>
|
|
||||||
<List.Item
|
|
||||||
title={item.name}
|
|
||||||
description={item.votes + ' ' + i18n.t('screens.vote.results.votes')}
|
|
||||||
left={props => isWinner
|
|
||||||
? <List.Icon {...props} icon={isDraw ? "trophy-outline" : "trophy"} color={colors.primary}/>
|
|
||||||
: null}
|
|
||||||
titleStyle={{
|
|
||||||
color: isWinner
|
|
||||||
? colors.primary
|
|
||||||
: colors.text
|
|
||||||
}}
|
|
||||||
style={{padding: 0}}
|
|
||||||
/>
|
|
||||||
<ProgressBar progress={item.votes / this.totalVotes} color={colors.primary}/>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Title
|
|
||||||
title={i18n.t('screens.vote.results.title')}
|
|
||||||
subtitle={i18n.t('screens.vote.results.subtitle') + ' ' + this.props.dateEnd}
|
|
||||||
left={(props) => <Avatar.Icon
|
|
||||||
{...props}
|
|
||||||
icon={"podium-gold"}
|
|
||||||
/>}
|
|
||||||
/>
|
|
||||||
<Card.Content>
|
|
||||||
<Subheading>{i18n.t('screens.vote.results.totalVotes') + ' ' + this.totalVotes}</Subheading>
|
|
||||||
{/*$FlowFixMe*/}
|
|
||||||
<FlatList
|
|
||||||
data={this.props.teams}
|
|
||||||
keyExtractor={this.voteKeyExtractor}
|
|
||||||
renderItem={this.resultRenderItem}
|
|
||||||
/>
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
card: {
|
card: {
|
||||||
margin: 10,
|
margin: 10,
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
class VoteResults extends React.Component<PropsType> {
|
||||||
|
totalVotes: number;
|
||||||
|
|
||||||
|
winnerIds: Array<number>;
|
||||||
|
|
||||||
|
constructor(props: PropsType) {
|
||||||
|
super();
|
||||||
|
props.teams.sort(this.sortByVotes);
|
||||||
|
this.getTotalVotes(props.teams);
|
||||||
|
this.getWinnerIds(props.teams);
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTotalVotes(teams: Array<VoteTeamType>) {
|
||||||
|
this.totalVotes = 0;
|
||||||
|
for (let i = 0; i < teams.length; i += 1) {
|
||||||
|
this.totalVotes += teams[i].votes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getWinnerIds(teams: Array<VoteTeamType>) {
|
||||||
|
const max = teams[0].votes;
|
||||||
|
this.winnerIds = [];
|
||||||
|
for (let i = 0; i < teams.length; i += 1) {
|
||||||
|
if (teams[i].votes === max) this.winnerIds.push(teams[i].id);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortByVotes = (a: VoteTeamType, b: VoteTeamType): number => b.votes - a.votes;
|
||||||
|
|
||||||
|
voteKeyExtractor = (item: VoteTeamType): string => item.id.toString();
|
||||||
|
|
||||||
|
resultRenderItem = ({item}: {item: VoteTeamType}): React.Node => {
|
||||||
|
const isWinner = this.winnerIds.indexOf(item.id) !== -1;
|
||||||
|
const isDraw = this.winnerIds.length > 1;
|
||||||
|
const {props} = this;
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
style={{
|
||||||
|
marginTop: 10,
|
||||||
|
elevation: isWinner ? 5 : 3,
|
||||||
|
}}>
|
||||||
|
<List.Item
|
||||||
|
title={item.name}
|
||||||
|
description={`${item.votes} ${i18n.t('screens.vote.results.votes')}`}
|
||||||
|
left={({size}: {size: number}): React.Node =>
|
||||||
|
isWinner ? (
|
||||||
|
<List.Icon
|
||||||
|
size={size}
|
||||||
|
icon={isDraw ? 'trophy-outline' : 'trophy'}
|
||||||
|
color={props.theme.colors.primary}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
titleStyle={{
|
||||||
|
color: isWinner
|
||||||
|
? props.theme.colors.primary
|
||||||
|
: props.theme.colors.text,
|
||||||
|
}}
|
||||||
|
style={{padding: 0}}
|
||||||
|
/>
|
||||||
|
<ProgressBar
|
||||||
|
progress={item.votes / this.totalVotes}
|
||||||
|
color={props.theme.colors.primary}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render(): React.Node {
|
||||||
|
const {props} = this;
|
||||||
|
return (
|
||||||
|
<Card style={styles.card}>
|
||||||
|
<Card.Title
|
||||||
|
title={i18n.t('screens.vote.results.title')}
|
||||||
|
subtitle={`${i18n.t('screens.vote.results.subtitle')} ${
|
||||||
|
props.dateEnd
|
||||||
|
}`}
|
||||||
|
left={({size}: {size: number}): React.Node => (
|
||||||
|
<Avatar.Icon size={size} icon="podium-gold" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Card.Content>
|
||||||
|
<Subheading>{`${i18n.t('screens.vote.results.totalVotes')} ${
|
||||||
|
this.totalVotes
|
||||||
|
}`}</Subheading>
|
||||||
|
{/* $FlowFixMe */}
|
||||||
|
<FlatList
|
||||||
|
data={props.teams}
|
||||||
|
keyExtractor={this.voteKeyExtractor}
|
||||||
|
renderItem={this.resultRenderItem}
|
||||||
|
/>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default withTheme(VoteResults);
|
export default withTheme(VoteResults);
|
||||||
|
|
|
@ -1,137 +1,146 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Avatar, Button, Card, RadioButton} from "react-native-paper";
|
import {Avatar, Button, Card, RadioButton} from 'react-native-paper';
|
||||||
import {FlatList, StyleSheet, View} from "react-native";
|
import {FlatList, StyleSheet, View} from 'react-native';
|
||||||
import ConnectionManager from "../../../managers/ConnectionManager";
|
|
||||||
import LoadingConfirmDialog from "../../Dialogs/LoadingConfirmDialog";
|
|
||||||
import ErrorDialog from "../../Dialogs/ErrorDialog";
|
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import type {team} from "../../../screens/Amicale/VoteScreen";
|
import ConnectionManager from '../../../managers/ConnectionManager';
|
||||||
|
import LoadingConfirmDialog from '../../Dialogs/LoadingConfirmDialog';
|
||||||
|
import ErrorDialog from '../../Dialogs/ErrorDialog';
|
||||||
|
import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
teams: Array<team>,
|
teams: Array<VoteTeamType>,
|
||||||
onVoteSuccess: () => void,
|
onVoteSuccess: () => void,
|
||||||
onVoteError: () => void,
|
onVoteError: () => void,
|
||||||
}
|
};
|
||||||
|
|
||||||
type State = {
|
type StateType = {
|
||||||
selectedTeam: string,
|
selectedTeam: string,
|
||||||
voteDialogVisible: boolean,
|
voteDialogVisible: boolean,
|
||||||
errorDialogVisible: boolean,
|
errorDialogVisible: boolean,
|
||||||
currentError: number,
|
currentError: number,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
export default class VoteSelect extends React.PureComponent<Props, State> {
|
|
||||||
|
|
||||||
state = {
|
|
||||||
selectedTeam: "none",
|
|
||||||
voteDialogVisible: false,
|
|
||||||
errorDialogVisible: false,
|
|
||||||
currentError: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
onVoteSelectionChange = (team: string) => this.setState({selectedTeam: team});
|
|
||||||
|
|
||||||
voteKeyExtractor = (item: team) => item.id.toString();
|
|
||||||
|
|
||||||
voteRenderItem = ({item}: { item: team }) => <RadioButton.Item label={item.name} value={item.id.toString()}/>;
|
|
||||||
|
|
||||||
showVoteDialog = () => this.setState({voteDialogVisible: true});
|
|
||||||
|
|
||||||
onVoteDialogDismiss = () => this.setState({voteDialogVisible: false,});
|
|
||||||
|
|
||||||
onVoteDialogAccept = async () => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
ConnectionManager.getInstance().authenticatedRequest(
|
|
||||||
"elections/vote",
|
|
||||||
{"team": parseInt(this.state.selectedTeam)})
|
|
||||||
.then(() => {
|
|
||||||
this.onVoteDialogDismiss();
|
|
||||||
this.props.onVoteSuccess();
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.catch((error: number) => {
|
|
||||||
this.onVoteDialogDismiss();
|
|
||||||
this.showErrorDialog(error);
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
showErrorDialog = (error: number) => this.setState({
|
|
||||||
errorDialogVisible: true,
|
|
||||||
currentError: error,
|
|
||||||
});
|
|
||||||
|
|
||||||
onErrorDialogDismiss = () => {
|
|
||||||
this.setState({errorDialogVisible: false});
|
|
||||||
this.props.onVoteError();
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<View>
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Title
|
|
||||||
title={i18n.t('screens.vote.select.title')}
|
|
||||||
subtitle={i18n.t('screens.vote.select.subtitle')}
|
|
||||||
left={(props) =>
|
|
||||||
<Avatar.Icon
|
|
||||||
{...props}
|
|
||||||
icon={"alert-decagram"}
|
|
||||||
/>}
|
|
||||||
/>
|
|
||||||
<Card.Content>
|
|
||||||
<RadioButton.Group
|
|
||||||
onValueChange={this.onVoteSelectionChange}
|
|
||||||
value={this.state.selectedTeam}
|
|
||||||
>
|
|
||||||
{/*$FlowFixMe*/}
|
|
||||||
<FlatList
|
|
||||||
data={this.props.teams}
|
|
||||||
keyExtractor={this.voteKeyExtractor}
|
|
||||||
extraData={this.state.selectedTeam}
|
|
||||||
renderItem={this.voteRenderItem}
|
|
||||||
/>
|
|
||||||
</RadioButton.Group>
|
|
||||||
</Card.Content>
|
|
||||||
<Card.Actions>
|
|
||||||
<Button
|
|
||||||
icon="send"
|
|
||||||
mode="contained"
|
|
||||||
onPress={this.showVoteDialog}
|
|
||||||
style={{marginLeft: 'auto'}}
|
|
||||||
disabled={this.state.selectedTeam === "none"}
|
|
||||||
>
|
|
||||||
{i18n.t('screens.vote.select.sendButton')}
|
|
||||||
</Button>
|
|
||||||
</Card.Actions>
|
|
||||||
</Card>
|
|
||||||
<LoadingConfirmDialog
|
|
||||||
visible={this.state.voteDialogVisible}
|
|
||||||
onDismiss={this.onVoteDialogDismiss}
|
|
||||||
onAccept={this.onVoteDialogAccept}
|
|
||||||
title={i18n.t('screens.vote.select.dialogTitle')}
|
|
||||||
titleLoading={i18n.t('screens.vote.select.dialogTitleLoading')}
|
|
||||||
message={i18n.t('screens.vote.select.dialogMessage')}
|
|
||||||
/>
|
|
||||||
<ErrorDialog
|
|
||||||
visible={this.state.errorDialogVisible}
|
|
||||||
onDismiss={this.onErrorDialogDismiss}
|
|
||||||
errorCode={this.state.currentError}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
card: {
|
card: {
|
||||||
margin: 10,
|
margin: 10,
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default class VoteSelect extends React.PureComponent<
|
||||||
|
PropsType,
|
||||||
|
StateType,
|
||||||
|
> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
selectedTeam: 'none',
|
||||||
|
voteDialogVisible: false,
|
||||||
|
errorDialogVisible: false,
|
||||||
|
currentError: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onVoteSelectionChange = (teamName: string): void =>
|
||||||
|
this.setState({selectedTeam: teamName});
|
||||||
|
|
||||||
|
voteKeyExtractor = (item: VoteTeamType): string => item.id.toString();
|
||||||
|
|
||||||
|
voteRenderItem = ({item}: {item: VoteTeamType}): React.Node => (
|
||||||
|
<RadioButton.Item label={item.name} value={item.id.toString()} />
|
||||||
|
);
|
||||||
|
|
||||||
|
showVoteDialog = (): void => this.setState({voteDialogVisible: true});
|
||||||
|
|
||||||
|
onVoteDialogDismiss = (): void => this.setState({voteDialogVisible: false});
|
||||||
|
|
||||||
|
onVoteDialogAccept = async (): Promise<void> => {
|
||||||
|
return new Promise((resolve: () => void) => {
|
||||||
|
const {state} = this;
|
||||||
|
ConnectionManager.getInstance()
|
||||||
|
.authenticatedRequest('elections/vote', {
|
||||||
|
team: parseInt(state.selectedTeam, 10),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.onVoteDialogDismiss();
|
||||||
|
const {props} = this;
|
||||||
|
props.onVoteSuccess();
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error: number) => {
|
||||||
|
this.onVoteDialogDismiss();
|
||||||
|
this.showErrorDialog(error);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
showErrorDialog = (error: number): void =>
|
||||||
|
this.setState({
|
||||||
|
errorDialogVisible: true,
|
||||||
|
currentError: error,
|
||||||
|
});
|
||||||
|
|
||||||
|
onErrorDialogDismiss = () => {
|
||||||
|
this.setState({errorDialogVisible: false});
|
||||||
|
const {props} = this;
|
||||||
|
props.onVoteError();
|
||||||
|
};
|
||||||
|
|
||||||
|
render(): React.Node {
|
||||||
|
const {state, props} = this;
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Card style={styles.card}>
|
||||||
|
<Card.Title
|
||||||
|
title={i18n.t('screens.vote.select.title')}
|
||||||
|
subtitle={i18n.t('screens.vote.select.subtitle')}
|
||||||
|
left={({size}: {size: number}): React.Node => (
|
||||||
|
<Avatar.Icon size={size} icon="alert-decagram" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Card.Content>
|
||||||
|
<RadioButton.Group
|
||||||
|
onValueChange={this.onVoteSelectionChange}
|
||||||
|
value={state.selectedTeam}>
|
||||||
|
{/* $FlowFixMe */}
|
||||||
|
<FlatList
|
||||||
|
data={props.teams}
|
||||||
|
keyExtractor={this.voteKeyExtractor}
|
||||||
|
extraData={state.selectedTeam}
|
||||||
|
renderItem={this.voteRenderItem}
|
||||||
|
/>
|
||||||
|
</RadioButton.Group>
|
||||||
|
</Card.Content>
|
||||||
|
<Card.Actions>
|
||||||
|
<Button
|
||||||
|
icon="send"
|
||||||
|
mode="contained"
|
||||||
|
onPress={this.showVoteDialog}
|
||||||
|
style={{marginLeft: 'auto'}}
|
||||||
|
disabled={state.selectedTeam === 'none'}>
|
||||||
|
{i18n.t('screens.vote.select.sendButton')}
|
||||||
|
</Button>
|
||||||
|
</Card.Actions>
|
||||||
|
</Card>
|
||||||
|
<LoadingConfirmDialog
|
||||||
|
visible={state.voteDialogVisible}
|
||||||
|
onDismiss={this.onVoteDialogDismiss}
|
||||||
|
onAccept={this.onVoteDialogAccept}
|
||||||
|
title={i18n.t('screens.vote.select.dialogTitle')}
|
||||||
|
titleLoading={i18n.t('screens.vote.select.dialogTitleLoading')}
|
||||||
|
message={i18n.t('screens.vote.select.dialogMessage')}
|
||||||
|
/>
|
||||||
|
<ErrorDialog
|
||||||
|
visible={state.errorDialogVisible}
|
||||||
|
onDismiss={this.onErrorDialogDismiss}
|
||||||
|
errorCode={state.currentError}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Avatar, Card, Paragraph} from "react-native-paper";
|
import {Avatar, Card, Paragraph} from 'react-native-paper';
|
||||||
import {StyleSheet} from "react-native";
|
import {StyleSheet} from 'react-native';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
startDate: string,
|
startDate: string,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default class VoteTease extends React.Component<Props> {
|
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Title
|
|
||||||
title={i18n.t('screens.vote.tease.title')}
|
|
||||||
subtitle={i18n.t('screens.vote.tease.subtitle')}
|
|
||||||
left={props => <Avatar.Icon
|
|
||||||
{...props}
|
|
||||||
icon="vote"/>}
|
|
||||||
/>
|
|
||||||
<Card.Content>
|
|
||||||
<Paragraph>
|
|
||||||
{i18n.t('screens.vote.tease.message') + ' ' + this.props.startDate}
|
|
||||||
</Paragraph>
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
card: {
|
card: {
|
||||||
margin: 10,
|
margin: 10,
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default class VoteTease extends React.Component<PropsType> {
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): React.Node {
|
||||||
|
const {props} = this;
|
||||||
|
return (
|
||||||
|
<Card style={styles.card}>
|
||||||
|
<Card.Title
|
||||||
|
title={i18n.t('screens.vote.tease.title')}
|
||||||
|
subtitle={i18n.t('screens.vote.tease.subtitle')}
|
||||||
|
left={({size}: {size: number}): React.Node => (
|
||||||
|
<Avatar.Icon size={size} icon="vote" />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Card.Content>
|
||||||
|
<Paragraph>
|
||||||
|
{`${i18n.t('screens.vote.tease.message')} ${props.startDate}`}
|
||||||
|
</Paragraph>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,72 +1,78 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {ActivityIndicator, Card, Paragraph, withTheme} from "react-native-paper";
|
import {
|
||||||
import {StyleSheet} from "react-native";
|
ActivityIndicator,
|
||||||
|
Card,
|
||||||
|
Paragraph,
|
||||||
|
withTheme,
|
||||||
|
} from 'react-native-paper';
|
||||||
|
import {StyleSheet} from 'react-native';
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import type {CustomTheme} from "../../../managers/ThemeManager";
|
import type {CustomTheme} from '../../../managers/ThemeManager';
|
||||||
|
|
||||||
type Props = {
|
type PropsType = {
|
||||||
startDate: string | null,
|
startDate: string | null,
|
||||||
justVoted: boolean,
|
justVoted: boolean,
|
||||||
hasVoted: boolean,
|
hasVoted: boolean,
|
||||||
isVoteRunning: boolean,
|
isVoteRunning: boolean,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
};
|
||||||
|
|
||||||
class VoteWait extends React.Component<Props> {
|
|
||||||
|
|
||||||
shouldComponentUpdate() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const colors = this.props.theme.colors;
|
|
||||||
const startDate = this.props.startDate;
|
|
||||||
return (
|
|
||||||
<Card style={styles.card}>
|
|
||||||
<Card.Title
|
|
||||||
title={this.props.isVoteRunning
|
|
||||||
? i18n.t('screens.vote.wait.titleSubmitted')
|
|
||||||
: i18n.t('screens.vote.wait.titleEnded')}
|
|
||||||
subtitle={i18n.t('screens.vote.wait.subtitle')}
|
|
||||||
left={(props) => <ActivityIndicator {...props}/>}
|
|
||||||
/>
|
|
||||||
<Card.Content>
|
|
||||||
{
|
|
||||||
this.props.justVoted
|
|
||||||
? <Paragraph style={{color: colors.success}}>
|
|
||||||
{i18n.t('screens.vote.wait.messageSubmitted')}
|
|
||||||
</Paragraph>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.props.hasVoted
|
|
||||||
? <Paragraph style={{color: colors.success}}>
|
|
||||||
{i18n.t('screens.vote.wait.messageVoted')}
|
|
||||||
</Paragraph>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{
|
|
||||||
startDate != null
|
|
||||||
? <Paragraph>
|
|
||||||
{i18n.t('screens.vote.wait.messageDate') + ' ' + startDate}
|
|
||||||
</Paragraph>
|
|
||||||
: <Paragraph>{i18n.t('screens.vote.wait.messageDateUndefined')}</Paragraph>
|
|
||||||
}
|
|
||||||
</Card.Content>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
card: {
|
card: {
|
||||||
margin: 10,
|
margin: 10,
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
class VoteWait extends React.Component<PropsType> {
|
||||||
|
shouldComponentUpdate(): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(): React.Node {
|
||||||
|
const {props} = this;
|
||||||
|
const {startDate} = props;
|
||||||
|
return (
|
||||||
|
<Card style={styles.card}>
|
||||||
|
<Card.Title
|
||||||
|
title={
|
||||||
|
props.isVoteRunning
|
||||||
|
? i18n.t('screens.vote.wait.titleSubmitted')
|
||||||
|
: i18n.t('screens.vote.wait.titleEnded')
|
||||||
|
}
|
||||||
|
subtitle={i18n.t('screens.vote.wait.subtitle')}
|
||||||
|
left={({size}: {size: number}): React.Node => (
|
||||||
|
<ActivityIndicator size={size} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Card.Content>
|
||||||
|
{props.justVoted ? (
|
||||||
|
<Paragraph style={{color: props.theme.colors.success}}>
|
||||||
|
{i18n.t('screens.vote.wait.messageSubmitted')}
|
||||||
|
</Paragraph>
|
||||||
|
) : null}
|
||||||
|
{props.hasVoted ? (
|
||||||
|
<Paragraph style={{color: props.theme.colors.success}}>
|
||||||
|
{i18n.t('screens.vote.wait.messageVoted')}
|
||||||
|
</Paragraph>
|
||||||
|
) : null}
|
||||||
|
{startDate != null ? (
|
||||||
|
<Paragraph>
|
||||||
|
{`${i18n.t('screens.vote.wait.messageDate')} ${startDate}`}
|
||||||
|
</Paragraph>
|
||||||
|
) : (
|
||||||
|
<Paragraph>
|
||||||
|
{i18n.t('screens.vote.wait.messageDateUndefined')}
|
||||||
|
</Paragraph>
|
||||||
|
)}
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default withTheme(VoteWait);
|
export default withTheme(VoteWait);
|
||||||
|
|
Loading…
Reference in a new issue